From c6983e3ce0bb9708afabb9fb7cbdf54ba46fb594 Mon Sep 17 00:00:00 2001 From: Dave Hylands Date: Thu, 18 Aug 2016 20:47:49 -0700 Subject: [PATCH] stmhal: Fix timer capture/compare interrupt handling for TIM1 and TIM8. It turns out that TIM1 and TIM8 have their own Capture/Compare interrupt vector. For all of the other timers, the capture/compare interrupt vector is the same as the update vector. So we need to add handlers for these vectors and enable them when using capture/compare callbacks. During testing of this, I also found that passing a channel callback into the channel constructor would not enable interrupts properly. I tested using: ``` >>> pyb.Timer(1, freq=4).channel(1, pyb.Timer.OC_TOGGLE, callback=lambda t: print('.', end='')) ``` I tested the above with channels 1, 4, and 8 --- stmhal/stm32_it.c | 18 ++++++++++++++++++ stmhal/timer.c | 24 ++++++++++++++++++++---- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/stmhal/stm32_it.c b/stmhal/stm32_it.c index c9af20ce58..d2f8c271c4 100644 --- a/stmhal/stm32_it.c +++ b/stmhal/stm32_it.c @@ -556,6 +556,12 @@ void TIM1_TRG_COM_TIM17_IRQHandler(void) { } #endif +void TIM1_CC_IRQHandler(void) { + IRQ_ENTER(TIM1_CC_IRQn); + timer_irq_handler(1); + IRQ_EXIT(TIM1_CC_IRQn); +} + void TIM2_IRQHandler(void) { IRQ_ENTER(TIM2_IRQn); timer_irq_handler(2); @@ -581,18 +587,23 @@ void TIM5_IRQHandler(void) { IRQ_EXIT(TIM5_IRQn); } +#if defined(TIM6) // STM32F401 doesn't have TIM6 void TIM6_DAC_IRQHandler(void) { IRQ_ENTER(TIM6_DAC_IRQn); timer_irq_handler(6); IRQ_EXIT(TIM6_DAC_IRQn); } +#endif +#if defined(TIM7) // STM32F401 doesn't have TIM7 void TIM7_IRQHandler(void) { IRQ_ENTER(TIM7_IRQn); timer_irq_handler(7); IRQ_EXIT(TIM7_IRQn); } +#endif +#if defined(TIM8) // STM32F401 doesn't have TIM8 void TIM8_BRK_TIM12_IRQHandler(void) { IRQ_ENTER(TIM8_BRK_TIM12_IRQn); timer_irq_handler(12); @@ -614,11 +625,18 @@ void TIM8_UP_IRQHandler(void) { } #endif +void TIM8_CC_IRQHandler(void) { + IRQ_ENTER(TIM8_CC_IRQn); + timer_irq_handler(8); + IRQ_EXIT(TIM8_CC_IRQn); +} + void TIM8_TRG_COM_TIM14_IRQHandler(void) { IRQ_ENTER(TIM8_TRG_COM_TIM14_IRQn); timer_irq_handler(14); IRQ_EXIT(TIM8_TRG_COM_TIM14_IRQn); } +#endif // UART/USART IRQ handlers void USART1_IRQHandler(void) { diff --git a/stmhal/timer.c b/stmhal/timer.c index f1f14f3315..e8b29eb97f 100644 --- a/stmhal/timer.c +++ b/stmhal/timer.c @@ -603,6 +603,13 @@ STATIC mp_obj_t pyb_timer_init_helper(pyb_timer_obj_t *self, mp_uint_t n_args, c // set IRQ priority (if not a special timer) if (self->tim_id != 3 && self->tim_id != 5) { HAL_NVIC_SetPriority(self->irqn, IRQ_PRI_TIMX, IRQ_SUBPRI_TIMX); + if (self->tim_id == 1) { + HAL_NVIC_SetPriority(TIM1_CC_IRQn, IRQ_PRI_TIMX, IRQ_SUBPRI_TIMX); + #if defined(TIM8) + } else if (self->tim_id == 8) { + HAL_NVIC_SetPriority(TIM8_CC_IRQn, IRQ_PRI_TIMX, IRQ_SUBPRI_TIMX); + #endif + } } // init TIM @@ -932,7 +939,7 @@ STATIC mp_obj_t pyb_timer_channel(mp_uint_t n_args, const mp_obj_t *pos_args, mp if (chan->callback == mp_const_none) { HAL_TIM_PWM_Start(&self->tim, TIMER_CHANNEL(chan)); } else { - HAL_TIM_PWM_Start_IT(&self->tim, TIMER_CHANNEL(chan)); + pyb_timer_channel_callback(chan, chan->callback); } // Start the complimentary channel too (if its supported) if (IS_TIM_CCXN_INSTANCE(self->tim.Instance, TIMER_CHANNEL(chan))) { @@ -970,7 +977,7 @@ STATIC mp_obj_t pyb_timer_channel(mp_uint_t n_args, const mp_obj_t *pos_args, mp if (chan->callback == mp_const_none) { HAL_TIM_OC_Start(&self->tim, TIMER_CHANNEL(chan)); } else { - HAL_TIM_OC_Start_IT(&self->tim, TIMER_CHANNEL(chan)); + pyb_timer_channel_callback(chan, chan->callback); } // Start the complimentary channel too (if its supported) if (IS_TIM_CCXN_INSTANCE(self->tim.Instance, TIMER_CHANNEL(chan))) { @@ -997,7 +1004,7 @@ STATIC mp_obj_t pyb_timer_channel(mp_uint_t n_args, const mp_obj_t *pos_args, mp if (chan->callback == mp_const_none) { HAL_TIM_IC_Start(&self->tim, TIMER_CHANNEL(chan)); } else { - HAL_TIM_IC_Start_IT(&self->tim, TIMER_CHANNEL(chan)); + pyb_timer_channel_callback(chan, chan->callback); } break; } @@ -1294,7 +1301,16 @@ STATIC mp_obj_t pyb_timer_channel_callback(mp_obj_t self_in, mp_obj_t callback) self->callback = mp_const_none; } else if (mp_obj_is_callable(callback)) { self->callback = callback; - HAL_NVIC_EnableIRQ(self->timer->irqn); + uint8_t tim_id = self->timer->tim_id; + if (tim_id == 1) { + HAL_NVIC_EnableIRQ(TIM1_CC_IRQn); + #if defined(TIM8) // STM32F401 doesn't have a TIM8 + } else if (tim_id == 8) { + HAL_NVIC_EnableIRQ(TIM8_CC_IRQn); + #endif + } else { + HAL_NVIC_EnableIRQ(self->timer->irqn); + } // start timer, so that it interrupts on overflow switch (self->mode) { case CHANNEL_MODE_PWM_NORMAL: