Commit c6983e3c authored by Dave Hylands's avatar Dave Hylands Committed by Damien George
Browse files

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
parent f2a21a24
...@@ -556,6 +556,12 @@ void TIM1_TRG_COM_TIM17_IRQHandler(void) { ...@@ -556,6 +556,12 @@ void TIM1_TRG_COM_TIM17_IRQHandler(void) {
} }
#endif #endif
void TIM1_CC_IRQHandler(void) {
IRQ_ENTER(TIM1_CC_IRQn);
timer_irq_handler(1);
IRQ_EXIT(TIM1_CC_IRQn);
}
void TIM2_IRQHandler(void) { void TIM2_IRQHandler(void) {
IRQ_ENTER(TIM2_IRQn); IRQ_ENTER(TIM2_IRQn);
timer_irq_handler(2); timer_irq_handler(2);
...@@ -581,18 +587,23 @@ void TIM5_IRQHandler(void) { ...@@ -581,18 +587,23 @@ void TIM5_IRQHandler(void) {
IRQ_EXIT(TIM5_IRQn); IRQ_EXIT(TIM5_IRQn);
} }
#if defined(TIM6) // STM32F401 doesn't have TIM6
void TIM6_DAC_IRQHandler(void) { void TIM6_DAC_IRQHandler(void) {
IRQ_ENTER(TIM6_DAC_IRQn); IRQ_ENTER(TIM6_DAC_IRQn);
timer_irq_handler(6); timer_irq_handler(6);
IRQ_EXIT(TIM6_DAC_IRQn); IRQ_EXIT(TIM6_DAC_IRQn);
} }
#endif
#if defined(TIM7) // STM32F401 doesn't have TIM7
void TIM7_IRQHandler(void) { void TIM7_IRQHandler(void) {
IRQ_ENTER(TIM7_IRQn); IRQ_ENTER(TIM7_IRQn);
timer_irq_handler(7); timer_irq_handler(7);
IRQ_EXIT(TIM7_IRQn); IRQ_EXIT(TIM7_IRQn);
} }
#endif
#if defined(TIM8) // STM32F401 doesn't have TIM8
void TIM8_BRK_TIM12_IRQHandler(void) { void TIM8_BRK_TIM12_IRQHandler(void) {
IRQ_ENTER(TIM8_BRK_TIM12_IRQn); IRQ_ENTER(TIM8_BRK_TIM12_IRQn);
timer_irq_handler(12); timer_irq_handler(12);
...@@ -614,11 +625,18 @@ void TIM8_UP_IRQHandler(void) { ...@@ -614,11 +625,18 @@ void TIM8_UP_IRQHandler(void) {
} }
#endif #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) { void TIM8_TRG_COM_TIM14_IRQHandler(void) {
IRQ_ENTER(TIM8_TRG_COM_TIM14_IRQn); IRQ_ENTER(TIM8_TRG_COM_TIM14_IRQn);
timer_irq_handler(14); timer_irq_handler(14);
IRQ_EXIT(TIM8_TRG_COM_TIM14_IRQn); IRQ_EXIT(TIM8_TRG_COM_TIM14_IRQn);
} }
#endif
// UART/USART IRQ handlers // UART/USART IRQ handlers
void USART1_IRQHandler(void) { void USART1_IRQHandler(void) {
......
...@@ -603,6 +603,13 @@ STATIC mp_obj_t pyb_timer_init_helper(pyb_timer_obj_t *self, mp_uint_t n_args, 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) // set IRQ priority (if not a special timer)
if (self->tim_id != 3 && self->tim_id != 5) { if (self->tim_id != 3 && self->tim_id != 5) {
HAL_NVIC_SetPriority(self->irqn, IRQ_PRI_TIMX, IRQ_SUBPRI_TIMX); 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 // 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 ...@@ -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) { if (chan->callback == mp_const_none) {
HAL_TIM_PWM_Start(&self->tim, TIMER_CHANNEL(chan)); HAL_TIM_PWM_Start(&self->tim, TIMER_CHANNEL(chan));
} else { } 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) // Start the complimentary channel too (if its supported)
if (IS_TIM_CCXN_INSTANCE(self->tim.Instance, TIMER_CHANNEL(chan))) { 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 ...@@ -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) { if (chan->callback == mp_const_none) {
HAL_TIM_OC_Start(&self->tim, TIMER_CHANNEL(chan)); HAL_TIM_OC_Start(&self->tim, TIMER_CHANNEL(chan));
} else { } 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) // Start the complimentary channel too (if its supported)
if (IS_TIM_CCXN_INSTANCE(self->tim.Instance, TIMER_CHANNEL(chan))) { 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 ...@@ -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) { if (chan->callback == mp_const_none) {
HAL_TIM_IC_Start(&self->tim, TIMER_CHANNEL(chan)); HAL_TIM_IC_Start(&self->tim, TIMER_CHANNEL(chan));
} else { } else {
HAL_TIM_IC_Start_IT(&self->tim, TIMER_CHANNEL(chan)); pyb_timer_channel_callback(chan, chan->callback);
} }
break; break;
} }
...@@ -1294,7 +1301,16 @@ STATIC mp_obj_t pyb_timer_channel_callback(mp_obj_t self_in, mp_obj_t callback) ...@@ -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; self->callback = mp_const_none;
} else if (mp_obj_is_callable(callback)) { } else if (mp_obj_is_callable(callback)) {
self->callback = 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 // start timer, so that it interrupts on overflow
switch (self->mode) { switch (self->mode) {
case CHANNEL_MODE_PWM_NORMAL: case CHANNEL_MODE_PWM_NORMAL:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment