mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-29 18:27:20 +02:00
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
|
||||
*/
|
||||
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- |
|
||||
|
Reference in New Issue
Block a user