Allow to configure sleep RTC calibration

* The default behaviour is to run some
  calibration cycles to ensure RTC slow clock is
  vlaid during the sleep time.
* However, depending on the application this might
  be redundant or detrimental
* Added an option to configure it if required

# Conflicts:
#	components/esp_hw_support/sleep_modes.c
This commit is contained in:
Daniel Ansorregui 2024-03-17 13:51:56 +00:00
parent 6b9c2fca79
commit 3eed53a071
2 changed files with 37 additions and 10 deletions

View File

@ -85,6 +85,24 @@ config RTC_CLK_CAL_CYCLES
In case more value will help improve the definition of the launch of the crystal.
If the crystal could not start, it will be switched to internal RC.
config RTC_CLK_SLEEP_CAL_CYCLES
int "Number of cycles to calibrate RTC_SLOW_CLK before sleep"
default 10
range 0 1000
help
Just before entering light/deep sleep, a small calibration is done
on the RTC_SLOW_CLK. Having a calibrated RTC_SLOW_CLK is required
in order to proper measure time while in sleep modes and allow proper
wake up from timers.
This option defaults to 10 cycles (around 300us) but can be lowered
down to 0 to avoid calibration, and take the previous one as valid.
It can be particularly useful when the RTC_SLOW_CLK calibration is
done by the APP code using various external sources like NTP
and comparing the long term drift of the clock, or when using a very
stable external oscillator.
It can also be interesting for reducing power usage in APPs that are
constantly entering light sleep.
config RTC_XTAL_CAL_RETRY
int "Number of attempts to repeat 32k XTAL calibration"
default 1

View File

@ -125,7 +125,11 @@
#define ESP_SLEEP_WAIT_FLASH_READY_DEFAULT_DELAY_US 700
// Cycles for RTC Timer clock source (internal oscillator) calibrate
#ifndef CONFIG_RTC_CLK_SLEEP_CAL_CYCLES
#define RTC_CLK_SRC_CAL_CYCLES (10)
#else
#define RTC_CLK_SRC_CAL_CYCLES CONFIG_RTC_CLK_SLEEP_CAL_CYCLES
#endif
#define FAST_CLK_SRC_CAL_CYCLES (2048) /* ~ 127.4 us */
#ifdef CONFIG_IDF_TARGET_ESP32
@ -617,7 +621,22 @@ FORCE_INLINE_ATTR void misc_modules_wake_prepare(void)
static IRAM_ATTR void sleep_low_power_clock_calibration(bool is_dslp)
{
// Calibrate rtc fast clock, only PMU supported chips sleep process is needed.
#if SOC_PMU_SUPPORTED
#if CONFIG_PM_ENABLE
if ((s_lightsleep_cnt % CONFIG_PM_LIGHTSLEEP_RTC_OSC_CAL_INTERVAL == 0) || is_dslp)
#endif
{
s_config.fast_clk_cal_period = rtc_clk_cal(RTC_CAL_RC_FAST, FAST_CLK_SRC_CAL_CYCLES);
}
#endif
// Calibrate rtc slow clock
if (RTC_CLK_SRC_CAL_CYCLES <= 0)
s_config.rtc_clk_cal_period = esp_clk_slowclk_cal_get();
return;
}
#ifdef CONFIG_ESP_SYSTEM_RTC_EXT_XTAL
if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
uint64_t time_per_us = 1000000ULL;
@ -640,16 +659,6 @@ static IRAM_ATTR void sleep_low_power_clock_calibration(bool is_dslp)
esp_clk_slowclk_cal_set(s_config.rtc_clk_cal_period);
}
#endif
// Calibrate rtc fast clock, only PMU supported chips sleep process is needed.
#if SOC_PMU_SUPPORTED
#if CONFIG_PM_ENABLE
if ((s_lightsleep_cnt % CONFIG_PM_LIGHTSLEEP_RTC_OSC_CAL_INTERVAL == 0) || is_dslp)
#endif
{
s_config.fast_clk_cal_period = rtc_clk_cal(RTC_CAL_RC_FAST, FAST_CLK_SRC_CAL_CYCLES);
}
#endif
}