From 824e0ddca81bc98148e063a6a8d325e08963f5db Mon Sep 17 00:00:00 2001 From: jingli Date: Tue, 26 Apr 2022 11:27:40 +0800 Subject: [PATCH 1/2] improve flash power down logic --- components/esp_hw_support/Kconfig | 24 ++++++++++++++++++++++++ components/esp_hw_support/sleep_modes.c | 11 ++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) 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; } From 3a908c66e61816bc792f1dd151557b41d03d9944 Mon Sep 17 00:00:00 2001 From: jingli Date: Sat, 30 Apr 2022 23:13:50 +0800 Subject: [PATCH 2/2] use API instead of Kconfig --- components/esp_hw_support/Kconfig | 24 ------------------------ components/esp_hw_support/sleep_modes.c | 21 +++++++++++++-------- 2 files changed, 13 insertions(+), 32 deletions(-) diff --git a/components/esp_hw_support/Kconfig b/components/esp_hw_support/Kconfig index 3fc570dade..bcccf04e32 100644 --- a/components/esp_hw_support/Kconfig +++ b/components/esp_hw_support/Kconfig @@ -32,30 +32,6 @@ 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 63f87666b8..7c43dbae55 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -636,13 +636,20 @@ static esp_err_t esp_light_sleep_inner(uint32_t pd_flags, return err; } +/** + * vddsdio is used for power supply of spi flash + * + * pd flash via menuconfig | pd flash via `esp_sleep_pd_config` | result + * --------------------------------------------------------------------------------------------------- + * 0 | 0 | no pd flash + * x | 1 | pd flash with relaxed conditions(force_pd) + * 1 | 0 | pd flash with strict conditions(safe_pd) + */ 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 - ; + bool force_pd = !(s_config.wakeup_triggers & RTC_TIMER_TRIG_EN) || (s_config.sleep_duration > vddsdio_pd_sleep_duration); + bool safe_pd = (s_config.wakeup_triggers == RTC_TIMER_TRIG_EN) && (s_config.sleep_duration > vddsdio_pd_sleep_duration); + return (s_config.pd_options[ESP_PD_DOMAIN_VDDSDIO] == ESP_PD_OPTION_OFF) ? force_pd : safe_pd; } esp_err_t esp_light_sleep_start(void) @@ -1352,9 +1359,7 @@ static uint32_t get_power_down_flags(void) * value of this field. */ if (s_config.pd_options[ESP_PD_DOMAIN_VDDSDIO] == ESP_PD_OPTION_AUTO) { -#ifdef CONFIG_ESP_SLEEP_POWER_DOWN_FLASH - s_config.pd_options[ESP_PD_DOMAIN_VDDSDIO] = ESP_PD_OPTION_OFF; -#else +#ifndef CONFIG_ESP_SLEEP_POWER_DOWN_FLASH s_config.pd_options[ESP_PD_DOMAIN_VDDSDIO] = ESP_PD_OPTION_ON; #endif }