feat(esp_hw_support): remeasure sleep_time_overhead_out if min_freq_mhz changed

This commit is contained in:
wuzhenghui
2025-03-21 20:49:24 +08:00
parent 81860c55d6
commit 41e6e25e2d
4 changed files with 36 additions and 5 deletions

View File

@ -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
*/
@ -124,6 +124,15 @@ void esp_sleep_mmu_retention(bool backup_or_restore);
bool mmu_domain_pd_allowed(void);
#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

View File

@ -248,6 +248,7 @@ typedef struct {
#if SOC_DCDC_SUPPORTED
uint64_t rtc_ticks_at_ldo_prepare;
#endif
bool overhead_out_need_remeasure;
} sleep_config_t;
@ -276,7 +277,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
@ -291,6 +293,12 @@ static const char *TAG = "sleep";
static RTC_FAST_ATTR int32_t s_sleep_sub_mode_ref_cnt[ESP_SLEEP_MODE_MAX] = { 0 };
//in this mode, 2uA is saved, but RTC memory can't use at high temperature, and RTCIO can't be used as INPUT.
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);
static uint32_t get_sleep_flags(uint32_t pd_flags, bool deepsleep);
@ -1397,6 +1405,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;
@ -1561,6 +1579,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);
@ -1645,9 +1664,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;
}

View File

@ -19,6 +19,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"
@ -478,6 +479,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.

View File

@ -1,2 +1,2 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- |