From 8ccd59a7d8df2410c991fac1ea16f8f298b94166 Mon Sep 17 00:00:00 2001 From: geeksville Date: Wed, 10 Jun 2020 14:36:11 -0700 Subject: [PATCH] Fix #115: wake from light sleep if a character arrives on the serial port Note - we do this not by using the uart wake feature, but by the lower power GPIO edge feature. Recommend sending "Z" 0x5A - because that has many edges. Send the character 4 times to make sure the device is awake --- src/PowerFSM.cpp | 5 +++++ src/configuration.h | 3 +++ src/sleep.cpp | 13 ++++++++++++- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/PowerFSM.cpp b/src/PowerFSM.cpp index 8f67b148..c495cd27 100644 --- a/src/PowerFSM.cpp +++ b/src/PowerFSM.cpp @@ -62,8 +62,13 @@ static void lsIdle() secsSlept += sleepTime; // DEBUG_MSG("sleeping, flash led!\n"); + } + if (wakeCause == ESP_SLEEP_WAKEUP_UART) { + // Not currently used (because uart triggers in hw have problems) + powerFSM.trigger(EVENT_SERIAL_CONNECTED); } else { // We woke for some other reason (button press, uart, device interrupt) + //uint64_t status = esp_sleep_get_ext1_wakeup_status(); DEBUG_MSG("wakeCause %d\n", wakeCause); #ifdef BUTTON_PIN diff --git a/src/configuration.h b/src/configuration.h index bc64d318..4759dfc7 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -258,7 +258,10 @@ along with this program. If not, see . #ifdef NO_ESP32 #define USE_SEGGER +#else +#define SERIAL0_RX_GPIO 3 // Always GPIO3 on ESP32 #endif + #ifdef USE_SEGGER #include "SEGGER_RTT.h" #define DEBUG_MSG(...) SEGGER_RTT_printf(0, __VA_ARGS__) diff --git a/src/sleep.cpp b/src/sleep.cpp index ceb21404..8cb0f679 100644 --- a/src/sleep.cpp +++ b/src/sleep.cpp @@ -14,6 +14,7 @@ #include "esp_pm.h" #include "rom/rtc.h" #include +#include #include "BluetoothUtil.h" @@ -111,7 +112,6 @@ void initDeepSleep() #endif } - bool doPreflightSleep() { if (preflightSleep.notifyObservers(NULL) != 0) @@ -257,6 +257,17 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r gpio_pullup_en((gpio_num_t)BUTTON_PIN); #endif +#ifdef SERIAL0_RX_GPIO + // We treat the serial port as a GPIO for a fast/low power way of waking, if we see a rising edge that means + // someone started to send something + + // Alas - doesn't work reliably, instead need to use the uart specific version (which burns a little power) + // FIXME: gpio 3 is RXD for serialport 0 on ESP32 + // Send a few Z characters to wake the port + gpio_wakeup_enable((gpio_num_t)SERIAL0_RX_GPIO, GPIO_INTR_LOW_LEVEL); + // uart_set_wakeup_threshold(UART_NUM_0, 3); + // esp_sleep_enable_uart_wakeup(0); +#endif #ifdef BUTTON_PIN gpio_wakeup_enable((gpio_num_t)BUTTON_PIN, GPIO_INTR_LOW_LEVEL); // when user presses, this button goes low #endif