From f1c18084495a7f6932ff99205cb86363a13e1db6 Mon Sep 17 00:00:00 2001 From: m1nl Date: Thu, 24 Apr 2025 00:36:47 +0200 Subject: [PATCH] dynamically adjust measurement interval in power management --- src/Power.cpp | 36 +++++++++++++++++++++++++++++++++++- src/power.h | 11 +++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/Power.cpp b/src/Power.cpp index 9c67977bd..a2e23a8ef 100644 --- a/src/Power.cpp +++ b/src/Power.cpp @@ -572,6 +572,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() @@ -708,6 +721,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; @@ -862,10 +877,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 c71f96c10..a3bd90229 100644 --- a/src/power.h +++ b/src/power.h @@ -109,6 +109,7 @@ class Power : private concurrency::OSThread Observable newStatus; Power(); + ~Power(); void shutdown(); void readPowerStatus(); @@ -133,6 +134,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;