Fix corner case that could cause the top of minute alarm to stop firing
This commit is contained in:
@@ -49,6 +49,8 @@ typedef struct {
|
|||||||
volatile bool enabled;
|
volatile bool enabled;
|
||||||
} comp_cb_t;
|
} comp_cb_t;
|
||||||
|
|
||||||
|
volatile uint32_t scheduled_comp_counter;
|
||||||
|
|
||||||
watch_cb_t tick_callbacks[8];
|
watch_cb_t tick_callbacks[8];
|
||||||
comp_cb_t comp_callbacks[WATCH_RTC_N_COMP_CB];
|
comp_cb_t comp_callbacks[WATCH_RTC_N_COMP_CB];
|
||||||
watch_cb_t alarm_callback;
|
watch_cb_t alarm_callback;
|
||||||
@@ -76,6 +78,8 @@ void _watch_rtc_init(void) {
|
|||||||
comp_callbacks[index].enabled = false;
|
comp_callbacks[index].enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scheduled_comp_counter = 0;
|
||||||
|
|
||||||
NVIC_ClearPendingIRQ(RTC_IRQn);
|
NVIC_ClearPendingIRQ(RTC_IRQn);
|
||||||
NVIC_EnableIRQ(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) {
|
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
|
// Because of the hardware, 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;
|
bool schedule_any = false;
|
||||||
rtc_counter_t comp_counter;
|
rtc_counter_t comp_counter;
|
||||||
@@ -216,8 +225,15 @@ static void _watch_rtc_schedule_next_comp(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (schedule_any) {
|
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);
|
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) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
rtc_disable_compare_interrupt();
|
|
||||||
|
|
||||||
comp_callbacks[index].counter = counter;
|
comp_callbacks[index].counter = counter;
|
||||||
comp_callbacks[index].callback = callback;
|
comp_callbacks[index].callback = callback;
|
||||||
comp_callbacks[index].enabled = true;
|
comp_callbacks[index].enabled = true;
|
||||||
@@ -239,8 +253,6 @@ void watch_rtc_disable_comp_callback(uint8_t index) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
rtc_disable_compare_interrupt();
|
|
||||||
|
|
||||||
comp_callbacks[index].enabled = false;
|
comp_callbacks[index].enabled = false;
|
||||||
|
|
||||||
_watch_rtc_schedule_next_comp();
|
_watch_rtc_schedule_next_comp();
|
||||||
|
|||||||
@@ -286,10 +286,15 @@ void watch_rtc_disable_comp_callback(uint8_t index) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void _watch_rtc_schedule_next_comp(void) {
|
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
|
// 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;
|
bool schedule_any = false;
|
||||||
rtc_counter_t comp_counter;
|
rtc_counter_t comp_counter;
|
||||||
@@ -309,6 +314,8 @@ static void _watch_rtc_schedule_next_comp(void) {
|
|||||||
|
|
||||||
if (schedule_any) {
|
if (schedule_any) {
|
||||||
scheduled_comp_counter = comp_counter;
|
scheduled_comp_counter = comp_counter;
|
||||||
|
} else {
|
||||||
|
scheduled_comp_counter = curr_counter - 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user