Skip to content

Commit

Permalink
platform/technic_hub: fix race condition in TIM2 irq handler
Browse files Browse the repository at this point in the history
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
  • Loading branch information
dlech committed Jan 20, 2021
1 parent ad0137a commit b22ad15
Showing 1 changed file with 4 additions and 1 deletion.
5 changes: 4 additions & 1 deletion lib/pbio/platform/technic_hub/platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,12 +205,14 @@ const pbdrv_pwm_stm32_tim_platform_data_t
// the GPIOs in the timer interrupt handler.
void TIM2_IRQHandler(void) {
uint32_t sr = TIM2->SR;
uint32_t handled = TIM_SR_UIF;

// green LED
if (TIM2->CCR1 == 0 || sr & TIM_SR_CC1IF) {
// If channel 1 duty cycle is 0 or we have reached the CC1 count,
// turn the GPIO off
GPIOA->BRR = GPIO_BRR_BR11;
handled |= TIM_SR_CC1IF;
} else if (sr & TIM_SR_UIF) {
// otherwise if it is the start of the next PWM period turn the GPIO on
GPIOA->BSRR = GPIO_BSRR_BS11;
Expand All @@ -221,13 +223,14 @@ void TIM2_IRQHandler(void) {
// If channel 2 duty cycle is 0 or we have reached the CC2 count,
// turn the GPIO off
GPIOB->BRR = GPIO_BRR_BR15;
handled |= TIM_SR_CC2IF;
} else if (sr & TIM_SR_UIF) {
// otherwise if it is the start of the next PWM period turn the GPIO on
GPIOB->BSRR = GPIO_BSRR_BS15;
}

// clear interrupts
TIM2->SR = 0;
TIM2->SR &= ~handled;
}

// Reset
Expand Down

0 comments on commit b22ad15

Please sign in to comment.