From 5ec7176155f33823b7b406a46f633ccce97376e2 Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Fri, 13 Mar 2026 19:04:54 +0800 Subject: [PATCH 1/3] feat(esp_hw_support): add sleep_reentent UT case back --- .../sleep_retention/pytest_retention.py | 20 +++++++++++++++++++ ...onfig.ci.defaults => sdkconfig.ci.default} | 0 2 files changed, 20 insertions(+) create mode 100644 components/esp_hw_support/test_apps/sleep_retention/pytest_retention.py rename components/esp_hw_support/test_apps/sleep_retention/{sdkconfig.ci.defaults => sdkconfig.ci.default} (100%) diff --git a/components/esp_hw_support/test_apps/sleep_retention/pytest_retention.py b/components/esp_hw_support/test_apps/sleep_retention/pytest_retention.py new file mode 100644 index 0000000000..563e9e4ca0 --- /dev/null +++ b/components/esp_hw_support/test_apps/sleep_retention/pytest_retention.py @@ -0,0 +1,20 @@ +# SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 +import pytest +from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize +from pytest_embedded_idf.utils import soc_filtered_targets + + +@pytest.mark.generic +@pytest.mark.parametrize( + 'config', + [ + 'default', + 'xip_psram', + ], + indirect=True, +) +@idf_parametrize('target', soc_filtered_targets('SOC_PAU_SUPPORTED == 1'), indirect=['target']) +def test_sleep_retention(dut: Dut) -> None: + dut.run_all_single_board_cases() diff --git a/components/esp_hw_support/test_apps/sleep_retention/sdkconfig.ci.defaults b/components/esp_hw_support/test_apps/sleep_retention/sdkconfig.ci.default similarity index 100% rename from components/esp_hw_support/test_apps/sleep_retention/sdkconfig.ci.defaults rename to components/esp_hw_support/test_apps/sleep_retention/sdkconfig.ci.default From defaa4340bc6ddf6dbb9b8e94020e1354cb91080 Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Mon, 16 Mar 2026 12:24:52 +0800 Subject: [PATCH 2/3] fix(esp_hw_support): adjust PSRAM half-sleep resume handling for CONFIG_SPIRAM_XIP_FROM_PSRAM --- components/esp_hw_support/sleep_modes.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index c350649201..fe308d2f43 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -993,6 +993,12 @@ static esp_err_t FORCE_IRAM_ATTR esp_sleep_start_safe(uint32_t sleep_flags, uint /* Cache Resume 1: Resume cache for continue running*/ resume_cache(); resume_timers(sleep_flags); +#if CONFIG_PM_SLP_SPIRAM_HALFSLEEP_ENABLED && CONFIG_SPIRAM_XIP_FROM_PSRAM + // Code outside of esp_sleep_start_safe may be linked to FLASH, and if CONFIG_SPIRAM_XIP_FROM_PSRAM + // is enabled, code in Flash will be copied to PSRAM for execution. We need to wait here until + // PSRAM exits half-sleep before returning. + esp_psram_impl_resume_from_halfsleep_mode(s_config.rtc_clk_cal_period); +#endif } return result; } @@ -1391,10 +1397,6 @@ static SLEEP_FN_ATTR esp_err_t esp_light_sleep_inner(uint32_t sleep_flags, uint3 #endif } -#if CONFIG_PM_SLP_SPIRAM_HALFSLEEP_ENABLED - esp_psram_impl_resume_from_halfsleep_mode(s_config.rtc_clk_cal_period); -#endif - #if CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION if (sleep_flags & RTC_SLEEP_PD_VDDSDIO) { /* Cache Resume 2: flash is ready now, we can resume the cache and access flash safely after */ @@ -1679,6 +1681,14 @@ esp_err_t esp_light_sleep_start(void) } #endif +#if CONFIG_PM_SLP_SPIRAM_HALFSLEEP_ENABLED && !CONFIG_SPIRAM_XIP_FROM_PSRAM + // If CONFIG_SPIRAM_XIP_FROM_PSRAM is not enabled, the sleep-wake process + // prior to this point does not access the PSRAM, so we can postpone waiting + // for the PSRAM to resume until here, in order to reuse the time overhead + // of the wake-up process as much as possible. + esp_psram_impl_resume_from_halfsleep_mode(s_config.rtc_clk_cal_period); +#endif + #if !CONFIG_FREERTOS_UNICORE esp_ipc_isr_stall_resume(); #if CONFIG_PM_ESP_SLEEP_POWER_DOWN_CPU && SOC_PM_CPU_RETENTION_BY_SW From 2bcc29510a845ac8df404c37afbb76e5e5895890 Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Mon, 16 Mar 2026 20:37:08 +0800 Subject: [PATCH 3/3] fix(esp_hw_support): move timers suspend/resume to misc modules prepare --- components/esp_hw_support/sleep_modes.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index fe308d2f43..f85256885d 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -723,6 +723,7 @@ static SLEEP_FN_ATTR void misc_modules_sleep_prepare(uint32_t sleep_flags, bool sar_periph_ctrl_power_disable(); } #endif + suspend_timers(sleep_flags); } /** @@ -730,6 +731,7 @@ static SLEEP_FN_ATTR void misc_modules_sleep_prepare(uint32_t sleep_flags, bool */ static SLEEP_FN_ATTR void misc_modules_wake_prepare(uint32_t sleep_flags) { + resume_timers(sleep_flags); #if CONFIG_ESP_ENABLE_PVT && SOC_PVT_EN_WITH_SLEEP pvt_func_enable(true); #endif @@ -906,7 +908,6 @@ static esp_err_t FORCE_IRAM_ATTR esp_sleep_start_safe(uint32_t sleep_flags, uint result = rtc_deep_sleep_start(s_config.wakeup_triggers, reject_triggers); #endif } else { - suspend_timers(sleep_flags); /* Cache Suspend 1: will wait cache idle in cache suspend */ suspend_cache(); if (!(sleep_flags & RTC_SLEEP_PD_VDDSDIO)) { @@ -992,7 +993,6 @@ static esp_err_t FORCE_IRAM_ATTR esp_sleep_start_safe(uint32_t sleep_flags, uint #endif /* Cache Resume 1: Resume cache for continue running*/ resume_cache(); - resume_timers(sleep_flags); #if CONFIG_PM_SLP_SPIRAM_HALFSLEEP_ENABLED && CONFIG_SPIRAM_XIP_FROM_PSRAM // Code outside of esp_sleep_start_safe may be linked to FLASH, and if CONFIG_SPIRAM_XIP_FROM_PSRAM // is enabled, code in Flash will be copied to PSRAM for execution. We need to wait here until