2017-08-16 08:33 AM
In TIMERS/03_InputCapureOnTI1/main.c and TIMERS/04_PWM_Input/main.c the flags after an interrupt are being cleared this way:
TIMx->SR = ~(TIM_SR_CC1OF | TIM_SR_CC1IF); /* Clear the flags */
Shouldn't it be like below?
TIMx->SR &= ~(TIM_SR_CC1OF | TIM_SR_CC1IF); /* Clear the flags */
#timer #stm32snippetsl0 #bugSolved! Go to Solution.
2017-08-16 09:22 AM
No, version with and is wrong. RMW operation for clearing flags is very bad idea.
2017-08-16 09:22 AM
No, version with and is wrong. RMW operation for clearing flags is very bad idea.
2017-08-16 10:18 AM
No this is a recurrent issue because people don't read and understand the manual and implementation.
RMW creates a hazard, it is not atomic, and the TIM can go through several cycles between the read and write operations.
Bit-Banding the TIM->SR is also highly hazardous, again not atomic from the peripherals perspective.
A singular write is contained to a cycle of the TIM.
The peripheral registers should not be viewed a memory cells, but as combinational logic.
2017-08-16 12:28 PM
From the user point of view: if a register bit is marked as rc_w0 (or rc_w1) in the RM, it means extra circuitry which is there for a reason...
J\W
2017-08-16 12:40 PM
I've covered this in multiple threads over many years, but ..
The nature of the hazard is when you AND something with ZERO it becomes ZERO, and you have a race condition here where the initial read of the SR might have a number of interrupts flagged as ZERO, and these bits may subsequently flag as ONE, and the RMW form will stomp on them, indiscriminately.
2017-08-17 03:50 AM
Thank you, now I understand the advantage of the fact that writing 1 into a bit marked as rc_w0 (or writing 0 into rc_w1) is ignored and this is how one issues atomic writes with changing only the desired bits without touching the others, instead of doing a RMW.