PIC24F - Set LATx specific pins without effecting the other pins - microcontroller

Is there a way to set specific port pins without effecting other pins at the same port?
For example:
I used LATB[13:6] for 7-segment LCD, the rest LATB bits are used for other purposes.
Now I need to set LATB = 0x003F for display '0', if i do this the rest of the bits are changed.
Someone can help me?

You'll have to split the operation, since you can't address specifically bits 6 to 13 in a 16 bit register. For instance, assuming LATB is a 16 bit register on which bits 6 to 13 (a range of 8 bits) map to a 7-segment display with period (making 8 segments), and we want to set those pins in particular to 0x3f = 0b00111111, we can do:
LATB = (LATB & ~(0xff<<6)) | (0x3f<<6);
0xff is a bit mask of which bits we want to affect, representing 8 bits, which we shift into position 6-13 using <<6.
However, this is not atomic; we are reading, masking out the bits we want to adjust, setting them to new values, and writing back the entire register including the preserved other bits. Thus we may need for instance to disable interrupts around such a line.
For many MCUs there are particular code paths supporting modification of single bits, or dedicated logic for clear/set. Those might mean that you could perform the adjustment without risking trampling another change if you stick to plainer operations, such as:
val = 0x3f;
LATB |= (val<<6); // set bits which should be set
LATB &= (val<<6) | ~(0xff<<6); // clear bits that should be clear
In this example, we're not doing the display update in one step, but each update we are making is left in a form the compiler might be able to optimize to a single instruction (IOR and AND, respectively).
Some processors also have instructions to access sections of a word like this, frequently named bitfield operations. I don't think PIC24 is among those. It does have single-bit access instructions, but they seem to either operate on the working file or require fixed bit positions, which means setting bit by bit would have to be unrolled.
C also does have a concept of bit fields, which means is is possible to define a struct interpretation of the latch register that does have a name for the bits you want to affect, but it's a fairly fragile method. You're writing architecture specific code anyway when relying on the particular register names. It is likely best to inspect documentation for your compiler and platform libraries.

Related

How to program a pressure sensor using the SPI Bus

I am using the STM32 Microcontroller (as part of the LoRa node MB1296D). I want to connect a pressure sensor (MS5803) to the LoRa node and program the sensor via the SPI Bus. Basically, this is all very new to me, which is why I looked up an example code
I am trying to understand this code and a couple of questions have come up:
the macros that are defined in the very beginning, what exactly is their purpose, and are the hexadecimal numbers inherent to the used microcontroller? - If I was to write a code from scratch, I figured I would start by defining macros for the GPIO Pins corresponding to SPI_SCK, SPI_MISO and SPI_MOSI
the function unsigned long cmd_adc(char cmd) contains a switch command, which I have absolutely no clue as on what is does. I mean it looks to me as if I am trying to set the resolution of the ADC, but how do I know the corresponding delay and why does the switch command contain the 0x0f ?
So. If you could find some time to give me a useful answer, that'd be great! Also, if you know any good readings with special focus on this topic, please tell me! I am trying to tackle this problem with little time available.
Your questions are basic C programming questions and are not really specific to this pressure sensor or example.
The macros are defined with hexadecimal numbers to make it clear that the values represent bit fields. It's very easy (and second nature for embedded software developers) to convert hexadecimal to binary. Read the register descriptions in the sensor's datasheet. The bits set in the hexadecimal values will correspond to meaningful bits in the sensor's register description.
switch (cmd & 0x0f) performs a bitwise AND of the cmd with 0x0f. The hexadecimal value 0x0f has the four least significant bits set. So the code is ignoring (i.e., masking off or zeroing out) the four most significant bits of cmd and considering only the four least significant bits of the cmd value.

synthesizable asynchronous fifo design towards an FPGA

