From 512800891e7bb7dc41ce3d3b4ac1ec1db7e3d72c Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Thu, 1 Apr 2021 19:52:30 +0800 Subject: [PATCH 1/4] light sleep: add uart new final state machine support for esp32s3 --- components/hal/esp32s3/include/hal/uart_ll.h | 3 +++ components/soc/esp32s3/include/soc/uart_caps.h | 3 +++ 2 files changed, 6 insertions(+) diff --git a/components/hal/esp32s3/include/hal/uart_ll.h b/components/hal/esp32s3/include/hal/uart_ll.h index 24bc307cea..cbf53d454a 100644 --- a/components/hal/esp32s3/include/hal/uart_ll.h +++ b/components/hal/esp32s3/include/hal/uart_ll.h @@ -33,6 +33,9 @@ extern "C" { #define UART_LL_MIN_WAKEUP_THRESH (2) #define UART_LL_INTR_MASK (0x7ffff) //All interrupt mask +#define UART_LL_FSM_IDLE (0x0) +#define UART_LL_FSM_TX_WAIT_SEND (0xf) + // Define UART interrupts typedef enum { UART_INTR_RXFIFO_FULL = (0x1 << 0), diff --git a/components/soc/esp32s3/include/soc/uart_caps.h b/components/soc/esp32s3/include/soc/uart_caps.h index 2024c7a2e5..30d219baac 100644 --- a/components/soc/esp32s3/include/soc/uart_caps.h +++ b/components/soc/esp32s3/include/soc/uart_caps.h @@ -23,6 +23,9 @@ extern "C" { #define SOC_UART_NUM (3) +// UART has an extra TX_WAIT_SEND state when the FIFO is not empty and XOFF is enabled +#define SOC_UART_SUPPORT_FSM_TX_WAIT_SEND (1) + #ifdef __cplusplus } #endif From 5a3d2b18743660f2ba569c55682292b3c9d8cae8 Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Thu, 1 Apr 2021 19:55:15 +0800 Subject: [PATCH 2/4] light sleep: modify some sleep params for esp32s3 --- components/esp32s3/Kconfig | 18 ++++++++++++++++++ components/esp_hw_support/sleep_modes.c | 15 ++++++--------- components/soc/esp32s3/include/soc/rtc.h | 8 ++++---- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/components/esp32s3/Kconfig b/components/esp32s3/Kconfig index 77b51f890d..2205b88470 100644 --- a/components/esp32s3/Kconfig +++ b/components/esp32s3/Kconfig @@ -456,6 +456,24 @@ menu "ESP32S3-Specific" In case more value will help improve the definition of the launch of the crystal. If the crystal could not start, it will be switched to internal RC. + config ESP32S3_DEEP_SLEEP_WAKEUP_DELAY + int "Extra delay in deep sleep wake stub (in us)" + default 2000 + range 0 5000 + help + When ESP32S3 exits deep sleep, the CPU and the flash chip are powered on + at the same time. CPU will run deep sleep stub first, and then + proceed to load code from flash. Some flash chips need sufficient + time to pass between power on and first read operation. By default, + without any extra delay, this time is approximately 900us, although + some flash chip types need more than that. + + By default extra delay is set to 2000us. When optimizing startup time + for applications which require it, this value may be reduced. + + If you are seeing "flash read err, 1000" message printed to the + console after deep sleep reset, try increasing this value. + config ESP32S3_NO_BLOBS bool "No Binary Blobs" depends on !BT_ENABLED diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index bf2fb66db0..8a0baff4d4 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -100,8 +100,8 @@ #define DEFAULT_HARDWARE_OUT_OVERHEAD_US (28) #elif CONFIG_IDF_TARGET_ESP32S3 #define DEFAULT_CPU_FREQ_MHZ CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ -#define DEFAULT_SLEEP_OUT_OVERHEAD_US (0) -#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (0) +#define DEFAULT_SLEEP_OUT_OVERHEAD_US (382) +#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (133) #elif CONFIG_IDF_TARGET_ESP32C3 #define DEFAULT_CPU_FREQ_MHZ CONFIG_ESP32C3_DEFAULT_CPU_FREQ_MHZ #define DEFAULT_SLEEP_OUT_OVERHEAD_US (105) @@ -113,11 +113,7 @@ #endif #define LIGHT_SLEEP_TIME_OVERHEAD_US DEFAULT_HARDWARE_OUT_OVERHEAD_US -#if defined(CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS) || \ - defined(CONFIG_ESP32S2_RTC_CLK_SRC_EXT_CRYS) || \ - defined(CONFIG_ESP32C3_RTC_CLK_SRC_EXT_CRYS) || \ - defined(CONFIG_ESP32H2_RTC_CLK_SRC_EXT_CRYS) || \ - defined(CONFIG_ESP32S3_RTC_CLK_SRC_EXT_CRYS) +#ifdef CONFIG_ESP_SYSTEM_RTC_EXT_XTAL #define DEEP_SLEEP_TIME_OVERHEAD_US (650 + 100 * 240 / DEFAULT_CPU_FREQ_MHZ) #else #define DEEP_SLEEP_TIME_OVERHEAD_US (250 + 100 * 240 / DEFAULT_CPU_FREQ_MHZ) @@ -125,6 +121,8 @@ #if defined(CONFIG_IDF_TARGET_ESP32) && defined(CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY) #define DEEP_SLEEP_WAKEUP_DELAY CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY +#elif defined(CONFIG_IDF_TARGET_ESP32S3) && defined(CONFIG_ESP32S3_DEEP_SLEEP_WAKEUP_DELAY) +#define DEEP_SLEEP_WAKEUP_DELAY CONFIG_ESP32S3_DEEP_SLEEP_WAKEUP_DELAY #else #define DEEP_SLEEP_WAKEUP_DELAY 0 #endif @@ -539,7 +537,6 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags) // Enter sleep rtc_sleep_config_t config = RTC_SLEEP_CONFIG_DEFAULT(pd_flags); rtc_sleep_init(config); - rtc_sleep_low_init(s_config.rtc_clk_cal_period); // Set state machine time for light sleep if (!deep_sleep) { @@ -710,7 +707,7 @@ esp_err_t esp_light_sleep_start(void) uint32_t pd_flags = get_power_down_flags(); // Re-calibrate the RTC Timer clock -#if defined(CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS) || defined(CONFIG_ESP32S2_RTC_CLK_SRC_EXT_CRYS) || defined(CONFIG_ESP32C3_RTC_CLK_SRC_EXT_CRYS) +#ifdef CONFIG_ESP_SYSTEM_RTC_EXT_XTAL uint64_t time_per_us = 1000000ULL; s_config.rtc_clk_cal_period = (time_per_us << RTC_CLK_CAL_FRACT) / rtc_clk_slow_freq_get_hz(); #elif defined(CONFIG_ESP32S2_RTC_CLK_SRC_INT_RC) diff --git a/components/soc/esp32s3/include/soc/rtc.h b/components/soc/esp32s3/include/soc/rtc.h index fa4e837a94..ac186e5e93 100644 --- a/components/soc/esp32s3/include/soc/rtc.h +++ b/components/soc/esp32s3/include/soc/rtc.h @@ -107,10 +107,10 @@ extern "C" { #define RTC_CK8M_ENABLE_WAIT_DEFAULT 5 /* Various delays to be programmed into power control state machines */ -#define RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES RTC_CNTL_PLL_BUF_WAIT_DEFAULT -#define RTC_CNTL_XTL_BUF_WAIT_SLP_US RTC_CNTL_XTL_BUF_WAIT_DEFAULT -#define RTC_CNTL_CK8M_WAIT_SLP_CYCLES RTC_CNTL_CK8M_WAIT_DEFAULT -#define RTC_CNTL_WAKEUP_DELAY_CYCLES (0) +#define RTC_CNTL_XTL_BUF_WAIT_SLP_US (250) +#define RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES (1) +#define RTC_CNTL_CK8M_WAIT_SLP_CYCLES (4) +#define RTC_CNTL_WAKEUP_DELAY_CYCLES (4) #define RTC_CNTL_CK8M_DFREQ_DEFAULT 100 #define RTC_CNTL_SCK_DCAP_DEFAULT 255 From d9aba74c0d15b9e2b2dc82171773acc2a99b3d93 Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Fri, 2 Jul 2021 11:33:40 +0800 Subject: [PATCH 3/4] light sleep: certain peripherals are powered up in sleep --- components/esp_hw_support/sleep_modes.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index 8a0baff4d4..92870b6641 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -371,7 +371,7 @@ static void IRAM_ATTR resume_uarts(void) } } -inline static uint32_t IRAM_ATTR call_rtc_sleep_start(uint32_t reject_triggers); +inline static uint32_t IRAM_ATTR call_rtc_sleep_start(uint32_t reject_triggers, uint32_t lslp_mem_inf_fpu); #if SOC_PM_SUPPORT_CPU_PD esp_err_t esp_sleep_cpu_pd_low_init(bool enable) @@ -565,7 +565,7 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags) result = 0; #else set_rtc_memory_crc(); - result = call_rtc_sleep_start(reject_triggers); + result = call_rtc_sleep_start(reject_triggers, config.lslp_mem_inf_fpu); #endif #else /* Otherwise, need to call the dedicated soc function for this */ @@ -574,7 +574,7 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags) portEXIT_CRITICAL(&spinlock_rtc_deep_sleep); } else { - result = call_rtc_sleep_start(reject_triggers); + result = call_rtc_sleep_start(reject_triggers, config.lslp_mem_inf_fpu); } // Restore CPU frequency @@ -601,12 +601,12 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags) return result; } -inline static uint32_t IRAM_ATTR call_rtc_sleep_start(uint32_t reject_triggers) +inline static uint32_t IRAM_ATTR call_rtc_sleep_start(uint32_t reject_triggers, uint32_t lslp_mem_inf_fpu) { #ifdef CONFIG_IDF_TARGET_ESP32 return rtc_sleep_start(s_config.wakeup_triggers, reject_triggers); #else - return rtc_sleep_start(s_config.wakeup_triggers, reject_triggers, 1); + return rtc_sleep_start(s_config.wakeup_triggers, reject_triggers, lslp_mem_inf_fpu); #endif } From 3c30099327d3dad6288407748191f9986997ec7f Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Wed, 28 Jul 2021 15:44:02 +0800 Subject: [PATCH 4/4] light sleep: add esp_timer light sleep test case --- components/esp_timer/test/test_esp_timer_light_sleep.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/components/esp_timer/test/test_esp_timer_light_sleep.c b/components/esp_timer/test/test_esp_timer_light_sleep.c index e6ef48e5c9..dc5cacdf3d 100644 --- a/components/esp_timer/test/test_esp_timer_light_sleep.c +++ b/components/esp_timer/test/test_esp_timer_light_sleep.c @@ -9,8 +9,6 @@ #include "esp_sleep.h" -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S3) // IDF-1780 ESP32-S3 Deep sleep and light sleep - static void timer_cb1(void *arg) { ++*((int*) arg); @@ -48,5 +46,3 @@ TEST_CASE("Test the periodic timer does not handle lost events during light slee TEST_ESP_OK(esp_timer_dump(stdout)); TEST_ESP_OK(esp_timer_delete(periodic_timer)); } - -#endif // !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S3)