mirror of
https://github.com/meshtastic/firmware.git
synced 2025-06-10 15:12:06 +00:00
Fix Light-sleep for ESP32 (#3521)
* Change wakeup source from EXT0 to GPIO * Avoid ISR issue on wake * Detect press from wake reason, instead of digitalRead * Missing #ifdef Risky phone-typed commit * Fix PowerFSM timed transition preventing light sleep Addresses https://github.com/meshtastic/firmware/issues/3517 --------- Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
This commit is contained in:
parent
8bb562c5fa
commit
f2ed0f7c8c
@ -102,23 +102,18 @@ static void lsIdle()
|
|||||||
powerFSM.trigger(EVENT_SERIAL_CONNECTED);
|
powerFSM.trigger(EVENT_SERIAL_CONNECTED);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ESP_SLEEP_WAKEUP_GPIO:
|
||||||
|
// GPIO wakeup is now used for all ESP32 devices during light sleep
|
||||||
|
powerFSM.trigger(EVENT_PRESS);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// We woke for some other reason (button press, device interrupt)
|
// We woke for some other reason (device interrupt?)
|
||||||
// uint64_t status = esp_sleep_get_ext1_wakeup_status();
|
|
||||||
LOG_INFO("wakeCause2 %d\n", wakeCause2);
|
LOG_INFO("wakeCause2 %d\n", wakeCause2);
|
||||||
|
|
||||||
#ifdef BUTTON_PIN
|
// Let the NB state handle the IRQ (and that state will handle stuff like IRQs etc)
|
||||||
bool pressed = !digitalRead(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN);
|
|
||||||
#else
|
|
||||||
bool pressed = false;
|
|
||||||
#endif
|
|
||||||
if (pressed) { // If we woke because of press, instead generate a PRESS event.
|
|
||||||
powerFSM.trigger(EVENT_PRESS);
|
|
||||||
} else {
|
|
||||||
// Otherwise let the NB state handle the IRQ (and that state will handle stuff like IRQs etc)
|
|
||||||
// we lie and say "wake timer" because the interrupt will be handled by the regular IRQ code
|
// we lie and say "wake timer" because the interrupt will be handled by the regular IRQ code
|
||||||
powerFSM.trigger(EVENT_WAKE_TIMER);
|
powerFSM.trigger(EVENT_WAKE_TIMER);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -348,9 +343,6 @@ void PowerFSM_setup()
|
|||||||
powerFSM.add_timed_transition(&statePOWER, &stateDARK,
|
powerFSM.add_timed_transition(&statePOWER, &stateDARK,
|
||||||
Default::getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs), NULL,
|
Default::getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs), NULL,
|
||||||
"Screen-on timeout");
|
"Screen-on timeout");
|
||||||
powerFSM.add_timed_transition(&stateDARK, &stateDARK,
|
|
||||||
Default::getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs), NULL,
|
|
||||||
"Screen-on timeout");
|
|
||||||
|
|
||||||
// We never enter light-sleep or NB states on NRF52 (because the CPU uses so little power normally)
|
// We never enter light-sleep or NB states on NRF52 (because the CPU uses so little power normally)
|
||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
@ -361,11 +353,24 @@ void PowerFSM_setup()
|
|||||||
powerFSM.add_timed_transition(&stateNB, &stateLS,
|
powerFSM.add_timed_transition(&stateNB, &stateLS,
|
||||||
Default::getConfiguredOrDefaultMs(config.power.min_wake_secs, default_min_wake_secs), NULL,
|
Default::getConfiguredOrDefaultMs(config.power.min_wake_secs, default_min_wake_secs), NULL,
|
||||||
"Min wake timeout");
|
"Min wake timeout");
|
||||||
|
|
||||||
|
// If ESP32 and using power-saving, timer mover from DARK to light-sleep
|
||||||
|
// Also serves purpose of the old DARK to DARK transition(?) See https://github.com/meshtastic/firmware/issues/3517
|
||||||
powerFSM.add_timed_transition(
|
powerFSM.add_timed_transition(
|
||||||
&stateDARK, &stateLS,
|
&stateDARK, &stateLS,
|
||||||
Default::getConfiguredOrDefaultMs(config.power.wait_bluetooth_secs, default_wait_bluetooth_secs), NULL,
|
Default::getConfiguredOrDefaultMs(config.power.wait_bluetooth_secs, default_wait_bluetooth_secs), NULL,
|
||||||
"Bluetooth timeout");
|
"Bluetooth timeout");
|
||||||
|
} else {
|
||||||
|
// If ESP32, but not using power-saving, check periodically if config has drifted out of stateDark
|
||||||
|
powerFSM.add_timed_transition(&stateDARK, &stateDARK,
|
||||||
|
Default::getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs),
|
||||||
|
NULL, "Screen-on timeout");
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
// If not ESP32, light-sleep not used. Check periodically if config has drifted out of stateDark
|
||||||
|
powerFSM.add_timed_transition(&stateDARK, &stateDARK,
|
||||||
|
Default::getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs), NULL,
|
||||||
|
"Screen-on timeout");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
powerFSM.run_machine(); // run one iteration of the state machine, so we run our on enter tasks for the initial DARK state
|
powerFSM.run_machine(); // run one iteration of the state machine, so we run our on enter tasks for the initial DARK state
|
||||||
|
@ -312,13 +312,11 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r
|
|||||||
// assert(esp_sleep_enable_uart_wakeup(0) == ESP_OK);
|
// assert(esp_sleep_enable_uart_wakeup(0) == ESP_OK);
|
||||||
#endif
|
#endif
|
||||||
#ifdef BUTTON_PIN
|
#ifdef BUTTON_PIN
|
||||||
#if SOC_PM_SUPPORT_EXT_WAKEUP
|
// The enableLoraInterrupt() method is using ext0_wakeup, so we are forced to use GPIO wakeup
|
||||||
esp_sleep_enable_ext0_wakeup((gpio_num_t)(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN),
|
gpio_num_t pin = (gpio_num_t)(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN);
|
||||||
LOW); // when user presses, this button goes low
|
gpio_intr_disable(pin);
|
||||||
#else
|
gpio_wakeup_enable(pin, GPIO_INTR_LOW_LEVEL);
|
||||||
esp_sleep_enable_gpio_wakeup();
|
esp_sleep_enable_gpio_wakeup();
|
||||||
gpio_wakeup_enable((gpio_num_t)BUTTON_PIN, GPIO_INTR_LOW_LEVEL);
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
enableLoraInterrupt();
|
enableLoraInterrupt();
|
||||||
#ifdef PMU_IRQ
|
#ifdef PMU_IRQ
|
||||||
@ -342,6 +340,12 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r
|
|||||||
}
|
}
|
||||||
assert(res == ESP_OK);
|
assert(res == ESP_OK);
|
||||||
|
|
||||||
|
#ifdef BUTTON_PIN
|
||||||
|
gpio_wakeup_disable(pin);
|
||||||
|
// Would have thought that need gpio_intr_enable() here, but nope..
|
||||||
|
// Works fine without it; crashes with it.
|
||||||
|
#endif
|
||||||
|
|
||||||
esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
|
esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
|
||||||
#ifdef BUTTON_PIN
|
#ifdef BUTTON_PIN
|
||||||
if (cause == ESP_SLEEP_WAKEUP_GPIO) {
|
if (cause == ESP_SLEEP_WAKEUP_GPIO) {
|
||||||
|
Loading…
Reference in New Issue
Block a user