mirror of
https://github.com/meshtastic/firmware.git
synced 2025-07-31 02:45:41 +00:00
another refactor to better handle variants without dynamic light sleep
This commit is contained in:
parent
fda2b899ff
commit
91d25d2b45
@ -29,17 +29,13 @@
|
|||||||
#include "mesh/wifi/WiFiAPClient.h"
|
#include "mesh/wifi/WiFiAPClient.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef SLEEP_TIME
|
|
||||||
#define SLEEP_TIME 30
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if MESHTASTIC_EXCLUDE_POWER_FSM
|
#if MESHTASTIC_EXCLUDE_POWER_FSM
|
||||||
FakeFsm powerFSM;
|
FakeFsm powerFSM;
|
||||||
void PowerFSM_setup(){};
|
void PowerFSM_setup(){};
|
||||||
#else
|
#else
|
||||||
|
|
||||||
static uint32_t sleepStart;
|
static uint32_t sleepStart;
|
||||||
static uint32_t sleepTime;
|
static uint32_t sleepTime;
|
||||||
|
static uint32_t sleepLeft;
|
||||||
|
|
||||||
/// Should we behave as if we have AC power now?
|
/// Should we behave as if we have AC power now?
|
||||||
static bool isPowered()
|
static bool isPowered()
|
||||||
@ -89,13 +85,24 @@ static void lsEnter()
|
|||||||
sleepStart = -1;
|
sleepStart = -1;
|
||||||
sleepTime = 0;
|
sleepTime = 0;
|
||||||
|
|
||||||
|
#ifdef HAS_ESP32_DYNAMIC_LIGHT_SLEEP
|
||||||
|
if (!doPreflightSleep()) {
|
||||||
|
LOG_DEBUG("Transition to LS state aborted because of tasks pending");
|
||||||
|
powerFSM.trigger(EVENT_WAKE_TIMER);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sleepStart = millis();
|
||||||
|
doLightSleep(LIGHT_SLEEP_DYNAMIC);
|
||||||
|
#endif
|
||||||
|
|
||||||
powerMon->setState(meshtastic_PowerMon_State_CPU_LightSleep);
|
powerMon->setState(meshtastic_PowerMon_State_CPU_LightSleep);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lsIdle()
|
static void lsIdle()
|
||||||
{
|
{
|
||||||
if (!doPreflightSleep()) {
|
if (!doPreflightSleep()) {
|
||||||
#ifdef HAS_DYNAMIC_LIGHT_SLEEP
|
#ifdef HAS_ESP32_DYNAMIC_LIGHT_SLEEP
|
||||||
powerFSM.trigger(EVENT_WAKE_TIMER);
|
powerFSM.trigger(EVENT_WAKE_TIMER);
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
@ -106,16 +113,15 @@ static void lsIdle()
|
|||||||
}
|
}
|
||||||
|
|
||||||
sleepTime = millis() - sleepStart;
|
sleepTime = millis() - sleepStart;
|
||||||
|
|
||||||
#ifdef ARCH_ESP32
|
|
||||||
uint32_t sleepLeft;
|
|
||||||
|
|
||||||
sleepLeft = config.power.ls_secs * 1000LL - sleepTime;
|
sleepLeft = config.power.ls_secs * 1000LL - sleepTime;
|
||||||
if (sleepLeft > SLEEP_TIME * 1000LL) {
|
if (sleepLeft > SLEEP_TIME_QUANTUM_S * 1000LL) {
|
||||||
sleepLeft = SLEEP_TIME * 1000LL;
|
sleepLeft = SLEEP_TIME_QUANTUM_S * 1000LL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ARCH_ESP32
|
||||||
|
#ifndef HAS_ESP32_DYNAMIC_LIGHT_SLEEP
|
||||||
doLightSleep(sleepLeft);
|
doLightSleep(sleepLeft);
|
||||||
|
#endif
|
||||||
|
|
||||||
esp_sleep_source_t cause = esp_sleep_get_wakeup_cause();
|
esp_sleep_source_t cause = esp_sleep_get_wakeup_cause();
|
||||||
|
|
||||||
@ -125,6 +131,11 @@ static void lsIdle()
|
|||||||
powerFSM.trigger(EVENT_INPUT);
|
powerFSM.trigger(EVENT_INPUT);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case ESP_SLEEP_WAKEUP_EXT0:
|
||||||
|
LOG_DEBUG("Wake cause ESP_SLEEP_WAKEUP_EXT0");
|
||||||
|
powerFSM.trigger(EVENT_RADIO_INTERRUPT);
|
||||||
|
return;
|
||||||
|
|
||||||
case ESP_SLEEP_WAKEUP_EXT1:
|
case ESP_SLEEP_WAKEUP_EXT1:
|
||||||
LOG_DEBUG("Wake cause ESP_SLEEP_WAKEUP_EXT1");
|
LOG_DEBUG("Wake cause ESP_SLEEP_WAKEUP_EXT1");
|
||||||
powerFSM.trigger(EVENT_PRESS);
|
powerFSM.trigger(EVENT_PRESS);
|
||||||
@ -132,7 +143,7 @@ static void lsIdle()
|
|||||||
|
|
||||||
case ESP_SLEEP_WAKEUP_GPIO:
|
case ESP_SLEEP_WAKEUP_GPIO:
|
||||||
LOG_DEBUG("Wake cause ESP_SLEEP_WAKEUP_GPIO");
|
LOG_DEBUG("Wake cause ESP_SLEEP_WAKEUP_GPIO");
|
||||||
powerFSM.trigger(EVENT_WAKE_TIMER);
|
// FSM events should be triggered by interrupt handlers
|
||||||
return;
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -147,7 +158,7 @@ static void lsIdle()
|
|||||||
|
|
||||||
static void lsExit()
|
static void lsExit()
|
||||||
{
|
{
|
||||||
#ifdef ARCH_ESP32
|
#ifdef HAS_ESP32_DYNAMIC_LIGHT_SLEEP
|
||||||
doLightSleep(LIGHT_SLEEP_ABORT);
|
doLightSleep(LIGHT_SLEEP_ABORT);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -321,7 +332,7 @@ void PowerFSM_setup()
|
|||||||
powerFSM.add_transition(&stateLS, &stateDARK, EVENT_WEB_REQUEST, NULL, "Web request");
|
powerFSM.add_transition(&stateLS, &stateDARK, EVENT_WEB_REQUEST, NULL, "Web request");
|
||||||
powerFSM.add_transition(&stateDARK, &stateDARK, EVENT_WEB_REQUEST, NULL, "Web request");
|
powerFSM.add_transition(&stateDARK, &stateDARK, EVENT_WEB_REQUEST, NULL, "Web request");
|
||||||
|
|
||||||
#ifdef HAS_DYNAMIC_LIGHT_SLEEP
|
#ifdef HAS_ESP32_DYNAMIC_LIGHT_SLEEP
|
||||||
// it's better to exit dynamic light sleep when packet is received to ensure routing is properly handled
|
// it's better to exit dynamic light sleep when packet is received to ensure routing is properly handled
|
||||||
powerFSM.add_transition(&stateLS, &stateDARK, EVENT_RADIO_INTERRUPT, NULL, "Radio interrupt");
|
powerFSM.add_transition(&stateLS, &stateDARK, EVENT_RADIO_INTERRUPT, NULL, "Radio interrupt");
|
||||||
powerFSM.add_transition(&stateDARK, &stateDARK, EVENT_RADIO_INTERRUPT, NULL, "Radio interrupt");
|
powerFSM.add_transition(&stateDARK, &stateDARK, EVENT_RADIO_INTERRUPT, NULL, "Radio interrupt");
|
||||||
|
@ -24,12 +24,16 @@
|
|||||||
#define EVENT_RADIO_INTERRUPT 18
|
#define EVENT_RADIO_INTERRUPT 18
|
||||||
#define EVENT_WEB_REQUEST 19
|
#define EVENT_WEB_REQUEST 19
|
||||||
|
|
||||||
#ifdef HAS_DYNAMIC_LIGHT_SLEEP
|
#ifdef HAS_ESP32_DYNAMIC_LIGHT_SLEEP
|
||||||
#define WAKE_TIME_MS 500
|
#define WAKE_TIME_MS 500
|
||||||
#else
|
#else
|
||||||
#define WAKE_TIME_MS (Default::getConfiguredOrDefaultMs(config.power.min_wake_secs, default_min_wake_secs))
|
#define WAKE_TIME_MS (Default::getConfiguredOrDefaultMs(config.power.min_wake_secs, default_min_wake_secs))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef SLEEP_TIME_QUANTUM_S
|
||||||
|
#define SLEEP_TIME_QUANTUM_S 5
|
||||||
|
#endif
|
||||||
|
|
||||||
#if MESHTASTIC_EXCLUDE_POWER_FSM
|
#if MESHTASTIC_EXCLUDE_POWER_FSM
|
||||||
class FakeFsm
|
class FakeFsm
|
||||||
{
|
{
|
||||||
@ -49,11 +53,10 @@ class FakeFsm
|
|||||||
};
|
};
|
||||||
extern FakeFsm powerFSM;
|
extern FakeFsm powerFSM;
|
||||||
void PowerFSM_setup();
|
void PowerFSM_setup();
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#include <Fsm.h>
|
#include <Fsm.h>
|
||||||
extern Fsm powerFSM;
|
extern Fsm powerFSM;
|
||||||
extern State stateON, statePOWER, stateSERIAL, stateDARK, stateNB, stateLS;
|
extern State stateON, statePOWER, stateSERIAL, stateDARK, stateNB, stateLS;
|
||||||
|
|
||||||
void PowerFSM_setup();
|
void PowerFSM_setup();
|
||||||
#endif
|
#endif
|
||||||
|
@ -219,5 +219,5 @@
|
|||||||
|
|
||||||
// Setup flag, which indicates if our device supports dynamic light sleep
|
// Setup flag, which indicates if our device supports dynamic light sleep
|
||||||
#if defined(HAS_ESP32_PM_SUPPORT) && defined(CONFIG_FREERTOS_USE_TICKLESS_IDLE)
|
#if defined(HAS_ESP32_PM_SUPPORT) && defined(CONFIG_FREERTOS_USE_TICKLESS_IDLE)
|
||||||
#define HAS_DYNAMIC_LIGHT_SLEEP
|
#define HAS_ESP32_DYNAMIC_LIGHT_SLEEP
|
||||||
#endif
|
#endif
|
||||||
|
101
src/sleep.cpp
101
src/sleep.cpp
@ -45,7 +45,7 @@ Observable<void *> notifyDeepSleep;
|
|||||||
Observable<void *> notifyReboot;
|
Observable<void *> notifyReboot;
|
||||||
|
|
||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
// Wake cause when returning from a deep sleep
|
// Wake cause when returning from sleep
|
||||||
esp_sleep_source_t wakeCause;
|
esp_sleep_source_t wakeCause;
|
||||||
|
|
||||||
/// Called to tell observers that light sleep is about to begin
|
/// Called to tell observers that light sleep is about to begin
|
||||||
@ -55,7 +55,7 @@ Observable<void *> notifyLightSleep;
|
|||||||
Observable<esp_sleep_wakeup_cause_t> notifyLightSleepEnd;
|
Observable<esp_sleep_wakeup_cause_t> notifyLightSleepEnd;
|
||||||
|
|
||||||
#ifdef HAS_ESP32_PM_SUPPORT
|
#ifdef HAS_ESP32_PM_SUPPORT
|
||||||
esp_pm_lock_handle_t pmHandle;
|
esp_pm_lock_handle_t pmLightSleepLock;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// restores GPIO function after sleep
|
// restores GPIO function after sleep
|
||||||
@ -323,8 +323,10 @@ void doDeepSleep(uint32_t msecToWake, bool skipPreflight = false, bool skipSaveN
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
static bool pmLockAcquired;
|
#ifdef HAS_ESP32_DYNAMIC_LIGHT_SLEEP
|
||||||
static concurrency::Lock *pmLightSleepLock;
|
static bool pmLightSleepLockAcquired;
|
||||||
|
#endif
|
||||||
|
static concurrency::Lock *lightSleepConcurrencyLock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* enter light sleep (preserves ram but stops everything about CPU).
|
* enter light sleep (preserves ram but stops everything about CPU).
|
||||||
@ -335,48 +337,45 @@ void doLightSleep(uint32_t sleepMsec)
|
|||||||
{
|
{
|
||||||
esp_err_t res;
|
esp_err_t res;
|
||||||
|
|
||||||
assert(pmLightSleepLock);
|
assert(lightSleepConcurrencyLock);
|
||||||
pmLightSleepLock->lock();
|
lightSleepConcurrencyLock->lock();
|
||||||
|
|
||||||
if (sleepMsec == LIGHT_SLEEP_ABORT) {
|
#ifndef HAS_ESP32_DYNAMIC_LIGHT_SLEEP
|
||||||
if (pmLockAcquired) {
|
assert(sleepMsec != LIGHT_SLEEP_ABORT);
|
||||||
pmLightSleepLock->unlock();
|
assert(sleepMsec != LIGHT_SLEEP_DYNAMIC);
|
||||||
return; // nothing to do
|
#else
|
||||||
|
if (!pmLightSleepLockAcquired) {
|
||||||
|
if (sleepMsec == LIGHT_SLEEP_DYNAMIC) {
|
||||||
|
lightSleepConcurrencyLock->unlock();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAS_ESP32_PM_SUPPORT
|
res = esp_pm_lock_acquire(pmLightSleepLock);
|
||||||
res = esp_pm_lock_acquire(pmHandle);
|
|
||||||
assert(res == ESP_OK);
|
assert(res == ESP_OK);
|
||||||
#endif
|
|
||||||
pmLockAcquired = true;
|
wakeCause = esp_sleep_get_wakeup_cause();
|
||||||
|
|
||||||
|
pmLightSleepLockAcquired = true;
|
||||||
|
|
||||||
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL);
|
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL);
|
||||||
gpioReset();
|
gpioReset();
|
||||||
|
|
||||||
notifyLightSleepEnd.notifyObservers(esp_sleep_get_wakeup_cause());
|
notifyLightSleepEnd.notifyObservers(wakeCause);
|
||||||
|
|
||||||
pmLightSleepLock->unlock();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pmLockAcquired) {
|
if (sleepMsec == LIGHT_SLEEP_ABORT) {
|
||||||
console->flush();
|
lightSleepConcurrencyLock->unlock();
|
||||||
|
return;
|
||||||
#ifndef HAS_DYNAMIC_LIGHT_SLEEP
|
}
|
||||||
esp_light_sleep_start();
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pmLightSleepLock->unlock();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
enableLoraInterrupt();
|
enableLoraInterrupt();
|
||||||
enableButtonInterrupt();
|
enableButtonInterrupt();
|
||||||
|
|
||||||
#ifndef HAS_DYNAMIC_LIGHT_SLEEP
|
if (sleepMsec != LIGHT_SLEEP_DYNAMIC) {
|
||||||
res = esp_sleep_enable_timer_wakeup(sleepMsec * 1000LL);
|
res = esp_sleep_enable_timer_wakeup(sleepMsec * 1000LL);
|
||||||
assert(res == ESP_OK);
|
assert(res == ESP_OK);
|
||||||
#endif
|
}
|
||||||
|
|
||||||
res = uart_set_wakeup_threshold(UART_NUM_0, 3);
|
res = uart_set_wakeup_threshold(UART_NUM_0, 3);
|
||||||
assert(res == ESP_OK);
|
assert(res == ESP_OK);
|
||||||
@ -387,7 +386,6 @@ void doLightSleep(uint32_t sleepMsec)
|
|||||||
#if defined(VEXT_ENABLE)
|
#if defined(VEXT_ENABLE)
|
||||||
gpio_hold_en((gpio_num_t)VEXT_ENABLE);
|
gpio_hold_en((gpio_num_t)VEXT_ENABLE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(RESET_OLED)
|
#if defined(RESET_OLED)
|
||||||
gpio_hold_en((gpio_num_t)RESET_OLED);
|
gpio_hold_en((gpio_num_t)RESET_OLED);
|
||||||
#endif
|
#endif
|
||||||
@ -415,17 +413,25 @@ void doLightSleep(uint32_t sleepMsec)
|
|||||||
|
|
||||||
console->flush();
|
console->flush();
|
||||||
|
|
||||||
#ifdef HAS_ESP32_PM_SUPPORT
|
if (sleepMsec != LIGHT_SLEEP_DYNAMIC) {
|
||||||
res = esp_pm_lock_release(pmHandle);
|
esp_light_sleep_start();
|
||||||
assert(res == ESP_OK);
|
|
||||||
#endif
|
|
||||||
pmLockAcquired = false;
|
|
||||||
|
|
||||||
#ifndef HAS_DYNAMIC_LIGHT_SLEEP
|
wakeCause = esp_sleep_get_wakeup_cause();
|
||||||
esp_light_sleep_start();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
pmLightSleepLock->unlock();
|
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL);
|
||||||
|
gpioReset();
|
||||||
|
|
||||||
|
notifyLightSleepEnd.notifyObservers(wakeCause);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
#ifdef HAS_ESP32_DYNAMIC_LIGHT_SLEEP
|
||||||
|
res = esp_pm_lock_release(pmLightSleepLock);
|
||||||
|
assert(res == ESP_OK);
|
||||||
|
pmLightSleepLockAcquired = false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
lightSleepConcurrencyLock->unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize power management settings to allow light sleep
|
// Initialize power management settings to allow light sleep
|
||||||
@ -434,16 +440,16 @@ void initLightSleep()
|
|||||||
esp_err_t res;
|
esp_err_t res;
|
||||||
|
|
||||||
#ifdef HAS_ESP32_PM_SUPPORT
|
#ifdef HAS_ESP32_PM_SUPPORT
|
||||||
res = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "meshtastic", &pmHandle);
|
res = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "meshtastic", &pmLightSleepLock);
|
||||||
assert(res == ESP_OK);
|
assert(res == ESP_OK);
|
||||||
|
|
||||||
res = esp_pm_lock_acquire(pmHandle);
|
res = esp_pm_lock_acquire(pmLightSleepLock);
|
||||||
assert(res == ESP_OK);
|
assert(res == ESP_OK);
|
||||||
|
|
||||||
esp_pm_config_esp32_t pm_config;
|
esp_pm_config_esp32_t pm_config;
|
||||||
pm_config.max_freq_mhz = 80;
|
pm_config.max_freq_mhz = 80;
|
||||||
pm_config.min_freq_mhz = 20;
|
pm_config.min_freq_mhz = 20;
|
||||||
#ifdef HAS_DYNAMIC_LIGHT_SLEEP
|
#ifdef HAS_ESP32_DYNAMIC_LIGHT_SLEEP
|
||||||
pm_config.light_sleep_enable = true;
|
pm_config.light_sleep_enable = true;
|
||||||
#else
|
#else
|
||||||
pm_config.light_sleep_enable = false;
|
pm_config.light_sleep_enable = false;
|
||||||
@ -456,8 +462,11 @@ void initLightSleep()
|
|||||||
pm_config.max_freq_mhz, pm_config.light_sleep_enable);
|
pm_config.max_freq_mhz, pm_config.light_sleep_enable);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pmLightSleepLock = new concurrency::Lock();
|
lightSleepConcurrencyLock = new concurrency::Lock();
|
||||||
pmLockAcquired = true;
|
|
||||||
|
#ifdef HAS_ESP32_DYNAMIC_LIGHT_SLEEP
|
||||||
|
pmLightSleepLockAcquired = true;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void gpioReset()
|
void gpioReset()
|
||||||
|
@ -13,6 +13,7 @@ extern XPowersLibInterface *PMU;
|
|||||||
#include "esp_sleep.h"
|
#include "esp_sleep.h"
|
||||||
|
|
||||||
#define LIGHT_SLEEP_ABORT 0
|
#define LIGHT_SLEEP_ABORT 0
|
||||||
|
#define LIGHT_SLEEP_DYNAMIC UINT32_MAX
|
||||||
|
|
||||||
void initLightSleep();
|
void initLightSleep();
|
||||||
void doLightSleep(uint32_t msecToWake);
|
void doLightSleep(uint32_t msecToWake);
|
||||||
|
Loading…
Reference in New Issue
Block a user