3030#include "hal/rtc_io_hal.h"
3131#include "hal/clk_tree_hal.h"
3232
33+ #if SOC_SLEEP_SYSTIMER_STALL_WORKAROUND
34+ #include "hal/systimer_ll.h"
35+ #endif
36+
37+ #if SOC_SLEEP_TGWDT_STOP_WORKAROUND
38+ #include "hal/mwdt_ll.h"
39+ #include "hal/timer_ll.h"
40+ #endif
41+
3342#if SOC_PM_SUPPORT_PMU_MODEM_STATE
3443#include "esp_private/pm_impl.h"
3544#endif
@@ -489,6 +498,52 @@ static void IRAM_ATTR resume_cache(void) {
489498 }
490499}
491500
501+ #if SOC_SLEEP_TGWDT_STOP_WORKAROUND
502+ static uint32_t s_stopped_tgwdt_bmap = 0 ;
503+ #endif
504+
505+ // Must be called from critical sections.
506+ static void IRAM_ATTR suspend_timers (uint32_t pd_flags ) {
507+ if (!(pd_flags & RTC_SLEEP_PD_XTAL )) {
508+ #if SOC_SLEEP_TGWDT_STOP_WORKAROUND
509+ /* If timegroup implemented task watchdog or interrupt watchdog is running, we have to stop it. */
510+ for (uint32_t tg_num = 0 ; tg_num < SOC_TIMER_GROUPS ; ++ tg_num ) {
511+ if (mwdt_ll_check_if_enabled (TIMER_LL_GET_HW (tg_num ))) {
512+ mwdt_ll_write_protect_disable (TIMER_LL_GET_HW (tg_num ));
513+ mwdt_ll_disable (TIMER_LL_GET_HW (tg_num ));
514+ mwdt_ll_write_protect_enable (TIMER_LL_GET_HW (tg_num ));
515+ s_stopped_tgwdt_bmap |= BIT (tg_num );
516+ }
517+ }
518+ #endif
519+ #if SOC_SLEEP_SYSTIMER_STALL_WORKAROUND
520+ for (uint32_t counter_id = 0 ; counter_id < SOC_SYSTIMER_COUNTER_NUM ; ++ counter_id ) {
521+ systimer_ll_enable_counter (& SYSTIMER , counter_id , false);
522+ }
523+ #endif
524+ }
525+ }
526+
527+ // Must be called from critical sections.
528+ static void IRAM_ATTR resume_timers (uint32_t pd_flags ) {
529+ if (!(pd_flags & RTC_SLEEP_PD_XTAL )) {
530+ #if SOC_SLEEP_SYSTIMER_STALL_WORKAROUND
531+ for (uint32_t counter_id = 0 ; counter_id < SOC_SYSTIMER_COUNTER_NUM ; ++ counter_id ) {
532+ systimer_ll_enable_counter (& SYSTIMER , counter_id , true);
533+ }
534+ #endif
535+ #if SOC_SLEEP_TGWDT_STOP_WORKAROUND
536+ for (uint32_t tg_num = 0 ; tg_num < SOC_TIMER_GROUPS ; ++ tg_num ) {
537+ if (s_stopped_tgwdt_bmap & BIT (tg_num )) {
538+ mwdt_ll_write_protect_disable (TIMER_LL_GET_HW (tg_num ));
539+ mwdt_ll_enable (TIMER_LL_GET_HW (tg_num ));
540+ mwdt_ll_write_protect_enable (TIMER_LL_GET_HW (tg_num ));
541+ }
542+ }
543+ #endif
544+ }
545+ }
546+
492547// [refactor-todo] provide target logic for body of uart functions below
493548static void IRAM_ATTR flush_uarts (void )
494549{
@@ -870,11 +925,6 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
870925 }
871926 }
872927
873- #if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND
874- if (!(pd_flags & RTC_SLEEP_PD_XTAL )) {
875- rtc_sleep_systimer_enable (false);
876- }
877- #endif
878928
879929 if (should_skip_sleep ) {
880930 result = ESP_ERR_SLEEP_REJECT ;
@@ -883,9 +933,9 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
883933#endif
884934 } else {
885935#if CONFIG_ESP_SLEEP_DEBUG
886- if (s_sleep_ctx != NULL ) {
887- s_sleep_ctx -> wakeup_triggers = s_config .wakeup_triggers ;
888- }
936+ if (s_sleep_ctx != NULL ) {
937+ s_sleep_ctx -> wakeup_triggers = s_config .wakeup_triggers ;
938+ }
889939#endif
890940 if (deep_sleep ) {
891941#if !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
@@ -913,6 +963,7 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
913963 result = rtc_deep_sleep_start (s_config .wakeup_triggers , reject_triggers );
914964#endif
915965 } else {
966+ suspend_timers (pd_flags );
916967 /* Cache Suspend 1: will wait cache idle in cache suspend */
917968 suspend_cache ();
918969 /* On esp32c6, only the lp_aon pad hold function can only hold the GPIO state in the active mode.
@@ -977,13 +1028,8 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
9771028#endif
9781029 /* Cache Resume 1: Resume cache for continue running*/
9791030 resume_cache ();
1031+ resume_timers (pd_flags );
9801032 }
981-
982- #if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND
983- if (!(pd_flags & RTC_SLEEP_PD_XTAL )) {
984- rtc_sleep_systimer_enable (true);
985- }
986- #endif
9871033 }
9881034#if CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION
9891035 if (pd_flags & RTC_SLEEP_PD_VDDSDIO ) {
0 commit comments