Skip to content

Commit b22ad15

Browse files
committed
platform/technic_hub: fix race condition in TIM2 irq handler
This fixes a race condition where an interrupt status flag is set while the interrupt handler is running. We were clearing all flags each time the handler ran but now we only clear the flags we have handled. This was triggered when CCR1 was set to 3, causing the green LED to turn on and stay on all of the time. Fixes: pybricks/support#224
1 parent ad0137a commit b22ad15

File tree

1 file changed

+4
-1
lines changed

1 file changed

+4
-1
lines changed

lib/pbio/platform/technic_hub/platform.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,12 +205,14 @@ const pbdrv_pwm_stm32_tim_platform_data_t
205205
// the GPIOs in the timer interrupt handler.
206206
void TIM2_IRQHandler(void) {
207207
uint32_t sr = TIM2->SR;
208+
uint32_t handled = TIM_SR_UIF;
208209

209210
// green LED
210211
if (TIM2->CCR1 == 0 || sr & TIM_SR_CC1IF) {
211212
// If channel 1 duty cycle is 0 or we have reached the CC1 count,
212213
// turn the GPIO off
213214
GPIOA->BRR = GPIO_BRR_BR11;
215+
handled |= TIM_SR_CC1IF;
214216
} else if (sr & TIM_SR_UIF) {
215217
// otherwise if it is the start of the next PWM period turn the GPIO on
216218
GPIOA->BSRR = GPIO_BSRR_BS11;
@@ -221,13 +223,14 @@ void TIM2_IRQHandler(void) {
221223
// If channel 2 duty cycle is 0 or we have reached the CC2 count,
222224
// turn the GPIO off
223225
GPIOB->BRR = GPIO_BRR_BR15;
226+
handled |= TIM_SR_CC2IF;
224227
} else if (sr & TIM_SR_UIF) {
225228
// otherwise if it is the start of the next PWM period turn the GPIO on
226229
GPIOB->BSRR = GPIO_BSRR_BS15;
227230
}
228231

229232
// clear interrupts
230-
TIM2->SR = 0;
233+
TIM2->SR &= ~handled;
231234
}
232235

233236
// Reset

0 commit comments

Comments
 (0)