Skip to content

Commit 49d8e5e

Browse files
dhylandsdpgeorge
authored andcommitted
stmhal: Fix a bug related to unhandled channel interrupts.
This also cleans up spurious interrupts which happen at timer initilaization time.
1 parent 3cc17c6 commit 49d8e5e

File tree

1 file changed

+15
-3
lines changed

1 file changed

+15
-3
lines changed

stmhal/timer.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -988,8 +988,17 @@ STATIC mp_obj_t pyb_timer_channel(mp_uint_t n_args, const mp_obj_t *pos_args, mp
988988
&& self->tim.Instance != TIM8 ) {
989989
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "encoder not supported on timer %d", self->tim_id));
990990
}
991+
992+
// Disable & clear the timer interrupt so that we don't trigger
993+
// an interrupt by initializing the timer.
994+
__HAL_TIM_DISABLE_IT(&self->tim, TIM_IT_UPDATE);
991995
HAL_TIM_Encoder_Init(&self->tim, &enc_config);
992996
__HAL_TIM_SetCounter(&self->tim, 0);
997+
if (self->callback != mp_const_none) {
998+
__HAL_TIM_CLEAR_FLAG(&self->tim, TIM_IT_UPDATE);
999+
__HAL_TIM_ENABLE_IT(&self->tim, TIM_IT_UPDATE);
1000+
}
1001+
HAL_TIM_Encoder_Start(&self->tim, TIM_CHANNEL_ALL);
9931002
break;
9941003
}
9951004

@@ -1095,9 +1104,12 @@ STATIC mp_obj_t pyb_timer_callback(mp_obj_t self_in, mp_obj_t callback) {
10951104
__HAL_TIM_DISABLE_IT(&self->tim, TIM_IT_UPDATE);
10961105
self->callback = mp_const_none;
10971106
} else if (mp_obj_is_callable(callback)) {
1107+
__HAL_TIM_DISABLE_IT(&self->tim, TIM_IT_UPDATE);
10981108
self->callback = callback;
1099-
// start timer, so that it interrupts on overflow
1100-
HAL_TIM_Base_Start_IT(&self->tim);
1109+
// start timer, so that it interrupts on overflow, but clear any
1110+
// pending interrupts which may have been set by initializing it.
1111+
__HAL_TIM_CLEAR_FLAG(&self->tim, TIM_IT_UPDATE);
1112+
HAL_TIM_Base_Start_IT(&self->tim); // This will re-enable the IRQ
11011113
HAL_NVIC_EnableIRQ(self->irqn);
11021114
} else {
11031115
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "callback must be None or a callable object"));
@@ -1330,7 +1342,7 @@ void timer_irq_handler(uint tim_id) {
13301342

13311343
// Finally, clear any remaining interrupt sources. Otherwise we'll
13321344
// just get called continuously.
1333-
uint32_t unhandled = __HAL_TIM_GET_ITSTATUS(&tim->tim, 0xff & ~handled);
1345+
uint32_t unhandled = tim->tim.Instance->DIER & 0xff & ~handled;
13341346
if (unhandled != 0) {
13351347
__HAL_TIM_CLEAR_IT(&tim->tim, unhandled);
13361348
printf("Unhandled interrupt SR=0x%02lx (now disabled)\n", unhandled);

0 commit comments

Comments
 (0)