Fix corner case that could cause the top of minute alarm to stop firing

This commit is contained in:
Alessandro Genova
2025-08-07 23:34:13 -04:00
parent 7acc9cc414
commit a616ac6cc4
2 changed files with 29 additions and 10 deletions
+19 -7
View File
@@ -49,6 +49,8 @@ typedef struct {
volatile bool enabled;
} comp_cb_t;
volatile uint32_t scheduled_comp_counter;
watch_cb_t tick_callbacks[8];
comp_cb_t comp_callbacks[WATCH_RTC_N_COMP_CB];
watch_cb_t alarm_callback;
@@ -76,6 +78,8 @@ void _watch_rtc_init(void) {
comp_callbacks[index].enabled = false;
}
scheduled_comp_counter = 0;
NVIC_ClearPendingIRQ(RTC_IRQn);
NVIC_EnableIRQ(RTC_IRQn);
}
@@ -195,10 +199,15 @@ void watch_rtc_disable_all_periodic_callbacks(void) {
}
static void _watch_rtc_schedule_next_comp(void) {
rtc_disable_compare_interrupt();
rtc_counter_t curr_counter = watch_rtc_get_counter();
// If there is already a pending comp interrupt for this very tick, let it fire
// And this function will be called again as soon as the interrupt fires.
if (curr_counter == scheduled_comp_counter) {
return;
}
// The soonest we can schedule is the next tick
rtc_counter_t curr_counter = watch_rtc_get_counter() + 1;
// Because of the hardware, the soonest we can schedule is the next tick
curr_counter +=1;
bool schedule_any = false;
rtc_counter_t comp_counter;
@@ -216,8 +225,15 @@ static void _watch_rtc_schedule_next_comp(void) {
}
if (schedule_any) {
// If we are changing the comp counter at the front of the line
if (comp_counter != scheduled_comp_counter) {
scheduled_comp_counter = comp_counter;
rtc_enable_compare_interrupt(comp_counter);
}
} else {
scheduled_comp_counter = curr_counter - 2;
rtc_disable_compare_interrupt();
}
}
void watch_rtc_register_comp_callback(watch_cb_t callback, rtc_counter_t counter, uint8_t index) {
@@ -225,8 +241,6 @@ void watch_rtc_register_comp_callback(watch_cb_t callback, rtc_counter_t counter
return;
}
rtc_disable_compare_interrupt();
comp_callbacks[index].counter = counter;
comp_callbacks[index].callback = callback;
comp_callbacks[index].enabled = true;
@@ -239,8 +253,6 @@ void watch_rtc_disable_comp_callback(uint8_t index) {
return;
}
rtc_disable_compare_interrupt();
comp_callbacks[index].enabled = false;
_watch_rtc_schedule_next_comp();
+9 -2
View File
@@ -286,10 +286,15 @@ void watch_rtc_disable_comp_callback(uint8_t index) {
}
static void _watch_rtc_schedule_next_comp(void) {
scheduled_comp_counter = 0;
rtc_counter_t curr_counter = watch_rtc_get_counter();
// If there is already a pending comp interrupt for this very tick, let it fire
// And this function will be called again as soon as the interrupt fires.
if (curr_counter == scheduled_comp_counter) {
return;
}
// The soonest we can schedule is the next tick
rtc_counter_t curr_counter = watch_rtc_get_counter() + 1;
curr_counter +=1;
bool schedule_any = false;
rtc_counter_t comp_counter;
@@ -309,6 +314,8 @@ static void _watch_rtc_schedule_next_comp(void) {
if (schedule_any) {
scheduled_comp_counter = comp_counter;
} else {
scheduled_comp_counter = curr_counter - 2;
}
}