Skip to content

Commit

Permalink
Merge branch 'bugfix/fix_systimer_stall_issue_in_lightsleep' into 'ma…
Browse files Browse the repository at this point in the history
…ster'

rtc_sleep: workaround systimer stall issue during sleep on ESP32C3

See merge request espressif/esp-idf!22739
  • Loading branch information
jack0c committed Mar 17, 2023
2 parents 34ad5d8 + 14ca81f commit 3f3a2cf
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 0 deletions.
12 changes: 12 additions & 0 deletions components/esp_hw_support/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,18 @@ menu "Hardware Settings"
console after deep sleep reset, try increasing this value.
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
14 changes: 14 additions & 0 deletions components/esp_hw_support/port/esp32c3/rtc_sleep.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
#include "soc/regi2c_dig_reg.h"
#include "soc/regi2c_lp_bias.h"
#include "hal/efuse_hal.h"
#if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND
#include "soc/systimer_reg.h"
#endif

/**
* Configure whether certain peripherals are powered down in deep sleep
Expand Down Expand Up @@ -194,6 +197,17 @@ 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
12 changes: 12 additions & 0 deletions components/esp_hw_support/sleep_modes.c
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,12 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t mo
timer_wakeup_prepare();
}

#if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND
if (!(pd_flags & RTC_SLEEP_PD_XTAL)) {
rtc_sleep_systimer_enable(false);
}
#endif

uint32_t result;
if (deep_sleep) {
#if !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
Expand Down Expand Up @@ -630,6 +636,12 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t mo
#endif
}

#if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND
if (!(pd_flags & RTC_SLEEP_PD_XTAL)) {
rtc_sleep_systimer_enable(true);
}
#endif

// Restore CPU frequency
#if SOC_PM_SUPPORT_PMU_MODEM_STATE
if (pmu_sleep_pll_already_enabled()) {
Expand Down
1 change: 1 addition & 0 deletions components/freertos/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,7 @@ menu "FreeRTOS"
config FREERTOS_SYSTICK_USES_SYSTIMER
bool
default y if FREERTOS_CORETIMER_SYSTIMER_LVL1 || FREERTOS_CORETIMER_SYSTIMER_LVL3
select ESP_SLEEP_SYSTIMER_STALL_WORKAROUND if IDF_TARGET_ESP32C3

config FREERTOS_SYSTICK_USES_CCOUNT
bool
Expand Down
12 changes: 12 additions & 0 deletions components/soc/esp32c3/include/soc/rtc.h
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,18 @@ 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

0 comments on commit 3f3a2cf

Please sign in to comment.