TMS320F28388D: Problem Clearing Bits with Bit Mask in the GPADAT Register

Part Number: TMS320F28388D

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.

  • Note that clearMask2 = 0x0F000000

    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