Skip to content

Commit

Permalink
timer: stop alarm if alarm value doesn't change in ISR handler
Browse files Browse the repository at this point in the history
Alarm will be disabled by hardware when alarm event happend.
In the ISR, if auto-reload is enabled, we should re-enable the alarm.
If the alarm target value is changed in user's callback,
the alarm will be reenabled as well.

Closes #7001
Closes #8095
  • Loading branch information
suda-morris committed Dec 24, 2021
1 parent 2515d11 commit 7abb92f
Showing 1 changed file with 10 additions and 8 deletions.
18 changes: 10 additions & 8 deletions components/driver/timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -213,15 +213,17 @@ static void IRAM_ATTR timer_isr_default(void *arg)
uint32_t intr_status = 0;
timer_hal_get_intr_status(&(timer_obj->hal), &intr_status);
if (intr_status & BIT(timer_obj->hal.idx)) {
is_awoken = timer_obj->timer_isr_fun.fn(timer_obj->timer_isr_fun.args);
//Clear intrrupt status
// Clear intrrupt status
timer_hal_clear_intr_status(&(timer_obj->hal));
//If the timer is set to auto reload, we need enable it again, so it is triggered the next time.
if (timer_hal_get_auto_reload(&timer_obj->hal)) {
timer_hal_set_alarm_enable(&(timer_obj->hal), TIMER_ALARM_EN);
} else {
timer_hal_set_alarm_enable(&(timer_obj->hal), TIMER_ALARM_DIS);
}
uint64_t old_alarm_value = 0;
timer_hal_get_alarm_value(&(timer_obj->hal), &old_alarm_value);
// call user registered callback
is_awoken = timer_obj->timer_isr_fun.fn(timer_obj->timer_isr_fun.args);
// reenable alarm if required
uint64_t new_alarm_value = 0;
timer_hal_get_alarm_value(&(timer_obj->hal), &new_alarm_value);
bool reenable_alarm = (new_alarm_value != old_alarm_value) || timer_hal_get_auto_reload(&timer_obj->hal);
timer_hal_set_alarm_enable(&(timer_obj->hal), reenable_alarm);
}
}
TIMER_EXIT_CRITICAL(&timer_spinlock[timer_obj->timer_isr_fun.isr_timer_group]);
Expand Down

0 comments on commit 7abb92f

Please sign in to comment.