Skip to content

Commit

Permalink
Merge branch 'bugfix/stop_tg_wdt_in_xpd_xtal_lightsleep_v5.3' into 'r…
Browse files Browse the repository at this point in the history
…elease/v5.3'

fix(esp_hw_support): stop tg wdt in xpd xtal lightsleep (v5.3)

See merge request espressif/esp-idf!30992
  • Loading branch information
jack0c committed May 21, 2024
2 parents 1a7c782 + 8b36907 commit 85048f3
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 50 deletions.
12 changes: 0 additions & 12 deletions components/esp_hw_support/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -214,18 +214,6 @@ menu "Hardware Settings"
callback and hence it is highly recommended to keep them as short as possible.
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"
orsource "./port/$IDF_TARGET/Kconfig.rtc"
endmenu
Expand Down
12 changes: 0 additions & 12 deletions components/esp_hw_support/port/esp32c3/include/soc/rtc.h
Original file line number Diff line number Diff line change
Expand Up @@ -646,18 +646,6 @@ void rtc_sleep_init(rtc_sleep_config_t cfg);
*/
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_TIMER_TRIG_EN BIT(3) //!< Timer wakeup
#define RTC_WIFI_TRIG_EN BIT(5) //!< WIFI wakeup (light sleep only)
Expand Down
13 changes: 1 addition & 12 deletions components/esp_hw_support/port/esp32c3/rtc_sleep.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
#include "soc/regi2c_dig_reg.h"
#include "soc/regi2c_lp_bias.h"
#include "hal/efuse_hal.h"
#if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND
#if SOC_SLEEP_SYSTIMER_STALL_WORKAROUND
#include "soc/systimer_reg.h"
#endif

Expand Down Expand Up @@ -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);
}

#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);

uint32_t rtc_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu)
Expand Down
74 changes: 60 additions & 14 deletions components/esp_hw_support/sleep_modes.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@
#include "hal/rtc_io_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
#include "esp_private/pm_impl.h"
#endif
Expand Down Expand Up @@ -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
static void IRAM_ATTR flush_uarts(void)
{
Expand Down Expand Up @@ -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) {
result = ESP_ERR_SLEEP_REJECT;
Expand All @@ -883,9 +933,9 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
#endif
} else {
#if CONFIG_ESP_SLEEP_DEBUG
if (s_sleep_ctx != NULL) {
s_sleep_ctx->wakeup_triggers = s_config.wakeup_triggers;
}
if (s_sleep_ctx != NULL) {
s_sleep_ctx->wakeup_triggers = s_config.wakeup_triggers;
}
#endif
if (deep_sleep) {
#if !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
Expand Down Expand Up @@ -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);
#endif
} else {
suspend_timers(pd_flags);
/* Cache Suspend 1: will wait cache idle in cache suspend */
suspend_cache();
/* On esp32c6, only the lp_aon pad hold function can only hold the GPIO state in the active mode.
Expand Down Expand Up @@ -977,13 +1028,8 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
#endif
/* Cache Resume 1: Resume cache for continue running*/
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 (pd_flags & RTC_SLEEP_PD_VDDSDIO) {
Expand Down
4 changes: 4 additions & 0 deletions components/esp_timer/src/esp_timer_impl_systimer.c
Original file line number Diff line number Diff line change
Expand Up @@ -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_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;
}

Expand Down
8 changes: 8 additions & 0 deletions components/soc/esp32c3/include/soc/Kconfig.soc_caps.in
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,14 @@ config SOC_RTC_CNTL_CPU_PD_REG_FILE_NUM
int
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
int
default 0
Expand Down
3 changes: 3 additions & 0 deletions components/soc/esp32c3/include/soc/soc_caps.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_SLEEP_SYSTIMER_STALL_WORKAROUND 1
#define SOC_SLEEP_TGWDT_STOP_WORKAROUND 1

/*-------------------------- RTCIO CAPS --------------------------------------*/
/* No dedicated RTCIO subsystem on ESP32-C3. RTC functions are still supported
* for hold, wake & 32kHz crystal functions - via rtc_cntl_reg */
Expand Down

0 comments on commit 85048f3

Please sign in to comment.