fix(esp_hw_support/sleep): stop TG0/TG1 watchdog if XTAL not power down in lightsleep

This commit is contained in:
wuzhenghui
2023-12-26 20:50:52 +08:00
committed by BOT
parent 92e3fd4e44
commit 1090b496a1
3 changed files with 59 additions and 14 deletions

View File

@ -30,6 +30,11 @@
#include "hal/systimer_ll.h" #include "hal/systimer_ll.h"
#endif #endif
#if SOC_SLEEP_TGWDT_STOP_WORKAROUND
#include "hal/mwdt_ll.h"
#include "hal/timer_ll.h"
#endif
#if SOC_PM_SUPPORT_PMU_MODEM_STATE #if SOC_PM_SUPPORT_PMU_MODEM_STATE
#include "esp_private/pm_impl.h" #include "esp_private/pm_impl.h"
#endif #endif
@ -466,6 +471,52 @@ static void IRAM_ATTR resume_cache(void) {
} }
} }
#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 // [refactor-todo] provide target logic for body of uart functions below
static void IRAM_ATTR flush_uarts(void) static void IRAM_ATTR flush_uarts(void)
{ {
@ -860,13 +911,7 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
#endif #endif
#endif // SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY #endif // SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
} else { } else {
#if SOC_SLEEP_SYSTIMER_STALL_WORKAROUND suspend_timers(pd_flags);
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
/* Cache Suspend 1: will wait cache idle in cache suspend */ /* Cache Suspend 1: will wait cache idle in cache suspend */
suspend_cache(); suspend_cache();
/* On esp32c6, only the lp_aon pad hold function can only hold the GPIO state in the active mode. /* On esp32c6, only the lp_aon pad hold function can only hold the GPIO state in the active mode.
@ -905,13 +950,7 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
#endif #endif
/* Cache Resume 1: Resume cache for continue running*/ /* Cache Resume 1: Resume cache for continue running*/
resume_cache(); resume_cache();
#if SOC_SLEEP_SYSTIMER_STALL_WORKAROUND resume_timers(pd_flags);
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
} }
} }
#if CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION #if CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION

View File

@ -591,6 +591,10 @@ config SOC_SLEEP_SYSTIMER_STALL_WORKAROUND
bool bool
default y default y
config SOC_SLEEP_TGWDT_STOP_WORKAROUND
bool
default y
config SOC_RTCIO_PIN_COUNT config SOC_RTCIO_PIN_COUNT
int int
default 0 default 0

View File

@ -258,6 +258,8 @@
#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)) #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))
#define SOC_SLEEP_SYSTIMER_STALL_WORKAROUND 1 #define SOC_SLEEP_SYSTIMER_STALL_WORKAROUND 1
#define SOC_SLEEP_TGWDT_STOP_WORKAROUND 1
/*-------------------------- RTCIO CAPS --------------------------------------*/ /*-------------------------- RTCIO CAPS --------------------------------------*/
/* No dedicated RTCIO subsystem on ESP32-C3. RTC functions are still supported /* No dedicated RTCIO subsystem on ESP32-C3. RTC functions are still supported
* for hold, wake & 32kHz crystal functions - via rtc_cntl_reg */ * for hold, wake & 32kHz crystal functions - via rtc_cntl_reg */