Fix SENSOR power saving deep sleep truncating TX and skipping sleep on failed reads (#10939)
* Fix SENSOR power saving deep sleep behavior Deep sleep could be entered while a telemetry packet was still queued or on air, truncating the transmission. canSleep() gained a deepSleep parameter and now vetoes in that case; light sleep is unchanged. Telemetry modules defer a pending deep sleep (bounded to 30s) until the radio is idle and no longer let the sensor polling interval override the 5s pre-sleep grace period. A failed sensor read still arms deep sleep instead of leaving the node awake for a full telemetry interval. Fixes #10890 Fixes #10932 * Deduplicate telemetry deep sleep deferral logic Move the radio-busy deferral and its counter into BaseTelemetryModule and add an isPowerSavingSensor() helper. Removes the telemetry-specific counter from OSThread. The sleep arming block stays per module because it needs protected OSThread members not visible to the base class.
This commit is contained in:
co-authored by
GitHub
parent
ba473bf529
commit
38074f584f
+9
-6
@@ -190,20 +190,23 @@ void initDeepSleep()
|
||||
#endif
|
||||
}
|
||||
|
||||
bool doPreflightSleep()
|
||||
bool doPreflightSleep(bool deepSleep)
|
||||
{
|
||||
if (preflightSleep.notifyObservers(NULL) != 0)
|
||||
// Observers only get a void*: non-NULL means the hardware (radio) is about to be powered
|
||||
// down (deep sleep / shutdown), NULL means a light sleep where the radio keeps running
|
||||
static const bool deepSleepFlag = true;
|
||||
if (preflightSleep.notifyObservers(deepSleep ? (void *)&deepSleepFlag : NULL) != 0)
|
||||
return false; // vetoed
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Tell devices we are going to sleep and wait for them to handle things
|
||||
static void waitEnterSleep(bool skipPreflight = false)
|
||||
static void waitEnterSleep(bool skipPreflight, bool deepSleep)
|
||||
{
|
||||
if (!skipPreflight) {
|
||||
uint32_t now = millis();
|
||||
while (!doPreflightSleep()) {
|
||||
while (!doPreflightSleep(deepSleep)) {
|
||||
delay(100); // Kinda yucky - wait until radio says say we can shutdown (finished in process sends/receives)
|
||||
|
||||
if (!Throttle::isWithinTimespanMs(now,
|
||||
@@ -230,7 +233,7 @@ void doDeepSleep(uint32_t msecToWake, bool skipPreflight = false, bool skipSaveN
|
||||
|
||||
// not using wifi yet, but once we are this is needed to shutoff the radio hw
|
||||
// esp_wifi_stop();
|
||||
waitEnterSleep(skipPreflight);
|
||||
waitEnterSleep(skipPreflight, true);
|
||||
|
||||
#if defined(ARCH_ESP32) && !MESHTASTIC_EXCLUDE_BLUETOOTH
|
||||
// Full shutdown of bluetooth hardware
|
||||
@@ -410,7 +413,7 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r
|
||||
return ESP_SLEEP_WAKEUP_TIMER;
|
||||
#endif
|
||||
|
||||
waitEnterSleep(false);
|
||||
waitEnterSleep(false, false);
|
||||
notifyLightSleep.notifyObservers(NULL); // Button interrupts are detached here
|
||||
|
||||
uint64_t sleepUsec = sleepMsec * 1000LL;
|
||||
|
||||
Reference in New Issue
Block a user