mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 03:00:34 +03:00
Merge branch 'bugfix/idf-11425' into 'master'
power management module memory (iram or flash) usage optimization Closes IDF-11425 See merge request espressif/esp-idf!37550
This commit is contained in:
@@ -70,6 +70,10 @@ menu "Hardware Settings"
|
||||
# regardless of power management configuration.
|
||||
config ESP_SLEEP_POWER_DOWN_FLASH
|
||||
bool "Power down flash in light sleep when there is no SPIRAM or SPIRAM has independent power supply"
|
||||
# TODO: PM-383
|
||||
select PM_SLP_IRAM_OPT if (!IDF_TARGET_ESP32H21 && !IDF_TARGET_ESP32H4)
|
||||
select ESP_PERIPH_CTRL_FUNC_IN_IRAM
|
||||
select ESP_REGI2C_CTRL_FUNC_IN_IRAM
|
||||
depends on !SPIRAM || ESP_LDO_RESERVE_PSRAM
|
||||
depends on !(IDF_TARGET_ESP32P4 && (ESP32P4_REV_MIN_FULL < 100))
|
||||
default n
|
||||
@@ -219,12 +223,19 @@ menu "Hardware Settings"
|
||||
endmenu
|
||||
|
||||
menu "Peripheral Control"
|
||||
config PERIPH_CTRL_FUNC_IN_IRAM
|
||||
config ESP_PERIPH_CTRL_FUNC_IN_IRAM
|
||||
bool "Place peripheral control functions into IRAM"
|
||||
default n
|
||||
help
|
||||
Place peripheral control functions (e.g. periph_module_reset) into IRAM,
|
||||
so that these functions can be IRAM-safe and able to be called in the other IRAM interrupt context.
|
||||
|
||||
config ESP_REGI2C_CTRL_FUNC_IN_IRAM
|
||||
bool "Place regi2c control functions into IRAM"
|
||||
default y
|
||||
help
|
||||
Place analog i2c master control functions (e.g. regi2c_ctrl_read_reg, regi2c_ctrl_write_reg) into IRAM,
|
||||
so that these functions can be IRAM-safe and able to be called in the other IRAM interrupt context.
|
||||
endmenu
|
||||
|
||||
menu "ETM Configuration"
|
||||
|
||||
@@ -26,6 +26,12 @@
|
||||
|
||||
#define MHZ (1000000)
|
||||
|
||||
#if CONFIG_PM_SLP_IRAM_OPT
|
||||
# define ESP_CLK_FN_ATTR IRAM_ATTR
|
||||
#else
|
||||
# define ESP_CLK_FN_ATTR
|
||||
#endif
|
||||
|
||||
// g_ticks_us defined in ROMs for PRO and APP CPU
|
||||
extern uint32_t g_ticks_per_us_pro;
|
||||
|
||||
@@ -48,7 +54,7 @@ _Static_assert(offsetof(retain_mem_t, checksum) == sizeof(retain_mem_t) - sizeof
|
||||
#if !NON_OS_BUILD
|
||||
static __attribute__((section(".rtc_timer_data_in_rtc_mem"))) retain_mem_t s_rtc_timer_retain_mem;
|
||||
|
||||
static uint32_t calc_checksum(void)
|
||||
static ESP_CLK_FN_ATTR uint32_t calc_checksum(void)
|
||||
{
|
||||
uint32_t checksum = 0;
|
||||
uint32_t *data = (uint32_t*) &s_rtc_timer_retain_mem;
|
||||
|
||||
@@ -12,36 +12,61 @@ entries:
|
||||
cpu: esp_cpu_clear_watchpoint (noflash)
|
||||
cpu: esp_cpu_compare_and_set (noflash)
|
||||
esp_memory_utils (noflash)
|
||||
rtc_clk (noflash)
|
||||
clk_utils (noflash)
|
||||
if PM_SLP_IRAM_OPT = y:
|
||||
rtc_clk (noflash)
|
||||
rtc_time (noflash_text)
|
||||
if SOC_CONFIGURABLE_VDDSDIO_SUPPORTED = y:
|
||||
rtc_init:rtc_vddsdio_get_config (noflash)
|
||||
rtc_init:rtc_vddsdio_set_config (noflash)
|
||||
if IDF_TARGET_ESP32 = y || IDF_TARGET_ESP32S2 = y || IDF_TARGET_ESP32S3 = y || IDF_TARGET_ESP32C2 = y || IDF_TARGET_ESP32C3 = y:
|
||||
rtc_sleep (noflash_text)
|
||||
rtc_time (noflash_text)
|
||||
rtc_sleep:rtc_sleep_start (noflash)
|
||||
if PM_SLP_IRAM_OPT = y:
|
||||
rtc_sleep:rtc_sleep_get_default_config (noflash)
|
||||
rtc_sleep:rtc_sleep_init (noflash)
|
||||
rtc_sleep:rtc_sleep_low_init (noflash)
|
||||
if IDF_TARGET_ESP32 = y || IDF_TARGET_ESP32S2 = y:
|
||||
rtc_sleep:rtc_sleep_pd (noflash)
|
||||
if IDF_TARGET_ESP32S3 = y || IDF_TARGET_ESP32C2 = y || IDF_TARGET_ESP32C3 = y:
|
||||
rtc_sleep:rtc_sleep_pu (noflash)
|
||||
if SOC_PMU_SUPPORTED = y && SOC_LIGHT_SLEEP_SUPPORTED = y:
|
||||
pmu_sleep (noflash)
|
||||
if SPIRAM_FLASH_LOAD_TO_PSRAM = y:
|
||||
pmu_init (noflash)
|
||||
pmu_param (noflash)
|
||||
if SOC_USB_SERIAL_JTAG_SUPPORTED = y:
|
||||
if SPIRAM_FLASH_LOAD_TO_PSRAM = y:
|
||||
pmu_init (noflash)
|
||||
pmu_param (noflash)
|
||||
elif PM_SLP_IRAM_OPT = y && IDF_TARGET_ESP32P4 != y:
|
||||
pmu_param:get_act_hp_dbias (noflash)
|
||||
pmu_param:get_act_lp_dbias (noflash)
|
||||
if PM_SLP_IRAM_OPT = y && SOC_USB_SERIAL_JTAG_SUPPORTED = y:
|
||||
sleep_console (noflash)
|
||||
if SOC_USB_OTG_SUPPORTED && SOC_PM_SUPPORT_CNNT_PD = y:
|
||||
if PM_SLP_IRAM_OPT = y && SOC_USB_OTG_SUPPORTED && SOC_PM_SUPPORT_CNNT_PD = y:
|
||||
sleep_usb (noflash)
|
||||
if IDF_TARGET_ESP32 = y || IDF_TARGET_ESP32S2 = y:
|
||||
rtc_wdt (noflash_text)
|
||||
if PERIPH_CTRL_FUNC_IN_IRAM = y:
|
||||
periph_ctrl: periph_module_reset (noflash)
|
||||
if PERIPH_CTRL_FUNC_IN_IRAM = y && ESP_WIFI_ENABLED = y:
|
||||
if ESP_PERIPH_CTRL_FUNC_IN_IRAM = y:
|
||||
periph_ctrl:periph_module_reset (noflash)
|
||||
periph_ctrl:periph_rcc_enter (noflash)
|
||||
periph_ctrl:periph_rcc_exit (noflash)
|
||||
periph_ctrl:periph_rcc_acquire_enter (noflash)
|
||||
periph_ctrl:periph_rcc_acquire_exit (noflash)
|
||||
periph_ctrl:periph_rcc_release_enter (noflash)
|
||||
periph_ctrl:periph_rcc_release_exit (noflash)
|
||||
if ESP_PERIPH_CTRL_FUNC_IN_IRAM = y && ESP_WIFI_ENABLED = y:
|
||||
periph_ctrl: wifi_module_enable (noflash)
|
||||
periph_ctrl: wifi_module_disable (noflash)
|
||||
if ESP_REGI2C_CTRL_FUNC_IN_IRAM = y:
|
||||
regi2c_ctrl:regi2c_ctrl_read_reg (noflash)
|
||||
regi2c_ctrl:regi2c_ctrl_read_reg_mask (noflash)
|
||||
regi2c_ctrl:regi2c_ctrl_write_reg (noflash)
|
||||
regi2c_ctrl:regi2c_ctrl_write_reg_mask (noflash)
|
||||
regi2c_ctrl:regi2c_enter_critical (noflash)
|
||||
regi2c_ctrl:regi2c_exit_critical (noflash)
|
||||
if SOC_SYSTIMER_SUPPORTED = y:
|
||||
systimer (noflash)
|
||||
if SOC_ADC_SHARED_POWER = y:
|
||||
if ADC_ONESHOT_CTRL_FUNC_IN_IRAM = y:
|
||||
sar_periph_ctrl (noflash)
|
||||
else:
|
||||
elif PM_SLP_IRAM_OPT = y:
|
||||
sar_periph_ctrl: sar_periph_ctrl_power_enable (noflash)
|
||||
|
||||
[mapping:soc_pm]
|
||||
|
||||
@@ -21,35 +21,35 @@ static portMUX_TYPE periph_spinlock = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
static uint8_t ref_counts[PERIPH_MODULE_MAX] = {0};
|
||||
|
||||
IRAM_ATTR void periph_rcc_enter(void)
|
||||
void periph_rcc_enter(void)
|
||||
{
|
||||
portENTER_CRITICAL_SAFE(&periph_spinlock);
|
||||
}
|
||||
|
||||
IRAM_ATTR void periph_rcc_exit(void)
|
||||
void periph_rcc_exit(void)
|
||||
{
|
||||
portEXIT_CRITICAL_SAFE(&periph_spinlock);
|
||||
}
|
||||
|
||||
IRAM_ATTR uint8_t periph_rcc_acquire_enter(periph_module_t periph)
|
||||
uint8_t periph_rcc_acquire_enter(periph_module_t periph)
|
||||
{
|
||||
periph_rcc_enter();
|
||||
return ref_counts[periph];
|
||||
}
|
||||
|
||||
IRAM_ATTR void periph_rcc_acquire_exit(periph_module_t periph, uint8_t ref_count)
|
||||
void periph_rcc_acquire_exit(periph_module_t periph, uint8_t ref_count)
|
||||
{
|
||||
ref_counts[periph] = ++ref_count;
|
||||
periph_rcc_exit();
|
||||
}
|
||||
|
||||
IRAM_ATTR uint8_t periph_rcc_release_enter(periph_module_t periph)
|
||||
uint8_t periph_rcc_release_enter(periph_module_t periph)
|
||||
{
|
||||
periph_rcc_enter();
|
||||
return ref_counts[periph] - 1;
|
||||
}
|
||||
|
||||
IRAM_ATTR void periph_rcc_release_exit(periph_module_t periph, uint8_t ref_count)
|
||||
void periph_rcc_release_exit(periph_module_t periph, uint8_t ref_count)
|
||||
{
|
||||
ref_counts[periph] = ref_count;
|
||||
periph_rcc_exit();
|
||||
|
||||
@@ -65,7 +65,7 @@ typedef struct {
|
||||
* Configure whether certain peripherals are powered down in deep sleep
|
||||
* @param cfg power down flags as rtc_sleep_pd_config_t structure
|
||||
*/
|
||||
static void rtc_sleep_pd(rtc_sleep_pd_config_t cfg)
|
||||
void rtc_sleep_pd(rtc_sleep_pd_config_t cfg)
|
||||
{
|
||||
REG_SET_FIELD(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_LSLP_MEM_FORCE_PU, ~cfg.dig_pd);
|
||||
REG_SET_FIELD(RTC_CNTL_PWC_REG, RTC_CNTL_SLOWMEM_FORCE_LPU, ~cfg.rtc_pd);
|
||||
@@ -345,7 +345,7 @@ uint32_t rtc_deep_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt)
|
||||
return rtc_sleep_finish();
|
||||
}
|
||||
|
||||
static uint32_t rtc_sleep_finish(void)
|
||||
static IRAM_ATTR uint32_t rtc_sleep_finish(void)
|
||||
{
|
||||
/* In deep sleep mode, we never get here */
|
||||
uint32_t reject = REG_GET_FIELD(RTC_CNTL_INT_RAW_REG, RTC_CNTL_SLP_REJECT_INT_RAW);
|
||||
|
||||
@@ -222,7 +222,7 @@ uint32_t rtc_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp
|
||||
return rtc_sleep_finish(lslp_mem_inf_fpu);
|
||||
}
|
||||
|
||||
static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu)
|
||||
static IRAM_ATTR uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu)
|
||||
{
|
||||
/* In deep sleep mode, we never get here */
|
||||
uint32_t reject = REG_GET_FIELD(RTC_CNTL_INT_RAW_REG, RTC_CNTL_SLP_REJECT_INT_RAW);
|
||||
|
||||
@@ -352,7 +352,7 @@ uint32_t rtc_deep_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt)
|
||||
return rtc_sleep_finish(0);
|
||||
}
|
||||
|
||||
static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu)
|
||||
static IRAM_ATTR uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu)
|
||||
{
|
||||
/* In deep sleep mode, we never get here */
|
||||
uint32_t reject = REG_GET_FIELD(RTC_CNTL_INT_RAW_REG, RTC_CNTL_SLP_REJECT_INT_RAW);
|
||||
|
||||
@@ -361,7 +361,7 @@ uint32_t rtc_deep_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt)
|
||||
return rtc_sleep_finish(0);
|
||||
}
|
||||
|
||||
static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu)
|
||||
static IRAM_ATTR uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu)
|
||||
{
|
||||
/* In deep sleep mode, we never get here */
|
||||
uint32_t reject = REG_GET_FIELD(RTC_CNTL_INT_RAW_REG, RTC_CNTL_SLP_REJECT_INT_RAW);
|
||||
|
||||
@@ -284,7 +284,7 @@ __attribute__((weak)) uint32_t rtc_sleep_start(uint32_t wakeup_opt, uint32_t rej
|
||||
return rtc_sleep_finish(lslp_mem_inf_fpu);
|
||||
}
|
||||
|
||||
static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu)
|
||||
static IRAM_ATTR uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu)
|
||||
{
|
||||
/* In deep sleep mode, we never get here */
|
||||
uint32_t reject = REG_GET_FIELD(RTC_CNTL_INT_RAW_REG, RTC_CNTL_SLP_REJECT_INT_RAW);
|
||||
|
||||
@@ -18,7 +18,7 @@ static portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
static DRAM_ATTR __attribute__((unused)) const char *TAG = "REGI2C";
|
||||
|
||||
uint8_t IRAM_ATTR regi2c_ctrl_read_reg(uint8_t block, uint8_t host_id, uint8_t reg_add)
|
||||
uint8_t regi2c_ctrl_read_reg(uint8_t block, uint8_t host_id, uint8_t reg_add)
|
||||
{
|
||||
REGI2C_CLOCK_ENABLE();
|
||||
portENTER_CRITICAL_SAFE(&mux);
|
||||
@@ -28,7 +28,7 @@ uint8_t IRAM_ATTR regi2c_ctrl_read_reg(uint8_t block, uint8_t host_id, uint8_t r
|
||||
return value;
|
||||
}
|
||||
|
||||
uint8_t IRAM_ATTR regi2c_ctrl_read_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb)
|
||||
uint8_t regi2c_ctrl_read_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb)
|
||||
{
|
||||
REGI2C_CLOCK_ENABLE();
|
||||
portENTER_CRITICAL_SAFE(&mux);
|
||||
@@ -38,7 +38,7 @@ uint8_t IRAM_ATTR regi2c_ctrl_read_reg_mask(uint8_t block, uint8_t host_id, uint
|
||||
return value;
|
||||
}
|
||||
|
||||
void IRAM_ATTR regi2c_ctrl_write_reg(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data)
|
||||
void regi2c_ctrl_write_reg(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data)
|
||||
{
|
||||
REGI2C_CLOCK_ENABLE();
|
||||
portENTER_CRITICAL_SAFE(&mux);
|
||||
@@ -47,7 +47,7 @@ void IRAM_ATTR regi2c_ctrl_write_reg(uint8_t block, uint8_t host_id, uint8_t reg
|
||||
REGI2C_CLOCK_DISABLE();
|
||||
}
|
||||
|
||||
void IRAM_ATTR regi2c_ctrl_write_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data)
|
||||
void regi2c_ctrl_write_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data)
|
||||
{
|
||||
REGI2C_CLOCK_ENABLE();
|
||||
portENTER_CRITICAL_SAFE(&mux);
|
||||
@@ -56,12 +56,12 @@ void IRAM_ATTR regi2c_ctrl_write_reg_mask(uint8_t block, uint8_t host_id, uint8_
|
||||
REGI2C_CLOCK_DISABLE();
|
||||
}
|
||||
|
||||
void IRAM_ATTR regi2c_enter_critical(void)
|
||||
void regi2c_enter_critical(void)
|
||||
{
|
||||
portENTER_CRITICAL_SAFE(&mux);
|
||||
}
|
||||
|
||||
void IRAM_ATTR regi2c_exit_critical(void)
|
||||
void regi2c_exit_critical(void)
|
||||
{
|
||||
portEXIT_CRITICAL_SAFE(&mux);
|
||||
}
|
||||
|
||||
@@ -33,6 +33,12 @@ static const char *TAG_TSENS = "temperature_sensor";
|
||||
#define TSENS_RCC_ATOMIC()
|
||||
#endif
|
||||
|
||||
#if CONFIG_PM_SLP_IRAM_OPT
|
||||
# define SAR_PERIPH_CTRL_COMMON_FN_ATTR IRAM_ATTR
|
||||
#else
|
||||
# define SAR_PERIPH_CTRL_COMMON_FN_ATTR
|
||||
#endif
|
||||
|
||||
static int s_record_min = INT_NOT_USED;
|
||||
static int s_record_max = INT_NOT_USED;
|
||||
static int s_temperature_sensor_power_cnt;
|
||||
@@ -79,7 +85,7 @@ void temperature_sensor_power_release(void)
|
||||
portEXIT_CRITICAL(&rtc_spinlock);
|
||||
}
|
||||
|
||||
static int temperature_sensor_get_raw_value(void)
|
||||
static SAR_PERIPH_CTRL_COMMON_FN_ATTR int temperature_sensor_get_raw_value(void)
|
||||
{
|
||||
int raw_value = temperature_sensor_ll_get_raw_value();
|
||||
return (TEMPERATURE_SENSOR_LL_ADC_FACTOR * raw_value - TEMPERATURE_SENSOR_LL_DAC_FACTOR * temperature_sensor_attributes[s_tsens_idx].offset - TEMPERATURE_SENSOR_LL_OFFSET_FACTOR);
|
||||
|
||||
@@ -7,3 +7,5 @@ CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS CONFIG_ESP32_UNIVERSAL_M
|
||||
|
||||
CONFIG_ESP_SYSTEM_PD_FLASH CONFIG_ESP_SLEEP_POWER_DOWN_FLASH
|
||||
CONFIG_ESP_SYSTEM_BROWNOUT_INTR CONFIG_ESP_BROWNOUT_USE_INTR
|
||||
|
||||
CONFIG_PERIPH_CTRL_FUNC_IN_IRAM CONFIG_ESP_PERIPH_CTRL_FUNC_IN_IRAM
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "esp_log.h"
|
||||
#include "esp_memory_utils.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/uart_pins.h"
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
@@ -151,6 +152,23 @@ IRAM_ATTR void esp_sleep_isolate_digital_gpio(void)
|
||||
/* isolate digital IO that is not held(keep the configuration of digital IOs held by users) */
|
||||
for (gpio_num_t gpio_num = GPIO_NUM_0; gpio_num < GPIO_NUM_MAX; gpio_num++) {
|
||||
if (GPIO_IS_VALID_DIGITAL_IO_PAD(gpio_num) && !gpio_hal_is_digital_io_hold(&gpio_hal, gpio_num)) {
|
||||
|
||||
bool is_mspi_io_pad = false;
|
||||
esp_mspi_io_t mspi_ios[] = { ESP_MSPI_IO_CS0, ESP_MSPI_IO_CLK, ESP_MSPI_IO_Q, ESP_MSPI_IO_D, ESP_MSPI_IO_HD, ESP_MSPI_IO_WP };
|
||||
for (int i = 0; i < sizeof(mspi_ios) / sizeof(mspi_ios[0]); i++) {
|
||||
if (esp_mspi_get_io(mspi_ios[i]) == gpio_num) {
|
||||
is_mspi_io_pad = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Ignore MSPI and default Console UART io pads, When the CPU executes
|
||||
// the following instructions to configure the MSPI IO PAD, access on
|
||||
// the MSPI signal lines (as CPU instruction execution and MSPI access
|
||||
// operations are asynchronous) may cause the SoC to hang.
|
||||
if (is_mspi_io_pad || gpio_num == U0RXD_GPIO_NUM || gpio_num == U0TXD_GPIO_NUM) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* disable I/O */
|
||||
gpio_hal_input_disable(&gpio_hal, gpio_num);
|
||||
gpio_hal_output_disable(&gpio_hal, gpio_num);
|
||||
|
||||
@@ -77,7 +77,7 @@ esp_err_t esp_unregister_mac_bb_pd_callback(mac_bb_power_down_cb_t cb)
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
void IRAM_ATTR mac_bb_power_down_cb_execute(void)
|
||||
void mac_bb_power_down_cb_execute(void)
|
||||
{
|
||||
for (int i = 0; i < MAC_BB_POWER_DOWN_CB_NO; i++) {
|
||||
if (s_mac_bb_power_down_cb[i]) {
|
||||
@@ -118,7 +118,7 @@ esp_err_t esp_unregister_mac_bb_pu_callback(mac_bb_power_up_cb_t cb)
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
void IRAM_ATTR mac_bb_power_up_cb_execute(void)
|
||||
void mac_bb_power_up_cb_execute(void)
|
||||
{
|
||||
for (int i = 0; i < MAC_BB_POWER_UP_CB_NO; i++) {
|
||||
if (s_mac_bb_power_up_cb[i]) {
|
||||
@@ -221,7 +221,7 @@ bool modem_domain_pd_allowed(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t IRAM_ATTR sleep_modem_reject_triggers(void)
|
||||
uint32_t sleep_modem_reject_triggers(void)
|
||||
{
|
||||
uint32_t reject_triggers = 0;
|
||||
#if SOC_PM_SUPPORT_PMU_MODEM_STATE
|
||||
|
||||
@@ -162,6 +162,12 @@
|
||||
#elif CONFIG_IDF_TARGET_ESP32C2
|
||||
#define DEFAULT_SLEEP_OUT_OVERHEAD_US (118)
|
||||
#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (9)
|
||||
# if !CONFIG_PM_SLP_IRAM_OPT
|
||||
#undef DEFAULT_SLEEP_OUT_OVERHEAD_US
|
||||
#define DEFAULT_SLEEP_OUT_OVERHEAD_US (2779)
|
||||
#undef DEFAULT_HARDWARE_OUT_OVERHEAD_US
|
||||
#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (157)
|
||||
# endif
|
||||
#elif CONFIG_IDF_TARGET_ESP32C6
|
||||
#define DEFAULT_SLEEP_OUT_OVERHEAD_US (318)
|
||||
#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (56)
|
||||
@@ -216,6 +222,12 @@
|
||||
#define CHECK_SOURCE(source, value, mask) ((s_config.wakeup_triggers & mask) && \
|
||||
(source == value))
|
||||
|
||||
#if CONFIG_PM_SLP_IRAM_OPT
|
||||
# define SLEEP_FN_ATTR IRAM_ATTR
|
||||
#else
|
||||
# define SLEEP_FN_ATTR
|
||||
#endif
|
||||
|
||||
#define MAX_DSLP_HOOKS 3
|
||||
|
||||
static esp_deep_sleep_cb_t s_dslp_cb[MAX_DSLP_HOOKS] = {0};
|
||||
@@ -525,7 +537,7 @@ static uint32_t s_stopped_tgwdt_bmap = 0;
|
||||
#endif
|
||||
|
||||
// Must be called from critical sections.
|
||||
static void IRAM_ATTR suspend_timers(uint32_t sleep_flags) {
|
||||
static SLEEP_FN_ATTR void suspend_timers(uint32_t sleep_flags) {
|
||||
if (!(sleep_flags & RTC_SLEEP_PD_XTAL)) {
|
||||
#if SOC_SLEEP_TGWDT_STOP_WORKAROUND
|
||||
/* If timegroup implemented task watchdog or interrupt watchdog is running, we have to stop it. */
|
||||
@@ -547,7 +559,7 @@ static void IRAM_ATTR suspend_timers(uint32_t sleep_flags) {
|
||||
}
|
||||
|
||||
// Must be called from critical sections.
|
||||
static void IRAM_ATTR resume_timers(uint32_t sleep_flags) {
|
||||
static SLEEP_FN_ATTR void resume_timers(uint32_t sleep_flags) {
|
||||
if (!(sleep_flags & RTC_SLEEP_PD_XTAL)) {
|
||||
#if SOC_SLEEP_SYSTIMER_STALL_WORKAROUND
|
||||
for (uint32_t counter_id = 0; counter_id < SOC_SYSTIMER_COUNTER_NUM; ++counter_id) {
|
||||
@@ -567,7 +579,7 @@ static void IRAM_ATTR resume_timers(uint32_t sleep_flags) {
|
||||
}
|
||||
|
||||
// [refactor-todo] provide target logic for body of uart functions below
|
||||
static void IRAM_ATTR flush_uarts(void)
|
||||
static SLEEP_FN_ATTR void flush_uarts(void)
|
||||
{
|
||||
for (int i = 0; i < SOC_UART_HP_NUM; ++i) {
|
||||
if (uart_ll_is_enabled(i)) {
|
||||
@@ -582,7 +594,7 @@ static uint32_t s_suspended_uarts_bmap = 0;
|
||||
* Suspend enabled uarts and return suspended uarts bit map.
|
||||
* Must be called from critical sections.
|
||||
*/
|
||||
FORCE_INLINE_ATTR void suspend_uarts(void)
|
||||
static SLEEP_FN_ATTR void suspend_uarts(void)
|
||||
{
|
||||
s_suspended_uarts_bmap = 0;
|
||||
for (int i = 0; i < SOC_UART_HP_NUM; ++i) {
|
||||
@@ -603,7 +615,7 @@ FORCE_INLINE_ATTR void suspend_uarts(void)
|
||||
}
|
||||
|
||||
// Must be called from critical sections
|
||||
FORCE_INLINE_ATTR void resume_uarts(void)
|
||||
static SLEEP_FN_ATTR void resume_uarts(void)
|
||||
{
|
||||
for (int i = 0; i < SOC_UART_HP_NUM; ++i) {
|
||||
if (s_suspended_uarts_bmap & 0x1) {
|
||||
@@ -629,7 +641,7 @@ FORCE_INLINE_ATTR void resume_uarts(void)
|
||||
completion time has exceeded the wakeup time, we should abandon the flush, skip the sleep and
|
||||
return ESP_ERR_SLEEP_REJECT.
|
||||
*/
|
||||
FORCE_INLINE_ATTR bool light_sleep_uart_prepare(uint32_t sleep_flags, int64_t sleep_duration)
|
||||
static SLEEP_FN_ATTR bool light_sleep_uart_prepare(uint32_t sleep_flags, int64_t sleep_duration)
|
||||
{
|
||||
bool should_skip_sleep = false;
|
||||
#if !SOC_PM_SUPPORT_TOP_PD || !CONFIG_ESP_CONSOLE_UART
|
||||
@@ -662,7 +674,7 @@ FORCE_INLINE_ATTR bool light_sleep_uart_prepare(uint32_t sleep_flags, int64_t sl
|
||||
/**
|
||||
* These save-restore workaround should be moved to lower layer
|
||||
*/
|
||||
FORCE_INLINE_ATTR void misc_modules_sleep_prepare(uint32_t sleep_flags, bool deep_sleep)
|
||||
static SLEEP_FN_ATTR void misc_modules_sleep_prepare(uint32_t sleep_flags, bool deep_sleep)
|
||||
{
|
||||
if (deep_sleep){
|
||||
for (int n = 0; n < MAX_DSLP_HOOKS; n++) {
|
||||
@@ -716,7 +728,7 @@ FORCE_INLINE_ATTR void misc_modules_sleep_prepare(uint32_t sleep_flags, bool dee
|
||||
/**
|
||||
* These save-restore workaround should be moved to lower layer
|
||||
*/
|
||||
FORCE_INLINE_ATTR void misc_modules_wake_prepare(uint32_t sleep_flags)
|
||||
static SLEEP_FN_ATTR void misc_modules_wake_prepare(uint32_t sleep_flags)
|
||||
{
|
||||
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
|
||||
if (sleep_flags & PMU_SLEEP_PD_TOP) {
|
||||
@@ -760,7 +772,7 @@ FORCE_INLINE_ATTR void misc_modules_wake_prepare(uint32_t sleep_flags)
|
||||
#endif
|
||||
}
|
||||
|
||||
static IRAM_ATTR void sleep_low_power_clock_calibration(bool is_dslp)
|
||||
static SLEEP_FN_ATTR void sleep_low_power_clock_calibration(bool is_dslp)
|
||||
{
|
||||
// Calibrate rtc slow clock
|
||||
#ifdef CONFIG_ESP_SYSTEM_RTC_EXT_XTAL
|
||||
@@ -800,7 +812,133 @@ static IRAM_ATTR void sleep_low_power_clock_calibration(bool is_dslp)
|
||||
|
||||
inline static uint32_t call_rtc_sleep_start(uint32_t reject_triggers, uint32_t lslp_mem_inf_fpu, bool dslp);
|
||||
|
||||
static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t sleep_flags, uint32_t clk_flags, esp_sleep_mode_t mode, bool allow_sleep_rejection)
|
||||
#if SOC_PMU_SUPPORTED
|
||||
static esp_err_t IRAM_ATTR esp_sleep_start_safe(uint32_t sleep_flags, uint32_t reject_triggers, bool deep_sleep, pmu_sleep_config_t *config)
|
||||
#else
|
||||
static esp_err_t IRAM_ATTR esp_sleep_start_safe(uint32_t sleep_flags, uint32_t reject_triggers, bool deep_sleep, rtc_sleep_config_t *config)
|
||||
#endif
|
||||
{
|
||||
esp_err_t result = ESP_OK;
|
||||
#if CONFIG_ESP_SLEEP_DEBUG
|
||||
if (s_sleep_ctx != NULL) {
|
||||
s_sleep_ctx->wakeup_triggers = s_config.wakeup_triggers;
|
||||
}
|
||||
#endif
|
||||
if (deep_sleep) {
|
||||
#if SOC_GPIO_SUPPORT_HOLD_IO_IN_DSLP && !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
|
||||
esp_sleep_isolate_digital_gpio();
|
||||
#endif
|
||||
|
||||
#if ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB && SOC_DEEP_SLEEP_SUPPORTED
|
||||
#if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
|
||||
esp_set_deep_sleep_wake_stub_default_entry();
|
||||
#elif !CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP && SOC_RTC_FAST_MEM_SUPPORTED
|
||||
/* If not possible stack is in RTC FAST memory, use the ROM function to calculate the CRC and save ~140 bytes IRAM */
|
||||
set_rtc_memory_crc();
|
||||
#endif // SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
|
||||
#endif
|
||||
|
||||
#if SOC_DCDC_SUPPORTED
|
||||
uint64_t ldo_increased_us = rtc_time_slowclk_to_us(rtc_time_get() - s_config.rtc_ticks_at_ldo_prepare, s_config.rtc_clk_cal_period);
|
||||
if (ldo_increased_us < LDO_POWER_TAKEOVER_PREPARATION_TIME_US) {
|
||||
esp_rom_delay_us(LDO_POWER_TAKEOVER_PREPARATION_TIME_US - ldo_increased_us);
|
||||
}
|
||||
pmu_sleep_shutdown_dcdc();
|
||||
#endif
|
||||
|
||||
// Enter Deep Sleep
|
||||
#if!ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB || SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY || !CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP
|
||||
#if SOC_PMU_SUPPORTED
|
||||
result = call_rtc_sleep_start(reject_triggers, config->power.hp_sys.dig_power.mem_dslp, deep_sleep);
|
||||
#else
|
||||
result = call_rtc_sleep_start(reject_triggers, config->lslp_mem_inf_fpu, deep_sleep);
|
||||
#endif
|
||||
#else
|
||||
/* Otherwise, need to call the dedicated soc function for this */
|
||||
result = rtc_deep_sleep_start(s_config.wakeup_triggers, reject_triggers);
|
||||
#endif
|
||||
} else {
|
||||
suspend_timers(sleep_flags);
|
||||
/* Cache Suspend 1: will wait cache idle in cache suspend */
|
||||
suspend_cache();
|
||||
/* On esp32c6, only the lp_aon pad hold function can only hold the GPIO state in the active mode.
|
||||
In order to avoid the leakage of the SPI cs pin, hold it here */
|
||||
|
||||
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
|
||||
if(!(sleep_flags & RTC_SLEEP_PD_VDDSDIO) && (sleep_flags & PMU_SLEEP_PD_TOP)) {
|
||||
#if CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND
|
||||
/* Cache suspend also means SPI bus IDLE, then we can hold SPI CS pin safely */
|
||||
#if !CONFIG_IDF_TARGET_ESP32H2 // ESP32H2 TODO IDF-7359
|
||||
gpio_ll_hold_en(&GPIO, MSPI_IOMUX_PIN_NUM_CS0);
|
||||
#endif
|
||||
#endif
|
||||
#if CONFIG_ESP_SLEEP_PSRAM_LEAKAGE_WORKAROUND && CONFIG_SPIRAM
|
||||
/* Cache suspend also means SPI bus IDLE, then we can hold SPI CS pin safely */
|
||||
gpio_ll_hold_en(&GPIO, MSPI_IOMUX_PIN_NUM_CS1);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_PM_MMU_TABLE_RETENTION_WHEN_TOP_PD
|
||||
if (sleep_flags & PMU_SLEEP_PD_TOP) {
|
||||
esp_sleep_mmu_retention(true);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SOC_DCDC_SUPPORTED && !CONFIG_ESP_SLEEP_KEEP_DCDC_ALWAYS_ON
|
||||
uint64_t ldo_increased_us = rtc_time_slowclk_to_us(rtc_time_get() - s_config.rtc_ticks_at_ldo_prepare, s_config.rtc_clk_cal_period);
|
||||
if (ldo_increased_us < LDO_POWER_TAKEOVER_PREPARATION_TIME_US) {
|
||||
esp_rom_delay_us(LDO_POWER_TAKEOVER_PREPARATION_TIME_US - ldo_increased_us);
|
||||
}
|
||||
pmu_sleep_shutdown_dcdc();
|
||||
#endif
|
||||
|
||||
#if SOC_PMU_SUPPORTED
|
||||
#if SOC_PM_CPU_RETENTION_BY_SW && ESP_SLEEP_POWER_DOWN_CPU
|
||||
esp_sleep_execute_event_callbacks(SLEEP_EVENT_HW_GOTO_SLEEP, (void *)0);
|
||||
if (sleep_flags & (PMU_SLEEP_PD_CPU | PMU_SLEEP_PD_TOP)) {
|
||||
result = esp_sleep_cpu_retention(pmu_sleep_start, s_config.wakeup_triggers, reject_triggers, config->power.hp_sys.dig_power.mem_dslp, deep_sleep);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
#if !CONFIG_FREERTOS_UNICORE && ESP_SLEEP_POWER_DOWN_CPU && SOC_PM_CPU_RETENTION_BY_SW
|
||||
// Skip smp retention if CPU power domain power-down is not allowed
|
||||
esp_sleep_cpu_skip_retention();
|
||||
#endif
|
||||
result = call_rtc_sleep_start(reject_triggers, config->power.hp_sys.dig_power.mem_dslp, deep_sleep);
|
||||
}
|
||||
esp_sleep_execute_event_callbacks(SLEEP_EVENT_HW_EXIT_SLEEP, (void *)0);
|
||||
#else
|
||||
result = call_rtc_sleep_start(reject_triggers, config->lslp_mem_inf_fpu, deep_sleep);
|
||||
#endif
|
||||
|
||||
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_PM_MMU_TABLE_RETENTION_WHEN_TOP_PD
|
||||
if (sleep_flags & PMU_SLEEP_PD_TOP) {
|
||||
esp_sleep_mmu_retention(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
|
||||
/* Unhold the SPI CS pin */
|
||||
if(!(sleep_flags & RTC_SLEEP_PD_VDDSDIO) && (sleep_flags & PMU_SLEEP_PD_TOP)) {
|
||||
#if CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND
|
||||
#if !CONFIG_IDF_TARGET_ESP32H2 // ESP32H2 TODO IDF-7359
|
||||
gpio_ll_hold_dis(&GPIO, MSPI_IOMUX_PIN_NUM_CS0);
|
||||
#endif
|
||||
#endif
|
||||
#if CONFIG_ESP_SLEEP_PSRAM_LEAKAGE_WORKAROUND && CONFIG_SPIRAM
|
||||
gpio_ll_hold_dis(&GPIO, MSPI_IOMUX_PIN_NUM_CS1);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
/* Cache Resume 1: Resume cache for continue running*/
|
||||
resume_cache();
|
||||
resume_timers(sleep_flags);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static esp_err_t SLEEP_FN_ATTR esp_sleep_start(uint32_t sleep_flags, uint32_t clk_flags, esp_sleep_mode_t mode, bool allow_sleep_rejection)
|
||||
{
|
||||
// Stop UART output so that output is not lost due to APB frequency change.
|
||||
// For light sleep, suspend UART output — it will resume after wakeup.
|
||||
@@ -980,123 +1118,7 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t sleep_flags, uint32_t clk_fl
|
||||
esp_sleep_cpu_skip_retention();
|
||||
#endif
|
||||
} else {
|
||||
#if CONFIG_ESP_SLEEP_DEBUG
|
||||
if (s_sleep_ctx != NULL) {
|
||||
s_sleep_ctx->wakeup_triggers = s_config.wakeup_triggers;
|
||||
}
|
||||
#endif
|
||||
if (deep_sleep) {
|
||||
#if SOC_GPIO_SUPPORT_HOLD_IO_IN_DSLP && !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
|
||||
esp_sleep_isolate_digital_gpio();
|
||||
#endif
|
||||
|
||||
#if ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB && SOC_DEEP_SLEEP_SUPPORTED
|
||||
#if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
|
||||
esp_set_deep_sleep_wake_stub_default_entry();
|
||||
#elif !CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP && SOC_RTC_FAST_MEM_SUPPORTED
|
||||
/* If not possible stack is in RTC FAST memory, use the ROM function to calculate the CRC and save ~140 bytes IRAM */
|
||||
set_rtc_memory_crc();
|
||||
#endif // SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
|
||||
#endif
|
||||
|
||||
#if SOC_DCDC_SUPPORTED
|
||||
uint64_t ldo_increased_us = rtc_time_slowclk_to_us(rtc_time_get() - s_config.rtc_ticks_at_ldo_prepare, s_config.rtc_clk_cal_period);
|
||||
if (ldo_increased_us < LDO_POWER_TAKEOVER_PREPARATION_TIME_US) {
|
||||
esp_rom_delay_us(LDO_POWER_TAKEOVER_PREPARATION_TIME_US - ldo_increased_us);
|
||||
}
|
||||
pmu_sleep_shutdown_dcdc();
|
||||
#endif
|
||||
|
||||
// Enter Deep Sleep
|
||||
#if!ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB || SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY || !CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP
|
||||
#if SOC_PMU_SUPPORTED
|
||||
result = call_rtc_sleep_start(reject_triggers, config.power.hp_sys.dig_power.mem_dslp, deep_sleep);
|
||||
#else
|
||||
result = call_rtc_sleep_start(reject_triggers, config.lslp_mem_inf_fpu, deep_sleep);
|
||||
#endif
|
||||
#else
|
||||
/* Otherwise, need to call the dedicated soc function for this */
|
||||
result = rtc_deep_sleep_start(s_config.wakeup_triggers, reject_triggers);
|
||||
#endif
|
||||
} else {
|
||||
suspend_timers(sleep_flags);
|
||||
/* Cache Suspend 1: will wait cache idle in cache suspend */
|
||||
suspend_cache();
|
||||
/* On esp32c6, only the lp_aon pad hold function can only hold the GPIO state in the active mode.
|
||||
In order to avoid the leakage of the SPI cs pin, hold it here */
|
||||
|
||||
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
|
||||
if(!(sleep_flags & RTC_SLEEP_PD_VDDSDIO) && (sleep_flags & PMU_SLEEP_PD_TOP)) {
|
||||
#if CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND
|
||||
/* Cache suspend also means SPI bus IDLE, then we can hold SPI CS pin safely */
|
||||
#if !CONFIG_IDF_TARGET_ESP32H2 // ESP32H2 TODO IDF-7359
|
||||
gpio_ll_hold_en(&GPIO, MSPI_IOMUX_PIN_NUM_CS0);
|
||||
#endif
|
||||
#endif
|
||||
#if CONFIG_ESP_SLEEP_PSRAM_LEAKAGE_WORKAROUND && CONFIG_SPIRAM
|
||||
/* Cache suspend also means SPI bus IDLE, then we can hold SPI CS pin safely */
|
||||
gpio_ll_hold_en(&GPIO, MSPI_IOMUX_PIN_NUM_CS1);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_PM_MMU_TABLE_RETENTION_WHEN_TOP_PD
|
||||
if (sleep_flags & PMU_SLEEP_PD_TOP) {
|
||||
esp_sleep_mmu_retention(true);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SOC_DCDC_SUPPORTED && !CONFIG_ESP_SLEEP_KEEP_DCDC_ALWAYS_ON
|
||||
uint64_t ldo_increased_us = rtc_time_slowclk_to_us(rtc_time_get() - s_config.rtc_ticks_at_ldo_prepare, s_config.rtc_clk_cal_period);
|
||||
if (ldo_increased_us < LDO_POWER_TAKEOVER_PREPARATION_TIME_US) {
|
||||
esp_rom_delay_us(LDO_POWER_TAKEOVER_PREPARATION_TIME_US - ldo_increased_us);
|
||||
}
|
||||
pmu_sleep_shutdown_dcdc();
|
||||
#endif
|
||||
|
||||
#if SOC_PMU_SUPPORTED
|
||||
#if SOC_PM_CPU_RETENTION_BY_SW && ESP_SLEEP_POWER_DOWN_CPU
|
||||
esp_sleep_execute_event_callbacks(SLEEP_EVENT_HW_GOTO_SLEEP, (void *)0);
|
||||
if (sleep_flags & (PMU_SLEEP_PD_CPU | PMU_SLEEP_PD_TOP)) {
|
||||
result = esp_sleep_cpu_retention(pmu_sleep_start, s_config.wakeup_triggers, reject_triggers, config.power.hp_sys.dig_power.mem_dslp, deep_sleep);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
#if !CONFIG_FREERTOS_UNICORE && ESP_SLEEP_POWER_DOWN_CPU && SOC_PM_CPU_RETENTION_BY_SW
|
||||
// Skip smp retention if CPU power domain power-down is not allowed
|
||||
esp_sleep_cpu_skip_retention();
|
||||
#endif
|
||||
result = call_rtc_sleep_start(reject_triggers, config.power.hp_sys.dig_power.mem_dslp, deep_sleep);
|
||||
}
|
||||
esp_sleep_execute_event_callbacks(SLEEP_EVENT_HW_EXIT_SLEEP, (void *)0);
|
||||
#else
|
||||
result = call_rtc_sleep_start(reject_triggers, config.lslp_mem_inf_fpu, deep_sleep);
|
||||
#endif
|
||||
|
||||
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_PM_MMU_TABLE_RETENTION_WHEN_TOP_PD
|
||||
if (sleep_flags & PMU_SLEEP_PD_TOP) {
|
||||
esp_sleep_mmu_retention(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
|
||||
/* Unhold the SPI CS pin */
|
||||
if(!(sleep_flags & RTC_SLEEP_PD_VDDSDIO) && (sleep_flags & PMU_SLEEP_PD_TOP)) {
|
||||
#if CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND
|
||||
#if !CONFIG_IDF_TARGET_ESP32H2 // ESP32H2 TODO IDF-7359
|
||||
gpio_ll_hold_dis(&GPIO, MSPI_IOMUX_PIN_NUM_CS0);
|
||||
#endif
|
||||
#endif
|
||||
#if CONFIG_ESP_SLEEP_PSRAM_LEAKAGE_WORKAROUND && CONFIG_SPIRAM
|
||||
gpio_ll_hold_dis(&GPIO, MSPI_IOMUX_PIN_NUM_CS1);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Cache Resume 1: Resume cache for continue running*/
|
||||
resume_cache();
|
||||
resume_timers(sleep_flags);
|
||||
}
|
||||
result = esp_sleep_start_safe(sleep_flags, reject_triggers, deep_sleep, &config);
|
||||
}
|
||||
#if CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION
|
||||
if (sleep_flags & RTC_SLEEP_PD_VDDSDIO) {
|
||||
@@ -1119,6 +1141,21 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t sleep_flags, uint32_t clk_fl
|
||||
|
||||
if (!deep_sleep) {
|
||||
if (result == ESP_OK) {
|
||||
#if !CONFIG_PM_SLP_IRAM_OPT && !CONFIG_IDF_TARGET_ESP32
|
||||
#if CONFIG_SPIRAM
|
||||
# if CONFIG_IDF_TARGET_ESP32P4
|
||||
cache_ll_writeback_all(CACHE_LL_LEVEL_ALL, CACHE_TYPE_DATA, CACHE_LL_ID_ALL);
|
||||
# else
|
||||
Cache_WriteBack_All();
|
||||
# endif
|
||||
#endif
|
||||
/* When the IRAM optimization for the sleep flow is disabled, all
|
||||
* cache contents are forcibly invalidated before exiting the sleep
|
||||
* flow. This ensures that the code execution time of sleep exit
|
||||
* flow remains consistent, allowing the use of ccount to
|
||||
* dynamically calculate the sleep adjustment time. */
|
||||
cache_ll_invalidate_all(CACHE_LL_LEVEL_ALL, CACHE_TYPE_ALL, CACHE_LL_ID_ALL);
|
||||
#endif
|
||||
s_config.ccount_ticks_record = esp_cpu_get_cycle_count();
|
||||
#if SOC_PM_RETENTION_SW_TRIGGER_REGDMA
|
||||
if (sleep_flags & PMU_SLEEP_PD_TOP) {
|
||||
@@ -1254,9 +1291,9 @@ esp_err_t IRAM_ATTR esp_deep_sleep_try_to_start(void)
|
||||
* Placed into IRAM as flash may need some time to be powered on.
|
||||
*/
|
||||
static esp_err_t esp_light_sleep_inner(uint32_t sleep_flags, uint32_t clk_flags,
|
||||
uint32_t flash_enable_time_us) IRAM_ATTR __attribute__((noinline));
|
||||
uint32_t flash_enable_time_us) __attribute__((noinline));
|
||||
|
||||
static esp_err_t esp_light_sleep_inner(uint32_t sleep_flags, uint32_t clk_flags,
|
||||
static SLEEP_FN_ATTR esp_err_t esp_light_sleep_inner(uint32_t sleep_flags, uint32_t clk_flags,
|
||||
uint32_t flash_enable_time_us)
|
||||
{
|
||||
#if SOC_CONFIGURABLE_VDDSDIO_SUPPORTED
|
||||
@@ -1687,7 +1724,7 @@ esp_err_t esp_sleep_enable_vad_wakeup(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
static esp_err_t timer_wakeup_prepare(int64_t sleep_duration)
|
||||
static SLEEP_FN_ATTR esp_err_t timer_wakeup_prepare(int64_t sleep_duration)
|
||||
{
|
||||
if (sleep_duration < 0) {
|
||||
sleep_duration = 0;
|
||||
@@ -2325,7 +2362,7 @@ FORCE_INLINE_ATTR bool top_domain_pd_allowed(void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
static uint32_t get_power_down_flags(void)
|
||||
static SLEEP_FN_ATTR uint32_t get_power_down_flags(void)
|
||||
{
|
||||
// Where needed, convert AUTO options to ON. Later interpret AUTO as OFF.
|
||||
|
||||
@@ -2502,7 +2539,7 @@ static uint32_t get_power_down_flags(void)
|
||||
return pd_flags;
|
||||
}
|
||||
|
||||
static uint32_t get_sleep_flags(uint32_t sleep_flags, bool deepsleep)
|
||||
static SLEEP_FN_ATTR uint32_t get_sleep_flags(uint32_t sleep_flags, bool deepsleep)
|
||||
{
|
||||
// Override user-configured FOSC power modes.
|
||||
if (s_sleep_sub_mode_ref_cnt[ESP_SLEEP_RTC_USE_RC_FAST_MODE]) {
|
||||
@@ -2554,7 +2591,7 @@ static uint32_t get_sleep_flags(uint32_t sleep_flags, bool deepsleep)
|
||||
return sleep_flags;
|
||||
}
|
||||
|
||||
static uint32_t get_sleep_clock_icg_flags(void)
|
||||
static SLEEP_FN_ATTR uint32_t get_sleep_clock_icg_flags(void)
|
||||
{
|
||||
uint32_t clk_flags = 0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user