diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig index 4112b33720..6ee5313b9b 100644 --- a/components/esp32/Kconfig +++ b/components/esp32/Kconfig @@ -452,6 +452,25 @@ config ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL endchoice +config ESP32_DEEP_SLEEP_WAKEUP_DELAY + int "Extra delay in deep sleep wake stub (in us)" + default 0 + range 0 5000 + help + When ESP32 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. + + If you are using a flash chip which needs more than 900us to become + ready after power on, set this parameter to add extra delay + to the default deep sleep stub. + + If you are seeing "flash read err, 1000" message printed to the + console after deep sleep reset, try increasing this value. + + config ESP32_PHY_AUTO_INIT bool "Initialize PHY in startup code" default y diff --git a/components/esp32/deepsleep.c b/components/esp32/deepsleep.c index cf9ee852e5..0b13ce99a8 100644 --- a/components/esp32/deepsleep.c +++ b/components/esp32/deepsleep.c @@ -26,6 +26,7 @@ #include "driver/rtc_io.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#include "sdkconfig.h" /* Updating RTC_MEMORY_CRC_REG register via set_rtc_memory_crc() is not thread-safe. */ @@ -66,6 +67,12 @@ void RTC_IRAM_ATTR esp_default_wake_deep_sleep(void) { /* Clear MMU for CPU 0 */ REG_SET_BIT(DPORT_PRO_CACHE_CTRL1_REG, DPORT_PRO_CACHE_MMU_IA_CLR); REG_CLR_BIT(DPORT_PRO_CACHE_CTRL1_REG, DPORT_PRO_CACHE_MMU_IA_CLR); +#if CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY > 0 + // ROM code has not started yet, so we need to set delay factor + // used by ets_delay_us first. + ets_update_cpu_frequency(ets_get_detected_xtal_freq() / 1000000); + ets_delay_us(CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY); +#endif } void __attribute__((weak, alias("esp_default_wake_deep_sleep"))) esp_wake_deep_sleep(void);