mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-01 19:54:32 +02:00
Merge branch 'bugfix/lightsleep_accuracy_opt' into 'master'
Lightsleep overhead time accuracy optimization See merge request espressif/esp-idf!11291
This commit is contained in:
@@ -2,9 +2,3 @@
|
||||
archive: libesp_common.a
|
||||
entries:
|
||||
esp_err (noflash)
|
||||
if PM_RTOS_IDLE_OPT = y:
|
||||
freertos_hooks:esp_vApplicationIdleHook (noflash)
|
||||
task_wdt:idle_hook_cb (noflash)
|
||||
task_wdt:esp_task_wdt_reset (noflash)
|
||||
task_wdt:find_task_in_twdt_list (noflash)
|
||||
task_wdt:reset_hw_timer (noflash)
|
||||
|
@@ -11,5 +11,3 @@ entries:
|
||||
rtc_sleep (noflash_text)
|
||||
rtc_time (noflash_text)
|
||||
rtc_wdt (noflash_text)
|
||||
if PM_SLP_IRAM_OPT = y:
|
||||
rtc_init:rtc_vddsdio_get_config (noflash)
|
||||
|
@@ -30,27 +30,20 @@
|
||||
|
||||
#define MHZ (1000000)
|
||||
|
||||
/* Various delays to be programmed into power control state machines */
|
||||
#define RTC_CNTL_XTL_BUF_WAIT_SLP 2
|
||||
#define RTC_CNTL_PLL_BUF_WAIT_SLP 2
|
||||
#define RTC_CNTL_CK8M_WAIT_SLP 4
|
||||
#define OTHER_BLOCKS_POWERUP 1
|
||||
#define OTHER_BLOCKS_WAIT 1
|
||||
#define ROM_RAM_POWERUP_CYCLES RTC_CNTL_OTHER_BLOCKS_POWERUP_CYCLES
|
||||
#define ROM_RAM_WAIT_CYCLES RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES
|
||||
|
||||
#define ROM_RAM_POWERUP_CYCLES OTHER_BLOCKS_POWERUP
|
||||
#define ROM_RAM_WAIT_CYCLES OTHER_BLOCKS_WAIT
|
||||
#define WIFI_POWERUP_CYCLES RTC_CNTL_OTHER_BLOCKS_POWERUP_CYCLES
|
||||
#define WIFI_WAIT_CYCLES RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES
|
||||
|
||||
#define WIFI_POWERUP_CYCLES OTHER_BLOCKS_POWERUP
|
||||
#define WIFI_WAIT_CYCLES OTHER_BLOCKS_WAIT
|
||||
#define RTC_POWERUP_CYCLES RTC_CNTL_OTHER_BLOCKS_POWERUP_CYCLES
|
||||
#define RTC_WAIT_CYCLES RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES
|
||||
|
||||
#define RTC_POWERUP_CYCLES OTHER_BLOCKS_POWERUP
|
||||
#define RTC_WAIT_CYCLES OTHER_BLOCKS_WAIT
|
||||
#define DG_WRAP_POWERUP_CYCLES RTC_CNTL_OTHER_BLOCKS_POWERUP_CYCLES
|
||||
#define DG_WRAP_WAIT_CYCLES RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES
|
||||
|
||||
#define DG_WRAP_POWERUP_CYCLES OTHER_BLOCKS_POWERUP
|
||||
#define DG_WRAP_WAIT_CYCLES OTHER_BLOCKS_WAIT
|
||||
|
||||
#define RTC_MEM_POWERUP_CYCLES OTHER_BLOCKS_POWERUP
|
||||
#define RTC_MEM_WAIT_CYCLES OTHER_BLOCKS_WAIT
|
||||
#define RTC_MEM_POWERUP_CYCLES RTC_CNTL_OTHER_BLOCKS_POWERUP_CYCLES
|
||||
#define RTC_MEM_WAIT_CYCLES RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES
|
||||
|
||||
/**
|
||||
* @brief Power down flags for rtc_sleep_pd function
|
||||
@@ -101,11 +94,6 @@ static void rtc_sleep_pd(rtc_sleep_pd_config_t cfg)
|
||||
|
||||
void rtc_sleep_init(rtc_sleep_config_t cfg)
|
||||
{
|
||||
// set 5 PWC state machine times to fit in main state machine time
|
||||
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, RTC_CNTL_PLL_BUF_WAIT_SLP);
|
||||
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_XTL_BUF_WAIT, RTC_CNTL_XTL_BUF_WAIT_SLP);
|
||||
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CNTL_CK8M_WAIT_SLP);
|
||||
|
||||
// set shortest possible sleep time limit
|
||||
REG_SET_FIELD(RTC_CNTL_TIMER5_REG, RTC_CNTL_MIN_SLP_VAL, RTC_CNTL_MIN_SLP_VAL_MIN);
|
||||
|
||||
@@ -220,6 +208,14 @@ void rtc_sleep_init(rtc_sleep_config_t cfg)
|
||||
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_SLP, cfg.dig_dbias_slp);
|
||||
}
|
||||
|
||||
void rtc_sleep_low_init(uint32_t slowclk_period)
|
||||
{
|
||||
// set 5 PWC state machine times to fit in main state machine time
|
||||
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES);
|
||||
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_XTL_BUF_WAIT, rtc_time_us_to_slowclk(RTC_CNTL_XTL_BUF_WAIT_SLP_US, slowclk_period));
|
||||
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CNTL_CK8M_WAIT_SLP_CYCLES);
|
||||
}
|
||||
|
||||
void rtc_sleep_set_wakeup_time(uint64_t t)
|
||||
{
|
||||
rtc_cntl_ll_set_wakeup_timer(t);
|
||||
|
@@ -127,6 +127,13 @@ void rtc_sleep_init(rtc_sleep_config_t cfg)
|
||||
REG_SET_FIELD(RTC_CNTL_SLP_REJECT_CONF_REG, RTC_CNTL_LIGHT_SLP_REJECT_EN, cfg.light_slp_reject);
|
||||
}
|
||||
|
||||
void rtc_sleep_low_init(uint32_t slowclk_period)
|
||||
{
|
||||
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES);
|
||||
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_XTL_BUF_WAIT, rtc_time_us_to_slowclk(RTC_CNTL_XTL_BUF_WAIT_SLP_US, slowclk_period));
|
||||
}
|
||||
|
||||
void rtc_sleep_set_wakeup_time(uint64_t t)
|
||||
{
|
||||
rtc_cntl_ll_set_wakeup_timer(t);
|
||||
|
@@ -31,35 +31,13 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Clock calibration function used by rtc_clk_cal and rtc_clk_cal_ratio
|
||||
* @brief One-off clock calibration function used by rtc_clk_cal_internal
|
||||
* @param cal_clk which clock to calibrate
|
||||
* @param slowclk_cycles number of slow clock cycles to count
|
||||
* @return number of XTAL clock cycles within the given number of slow clock cycles
|
||||
*/
|
||||
uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
|
||||
static uint32_t rtc_clk_cal_internal_oneoff(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
|
||||
{
|
||||
/* On ESP32S2, choosing RTC_CAL_RTC_MUX results in calibration of
|
||||
* the 90k RTC clock regardless of the currenlty selected SLOW_CLK.
|
||||
* On the ESP32, it used the currently selected SLOW_CLK.
|
||||
* The following code emulates ESP32 behavior:
|
||||
*/
|
||||
if (cal_clk == RTC_CAL_RTC_MUX) {
|
||||
rtc_slow_freq_t slow_freq = rtc_clk_slow_freq_get();
|
||||
if (slow_freq == RTC_SLOW_FREQ_32K_XTAL) {
|
||||
cal_clk = RTC_CAL_32K_XTAL;
|
||||
} else if (slow_freq == RTC_SLOW_FREQ_8MD256) {
|
||||
cal_clk = RTC_CAL_8MD256;
|
||||
}
|
||||
}
|
||||
/* Enable requested clock (150k clock is always on) */
|
||||
int dig_32k_xtal_state = REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN);
|
||||
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_state) {
|
||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN, 1);
|
||||
}
|
||||
|
||||
if (cal_clk == RTC_CAL_8MD256) {
|
||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_D256_EN);
|
||||
}
|
||||
/* Prepare calibration */
|
||||
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cal_clk);
|
||||
/* There may be another calibration process already running during we call this function,
|
||||
@@ -104,6 +82,91 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return cal_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Cycling clock calibration function used by rtc_clk_cal_internal
|
||||
* @param cal_clk which clock to calibrate
|
||||
* @param slowclk_cycles number of slow clock cycles to count
|
||||
* @return number of XTAL clock cycles within the given number of slow clock cycles
|
||||
*/
|
||||
static uint32_t rtc_clk_cal_internal_cycling(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
|
||||
{
|
||||
/* Get which slowclk is in calibration and max cali cycles */
|
||||
rtc_cal_sel_t in_calibration_clk;
|
||||
in_calibration_clk = REG_GET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL);
|
||||
uint32_t cali_slowclk_cycles = REG_GET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX);
|
||||
/* If no calibration in process or calibration period equal to 0, use slowclk_cycles cycles to calibrate slowclk */
|
||||
if (cali_slowclk_cycles == 0 || !GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING) || in_calibration_clk != cal_clk) {
|
||||
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING);
|
||||
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cal_clk);
|
||||
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles);
|
||||
SET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING);
|
||||
cali_slowclk_cycles = slowclk_cycles;
|
||||
}
|
||||
|
||||
/* Wait for calibration finished */
|
||||
while (!GET_PERI_REG_MASK(TIMG_RTCCALICFG1_REG(0), TIMG_RTC_CALI_CYCLING_DATA_VLD));
|
||||
uint32_t cal_val = REG_GET_FIELD(TIMG_RTCCALICFG1_REG(0), TIMG_RTC_CALI_VALUE);
|
||||
|
||||
return cal_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Slowclk period calculating funtion used by rtc_clk_cal and rtc_clk_cal_cycling
|
||||
* @param xtal_cycles number of xtal cycles count
|
||||
* @param slowclk_cycles number of slow clock cycles to count
|
||||
* @return slow clock period
|
||||
*/
|
||||
static uint32_t rtc_clk_xtal_to_slowclk(uint64_t xtal_cycles, uint32_t slowclk_cycles)
|
||||
{
|
||||
rtc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get();
|
||||
uint64_t divider = ((uint64_t)xtal_freq) * slowclk_cycles;
|
||||
uint64_t period_64 = ((xtal_cycles << RTC_CLK_CAL_FRACT) + divider / 2 - 1) / divider;
|
||||
uint32_t period = (uint32_t)(period_64 & UINT32_MAX);
|
||||
return period;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clock calibration function used by rtc_clk_cal and rtc_clk_cal_ratio
|
||||
* @param cal_clk which clock to calibrate
|
||||
* @param slowclk_cycles number of slow clock cycles to count
|
||||
* @return number of XTAL clock cycles within the given number of slow clock cycles
|
||||
*/
|
||||
uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles, uint32_t cal_mode)
|
||||
{
|
||||
/* On ESP32S2, choosing RTC_CAL_RTC_MUX results in calibration of
|
||||
* the 90k RTC clock regardless of the currenlty selected SLOW_CLK.
|
||||
* On the ESP32, it used the currently selected SLOW_CLK.
|
||||
* The following code emulates ESP32 behavior:
|
||||
*/
|
||||
if (cal_clk == RTC_CAL_RTC_MUX) {
|
||||
rtc_slow_freq_t slow_freq = rtc_clk_slow_freq_get();
|
||||
if (slow_freq == RTC_SLOW_FREQ_32K_XTAL) {
|
||||
cal_clk = RTC_CAL_32K_XTAL;
|
||||
} else if (slow_freq == RTC_SLOW_FREQ_8MD256) {
|
||||
cal_clk = RTC_CAL_8MD256;
|
||||
}
|
||||
}
|
||||
/* Enable requested clock (150k clock is always on) */
|
||||
int dig_32k_xtal_state = REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN);
|
||||
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_state) {
|
||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN, 1);
|
||||
}
|
||||
|
||||
if (cal_clk == RTC_CAL_8MD256) {
|
||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_D256_EN);
|
||||
}
|
||||
|
||||
uint32_t cal_val;
|
||||
if (cal_mode == RTC_TIME_CAL_ONEOFF_MODE) {
|
||||
cal_val = rtc_clk_cal_internal_oneoff(cal_clk, slowclk_cycles);
|
||||
} else {
|
||||
cal_val = rtc_clk_cal_internal_cycling(cal_clk, slowclk_cycles);
|
||||
}
|
||||
|
||||
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
|
||||
|
||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN, dig_32k_xtal_state);
|
||||
@@ -117,7 +180,7 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
|
||||
|
||||
uint32_t rtc_clk_cal_ratio(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
|
||||
{
|
||||
uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles);
|
||||
uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles, RTC_TIME_CAL_ONEOFF_MODE);
|
||||
uint64_t ratio_64 = ((xtal_cycles << RTC_CLK_CAL_FRACT)) / slowclk_cycles;
|
||||
uint32_t ratio = (uint32_t)(ratio_64 & UINT32_MAX);
|
||||
return ratio;
|
||||
@@ -125,11 +188,15 @@ uint32_t rtc_clk_cal_ratio(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
|
||||
|
||||
uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
|
||||
{
|
||||
rtc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get();
|
||||
uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles);
|
||||
uint64_t divider = ((uint64_t)xtal_freq) * slowclk_cycles;
|
||||
uint64_t period_64 = ((xtal_cycles << RTC_CLK_CAL_FRACT) + divider / 2 - 1) / divider;
|
||||
uint32_t period = (uint32_t)(period_64 & UINT32_MAX);
|
||||
uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles, RTC_TIME_CAL_ONEOFF_MODE);
|
||||
uint32_t period = rtc_clk_xtal_to_slowclk(xtal_cycles, slowclk_cycles);
|
||||
return period;
|
||||
}
|
||||
|
||||
uint32_t rtc_clk_cal_cycling(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
|
||||
{
|
||||
uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles, RTC_TIME_CAL_CYCLING_MODE);
|
||||
uint32_t period = rtc_clk_xtal_to_slowclk(xtal_cycles, slowclk_cycles);
|
||||
return period;
|
||||
}
|
||||
|
||||
|
@@ -136,6 +136,14 @@ void rtc_sleep_init(rtc_sleep_config_t cfg)
|
||||
REG_SET_FIELD(RTC_CNTL_SLP_REJECT_CONF_REG, RTC_CNTL_LIGHT_SLP_REJECT_EN, cfg.light_slp_reject);
|
||||
}
|
||||
|
||||
void rtc_sleep_low_init(uint32_t slowclk_period)
|
||||
{
|
||||
// set 5 PWC state machine times to fit in main state machine time
|
||||
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES);
|
||||
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_XTL_BUF_WAIT, rtc_time_us_to_slowclk(RTC_CNTL_XTL_BUF_WAIT_SLP_US, slowclk_period));
|
||||
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CNTL_CK8M_WAIT_SLP_CYCLES);
|
||||
}
|
||||
|
||||
void rtc_sleep_set_wakeup_time(uint64_t t)
|
||||
{
|
||||
WRITE_PERI_REG(RTC_CNTL_SLP_TIMER0_REG, t & UINT32_MAX);
|
||||
|
@@ -62,20 +62,19 @@ menu "Power Management"
|
||||
config PM_SLP_IRAM_OPT
|
||||
bool "Put lightsleep related codes in internal RAM"
|
||||
depends on FREERTOS_USE_TICKLESS_IDLE
|
||||
default n
|
||||
help
|
||||
If enabled, about 1.8KB of lightsleep related codes would be in IRAM and chip would sleep
|
||||
If enabled, about 1.8KB of lightsleep related source code would be in IRAM and chip would sleep
|
||||
longer for 760us at most each time.
|
||||
This feature is intended to be used when a lower power management mode is needed
|
||||
regardless of the internal memory.
|
||||
This feature is intended to be used when lower power consumption is needed
|
||||
while there is enough place in IRAM to place source code.
|
||||
|
||||
config PM_RTOS_IDLE_OPT
|
||||
bool "Put RTOS IDLE related codes in internal RAM"
|
||||
depends on FREERTOS_USE_TICKLESS_IDLE
|
||||
default n
|
||||
help
|
||||
If enabled, about 260B of RTOS_IDLE related codes would be in IRAM and chip would sleep
|
||||
If enabled, about 260B of RTOS_IDLE related source code would be in IRAM and chip would sleep
|
||||
longer for 40us at most each time.
|
||||
This feature is intended to be used when a lower power management mode is needed
|
||||
regardless of the internal memory.
|
||||
This feature is intended to be used when lower power consumption is needed
|
||||
while there is enough place in IRAM to place source code.
|
||||
|
||||
endmenu # "Power Management"
|
||||
|
@@ -4,3 +4,50 @@ entries:
|
||||
if PM_RTOS_IDLE_OPT = y:
|
||||
pm_impl:esp_pm_impl_idle_hook (noflash)
|
||||
pm_impl:esp_pm_impl_waiti (noflash)
|
||||
|
||||
[mapping:esp_common_pm]
|
||||
archive: libesp_common.a
|
||||
entries:
|
||||
if PM_RTOS_IDLE_OPT = y:
|
||||
freertos_hooks:esp_vApplicationIdleHook (noflash)
|
||||
task_wdt:idle_hook_cb (noflash)
|
||||
task_wdt:esp_task_wdt_reset (noflash)
|
||||
task_wdt:find_task_in_twdt_list (noflash)
|
||||
task_wdt:reset_hw_timer (noflash)
|
||||
|
||||
[mapping:esp_hw_support_pm]
|
||||
archive: libesp_hw_support.a
|
||||
entries:
|
||||
if PM_SLP_IRAM_OPT = y:
|
||||
rtc_init:rtc_vddsdio_get_config (noflash)
|
||||
|
||||
[mapping:esp_system_pm]
|
||||
archive: libesp_system.a
|
||||
entries:
|
||||
if PM_SLP_IRAM_OPT = y:
|
||||
sleep_modes:esp_light_sleep_start (noflash)
|
||||
sleep_modes:esp_sleep_enable_timer_wakeup (noflash)
|
||||
sleep_modes:timer_wakeup_prepare (noflash)
|
||||
sleep_modes:get_power_down_flags (noflash)
|
||||
|
||||
[mapping:esp_timer_pm]
|
||||
archive: libesp_timer.a
|
||||
entries:
|
||||
if PM_SLP_IRAM_OPT = y:
|
||||
esp_timer_impl_lac:esp_timer_impl_lock (noflash)
|
||||
esp_timer_impl_lac:esp_timer_impl_unlock (noflash)
|
||||
esp_timer_impl_lac:esp_timer_impl_advance (noflash)
|
||||
esp_timer_impl_systimer:esp_timer_impl_lock (noflash)
|
||||
esp_timer_impl_systimer:esp_timer_impl_unlock (noflash)
|
||||
esp_timer_impl_systimer:esp_timer_impl_advance (noflash)
|
||||
|
||||
[mapping:newlib_pm]
|
||||
archive: libnewlib.a
|
||||
entries:
|
||||
if PM_SLP_IRAM_OPT = y:
|
||||
esp_time_impl:esp_time_impl_set_boot_time (noflash)
|
||||
esp_time_impl:esp_time_impl_get_boot_time (noflash)
|
||||
esp_time_impl:esp_clk_slowclk_cal_get (noflash)
|
||||
esp_time_impl:esp_rtc_get_time_us (noflash)
|
||||
esp_time_impl:esp_clk_slowclk_cal_set (noflash)
|
||||
esp_time_impl:esp_set_time_from_rtc (noflash)
|
||||
|
@@ -79,4 +79,12 @@ menu "ESP System Settings"
|
||||
heap initialization order by early startup services and scheduler related code. Speed
|
||||
wise RTC fast memory operates on APB clock and hence does not have much performance impact.
|
||||
|
||||
config ESP_SYSTEM_PD_FLASH
|
||||
bool "PD flash at light sleep when there is no SPIRAM"
|
||||
depends on !SPIRAM
|
||||
default y
|
||||
help
|
||||
If enabled, chip will try to power down flash at light sleep, which costs more time when chip wakes up.
|
||||
Only can be enabled if there is no SPIRAM configured.
|
||||
|
||||
endmenu # ESP System Settings
|
||||
|
@@ -23,12 +23,6 @@ entries:
|
||||
usb_console:esp_usb_console_cdc_acm_cb (noflash)
|
||||
usb_console:esp_usb_console_dfu_detach_cb (noflash)
|
||||
usb_console:esp_usb_console_before_restart (noflash)
|
||||
if PM_SLP_IRAM_OPT = y:
|
||||
sleep_modes:esp_light_sleep_start (noflash)
|
||||
sleep_modes:esp_sleep_enable_timer_wakeup (noflash)
|
||||
sleep_modes:timer_wakeup_prepare (noflash)
|
||||
sleep_modes:get_power_down_flags (noflash)
|
||||
|
||||
|
||||
[mapping:vfs_cdcacm]
|
||||
archive: libvfs.a
|
||||
|
@@ -76,33 +76,32 @@
|
||||
// Time from VDD_SDIO power up to first flash read in ROM code
|
||||
#define VDD_SDIO_POWERUP_TO_FLASH_READ_US 700
|
||||
|
||||
// Cycles for RTC Timer clock source (internal oscillator) calibrate
|
||||
#define RTC_CLK_SRC_CAL_CYCLES (10)
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
#define DEFAULT_CPU_FREQ_MHZ CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ
|
||||
#define DEFAULT_SLEEP_OUT_OVERHEAD_US (212)
|
||||
#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (60)
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#define DEFAULT_CPU_FREQ_MHZ CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ
|
||||
#define DEFAULT_SLEEP_OUT_OVERHEAD_US (147)
|
||||
#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (28)
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
#define DEFAULT_CPU_FREQ_MHZ CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ
|
||||
#define DEFAULT_SLEEP_OUT_OVERHEAD_US (0)
|
||||
#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (0)
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#define DEFAULT_CPU_FREQ_MHZ CONFIG_ESP32C3_DEFAULT_CPU_FREQ_MHZ
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32)
|
||||
#if defined(CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS)
|
||||
#define LIGHT_SLEEP_TIME_OVERHEAD_US (650 + 30 * 240 / DEFAULT_CPU_FREQ_MHZ)
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2)
|
||||
#define LIGHT_SLEEP_TIME_OVERHEAD_US DEFAULT_HARDWARE_OUT_OVERHEAD_US
|
||||
#if defined(CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS) || defined (CONFIG_ESP32S2_RTC_CLK_SRC_EXT_CRYS)
|
||||
#define DEEP_SLEEP_TIME_OVERHEAD_US (650 + 100 * 240 / DEFAULT_CPU_FREQ_MHZ)
|
||||
#else // CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS
|
||||
#define LIGHT_SLEEP_TIME_OVERHEAD_US (250 + 30 * 240 / DEFAULT_CPU_FREQ_MHZ)
|
||||
#else
|
||||
#define DEEP_SLEEP_TIME_OVERHEAD_US (250 + 100 * 240 / DEFAULT_CPU_FREQ_MHZ)
|
||||
#endif // CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS
|
||||
|
||||
#elif defined(CONFIG_IDF_TARGET_ESP32S2)
|
||||
#if defined(CONFIG_ESP32S2_RTC_CLK_SRC_EXT_CRYS)
|
||||
#define LIGHT_SLEEP_TIME_OVERHEAD_US (1650 + 30 * 240 / DEFAULT_CPU_FREQ_MHZ)
|
||||
#define DEEP_SLEEP_TIME_OVERHEAD_US (650 + 100 * 240 / DEFAULT_CPU_FREQ_MHZ)
|
||||
#else // CONFIG_ESP32S2_RTC_CLK_SRC_EXT_CRYS
|
||||
#define LIGHT_SLEEP_TIME_OVERHEAD_US (1250 + 30 * 240 / DEFAULT_CPU_FREQ_MHZ)
|
||||
#define DEEP_SLEEP_TIME_OVERHEAD_US (250 + 100 * 240 / DEFAULT_CPU_FREQ_MHZ)
|
||||
#endif // CONFIG_ESP32S2_RTC_CLK_SRC_EXT_CRYS
|
||||
#endif // defined(CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS) || defined (CONFIG_ESP32S2_RTC_CLK_SRC_EXT_CRYS)
|
||||
|
||||
#elif defined(CONFIG_IDF_TARGET_ESP32C3)
|
||||
#ifdef CONFIG_ESP32C3_RTC_CLK_SRC_EXT_CRYS
|
||||
@@ -118,7 +117,6 @@
|
||||
#define DEEP_SLEEP_TIME_OVERHEAD_US 0
|
||||
#endif // CONFIG_IDF_TARGET_*
|
||||
|
||||
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32) && defined(CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY)
|
||||
#define DEEP_SLEEP_WAKEUP_DELAY CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY
|
||||
#else
|
||||
@@ -128,6 +126,8 @@
|
||||
// Minimal amount of time we can sleep for
|
||||
#define LIGHT_SLEEP_MIN_TIME_US 200
|
||||
|
||||
#define RTC_MODULE_SLEEP_PREPARE_CYCLES (6)
|
||||
|
||||
#define CHECK_SOURCE(source, value, mask) ((s_config.wakeup_triggers & mask) && \
|
||||
(source == value))
|
||||
|
||||
@@ -143,11 +143,16 @@ typedef struct {
|
||||
uint32_t ext0_trigger_level : 1;
|
||||
uint32_t ext0_rtc_gpio_num : 5;
|
||||
uint32_t sleep_time_adjustment;
|
||||
uint32_t ccount_ticks_record;
|
||||
uint32_t sleep_time_overhead_out;
|
||||
uint32_t rtc_clk_cal_period;
|
||||
uint64_t rtc_ticks_at_sleep_start;
|
||||
} sleep_config_t;
|
||||
|
||||
static sleep_config_t s_config = {
|
||||
.pd_options = { ESP_PD_OPTION_AUTO, ESP_PD_OPTION_AUTO, ESP_PD_OPTION_AUTO },
|
||||
.ccount_ticks_record = 0,
|
||||
.sleep_time_overhead_out = DEFAULT_SLEEP_OUT_OVERHEAD_US,
|
||||
.wakeup_triggers = 0
|
||||
};
|
||||
|
||||
@@ -344,6 +349,11 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags)
|
||||
rtc_sleep_config_t config = RTC_SLEEP_CONFIG_DEFAULT(pd_flags);
|
||||
rtc_sleep_init(config);
|
||||
|
||||
// Set state machine time for light sleep
|
||||
if(!deep_sleep) {
|
||||
rtc_sleep_low_init(s_config.rtc_clk_cal_period);
|
||||
}
|
||||
|
||||
// Configure timer wakeup
|
||||
if ((s_config.wakeup_triggers & RTC_TIMER_TRIG_EN) &&
|
||||
s_config.sleep_duration > 0) {
|
||||
@@ -377,6 +387,10 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags)
|
||||
// Restore CPU frequency
|
||||
rtc_clk_cpu_freq_set_config(&cpu_freq_config);
|
||||
|
||||
if (!deep_sleep) {
|
||||
s_config.ccount_ticks_record = cpu_ll_get_cycle_count();
|
||||
}
|
||||
|
||||
// re-enable UART output
|
||||
resume_uarts();
|
||||
|
||||
@@ -407,6 +421,8 @@ void IRAM_ATTR esp_deep_sleep_start(void)
|
||||
// Decide which power domains can be powered down
|
||||
uint32_t pd_flags = get_power_down_flags();
|
||||
|
||||
s_config.rtc_clk_cal_period = esp_clk_slowclk_cal_get();
|
||||
|
||||
// Correct the sleep time
|
||||
s_config.sleep_time_adjustment = DEEP_SLEEP_TIME_OVERHEAD_US;
|
||||
|
||||
@@ -458,30 +474,73 @@ esp_err_t esp_light_sleep_start(void)
|
||||
* lock, otherwise there will be deadlock.
|
||||
*/
|
||||
esp_timer_private_lock();
|
||||
|
||||
s_config.rtc_ticks_at_sleep_start = rtc_time_get();
|
||||
uint32_t ccount_at_sleep_start = cpu_ll_get_cycle_count();
|
||||
uint64_t frc_time_at_start = esp_system_get_time();
|
||||
uint32_t sleep_time_overhead_in = (ccount_at_sleep_start-s_config.ccount_ticks_record) / (esp_clk_cpu_freq() / 1000000ULL);
|
||||
|
||||
DPORT_STALL_OTHER_CPU_START();
|
||||
|
||||
// Decide which power domains can be powered down
|
||||
uint32_t pd_flags = get_power_down_flags();
|
||||
|
||||
// Amount of time to subtract from actual sleep time.
|
||||
// This is spent on entering and leaving light sleep.
|
||||
s_config.sleep_time_adjustment = LIGHT_SLEEP_TIME_OVERHEAD_US;
|
||||
// Re-calibrate the RTC Timer clock
|
||||
#if defined(CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS) || defined(CONFIG_ESP32S2_RTC_CLK_SRC_EXT_CRYS)
|
||||
uint64_t time_per_us = 1000000ULL;
|
||||
s_config.rtc_clk_cal_period = (time_per_us << RTC_CLK_CAL_FRACT) / rtc_clk_slow_freq_get_hz();
|
||||
#elif defined(CONFIG_ESP32S2_RTC_CLK_SRC_INT_RC)
|
||||
s_config.rtc_clk_cal_period = rtc_clk_cal_cycling(RTC_CAL_RTC_MUX, RTC_CLK_SRC_CAL_CYCLES);
|
||||
esp_clk_slowclk_cal_set(s_config.rtc_clk_cal_period);
|
||||
#else
|
||||
s_config.rtc_clk_cal_period = rtc_clk_cal(RTC_CAL_RTC_MUX, RTC_CLK_SRC_CAL_CYCLES);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Adjustment time consists of parts below:
|
||||
* 1. Hardware time waiting for internal 8M oscilate clock and XTAL;
|
||||
* 2. Hardware state swithing time of the rtc main state machine;
|
||||
* 3. Code execution time when clock is not stable;
|
||||
* 4. Code execution time which can be measured;
|
||||
*/
|
||||
|
||||
uint32_t rtc_cntl_xtl_buf_wait_slp_cycles = rtc_time_us_to_slowclk(RTC_CNTL_XTL_BUF_WAIT_SLP_US, s_config.rtc_clk_cal_period);
|
||||
s_config.sleep_time_adjustment = LIGHT_SLEEP_TIME_OVERHEAD_US + sleep_time_overhead_in + s_config.sleep_time_overhead_out
|
||||
+ rtc_time_slowclk_to_us(rtc_cntl_xtl_buf_wait_slp_cycles + RTC_CNTL_CK8M_WAIT_SLP_CYCLES + RTC_CNTL_WAKEUP_DELAY_CYCLES, s_config.rtc_clk_cal_period);
|
||||
|
||||
// Decide if VDD_SDIO needs to be powered down;
|
||||
// If it needs to be powered down, adjust sleep time.
|
||||
const uint32_t flash_enable_time_us = VDD_SDIO_POWERUP_TO_FLASH_READ_US + DEEP_SLEEP_WAKEUP_DELAY;
|
||||
|
||||
#ifndef CONFIG_SPIRAM
|
||||
#if CONFIG_ESP_SYSTEM_PD_FLASH
|
||||
/*
|
||||
* When SPIRAM is disabled in menuconfig, the minimum sleep time of the
|
||||
* system needs to meet the sum below:
|
||||
* 1. Wait time for the flash power-on after waking up;
|
||||
* 2. The execution time of codes between RTC Timer get start time
|
||||
* with hardware starts to switch state to sleep;
|
||||
* 3. The hardware state switching time of the rtc state machine during
|
||||
* sleep and wake-up. This process requires 6 cycles to complete.
|
||||
* The specific hardware state switching process and the cycles
|
||||
* consumed are rtc_cpu_run_stall(1), cut_pll_rtl(2), cut_8m(1),
|
||||
* min_protect(2);
|
||||
* 4. All the adjustment time which is s_config.sleep_time_adjustment below.
|
||||
*/
|
||||
const uint32_t vddsdio_pd_sleep_duration = MAX(FLASH_PD_MIN_SLEEP_TIME_US,
|
||||
flash_enable_time_us + LIGHT_SLEEP_TIME_OVERHEAD_US + LIGHT_SLEEP_MIN_TIME_US);
|
||||
flash_enable_time_us + LIGHT_SLEEP_MIN_TIME_US + s_config.sleep_time_adjustment
|
||||
+ rtc_time_slowclk_to_us(RTC_MODULE_SLEEP_PREPARE_CYCLES, s_config.rtc_clk_cal_period));
|
||||
|
||||
if (s_config.sleep_duration > vddsdio_pd_sleep_duration) {
|
||||
pd_flags |= RTC_SLEEP_PD_VDDSDIO;
|
||||
if (s_config.sleep_time_overhead_out < flash_enable_time_us) {
|
||||
s_config.sleep_time_adjustment += flash_enable_time_us;
|
||||
}
|
||||
#endif //CONFIG_SPIRAM
|
||||
} else {
|
||||
if (s_config.sleep_time_overhead_out > flash_enable_time_us) {
|
||||
s_config.sleep_time_adjustment -= flash_enable_time_us;
|
||||
}
|
||||
}
|
||||
#endif //CONFIG_ESP_SYSTEM_PD_FLASH
|
||||
|
||||
rtc_vddsdio_config_t vddsdio_config = rtc_vddsdio_get_config();
|
||||
|
||||
@@ -507,8 +566,7 @@ esp_err_t esp_light_sleep_start(void)
|
||||
uint64_t rtc_ticks_at_end = rtc_time_get();
|
||||
uint64_t frc_time_at_end = esp_system_get_time();
|
||||
|
||||
uint64_t rtc_time_diff = rtc_time_slowclk_to_us(rtc_ticks_at_end - s_config.rtc_ticks_at_sleep_start,
|
||||
esp_clk_slowclk_cal_get());
|
||||
uint64_t rtc_time_diff = rtc_time_slowclk_to_us(rtc_ticks_at_end - s_config.rtc_ticks_at_sleep_start, s_config.rtc_clk_cal_period);
|
||||
uint64_t frc_time_diff = frc_time_at_end - frc_time_at_start;
|
||||
|
||||
int64_t time_diff = rtc_time_diff - frc_time_diff;
|
||||
@@ -529,6 +587,7 @@ esp_err_t esp_light_sleep_start(void)
|
||||
wdt_hal_write_protect_enable(&rtc_wdt_ctx);
|
||||
}
|
||||
portEXIT_CRITICAL(&light_sleep_lock);
|
||||
s_config.sleep_time_overhead_out = (cpu_ll_get_cycle_count() - s_config.ccount_ticks_record) / (esp_clk_cpu_freq() / 1000000ULL);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -594,6 +653,7 @@ esp_err_t esp_sleep_enable_ulp_wakeup(void)
|
||||
|
||||
esp_err_t esp_sleep_enable_timer_wakeup(uint64_t time_in_us)
|
||||
{
|
||||
s_config.ccount_ticks_record = cpu_ll_get_cycle_count();
|
||||
s_config.wakeup_triggers |= RTC_TIMER_TRIG_EN;
|
||||
s_config.sleep_duration = time_in_us;
|
||||
return ESP_OK;
|
||||
@@ -601,13 +661,12 @@ esp_err_t esp_sleep_enable_timer_wakeup(uint64_t time_in_us)
|
||||
|
||||
static void timer_wakeup_prepare(void)
|
||||
{
|
||||
uint32_t period = esp_clk_slowclk_cal_get();
|
||||
int64_t sleep_duration = (int64_t) s_config.sleep_duration - (int64_t) s_config.sleep_time_adjustment;
|
||||
if (sleep_duration < 0) {
|
||||
sleep_duration = 0;
|
||||
}
|
||||
|
||||
int64_t ticks = rtc_time_us_to_slowclk(sleep_duration, period);
|
||||
int64_t ticks = rtc_time_us_to_slowclk(sleep_duration, s_config.rtc_clk_cal_period);
|
||||
rtc_hal_set_wakeup_timer(s_config.rtc_ticks_at_sleep_start + ticks);
|
||||
}
|
||||
|
||||
|
@@ -15,5 +15,4 @@ idf_component_register(SRCS "${srcs}"
|
||||
INCLUDE_DIRS include
|
||||
PRIV_INCLUDE_DIRS private_include
|
||||
REQUIRES esp_common
|
||||
PRIV_REQUIRES soc driver "${target}"
|
||||
LDFRAGMENTS linker.lf)
|
||||
PRIV_REQUIRES soc driver "${target}")
|
||||
|
@@ -20,5 +20,3 @@ ifdef CONFIG_IDF_TARGET_ESP32
|
||||
else
|
||||
$(error esp_timer is only supported by the Make build system for esp32 chip. For other chips, use the Cmake build system)
|
||||
endif
|
||||
|
||||
COMPONENT_ADD_LDFRAGMENTS += linker.lf
|
||||
|
@@ -1,10 +0,0 @@
|
||||
[mapping:esp_timer]
|
||||
archive: libesp_timer.a
|
||||
entries:
|
||||
if PM_SLP_IRAM_OPT = y:
|
||||
esp_timer_impl_lac:esp_timer_impl_lock (noflash)
|
||||
esp_timer_impl_lac:esp_timer_impl_unlock (noflash)
|
||||
esp_timer_impl_lac:esp_timer_impl_advance (noflash)
|
||||
esp_timer_impl_systimer:esp_timer_impl_lock (noflash)
|
||||
esp_timer_impl_systimer:esp_timer_impl_unlock (noflash)
|
||||
esp_timer_impl_systimer:esp_timer_impl_advance (noflash)
|
@@ -3,10 +3,3 @@ archive: libnewlib.a
|
||||
entries:
|
||||
heap (noflash)
|
||||
abort (noflash)
|
||||
if PM_SLP_IRAM_OPT = y:
|
||||
esp_time_impl:esp_time_impl_set_boot_time (noflash)
|
||||
esp_time_impl:esp_time_impl_get_boot_time (noflash)
|
||||
esp_time_impl:esp_clk_slowclk_cal_get (noflash)
|
||||
esp_time_impl:esp_rtc_get_time_us (noflash)
|
||||
esp_time_impl:esp_clk_slowclk_cal_set (noflash)
|
||||
esp_time_impl:esp_set_time_from_rtc (noflash)
|
||||
|
@@ -541,6 +541,14 @@ typedef struct rtc_sleep_config_s {
|
||||
#define RTC_SLEEP_PD_VDDSDIO BIT(5) //!< Power down VDDSDIO regulator
|
||||
#define RTC_SLEEP_PD_XTAL BIT(6) //!< Power down main XTAL
|
||||
|
||||
/* Various delays to be programmed into power control state machines */
|
||||
#define RTC_CNTL_XTL_BUF_WAIT_SLP_US (500)
|
||||
#define RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES (1)
|
||||
#define RTC_CNTL_CK8M_WAIT_SLP_CYCLES (4)
|
||||
#define RTC_CNTL_WAKEUP_DELAY_CYCLES (7)
|
||||
#define RTC_CNTL_OTHER_BLOCKS_POWERUP_CYCLES (1)
|
||||
#define RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES (1)
|
||||
|
||||
/**
|
||||
* @brief Prepare the chip to enter sleep mode
|
||||
*
|
||||
@@ -556,6 +564,17 @@ typedef struct rtc_sleep_config_s {
|
||||
*/
|
||||
void rtc_sleep_init(rtc_sleep_config_t cfg);
|
||||
|
||||
/**
|
||||
* @brief Low level initialize for rtc state machine waiting cycles after waking up
|
||||
*
|
||||
* This function configures the cycles chip need to wait for internal 8MHz
|
||||
* oscillator and external 40MHz crystal. As we configure fixed time for waiting
|
||||
* crystal, we need to pass period to calculate cycles. Now this function only
|
||||
* used in lightsleep mode.
|
||||
*
|
||||
* @param slowclk_period re-calibrated slow clock period
|
||||
*/
|
||||
void rtc_sleep_low_init(uint32_t slowclk_period);
|
||||
|
||||
/**
|
||||
* @brief Set target value of RTC counter for RTC_TIMER_TRIG_EN wakeup source
|
||||
|
@@ -104,6 +104,12 @@ extern "C" {
|
||||
#define RTC_CNTL_CK8M_WAIT_DEFAULT 20
|
||||
#define RTC_CK8M_ENABLE_WAIT_DEFAULT 1
|
||||
|
||||
/* Various delays to be programmed into power control state machines */
|
||||
#define RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES (1)
|
||||
#define RTC_CNTL_XTL_BUF_WAIT_SLP_US (1000)
|
||||
#define RTC_CNTL_CK8M_WAIT_SLP_CYCLES (4)
|
||||
#define RTC_CNTL_WAKEUP_DELAY_CYCLES (4)
|
||||
|
||||
#define RTC_CNTL_CK8M_DFREQ_DEFAULT 172
|
||||
#define RTC_CNTL_SCK_DCAP_DEFAULT 255
|
||||
|
||||
@@ -288,6 +294,10 @@ typedef struct {
|
||||
.rtc_mem_wait_cycles = OTHER_BLOCKS_WAIT, \
|
||||
}
|
||||
|
||||
/* Two different calibration mode for slow clock */
|
||||
#define RTC_TIME_CAL_ONEOFF_MODE 0
|
||||
#define RTC_TIME_CAL_CYCLING_MODE 1
|
||||
|
||||
void rtc_clk_divider_set(uint32_t div);
|
||||
|
||||
void rtc_clk_8m_divider_set(uint32_t div);
|
||||
@@ -518,7 +528,7 @@ void rtc_clk_apb_freq_update(uint32_t apb_freq);
|
||||
*/
|
||||
uint32_t rtc_clk_apb_freq_get(void);
|
||||
|
||||
uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles);
|
||||
uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles, uint32_t cal_mode);
|
||||
|
||||
/**
|
||||
* @brief Measure RTC slow clock's period, based on main XTAL frequency
|
||||
@@ -709,6 +719,17 @@ typedef struct {
|
||||
*/
|
||||
void rtc_sleep_init(rtc_sleep_config_t cfg);
|
||||
|
||||
/**
|
||||
* @brief Low level initialize for rtc state machine waiting cycles after waking up
|
||||
*
|
||||
* This function configures the cycles chip need to wait for internal 8MHz
|
||||
* oscillator and external 40MHz crystal. As we configure fixed time for waiting
|
||||
* crystal, we need to pass period to calculate cycles. Now this function only
|
||||
* used in lightsleep mode.
|
||||
*
|
||||
* @param slowclk_period re-calibrated slow clock period
|
||||
*/
|
||||
void rtc_sleep_low_init(uint32_t slowclk_period);
|
||||
|
||||
#define RTC_EXT0_TRIG_EN BIT(0) //!< EXT0 GPIO wakeup
|
||||
#define RTC_EXT1_TRIG_EN BIT(1) //!< EXT1 GPIO wakeup
|
||||
@@ -850,7 +871,13 @@ rtc_vddsdio_config_t rtc_vddsdio_get_config(void);
|
||||
*/
|
||||
void rtc_vddsdio_set_config(rtc_vddsdio_config_t config);
|
||||
|
||||
|
||||
/**
|
||||
* Using valid hardware calibration value to calibrate slowclk
|
||||
* If there is no hardware calibration in process, start hardware calibration and wait for calibration finished
|
||||
* @param cal_clk clock to be measured
|
||||
* @param slowclk_cycles if no hardware calibration in process, use this amount of slow cycles to calibrate slowclk.
|
||||
*/
|
||||
uint32_t rtc_clk_cal_cycling(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -106,6 +106,12 @@ extern "C" {
|
||||
#define RTC_CNTL_CK8M_WAIT_DEFAULT 20
|
||||
#define RTC_CK8M_ENABLE_WAIT_DEFAULT 5
|
||||
|
||||
/* Various delays to be programmed into power control state machines */
|
||||
#define RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES RTC_CNTL_PLL_BUF_WAIT_DEFAULT
|
||||
#define RTC_CNTL_XTL_BUF_WAIT_SLP_US RTC_CNTL_XTL_BUF_WAIT_DEFAULT
|
||||
#define RTC_CNTL_CK8M_WAIT_SLP_CYCLES RTC_CNTL_CK8M_WAIT_DEFAULT
|
||||
#define RTC_CNTL_WAKEUP_DELAY_CYCLES (0)
|
||||
|
||||
#define RTC_CNTL_CK8M_DFREQ_DEFAULT 100
|
||||
#define RTC_CNTL_SCK_DCAP_DEFAULT 255
|
||||
|
||||
@@ -687,6 +693,17 @@ typedef struct {
|
||||
*/
|
||||
void rtc_sleep_init(rtc_sleep_config_t cfg);
|
||||
|
||||
/**
|
||||
* @brief Low level initialize for rtc state machine waiting cycles after waking up
|
||||
*
|
||||
* This function configures the cycles chip need to wait for internal 8MHz
|
||||
* oscillator and external 40MHz crystal. As we configure fixed time for waiting
|
||||
* crystal, we need to pass period to calculate cycles. Now this function only
|
||||
* used in lightsleep mode.
|
||||
*
|
||||
* @param slowclk_period re-calibrated slow clock period
|
||||
*/
|
||||
void rtc_sleep_low_init(uint32_t slowclk_period);
|
||||
|
||||
/**
|
||||
* @brief Set target value of RTC counter for RTC_TIMER_TRIG_EN wakeup source
|
||||
|
@@ -6,3 +6,6 @@ CONFIG_PM_ENABLE=y
|
||||
CONFIG_FREERTOS_USE_TICKLESS_IDLE=y
|
||||
# Use RTC timer as reference
|
||||
CONFIG_PM_USE_RTC_TIMER_REF=y
|
||||
# Put related source code in IRAM
|
||||
CONFIG_PM_SLP_IRAM_OPT=y
|
||||
CONFIG_PM_RTOS_IDLE_OPT=y
|
||||
|
Reference in New Issue
Block a user