forked from espressif/esp-idf
feat(esp_hw_support): remeasure sleep_time_overhead_out if min_freq_mhz changed
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -73,6 +73,15 @@ esp_err_t esp_deep_sleep_register_phy_hook(esp_deep_sleep_cb_t new_dslp_cb);
|
||||
void esp_deep_sleep_deregister_phy_hook(esp_deep_sleep_cb_t old_dslp_cb);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Notify the sleep process that `sleep_time_overhead_out` needs to be remeasured, which must be called
|
||||
* in the following scenarios:
|
||||
* 1. When the CPU frequency changes to below the crystal oscillator frequency.
|
||||
* 2. When a new callback function is registered in the sleep process.
|
||||
* 3. Other events occur that affect the execution time of the CPU sleep process.
|
||||
*/
|
||||
void esp_sleep_overhead_out_time_refresh(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -232,6 +232,7 @@ typedef struct {
|
||||
#if SOC_DCDC_SUPPORTED
|
||||
uint64_t rtc_ticks_at_ldo_prepare;
|
||||
#endif
|
||||
bool overhead_out_need_remeasure;
|
||||
} sleep_config_t;
|
||||
|
||||
|
||||
@@ -258,7 +259,8 @@ static sleep_config_t s_config = {
|
||||
.lock = portMUX_INITIALIZER_UNLOCKED,
|
||||
.ccount_ticks_record = 0,
|
||||
.sleep_time_overhead_out = DEFAULT_SLEEP_OUT_OVERHEAD_US,
|
||||
.wakeup_triggers = 0
|
||||
.wakeup_triggers = 0,
|
||||
.overhead_out_need_remeasure = true
|
||||
};
|
||||
|
||||
/* Internal variable used to track if light sleep wakeup sources are to be
|
||||
@@ -281,6 +283,13 @@ void esp_sleep_periph_use_8m(bool use_or_not)
|
||||
s_periph_use_8m_flag = use_or_not;
|
||||
}
|
||||
|
||||
void esp_sleep_overhead_out_time_refresh(void)
|
||||
{
|
||||
portENTER_CRITICAL(&s_config.lock);
|
||||
s_config.overhead_out_need_remeasure = true;
|
||||
portEXIT_CRITICAL(&s_config.lock);
|
||||
}
|
||||
|
||||
static uint32_t get_power_down_flags(void);
|
||||
#if SOC_PM_SUPPORT_EXT0_WAKEUP
|
||||
static void ext0_wakeup_prepare(void);
|
||||
@@ -1369,6 +1378,16 @@ esp_err_t esp_light_sleep_start(void)
|
||||
// Re-calibrate the RTC clock
|
||||
sleep_low_power_clock_calibration(false);
|
||||
|
||||
if (s_config.overhead_out_need_remeasure) {
|
||||
uint32_t cur_cpu_freq = esp_clk_cpu_freq() / MHZ;
|
||||
uint32_t xtal_freq = rtc_clk_xtal_freq_get();
|
||||
if (cur_cpu_freq < xtal_freq) {
|
||||
s_config.sleep_time_overhead_out = DEFAULT_SLEEP_OUT_OVERHEAD_US * xtal_freq / cur_cpu_freq;
|
||||
} else {
|
||||
s_config.sleep_time_overhead_out = DEFAULT_SLEEP_OUT_OVERHEAD_US;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Adjustment time consists of parts below:
|
||||
* 1. Hardware time waiting for internal 8M oscillate clock and XTAL;
|
||||
@@ -1529,6 +1548,7 @@ esp_err_t esp_light_sleep_start(void)
|
||||
|
||||
if (s_light_sleep_wakeup) {
|
||||
s_config.sleep_time_overhead_out = (esp_cpu_get_cycle_count() - s_config.ccount_ticks_record) / (esp_clk_cpu_freq() / 1000000ULL);
|
||||
s_config.overhead_out_need_remeasure = false;
|
||||
}
|
||||
|
||||
portEXIT_CRITICAL(&s_config.lock);
|
||||
@@ -1613,9 +1633,10 @@ esp_err_t esp_sleep_enable_timer_wakeup(uint64_t time_in_us)
|
||||
if (time_in_us > ((BIT64(SOC_LP_TIMER_BIT_WIDTH_LO + SOC_LP_TIMER_BIT_WIDTH_HI) - 1) / esp_clk_tree_lp_slow_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX)) * MHZ ) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
portENTER_CRITICAL(&s_config.lock);
|
||||
s_config.wakeup_triggers |= RTC_TIMER_TRIG_EN;
|
||||
s_config.sleep_duration = time_in_us;
|
||||
portEXIT_CRITICAL(&s_config.lock);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
@@ -18,6 +18,7 @@
|
||||
#include "esp_clk_tree.h"
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#include "esp_private/esp_sleep_internal.h"
|
||||
#include "esp_private/crosscore_int.h"
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
|
||||
@@ -477,6 +478,7 @@ esp_err_t esp_pm_configure(const void* vconfig)
|
||||
// Enable the wakeup source here because the `esp_sleep_disable_wakeup_source` in the `else`
|
||||
// branch must be called if corresponding wakeup source is already enabled.
|
||||
esp_sleep_enable_timer_wakeup(0);
|
||||
esp_sleep_overhead_out_time_refresh();
|
||||
} else if (s_light_sleep_en) {
|
||||
// Since auto light-sleep will enable the timer wakeup source, to avoid affecting subsequent possible
|
||||
// deepsleep requests, disable the timer wakeup source here.
|
||||
|
Reference in New Issue
Block a user