lpcware

Unable to Update register using bitfield structure

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by mathseng on Thu Sep 18 23:31:13 MST 2014
Hi,
Can anyone advise me why I do not seem to be able to update registers using bitfield structs.

Specifically, when updating the PCLKSEL1 register, when using a bitfield struct, writing to one bitfield results in other fields being incorrectly updated. My example is updating PCLK_TIMER2, which is 2 bits at 13:12.


I have attached a source file which can be used to demonstrate the issue.
Below are snippets

Regards,
Mathseng

<code>
//Using the format to update TIMER2 with <anyPCLK value, eg PCLK1 ( divide by 1 clock)>, and then extract the PCLK value ALWAYS works
LPC_SC->PCLKSEL1 &= ~((0b11 << 12) | ((0b11 << 8) | (0b11 << 24))); // desired bitfield at 13:12 and reserved bitfields at 9:8, 25:24.
LPC_SC->PCLKSEL1 &= ~(0b11 << 12); // desired bitfield at 13:12, ignoring reserved bitfields at 9:8, 25:24.
LPC_SC->PCLKSEL1 |= (PCLK1 << 12);
PCLK_type pclk = ((LPC_SC->PCLKSEL1) & (0b11 << 12)) >> 12;

//Using a bitfield struct to read the register always works, but updating the register results in other fields being corrupted.
volatile PCLKSEL1_Type * pClkSel = (PCLKSEL1_Type*)&(LPC_SC->PCLKSEL1);
pClkSel->PCLK_TIMER2 = PCLK1;// FAILS with other register field values being corrupted
PCLK_type pValu = pClkSel->PCLK_TIMER2;// Always works

//Using the same bitfield struct to operate on a memory variable ALWAYS works correctly:
volatile uint32_t memVar = 0;
volatile PCLKSEL1_Type * pMemVar = (PCLKSEL1_Type*)&memVar ;
pMemVar ->PCLK_TIMER2 = PCLK1;// Always works
PCLK_type memClk = pMemVar ->PCLK_TIMER2;// Always works
</code>

Original Attachment has been moved to: WriteRegFail.c.zip

Outcomes