From 10c2cddddf329dff8fbe109e14fd00501d18e0c2 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Wed, 4 Jul 2018 12:11:07 +0800 Subject: [PATCH] sleep: fix flushing UARTs when entering deep sleep Since 94250e42a0, UART output is suspended when entering sleep mode (deep or light sleep). This makes sense for light sleep, where sleep normally takes small amount of time, and flushing the UART would add a lot of latency. But this breaks existing behaviour for deep sleep, where UART output was previously sent out before entering sleep mode. Closes https://github.com/espressif/esp-idf/issues/2145 --- components/esp32/sleep_modes.c | 17 +++++++++++++++-- docs/en/api-reference/system/sleep_modes.rst | 7 +++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/components/esp32/sleep_modes.c b/components/esp32/sleep_modes.c index c5b31b350..36730d291 100644 --- a/components/esp32/sleep_modes.c +++ b/components/esp32/sleep_modes.c @@ -141,6 +141,13 @@ void esp_deep_sleep(uint64_t time_in_us) esp_deep_sleep_start(); } +static void IRAM_ATTR flush_uarts() +{ + for (int i = 0; i < 3; ++i) { + uart_tx_wait_idle(i); + } +} + static void IRAM_ATTR suspend_uarts() { for (int i = 0; i < 3; ++i) { @@ -160,8 +167,14 @@ static void IRAM_ATTR resume_uarts() static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags) { - // Stop UART output so that output is not lost due to APB frequency change - suspend_uarts(); + // Stop UART output so that output is not lost due to APB frequency change. + // For light sleep, suspend UART output — it will resume after wakeup. + // For deep sleep, wait for the contents of UART FIFO to be sent. + if (pd_flags & RTC_SLEEP_PD_DIG) { + flush_uarts(); + } else { + suspend_uarts(); + } // Save current frequency and switch to XTAL rtc_cpu_freq_t cpu_freq = rtc_clk_cpu_freq_get(); diff --git a/docs/en/api-reference/system/sleep_modes.rst b/docs/en/api-reference/system/sleep_modes.rst index bc0033abc..de56c56e5 100644 --- a/docs/en/api-reference/system/sleep_modes.rst +++ b/docs/en/api-reference/system/sleep_modes.rst @@ -136,6 +136,13 @@ Add the following code before :cpp:func:`esp_deep_sleep_start` to remove this ex rtc_gpio_isolate(GPIO_NUM_12); ``` +UART output handling +-------------------- + +Before entering sleep mode, :cpp:func:`esp_deep_sleep_start` will flush the contents of UART FIFOs. + +When entering light sleep mode using :cpp:func:`esp_light_sleep_start`, UART FIFOs will not be flushed. Instead, UART output will be suspended, and remaining characters in the FIFO will be sent out after wakeup from light sleep. + Checking sleep wakeup cause ---------------------------