From 7521a518458c49018919581aa101011db74e8f89 Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Tue, 26 Dec 2023 20:50:52 +0800 Subject: [PATCH] fix(esp_hw_support/sleep): stop TG0/TG1 watchdog if XTAL not power down in lightsleep --- components/esp_hw_support/sleep_modes.c | 67 +++++++++++++++---- components/soc/esp32c3/include/soc/soc_caps.h | 1 + 2 files changed, 54 insertions(+), 14 deletions(-) diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index 6c3f0cad18..0e0aec220e 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -29,6 +29,11 @@ #include "hal/systimer_ll.h" #endif +#if SOC_SLEEP_TGWDT_STOP_WORKAROUND +#include "hal/mwdt_ll.h" +#include "hal/timer_ll.h" +#endif + #include "driver/uart.h" #include "soc/cpu.h" @@ -290,6 +295,52 @@ void esp_deep_sleep(uint64_t time_in_us) esp_deep_sleep_start(); } +#if SOC_SLEEP_TGWDT_STOP_WORKAROUND +static uint32_t s_stopped_tgwdt_bmap = 0; +#endif + +// Must be called from critical sections. +static void IRAM_ATTR suspend_timers(uint32_t pd_flags) { + if (!(pd_flags & RTC_SLEEP_PD_XTAL)) { +#if SOC_SLEEP_TGWDT_STOP_WORKAROUND + /* If timegroup implemented task watchdog or interrupt watchdog is running, we have to stop it. */ + for (uint32_t tg_num = 0; tg_num < SOC_TIMER_GROUPS; ++tg_num) { + if (mwdt_ll_check_if_enabled(TIMER_LL_GET_HW(tg_num))) { + mwdt_ll_write_protect_disable(TIMER_LL_GET_HW(tg_num)); + mwdt_ll_disable(TIMER_LL_GET_HW(tg_num)); + mwdt_ll_write_protect_enable(TIMER_LL_GET_HW(tg_num)); + s_stopped_tgwdt_bmap |= BIT(tg_num); + } + } +#endif +#if SOC_SLEEP_SYSTIMER_STALL_WORKAROUND + for (uint32_t counter_id = 0; counter_id < SOC_SYSTIMER_COUNTER_NUM; ++counter_id) { + systimer_ll_enable_counter(&SYSTIMER, counter_id, false); + } +#endif + } +} + +// Must be called from critical sections. +static void IRAM_ATTR resume_timers(uint32_t pd_flags) { + if (!(pd_flags & RTC_SLEEP_PD_XTAL)) { +#if SOC_SLEEP_SYSTIMER_STALL_WORKAROUND + for (uint32_t counter_id = 0; counter_id < SOC_SYSTIMER_COUNTER_NUM; ++counter_id) { + systimer_ll_enable_counter(&SYSTIMER, counter_id, true); + } +#endif +#if SOC_SLEEP_TGWDT_STOP_WORKAROUND + for (uint32_t tg_num = 0; tg_num < SOC_TIMER_GROUPS; ++tg_num) { + if (s_stopped_tgwdt_bmap & BIT(tg_num)) { + mwdt_ll_write_protect_disable(TIMER_LL_GET_HW(tg_num)); + mwdt_ll_enable(TIMER_LL_GET_HW(tg_num)); + mwdt_ll_write_protect_enable(TIMER_LL_GET_HW(tg_num)); + } + } +#endif + } +} + // [refactor-todo] provide target logic for body of uart functions below static void IRAM_ATTR flush_uarts(void) { @@ -563,25 +614,13 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags) #endif #endif // SOC_PM_SUPPORT_DEEPSLEEP_VERIFY_STUB_ONLY } else { -#if SOC_SLEEP_SYSTIMER_STALL_WORKAROUND - if (!(pd_flags & RTC_SLEEP_PD_XTAL)) { - for (uint32_t counter_id = 0; counter_id < SOC_SYSTIMER_COUNTER_NUM; ++counter_id) { - systimer_ll_enable_counter(&SYSTIMER, counter_id, false); - } - } -#endif + suspend_timers(pd_flags); uint32_t cache_state; uint32_t cpuid = cpu_ll_get_core_id(); spi_flash_disable_cache(cpuid, &cache_state); result = call_rtc_sleep_start(reject_triggers, config.lslp_mem_inf_fpu); spi_flash_restore_cache(cpuid, cache_state); -#if SOC_SLEEP_SYSTIMER_STALL_WORKAROUND - if (!(pd_flags & RTC_SLEEP_PD_XTAL)) { - for (uint32_t counter_id = 0; counter_id < SOC_SYSTIMER_COUNTER_NUM; ++counter_id) { - systimer_ll_enable_counter(&SYSTIMER, counter_id, true); - } - } -#endif + resume_timers(pd_flags); } // Restore CPU frequency diff --git a/components/soc/esp32c3/include/soc/soc_caps.h b/components/soc/esp32c3/include/soc/soc_caps.h index 8a3983953c..6dc769d8c9 100644 --- a/components/soc/esp32c3/include/soc/soc_caps.h +++ b/components/soc/esp32c3/include/soc/soc_caps.h @@ -179,6 +179,7 @@ #define SOC_RTC_SLOW_CLOCK_SUPPORT_8MD256 (1) #define SOC_SLEEP_SYSTIMER_STALL_WORKAROUND (1) +#define SOC_SLEEP_TGWDT_STOP_WORKAROUND (1) /*-------------------------- RTCIO CAPS --------------------------------------*/ /* No dedicated RTCIO subsystem on ESP32-C3. RTC functions are still supported