diff --git a/src/Power.cpp b/src/Power.cpp index bf74f6e53..c97c28028 100644 --- a/src/Power.cpp +++ b/src/Power.cpp @@ -586,6 +586,19 @@ Power::Power() : OSThread("Power") #ifdef DEBUG_HEAP lastheap = memGet.getFreeHeap(); #endif + +#ifdef ARCH_ESP32 + lsObserver.observe(¬ifyLightSleep); + lsEndObserver.observe(¬ifyLightSleepEnd); +#endif +} + +Power::~Power() +{ +#ifdef ARCH_ESP32 + lsObserver.unobserve(¬ifyLightSleep); + lsEndObserver.unobserve(¬ifyLightSleepEnd); +#endif } bool Power::analogInit() @@ -782,6 +795,8 @@ void Power::readPowerStatus() OptionalBool hasBattery = OptUnknown; // These must be static because NRF_APM code doesn't run every time OptionalBool isChargingNow = OptUnknown; + powerFSM.trigger(EVENT_WAKE_TIMER); // ensure we're not light-sleeping + if (batteryLevel) { hasBattery = batteryLevel->isBatteryConnect() ? OptTrue : OptFalse; usbPowered = batteryLevel->isVbusIn() ? OptTrue : OptFalse; @@ -936,10 +951,29 @@ int32_t Power::runOnce() PMU->clearIrqStatus(); } #endif + // Only read once every 20 seconds once the power status for the app has been initialized - return (statusHandler && statusHandler->isInitialized()) ? (1000 * 20) : RUN_SAME; + if (statusHandler && statusHandler->isInitialized() && interval == 0) { + setInterval(20 * 1000UL); + } + + return RUN_SAME; } +#ifdef ARCH_ESP32 +int Power::beforeLightSleep(void *unused) +{ + setInterval(config.power.ls_secs * 1000UL); + return 0; +} + +int Power::afterLightSleep(esp_sleep_wakeup_cause_t cause) +{ + setInterval(20 * 1000UL); + return 0; +} +#endif + /** * Init the power manager chip * diff --git a/src/power.h b/src/power.h index e96f5b022..477f33555 100644 --- a/src/power.h +++ b/src/power.h @@ -109,6 +109,7 @@ class Power : private concurrency::OSThread Observable newStatus; Power(); + ~Power(); void powerCommandsCheck(); void readPowerStatus(); @@ -139,6 +140,16 @@ class Power : private concurrency::OSThread #ifdef DEBUG_HEAP uint32_t lastheap; #endif + +#ifdef ARCH_ESP32 + // Get notified when lightsleep begins and ends to set power refresh interval + CallbackObserver lsObserver = CallbackObserver(this, &Power::beforeLightSleep); + CallbackObserver lsEndObserver = + CallbackObserver(this, &Power::afterLightSleep); + + int beforeLightSleep(void *unused); + int afterLightSleep(esp_sleep_wakeup_cause_t cause); +#endif }; extern Power *power;