Tool/software:
I use bit masks (my preference) to set bits in the TMS320F28388D microcontroller registers which works fine everywhere except that I am having problems clearing bits in the GPADAT data register; specifically, I can easily set specific bits using GPADAT |= aValue but when I try and clear specific bits using GPADAT &= clearMask bits with 1 will not clear to 0.
I think these values are correct with:
GPADAT defined as #define GPADAT (*((volatile Uint32 *)(GPIO_DAT_BASE_ADDRESS + GPADAT_OFFSET)))
with #define GPIO_DAT_BASE_ADDRESS 0x00007F00 and #define GPADAT_OFFSET 0x00000000 (just at the base address, but I use this form to facilitate setting up for other registers)
and with the value (aValue) being 4 bits in GPADAT bits 24 - 27 set up as aValue = aValue << 24
and with the mask (clearMask) to clear the positions before the OR'ing operation = 0xF0FFFFFF
so that I
aValue = aValue << 24 ; // To position the bits correctly
GPADAT &= clearMask; // To clear the respective bit positions in GPADAT
GPADAT |= aValue ; // To write the bit values to the respective positions in the data register
What happens is that when I start out with a zeroed GPADAT register, the ORing operation correctly writes aValue into the GPADAT register.
But after that, bit positions with a value of 1 don't get reset, by the AND operation but bit positions with 1 get writen by the OR operation so that eventually the 4-bit value is just 1111 (0xF).
I heard something about a clear-modify-set problem with the data register, so I tried substituting GPADAT &= clearMask; with GPACLEAR = clearMask2
where GPACLEAR is #define GPACLEAR (*((volatile Uint32 *)(GPIO_DAT_BASE_ADDRESS + GPACLEAR_OFFSET))) with #define GPACLEAR_OFFSET 0x00000004
and that did not work either (did not clear the 4 bits).
Finally, I got this to work by clearing each bit individually with this:
mask = 1;
GPADAT &= ~(mask << position) ;
But I would prefer to be able to just do it with a single mask in a single operation as i tried to do above.
Anybody see the problem? Thanks.
Hello,
Bit-wise read-modify-write operations should not be performed on this register. For bit-wise operations the GPxSET, GPxCLEAR, or GPxTOGGLE registers should be used instead. If direct writes to GPxDAT are necessary, the entire register should be written at one time.
Even though your mask was correct, this performs a read, then a bitwise AND, and then writes back—which violates the TRM guidance. I suggest to use GPACLEAR and GPASET instead.
Best Regards,
Masoud