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)
*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]
This instruction sequence do the job correctly:
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
The MPU Setup for the MCU peripheral Area is
// 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);
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?
Beside of the above suggestion, please check what you mean that RMW does not work here? Did it cause a fault or is the value in the targeted address not expected? If the later, you may check the value of the targeted address and then analyze.
Thank you for answering, you are correct, clearing the interrupt factor was propably lost, so my program flow didn't work as expected
View all questions in Cortex-M / M-Profile forum