diff --git a/src/PowerFSM.cpp b/src/PowerFSM.cpp index 1e9adbec..8f67b148 100644 --- a/src/PowerFSM.cpp +++ b/src/PowerFSM.cpp @@ -26,60 +26,65 @@ static void sdsEnter() #include "error.h" +static uint32_t secsSlept; + static void lsEnter() { DEBUG_MSG("lsEnter begin, ls_secs=%u\n", radioConfig.preferences.ls_secs); screen.setOn(false); + secsSlept = 0; // How long have we been sleeping this time DEBUG_MSG("lsEnter end\n"); } static void lsIdle() { - DEBUG_MSG("lsIdle begin ls_secs=%u\n", radioConfig.preferences.ls_secs); + // DEBUG_MSG("lsIdle begin ls_secs=%u\n", radioConfig.preferences.ls_secs); #ifndef NO_ESP32 - uint32_t secsSlept = 0; esp_sleep_source_t wakeCause = ESP_SLEEP_WAKEUP_UNDEFINED; - bool reached_ls_secs = false; - while (!reached_ls_secs) { + // Do we have more sleeping to do? + if (secsSlept < radioConfig.preferences.ls_secs) { // Briefly come out of sleep long enough to blink the led once every few seconds - uint32_t sleepTime = 5; + uint32_t sleepTime = 30; - setLed(false); // Never leave led on while in light sleep - wakeCause = doLightSleep(sleepTime * 1000LL); - if (wakeCause != ESP_SLEEP_WAKEUP_TIMER) - break; + // If some other service would stall sleep, don't let sleep happen yet + if (doPreflightSleep()) { + setLed(false); // Never leave led on while in light sleep + wakeCause = doLightSleep(sleepTime * 1000LL); - setLed(true); // briefly turn on led - doLightSleep(1); - if (wakeCause != ESP_SLEEP_WAKEUP_TIMER) - break; + if (wakeCause == ESP_SLEEP_WAKEUP_TIMER) { + // Normal case: timer expired, we should just go back to sleep ASAP - secsSlept += sleepTime; - reached_ls_secs = secsSlept >= radioConfig.preferences.ls_secs; - } - setLed(false); + setLed(true); // briefly turn on led + wakeCause = doLightSleep(1); // leave led on for 1ms - if (reached_ls_secs) { - // stay in LS mode but let loop check whatever it wants - DEBUG_MSG("reached ls_secs, servicing loop()\n"); - } else { - DEBUG_MSG("wakeCause %d\n", wakeCause); + secsSlept += sleepTime; + // DEBUG_MSG("sleeping, flash led!\n"); + } else { + // We woke for some other reason (button press, uart, device interrupt) + DEBUG_MSG("wakeCause %d\n", wakeCause); #ifdef BUTTON_PIN - bool pressed = !digitalRead(BUTTON_PIN); + bool pressed = !digitalRead(BUTTON_PIN); #else - bool pressed = false; + 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) - powerFSM.trigger(EVENT_WAKE_TIMER); + 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) + powerFSM.trigger(EVENT_WAKE_TIMER); + } + } } + } else { + // Time to stop sleeping! + setLed(false); + DEBUG_MSG("reached ls_secs, servicing loop()\n"); + powerFSM.trigger(EVENT_WAKE_TIMER); } #endif } diff --git a/src/mesh/RadioLibInterface.cpp b/src/mesh/RadioLibInterface.cpp index 53f99aae..5239f8f6 100644 --- a/src/mesh/RadioLibInterface.cpp +++ b/src/mesh/RadioLibInterface.cpp @@ -134,7 +134,7 @@ bool RadioLibInterface::canSleep() { bool res = txQueue.isEmpty(); if (!res) // only print debug messages if we are vetoing sleep - DEBUG_MSG("radio wait to sleep, txEmpty=%d\n", txQueue.isEmpty()); + DEBUG_MSG("radio wait to sleep, txEmpty=%d\n", res); return res; } @@ -173,11 +173,13 @@ void RadioLibInterface::loop() case ISR_TX: handleTransmitInterrupt(); startReceive(); + // DEBUG_MSG("tx complete - starting timer\n"); startTransmitTimer(); break; case ISR_RX: handleReceiveInterrupt(); startReceive(); + // DEBUG_MSG("rx complete - starting timer\n"); startTransmitTimer(); break; case TRANSMIT_DELAY_COMPLETED: @@ -192,6 +194,8 @@ void RadioLibInterface::loop() assert(txp); startSend(txp); } + } else { + // DEBUG_MSG("done with txqueue\n"); } break; default: @@ -216,7 +220,7 @@ void RadioLibInterface::startTransmitTimer(bool withDelay) uint32_t delay = !withDelay ? 1 : random(MIN_TX_WAIT_MSEC, MAX_TX_WAIT_MSEC); // See documentation for loop() wrt these values // DEBUG_MSG("xmit timer %d\n", delay); - + // DEBUG_MSG("delaying %u\n", delay); setPeriod(delay); } } diff --git a/src/sleep.cpp b/src/sleep.cpp index 18462de7..ceb21404 100644 --- a/src/sleep.cpp +++ b/src/sleep.cpp @@ -111,8 +111,8 @@ void initDeepSleep() #endif } -/// return true if sleep is allowed -static bool doPreflightSleep() + +bool doPreflightSleep() { if (preflightSleep.notifyObservers(NULL) != 0) return false; // vetoed diff --git a/src/sleep.h b/src/sleep.h index b3446882..66eafa61 100644 --- a/src/sleep.h +++ b/src/sleep.h @@ -19,6 +19,9 @@ void initDeepSleep(); void setCPUFast(bool on); void setLed(bool ledOn); +/** return true if sleep is allowed right now */ +bool doPreflightSleep(); + extern int bootCount; // is bluetooth sw currently running?