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
This commit is contained in:
Jiang Jiang Jian
2024-05-22 07:37:32 +08:00
7 changed files with 76 additions and 50 deletions

View File

@ -214,18 +214,6 @@ menu "Hardware Settings"
callback and hence it is highly recommended to keep them as short as possible. callback and hence it is highly recommended to keep them as short as possible.
endmenu endmenu
menu "ESP_SLEEP_WORKAROUND"
# No visible menu/configs for workaround
visible if 0
config ESP_SLEEP_SYSTIMER_STALL_WORKAROUND
bool "ESP32C3 SYSTIMER Stall Issue Workaround"
depends on IDF_TARGET_ESP32C3
help
Its not able to stall ESP32C3 systimer in sleep.
To fix related RTOS TICK issue, select it to disable related systimer during sleep.
TODO: IDF-7036
endmenu
menu "RTC Clock Config" menu "RTC Clock Config"
orsource "./port/$IDF_TARGET/Kconfig.rtc" orsource "./port/$IDF_TARGET/Kconfig.rtc"
endmenu endmenu

View File

@ -646,18 +646,6 @@ void rtc_sleep_init(rtc_sleep_config_t cfg);
*/ */
void rtc_sleep_low_init(uint32_t slowclk_period); void rtc_sleep_low_init(uint32_t slowclk_period);
#if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND
/**
* @brief Configure systimer for esp32c3 systimer stall issue workaround
*
* This function configures related systimer for esp32c3 systimer stall issue.
* Only apply workaround when xtal powered up.
*
* @param en enable systimer or not
*/
void rtc_sleep_systimer_enable(bool en);
#endif
#define RTC_GPIO_TRIG_EN BIT(2) //!< GPIO wakeup #define RTC_GPIO_TRIG_EN BIT(2) //!< GPIO wakeup
#define RTC_TIMER_TRIG_EN BIT(3) //!< Timer wakeup #define RTC_TIMER_TRIG_EN BIT(3) //!< Timer wakeup
#define RTC_WIFI_TRIG_EN BIT(5) //!< WIFI wakeup (light sleep only) #define RTC_WIFI_TRIG_EN BIT(5) //!< WIFI wakeup (light sleep only)

View File

@ -24,7 +24,7 @@
#include "soc/regi2c_dig_reg.h" #include "soc/regi2c_dig_reg.h"
#include "soc/regi2c_lp_bias.h" #include "soc/regi2c_lp_bias.h"
#include "hal/efuse_hal.h" #include "hal/efuse_hal.h"
#if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND #if SOC_SLEEP_SYSTIMER_STALL_WORKAROUND
#include "soc/systimer_reg.h" #include "soc/systimer_reg.h"
#endif #endif
@ -252,17 +252,6 @@ void rtc_sleep_low_init(uint32_t slowclk_period)
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CNTL_CK8M_WAIT_SLP_CYCLES); REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CNTL_CK8M_WAIT_SLP_CYCLES);
} }
#if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND
void rtc_sleep_systimer_enable(bool en)
{
if (en) {
REG_SET_BIT(SYSTIMER_CONF_REG, SYSTIMER_TIMER_UNIT1_WORK_EN);
} else {
REG_CLR_BIT(SYSTIMER_CONF_REG, SYSTIMER_TIMER_UNIT1_WORK_EN);
}
}
#endif
static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu); static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu);
uint32_t rtc_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu) uint32_t rtc_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu)

View File

@ -30,6 +30,15 @@
#include "hal/rtc_io_hal.h" #include "hal/rtc_io_hal.h"
#include "hal/clk_tree_hal.h" #include "hal/clk_tree_hal.h"
#if SOC_SLEEP_SYSTIMER_STALL_WORKAROUND
#include "hal/systimer_ll.h"
#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
@ -489,6 +498,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)
{ {
@ -870,11 +925,6 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
} }
} }
#if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND
if (!(pd_flags & RTC_SLEEP_PD_XTAL)) {
rtc_sleep_systimer_enable(false);
}
#endif
if (should_skip_sleep) { if (should_skip_sleep) {
result = ESP_ERR_SLEEP_REJECT; 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
#endif #endif
} else { } else {
#if CONFIG_ESP_SLEEP_DEBUG #if CONFIG_ESP_SLEEP_DEBUG
if (s_sleep_ctx != NULL) { if (s_sleep_ctx != NULL) {
s_sleep_ctx->wakeup_triggers = s_config.wakeup_triggers; s_sleep_ctx->wakeup_triggers = s_config.wakeup_triggers;
} }
#endif #endif
if (deep_sleep) { if (deep_sleep) {
#if !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP #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
result = rtc_deep_sleep_start(s_config.wakeup_triggers, reject_triggers); result = rtc_deep_sleep_start(s_config.wakeup_triggers, reject_triggers);
#endif #endif
} else { } else {
suspend_timers(pd_flags);
/* 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.
@ -977,13 +1028,8 @@ 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();
resume_timers(pd_flags);
} }
#if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND
if (!(pd_flags & RTC_SLEEP_PD_XTAL)) {
rtc_sleep_systimer_enable(true);
}
#endif
} }
#if CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION #if CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION
if (pd_flags & RTC_SLEEP_PD_VDDSDIO) { if (pd_flags & RTC_SLEEP_PD_VDDSDIO) {

View File

@ -180,6 +180,10 @@ esp_err_t esp_timer_impl_early_init(void)
systimer_hal_select_alarm_mode(&systimer_hal, SYSTIMER_ALARM_ESPTIMER, SYSTIMER_ALARM_MODE_ONESHOT); systimer_hal_select_alarm_mode(&systimer_hal, SYSTIMER_ALARM_ESPTIMER, SYSTIMER_ALARM_MODE_ONESHOT);
systimer_hal_connect_alarm_counter(&systimer_hal, SYSTIMER_ALARM_ESPTIMER, SYSTIMER_COUNTER_ESPTIMER); systimer_hal_connect_alarm_counter(&systimer_hal, SYSTIMER_ALARM_ESPTIMER, SYSTIMER_COUNTER_ESPTIMER);
for (unsigned cpuid = 0; cpuid < SOC_CPU_CORES_NUM; ++cpuid) {
systimer_hal_counter_can_stall_by_cpu(&systimer_hal, SYSTIMER_COUNTER_ESPTIMER, cpuid, (cpuid < portNUM_PROCESSORS) ? true : false);
}
return ESP_OK; return ESP_OK;
} }

View File

@ -619,6 +619,14 @@ config SOC_RTC_CNTL_CPU_PD_REG_FILE_NUM
int int
default 108 default 108
config SOC_SLEEP_SYSTIMER_STALL_WORKAROUND
bool
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

@ -257,6 +257,9 @@
#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_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 */