Improve CC13xx/CC26xx LPM logic
This commit applies a number of improvements to the logic used when trying to drop to a CC13xx/CC26xx low-power mode: * We identify whether there are any pending etimers by using `etimer_pending()` instead of `etimer_next_expiration_time()`. This subsequently allows us to also identify whether an etimer is set to fire at time 0. * We run a larger portion of the code with the global interrupt disabled. This prevents a number of messy conditions that can occur if an interrupt fires after we have started the low-power sequence. * We check whether there are pending events earlier in the sequence. * We make sure to schedule a next wakeup event even when an LPM module prohibits deep sleep and forces sleep instead. This fixes some of the issues discussed in #1236
This commit is contained in:
parent
08fddb6598
commit
571cf9364a
|
@ -244,8 +244,18 @@ lpm_drop()
|
|||
|
||||
uint32_t domains = LOCKABLE_DOMAINS;
|
||||
|
||||
/* Critical. Don't get interrupted! */
|
||||
ti_lib_int_master_disable();
|
||||
|
||||
/* Check if any events fired before we turned interrupts off. If so, abort */
|
||||
if(process_nevents()) {
|
||||
ti_lib_int_master_enable();
|
||||
return;
|
||||
}
|
||||
|
||||
if(RTIMER_CLOCK_LT(soc_rtc_get_next_trigger(),
|
||||
RTIMER_NOW() + STANDBY_MIN_DURATION)) {
|
||||
ti_lib_int_master_enable();
|
||||
lpm_sleep();
|
||||
return;
|
||||
}
|
||||
|
@ -261,30 +271,20 @@ lpm_drop()
|
|||
}
|
||||
}
|
||||
|
||||
/* Check if any events fired during this process. Last chance to abort */
|
||||
if(process_nevents()) {
|
||||
return;
|
||||
/* Reschedule AON RTC CH1 to fire just in time for the next etimer event */
|
||||
next_event = etimer_next_expiration_time();
|
||||
|
||||
if(etimer_pending()) {
|
||||
next_event = next_event - clock_time();
|
||||
soc_rtc_schedule_one_shot(AON_RTC_CH1, soc_rtc_last_isr_time() +
|
||||
(next_event * (RTIMER_SECOND / CLOCK_SECOND)));
|
||||
}
|
||||
|
||||
/* Drop */
|
||||
if(max_pm == LPM_MODE_SLEEP) {
|
||||
ti_lib_int_master_enable();
|
||||
lpm_sleep();
|
||||
} else {
|
||||
/* Critical. Don't get interrupted! */
|
||||
ti_lib_int_master_disable();
|
||||
|
||||
/*
|
||||
* Reschedule AON RTC CH1 to fire an event N ticks before the next etimer
|
||||
* event
|
||||
*/
|
||||
next_event = etimer_next_expiration_time();
|
||||
|
||||
if(next_event) {
|
||||
next_event = next_event - clock_time();
|
||||
soc_rtc_schedule_one_shot(AON_RTC_CH1, soc_rtc_last_isr_time() +
|
||||
(next_event * (RTIMER_SECOND / CLOCK_SECOND)));
|
||||
}
|
||||
|
||||
/*
|
||||
* Notify all registered modules that we are dropping to mode X. We do not
|
||||
* need to do this for simple sleep.
|
||||
|
|
Loading…
Reference in a new issue