This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

peripheral register access RMW vs Bit Banding

Hello Forum,

I'am porting a USB base driver from 16Bit CISC MCU to Cortex M3 MCU.

For set/clear peripheral registers at the CISC MCU I've used C-Standard RMW Operations (|=, &=) which resulted in atomic bit operations.

During porting I’ve used the also the RMW operations, because some registers are used exclusively in the interrupt context, there is no context switch. So my thought is that RMW is sufficient for set/clear bits in peripheral register.

Example this shows the problem:

This instruction sequence ( Bit Clear) fails to clear the interrupt factor (including asm mixed mode view)

Fullscreen
1
2
3
4
5
6
7
8
9
*EPnS0 &= ~MASK_EPS_DRQ; // Interrupt bestätigen
0x4ea8: 0xf8ba 0x1000 LDRH.W R1, [R10]
0x4eac: 0xf64f 0x30ff MOVW R0, #64511 ; 0xfbff
0x4eb0: 0x4001 ANDS R1, R1, R0
0x4eb2: 0xf8aa 0x1000 STRH.W R1, [R10]
*EPnS0 |= MASK_EPS_DRQIE; // Sendeinterrupt einschalten
0x4eb6: 0xf8ba 0x0000 LDRH.W R0, [R10]
0x4eba: 0xf450 0x4080 ORRS.W R0, R0, #16384 ; 0x4000
0x4ebe: 0xf8aa 0x0000 STRH.W R0, [R10]
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

This instruction sequence do the job correctly:

Fullscreen
1
2
3
4
5
6
7
8
9
bFM3_USB0_EP1S_DRQ = 0;
0x4ec2: 0x2000 MOVS R0, #0
0x4ec4: 0xf8df 0x17e4 LDR.W R1, [PC, #0x7e4] ; 0x428429a8 (1115957672)
0x4ec8: 0x6008 STR R0, [R1]
bFM3_USB0_EP1S_DRQIE = 1;
0x4eca: 0x2001 MOVS R0, #1
0x4ecc: 0xf8df 0x17e0 LDR.W R1, [PC, #0x7e0] ; 0x428429b8 (1115957688)
0x4ed0: 0x6008 STR R0, [R1]
0x4ed2: 0xe00c B.N 0x4eee
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

The MPU Setup for the MCU peripheral Area is

Fullscreen
1
2
3
4
5
// Peripherals + 32Mbyte Bit band alias
MPU->RBAR = ARM_MPU_RBAR(3, 0x40000000);
MPU->RASR = ARM_MPU_RASR(1, ARM_MPU_AP_FULL, 0, 1, 0, 1, 0, ARM_MPU_REGION_SIZE_64MB);
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

 

As far as I know bit banding is necessary to prevent race conditions between shared context accesses of any memory/peripheral area. The section decribed above is only access during the peripherals interrupt Handler.

Why the RMW Operations fails and bit band operation do the correct job in this case?

 

Regards

Lorenz

Fullscreen
1
2
3
4
5
6
7
8
9
*EPnS0 &= ~MASK_EPS_DRQ; // Interrupt bestätigen
0x4ea8: 0xf8ba 0x1000 LDRH.W R1, [R10]
0x4eac: 0xf64f 0x30ff MOVW R0, #64511 ; 0xfbff
0x4eb0: 0x4001 ANDS R1, R1, R0
0x4eb2: 0xf8aa 0x1000 STRH.W R1, [R10]
*EPnS0 |= MASK_EPS_DRQIE; // Sendeinterrupt einschalten
0x4eb6: 0xf8ba 0x0000 LDRH.W R0, [R10]
0x4eba: 0xf450 0x4080 ORRS.W R0, R0, #16384 ; 0x4000
0x4ebe: 0xf8aa 0x0000 STRH.W R0, [R10]
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

0