change(esp_hw_support/sleep): improve esp32c3 systimer stall bug workaround

This commit is contained in:
wuzhenghui 2023-12-05 13:38:47 +08:00
parent 562623c67e
commit ad54af74d6
No known key found for this signature in database
GPG Key ID: 3EFEDECDEBA39BB9
7 changed files with 29 additions and 48 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,10 @@
#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_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
@ -870,11 +874,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 +882,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 +912,13 @@ 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 {
#if SOC_SLEEP_SYSTIMER_STALL_WORKAROUND
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.
@ -977,13 +983,14 @@ 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
#if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND
if (!(pd_flags & RTC_SLEEP_PD_XTAL)) { if (!(pd_flags & RTC_SLEEP_PD_XTAL)) {
rtc_sleep_systimer_enable(true); for (uint32_t counter_id = 0; counter_id < SOC_SYSTIMER_COUNTER_NUM; ++counter_id) {
systimer_ll_enable_counter(&SYSTIMER, counter_id, true);
}
} }
#endif #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

@ -623,6 +623,10 @@ 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_RTCIO_PIN_COUNT config SOC_RTCIO_PIN_COUNT
int int
default 0 default 0

View File

@ -258,6 +258,7 @@
#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
/*-------------------------- 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 */