diff --git a/components/esp_hw_support/Kconfig b/components/esp_hw_support/Kconfig index bcccf04e32..3fc570dade 100644 --- a/components/esp_hw_support/Kconfig +++ b/components/esp_hw_support/Kconfig @@ -32,6 +32,30 @@ menu "Hardware Settings" possible to force a power domain to stay ON during light sleep by using esp_sleep_pd_config() function. + config ESP_SLEEP_FORCE_POWER_DOWN_FLASH + bool "Relax the conditions for power down flash" + depends on ESP_SLEEP_POWER_DOWN_FLASH + default n + help + Currently in IDF, whether the flash can be powered down depends on whether the RTC timer wakeup source + is enabled or not. Only when RTC timer is the only wakeup source and sleep_duration is big enough, we + can power down flash. The reason for this logic is: + + If the flash is powered up again(such as wakeup happens) during its power-down period, the flash may + not work properly. It means that if we are going to power down the flash, we must power down the flash + completely. The power-down process takes time. So, if we can't make sure the sleep time is long enough, + then we can't power down the flash. + + Considering that the probability of flash not working properly when powered up again during power-down + period is very small(< 1%). And maybe some kind of flash do not have this problem. So provide this configuration + item to relax the conditions for power down flash. + + If not enabled, The power-down conditions of flash are strict and absolute safe. If enabled, chip will + also power down flash when RTC timer wakeup source is not enabled or sleep_duration is big enough. + + Enabling this configuration item can bring better power consumption performance. But users need to pay + attention to the potential risks. + config ESP_SLEEP_RTC_BUS_ISO_WORKAROUND bool default y if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index f10a904454..63f87666b8 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -636,6 +636,15 @@ static esp_err_t esp_light_sleep_inner(uint32_t pd_flags, return err; } +static inline bool can_power_down_vddsdio(const uint32_t vddsdio_pd_sleep_duration) +{ + return ((s_config.wakeup_triggers == RTC_TIMER_TRIG_EN) && (s_config.sleep_duration > vddsdio_pd_sleep_duration)) +#if CONFIG_ESP_SLEEP_FORCE_POWER_DOWN_FLASH + || (!(s_config.wakeup_triggers & RTC_TIMER_TRIG_EN) || (s_config.sleep_duration > vddsdio_pd_sleep_duration)) +#endif + ; +} + esp_err_t esp_light_sleep_start(void) { s_config.ccount_ticks_record = cpu_ll_get_cycle_count(); @@ -711,7 +720,7 @@ esp_err_t esp_light_sleep_start(void) flash_enable_time_us + LIGHT_SLEEP_MIN_TIME_US + s_config.sleep_time_adjustment + rtc_time_slowclk_to_us(RTC_MODULE_SLEEP_PREPARE_CYCLES, s_config.rtc_clk_cal_period)); - if (s_config.sleep_duration > vddsdio_pd_sleep_duration) { + if (can_power_down_vddsdio(vddsdio_pd_sleep_duration)) { if (s_config.sleep_time_overhead_out < flash_enable_time_us) { s_config.sleep_time_adjustment += flash_enable_time_us; }