Skip to content

Commit 8b36907

Browse files
committed
fix(esp_hw_support/sleep): stop TG0/TG1 watchdog if XTAL not power down in lightsleep
1 parent d91dfe3 commit 8b36907

File tree

3 files changed

+59
-14
lines changed

3 files changed

+59
-14
lines changed

components/esp_hw_support/sleep_modes.c

Lines changed: 53 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@
3434
#include "hal/systimer_ll.h"
3535
#endif
3636

37+
#if SOC_SLEEP_TGWDT_STOP_WORKAROUND
38+
#include "hal/mwdt_ll.h"
39+
#include "hal/timer_ll.h"
40+
#endif
41+
3742
#if SOC_PM_SUPPORT_PMU_MODEM_STATE
3843
#include "esp_private/pm_impl.h"
3944
#endif
@@ -493,6 +498,52 @@ static void IRAM_ATTR resume_cache(void) {
493498
}
494499
}
495500

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+
496547
// [refactor-todo] provide target logic for body of uart functions below
497548
static void IRAM_ATTR flush_uarts(void)
498549
{
@@ -912,13 +963,7 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
912963
result = rtc_deep_sleep_start(s_config.wakeup_triggers, reject_triggers);
913964
#endif
914965
} else {
915-
#if SOC_SLEEP_SYSTIMER_STALL_WORKAROUND
916-
if (!(pd_flags & RTC_SLEEP_PD_XTAL)) {
917-
for (uint32_t counter_id = 0; counter_id < SOC_SYSTIMER_COUNTER_NUM; ++counter_id) {
918-
systimer_ll_enable_counter(&SYSTIMER, counter_id, false);
919-
}
920-
}
921-
#endif
966+
suspend_timers(pd_flags);
922967
/* Cache Suspend 1: will wait cache idle in cache suspend */
923968
suspend_cache();
924969
/* On esp32c6, only the lp_aon pad hold function can only hold the GPIO state in the active mode.
@@ -983,13 +1028,7 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
9831028
#endif
9841029
/* Cache Resume 1: Resume cache for continue running*/
9851030
resume_cache();
986-
#if SOC_SLEEP_SYSTIMER_STALL_WORKAROUND
987-
if (!(pd_flags & RTC_SLEEP_PD_XTAL)) {
988-
for (uint32_t counter_id = 0; counter_id < SOC_SYSTIMER_COUNTER_NUM; ++counter_id) {
989-
systimer_ll_enable_counter(&SYSTIMER, counter_id, true);
990-
}
991-
}
992-
#endif
1031+
resume_timers(pd_flags);
9931032
}
9941033
}
9951034
#if CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION

components/soc/esp32c3/include/soc/Kconfig.soc_caps.in

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -623,6 +623,10 @@ config SOC_SLEEP_SYSTIMER_STALL_WORKAROUND
623623
bool
624624
default y
625625

626+
config SOC_SLEEP_TGWDT_STOP_WORKAROUND
627+
bool
628+
default y
629+
626630
config SOC_RTCIO_PIN_COUNT
627631
int
628632
default 0

components/soc/esp32c3/include/soc/soc_caps.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,8 @@
258258
#define SOC_RTC_CNTL_CPU_PD_RETENTION_MEM_SIZE (SOC_RTC_CNTL_CPU_PD_REG_FILE_NUM * (SOC_RTC_CNTL_CPU_PD_DMA_BUS_WIDTH >> 3))
259259

260260
#define SOC_SLEEP_SYSTIMER_STALL_WORKAROUND 1
261+
#define SOC_SLEEP_TGWDT_STOP_WORKAROUND 1
262+
261263
/*-------------------------- RTCIO CAPS --------------------------------------*/
262264
/* No dedicated RTCIO subsystem on ESP32-C3. RTC functions are still supported
263265
* for hold, wake & 32kHz crystal functions - via rtc_cntl_reg */

0 commit comments

Comments
 (0)