I need some advice on how to design an asynchronous FIFO. I understand the meta stability issue when capturing data into a different clock domain, my question is how does using a two flip flop shift register assist in synchronization of write pointer and read pointer values for full and empty flag calculation.
When register captures a data of a different domain there is a possibility it can enter a metastable state and can settle to a unknown value, so how do u effectively resolve this issue.
Thanks
Your read and write pointers need to use gray encoding when transferred from one clock domain to the other. As you should know, only 1 bit of a gray counter is different between two consecutive values. Thus, metastability can affect only the one changing bit. After re-synchronization, the transferred pointer will be either the updated pointer or its previous value.
In either case, this is not a problem and only lead to pessimistic flags/count for your FIFO.
I use regular counter for my read/write pointer, and use the following functions to convert them to gray code. They are in VHDL, but you should get the idea:
function bin_to_gray(a: unsigned) return unsigned is
begin
return a xor ('0' & a(a'left downto 1));
end function bin_to_gray;
function gray_to_bin(a: unsigned) return unsigned is
variable ret : unsigned(a'range);
begin
ret(a'left) := a(a'left);
for i in a'left-1 downto 0 loop
ret(i) := ret(i+1) xor a(i);
end loop;
return ret;
end function gray_to_bin;
Jonathan explained it well.
I would just like to add a few points:
First, in addition to your 2-stage synchronizer registers you must also have a source register.
You can never feed signals from combinational logic into your 2-stage synchronizer, since combinational logic produce glitches.
You must also be aware that Verilog and VHDL has no built-in support for clock domain crossings and metastability.
Even if you create a proper 2-stage synchronizer to transfer the gray coded pointers, there is no guarantee that the synthesis tool does not change your synchronizers in a way which make it ineffective in protecting againsts metastability. Some synthesis tools try to detect synchronizers and leave them alone. Some don't. And in either case, you should not rely on it.
For a completely proper clock domain crossing, you must constrain the synchronizer and the source register using vendor-specific attributes and SDC timing constraints.

ATMEGA32 UART Communication

I am trying to do serial communication in ATMEGA32 and I have a question:
In asynchronous serial communication both UBRRH and UCSRC registers have same location. I don't know which conditions that location will act as UBRRH and for which conditions, it will act as UCSRC. I need different values for each register according to the work assigned to those registers
In the datasheet, they have mentioned the use of URSEL bit for selection betweem two registers but somehow I am not getting that.
The answer is: Yes, the URSEL bit. According to the datasheet:
When doing a write access of this I/O location, the high bit of the
value written, the USART Register Select (URSEL) bit, controls which
one of the two registers that will be written. If URSEL is zero during
a write operation, the UBRRH value will be updated. If URSEL is one,
the UCSRC setting will be updated.
This means, when you write to UCSRC, regardless of what value you want to put there, also set the URSEL bit (make sure that URSEL is 1):
UCSRC = (1<<URSEL)| ... whatever else ...
When you write to UBRRH, make sure that URSEL bit must is zero. Here are some different ways of doing that:
UBRRH = (0<<URSEL)| ... whatever else ... // just showing that URSEL isn't set
UBRRH = ...some value... // simple not setting URSEL
UBRRH = (someValue)&(~(1<<URSEL) // Ensuring that URSEL isn't set
URSEL bit is just a high bit. So whatever value you write to UCSRC, set (turn on, make 1) the high bit (bit 7). And when writing to UBRRH, make sure that bit 7 is cleared. Another way of thinking about it, every value you write to UBRRH must be under 128. And every value that you want to write to UCSRC, add 128 to it: this will turn on bit 7. This is just as a way of explanation, the code above is clearer.
How is this done? I don't know, I am not a uC designer. What seems likely is that the same IO location location is mapped to two different registers in the processor. Say you have a register named foo, and when you write a value to it the uC checks if the high bit is set. If it is it writes the value to internal memory location 1 and if it isn't it writes the value to internal memory location 2.
If you are using the URSEL bit correctly, then the values are being written correctly. Your testing not showing the correct values because you are not reading them propertly. Page 162 of the datasheet:
Doing a read access to the UBRRH or the UCSRC Register is a more
complex operation. How- ever, in most applications, it is rarely
necessary to read any of these registers.
The read access is controlled by a timed sequence. Reading the I/O
location once returns the UBRRH Register contents. If the register
location was read in previous system clock cycle, reading the register
in the current clock cycle will return the UCSRC contents. Note that
the timed sequence for reading the UCSRC is an atomic operation.
Interrupts must therefore be controlled (for example by disabling
interrupts globally) during the read operation.
So when your read UBRRH / UCSRC for the first time you get UBRRH. If you immediately read again you read UCSRC. But as the documentation suggests, there is no real reason to read these registers. It seems that you do not trust the datasheet, but this is a mistake: the datasheet is the best source of information about such matters: without datasheets we would be nowhere.

VHDL UCF - how to define a constraint that has no pin?

I'm working with some simple VGA driver code for use with the Xilinx Spartan 6 FPGA (via a Papilio Pro board). The code expects to have 4-bits of output per color, and so defines logic vectors for each color. However, my setup doesn't happen to provide the full 4 bits per color so I wanted to find a creative way to control this via the UCF.
The original UCF defined 4 pins for each color. In the case of blue, I only have two pins, so I chose to map the two I have to blues MSBs, thus:
NET Blue(0) IOSTANDARD=LVTTL; # N/C
NET Blue(1) IOSTANDARD=LVTTL; # N/C
NET Blue(2) LOC="P92" | IOSTANDARD=LVTTL; # to a pin
NET Blue(3) LOC="P87" | IOSTANDARD=LVTTL; # to a pin
(I totally omitted the first two constraints at first, and it still compiled and worked but complained about the inconsistent voltage standards (the absent ones defaulted to IOSTANDARD = LVCMOS25), thus throwing "WARNING:Place:838 - An IO Bus with more than one IO standard is found.")
The main warning is the one I'd like to know how to eliminate, preferably within the UCF:
WARNING:Place:837 - Partially locked IO Bus is found.
Following components of the bus are not locked:
Comp: Blue<1>
Comp: Blue<0>
What's the right way to map a net without a programmable pin location to a default value (logic '1' or '0', or perhaps a tri-state value) within the UCF in such a way as to eliminate this "Partially locked IO Bus" sort of warning?
My goal is that, in a setup with more or fewer bits per channel being driven by pins, only the UCF should need to change (not the source code). What I did works, despite the warnings... I'd just like to do it better and properly eliminate these warnings.
You've asked for pins within the top level of your code (on your entity). The tools therefore have to provide them. Hence you have to map them (otherwise it'll pick some random ones for you, which you usually don't want)
If those pins really have nowhere to go on the board and never will have, then remove them from the design completely (UCF and HDL).
Otherwise, you have to LOC them. You could add a PULLDOWN in the UCF to them to ensure they go to a low value.

What is the difference between using mark/space parity and parity none?

What is the purpose having created three type of parity bits that all define a state where the parity bit is precisely not used ?
"If the parity bit is present but not used, it may be referred to as mark parity (when the parity bit is always 1) or space parity (the bit is always 0)" - Wikipedia
There is a very simple and very useful reason to have mark or space parity that appears to be left out here: node address flagging.
Very low-power and/or small embedded systems sometimes utilize an industrial serial bus like RS485 or RS422. Perhaps many very tiny processors may be attached to the same bus.
These tiny devices don't want to waste power or processing time looking at every single character that comes in over the serial port. Most of the time, it's not something they're interested in.
So, you design a bus protocol that uses for example maybe 9 bits... 8 data bits and a mark/space parity bit. Each data packet contains exactly one byte or word (the node address) with the mark parity bit set. Everything else is space parity. Then, these tiny devices can simply wait around for a parity error interrupt. Once it get's the interrupt, it checks that byte. Is that my address? No, go back to sleep.
It's a very power-efficient system... and only 10% wasteful on bandwidth. In many environments, that's a very good trade-off.
So... if you've then got a PC-class system trying to TALK to these tiny devices, you need to be able to set/clear that parity bit. So, you set MARK parity when you transmit the node addresses, and SPACE parity everywhere else.
So there are five possibilities, not three: no parity, mark, space, odd and even. With no parity the extra bit is just omitted in the frame, often selected when the protocol is already checking for errors with a checksum or CRC or data corruption is not deemed likely or critical.
Nobody ever selects mark or space, that's just wasting bandwidth. Modulo some odd standard, like 9-bit data protocols that hardware vendors like to force you to buy their hardware since you have no real shot at reprogramming the UART on the fly without writing a driver.
Setting mark or space parity is useful if you're generating data to send to hardware that requires a parity bit (perhaps because it has a hard coded word length built into the electronics) but doesn't care what its value is.
RS485 requires 9 bits transmission, as described above. RS485 is widely used in industrial applications, whatever the controlled device 'size' (for instance there are many air conditioners or refrigerators offering a RS485 interface, not really 'tiny' things). RS485 allows up to 10Mbs throughput or distances up to 4000 feet. Using the parity bit to distinguish address/data bytes eases hardware implementation, each node of the network can have their own hardware to generate interrupts only if an address byte on the wire matches the node's address.
Very clear and helpful answers and remarks.
For those who find the concept perverse, relax; the term is a problem of semantics rather than information theory or engineering, the difficulty arising from the use of the word "parity".
"Mark" and "space" bits are not parity bits in those applications, and the term arises from the fact that they occupy the bit position in which a parity bit might be expected in other contexts. In reality they have nothing to do with parity, but are used for any relevant purpose where a constant bit value is needed, such as to mark the start of a byte or other signal, or as a delay,or to indicate the status of a signal as being data or address or the like.
Accordingly they sometimes are more logically called "stick (parity) bits", being stuck in "on" or "off" state. Sometimes they really are "don't cares".

Resources