Skip to content

Commit 85048f3

Browse files
committed
Merge branch 'bugfix/stop_tg_wdt_in_xpd_xtal_lightsleep_v5.3' into 'release/v5.3'
fix(esp_hw_support): stop tg wdt in xpd xtal lightsleep (v5.3) See merge request espressif/esp-idf!30992
2 parents 1a7c782 + 8b36907 commit 85048f3

File tree

7 files changed

+76
-50
lines changed

7 files changed

+76
-50
lines changed

components/esp_hw_support/Kconfig

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -214,18 +214,6 @@ menu "Hardware Settings"
214214
callback and hence it is highly recommended to keep them as short as possible.
215215
endmenu
216216

217-
menu "ESP_SLEEP_WORKAROUND"
218-
# No visible menu/configs for workaround
219-
visible if 0
220-
config ESP_SLEEP_SYSTIMER_STALL_WORKAROUND
221-
bool "ESP32C3 SYSTIMER Stall Issue Workaround"
222-
depends on IDF_TARGET_ESP32C3
223-
help
224-
Its not able to stall ESP32C3 systimer in sleep.
225-
To fix related RTOS TICK issue, select it to disable related systimer during sleep.
226-
TODO: IDF-7036
227-
endmenu
228-
229217
menu "RTC Clock Config"
230218
orsource "./port/$IDF_TARGET/Kconfig.rtc"
231219
endmenu

components/esp_hw_support/port/esp32c3/include/soc/rtc.h

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -646,18 +646,6 @@ void rtc_sleep_init(rtc_sleep_config_t cfg);
646646
*/
647647
void rtc_sleep_low_init(uint32_t slowclk_period);
648648

649-
#if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND
650-
/**
651-
* @brief Configure systimer for esp32c3 systimer stall issue workaround
652-
*
653-
* This function configures related systimer for esp32c3 systimer stall issue.
654-
* Only apply workaround when xtal powered up.
655-
*
656-
* @param en enable systimer or not
657-
*/
658-
void rtc_sleep_systimer_enable(bool en);
659-
#endif
660-
661649
#define RTC_GPIO_TRIG_EN BIT(2) //!< GPIO wakeup
662650
#define RTC_TIMER_TRIG_EN BIT(3) //!< Timer wakeup
663651
#define RTC_WIFI_TRIG_EN BIT(5) //!< WIFI wakeup (light sleep only)

components/esp_hw_support/port/esp32c3/rtc_sleep.c

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
#include "soc/regi2c_dig_reg.h"
2525
#include "soc/regi2c_lp_bias.h"
2626
#include "hal/efuse_hal.h"
27-
#if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND
27+
#if SOC_SLEEP_SYSTIMER_STALL_WORKAROUND
2828
#include "soc/systimer_reg.h"
2929
#endif
3030

@@ -252,17 +252,6 @@ void rtc_sleep_low_init(uint32_t slowclk_period)
252252
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CNTL_CK8M_WAIT_SLP_CYCLES);
253253
}
254254

255-
#if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND
256-
void rtc_sleep_systimer_enable(bool en)
257-
{
258-
if (en) {
259-
REG_SET_BIT(SYSTIMER_CONF_REG, SYSTIMER_TIMER_UNIT1_WORK_EN);
260-
} else {
261-
REG_CLR_BIT(SYSTIMER_CONF_REG, SYSTIMER_TIMER_UNIT1_WORK_EN);
262-
}
263-
}
264-
#endif
265-
266255
static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu);
267256

268257
uint32_t rtc_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu)

components/esp_hw_support/sleep_modes.c

Lines changed: 60 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,15 @@
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
493548
static 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) {

components/esp_timer/src/esp_timer_impl_systimer.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,10 @@ esp_err_t esp_timer_impl_early_init(void)
180180
systimer_hal_select_alarm_mode(&systimer_hal, SYSTIMER_ALARM_ESPTIMER, SYSTIMER_ALARM_MODE_ONESHOT);
181181
systimer_hal_connect_alarm_counter(&systimer_hal, SYSTIMER_ALARM_ESPTIMER, SYSTIMER_COUNTER_ESPTIMER);
182182

183+
for (unsigned cpuid = 0; cpuid < SOC_CPU_CORES_NUM; ++cpuid) {
184+
systimer_hal_counter_can_stall_by_cpu(&systimer_hal, SYSTIMER_COUNTER_ESPTIMER, cpuid, (cpuid < portNUM_PROCESSORS) ? true : false);
185+
}
186+
183187
return ESP_OK;
184188
}
185189

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,14 @@ config SOC_RTC_CNTL_CPU_PD_REG_FILE_NUM
619619
int
620620
default 108
621621

622+
config SOC_SLEEP_SYSTIMER_STALL_WORKAROUND
623+
bool
624+
default y
625+
626+
config SOC_SLEEP_TGWDT_STOP_WORKAROUND
627+
bool
628+
default y
629+
622630
config SOC_RTCIO_PIN_COUNT
623631
int
624632
default 0

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,9 @@
257257

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

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

0 commit comments

Comments
 (0)