diff --git a/src/PowerFSM.cpp b/src/PowerFSM.cpp index b8c70292c..b9c7586e4 100644 --- a/src/PowerFSM.cpp +++ b/src/PowerFSM.cpp @@ -348,10 +348,8 @@ void PowerFSM_setup() getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs), NULL, "Screen-on timeout"); +// We never enter light-sleep or NB states on NRF52 (because the CPU uses so little power normally) #ifdef ARCH_ESP32 - State *lowPowerState = &stateLS; - // We never enter light-sleep or NB states on NRF52 (because the CPU uses so little power normally) - // See: https://github.com/meshtastic/firmware/issues/1071 if (isRouter || config.power.is_power_saving) { powerFSM.add_timed_transition(&stateNB, &stateLS, diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 9ccd28aba..547d7f59e 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -164,11 +164,28 @@ static void drawIconScreen(const char *upperMsg, OLEDDisplay *display, OLEDDispl // FIXME - draw serial # somewhere? } +#ifdef ARCH_ESP32 +static void drawFrameResume(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) +{ + uint16_t x_offset = display->width() / 2; + display->setTextAlignment(TEXT_ALIGN_CENTER); + display->setFont(FONT_MEDIUM); + display->drawString(x_offset + x, 26 + y, "Resuming..."); +} +#endif + static void drawBootScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) { - // Draw region in upper left - const char *region = myRegion ? myRegion->name : NULL; - drawIconScreen(region, display, state, x, y); +#ifdef ARCH_ESP32 + if (wakeCause == ESP_SLEEP_WAKEUP_TIMER || wakeCause == ESP_SLEEP_WAKEUP_EXT1) { + drawFrameResume(display, state, x, y); + } else +#endif + { + // Draw region in upper left + const char *region = myRegion ? myRegion->name : NULL; + drawIconScreen(region, display, state, x, y); + } } static void drawOEMIconScreen(const char *upperMsg, OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) diff --git a/src/platform/esp32/main-esp32.cpp b/src/platform/esp32/main-esp32.cpp index 524f8035f..833e058d8 100644 --- a/src/platform/esp32/main-esp32.cpp +++ b/src/platform/esp32/main-esp32.cpp @@ -193,8 +193,26 @@ void cpuDeepSleep(uint32_t msecToWake) rtc_gpio_isolate((gpio_num_t)rtcGpios[i]); #endif - // FIXME, disable internal rtc pullups/pulldowns on the non isolated pins. for inputs that we aren't using - // to detect wake and in normal operation the external part drives them hard. + // FIXME, disable internal rtc pullups/pulldowns on the non isolated pins. for inputs that we aren't using + // to detect wake and in normal operation the external part drives them hard. +#ifdef BUTTON_PIN + // Only GPIOs which are have RTC functionality can be used in this bit map: 0,2,4,12-15,25-27,32-39. +#if SOC_RTCIO_HOLD_SUPPORTED + uint64_t gpioMask = (1ULL << (config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN)); +#endif + +#ifdef BUTTON_NEED_PULLUP + gpio_pullup_en((gpio_num_t)BUTTON_PIN); +#endif + + // Not needed because both of the current boards have external pullups + // FIXME change polarity in hw so we can wake on ANY_HIGH instead - that would allow us to use all three buttons (instead of + // just the first) gpio_pullup_en((gpio_num_t)BUTTON_PIN); + +#if SOC_PM_SUPPORT_EXT_WAKEUP + esp_sleep_enable_ext1_wakeup(gpioMask, ESP_EXT1_WAKEUP_ALL_LOW); +#endif +#endif // We want RTC peripherals to stay on esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); diff --git a/src/sleep.cpp b/src/sleep.cpp index 9d0468e70..532aad519 100644 --- a/src/sleep.cpp +++ b/src/sleep.cpp @@ -95,7 +95,29 @@ void initDeepSleep() { #ifdef ARCH_ESP32 bootCount++; + const char *reason; wakeCause = esp_sleep_get_wakeup_cause(); + + switch (wakeCause) { + case ESP_SLEEP_WAKEUP_EXT0: + reason = "ext0 RTC_IO"; + break; + case ESP_SLEEP_WAKEUP_EXT1: + reason = "ext1 RTC_CNTL"; + break; + case ESP_SLEEP_WAKEUP_TIMER: + reason = "timer"; + break; + case ESP_SLEEP_WAKEUP_TOUCHPAD: + reason = "touchpad"; + break; + case ESP_SLEEP_WAKEUP_ULP: + reason = "ULP program"; + break; + default: + reason = "reset"; + break; + } /* Not using yet because we are using wake on all buttons being low @@ -106,7 +128,6 @@ void initDeepSleep() #ifdef DEBUG_PORT // If we booted because our timer ran out or the user pressed reset, send those as fake events - const char *reason = "reset"; // our best guess RESET_REASON hwReason = rtc_get_reset_reason(0); if (hwReason == RTCWDT_BROWN_OUT_RESET) @@ -118,9 +139,6 @@ void initDeepSleep() if (hwReason == TG1WDT_SYS_RESET) reason = "intWatchdog"; - if (wakeCause == ESP_SLEEP_WAKEUP_TIMER) - reason = "timeout"; - LOG_INFO("Booted, wake cause %d (boot count %d), reset_reason=%s\n", wakeCause, bootCount, reason); #endif #endif