forked from espressif/esp-idf
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:
@@ -2,6 +2,7 @@ menu "ADC and ADC Calibration"
|
||||
|
||||
config ADC_ONESHOT_CTRL_FUNC_IN_IRAM
|
||||
bool "Place ISR version ADC oneshot mode read function into IRAM"
|
||||
select ESP_PERIPH_CTRL_FUNC_IN_IRAM
|
||||
default n
|
||||
help
|
||||
Place ISR version ADC oneshot mode read function into IRAM.
|
||||
|
@@ -6,6 +6,7 @@ menu "ESP-Driver:Parallel IO Configurations"
|
||||
default y
|
||||
select PARLIO_OBJ_CACHE_SAFE
|
||||
select GDMA_CTRL_FUNC_IN_IRAM
|
||||
select ESP_PERIPH_CTRL_FUNC_IN_IRAM
|
||||
help
|
||||
Place Parallel IO TX ISR handler in IRAM to reduce latency caused by cache miss.
|
||||
|
||||
|
@@ -23,6 +23,7 @@ menu "ESP-Driver:SPI Configurations"
|
||||
bool "Place SPI master ISR function into IRAM"
|
||||
default y
|
||||
depends on !HEAP_PLACE_FUNCTION_INTO_FLASH
|
||||
select ESP_PERIPH_CTRL_FUNC_IN_IRAM
|
||||
select ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM
|
||||
select GDMA_CTRL_FUNC_IN_IRAM if SOC_GDMA_SUPPORTED
|
||||
help
|
||||
@@ -51,6 +52,7 @@ menu "ESP-Driver:SPI Configurations"
|
||||
config SPI_SLAVE_ISR_IN_IRAM
|
||||
bool "Place SPI slave ISR function into IRAM"
|
||||
default y
|
||||
select ESP_PERIPH_CTRL_FUNC_IN_IRAM
|
||||
select GDMA_CTRL_FUNC_IN_IRAM if SOC_GDMA_SUPPORTED
|
||||
help
|
||||
Place the SPI slave ISR in to IRAM to avoid possible cache miss.
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -10,6 +10,7 @@ menu "ESP-Driver:LCD Controller Configurations"
|
||||
config LCD_RGB_ISR_IRAM_SAFE
|
||||
bool "RGB LCD ISR IRAM-Safe"
|
||||
select GDMA_ISR_HANDLER_IN_IRAM # bounce buffer mode relies on GDMA EOF interrupt
|
||||
select ESP_PERIPH_CTRL_FUNC_IN_IRAM
|
||||
default n
|
||||
help
|
||||
Ensure the LCD interrupt is IRAM-Safe by allowing the interrupt handler to be
|
||||
|
@@ -1,4 +1,14 @@
|
||||
menu "Power Management"
|
||||
|
||||
config PM_SLEEP_FUNC_IN_IRAM
|
||||
bool "Place Power Management module functions in IRAM" if IDF_TARGET_ESP32C2
|
||||
default y
|
||||
select PM_SLP_IRAM_OPT if SOC_LIGHT_SLEEP_SUPPORTED
|
||||
select PM_RTOS_IDLE_OPT if FREERTOS_USE_TICKLESS_IDLE
|
||||
select ESP_PERIPH_CTRL_FUNC_IN_IRAM
|
||||
select ESP_REGI2C_CTRL_FUNC_IN_IRAM
|
||||
|
||||
|
||||
config PM_ENABLE
|
||||
bool "Support for power management"
|
||||
# SMP FreeRTOS currently does not support power management IDF-4997
|
||||
@@ -49,7 +59,8 @@ menu "Power Management"
|
||||
|
||||
config PM_SLP_IRAM_OPT
|
||||
bool "Put lightsleep related codes in internal RAM"
|
||||
depends on SOC_LIGHT_SLEEP_SUPPORTED && ESP_TIMER_IN_IRAM
|
||||
depends on SOC_LIGHT_SLEEP_SUPPORTED
|
||||
select ESP_TIMER_IN_IRAM
|
||||
help
|
||||
If enabled, about 2.1KB of lightsleep related source code would be in IRAM and chip would sleep
|
||||
longer for 310us at 160MHz CPU frequency most each time.
|
||||
|
@@ -7,44 +7,45 @@ entries:
|
||||
|
||||
if PM_SLP_IRAM_OPT = y:
|
||||
pm_impl:esp_pm_impl_get_cpu_freq (noflash)
|
||||
if FREERTOS_USE_TICKLESS_IDLE = y:
|
||||
pm_impl:vApplicationSleep (noflash)
|
||||
|
||||
[mapping:esp_hw_support_pm]
|
||||
archive: libesp_hw_support.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)
|
||||
sleep_modes:get_sleep_flags (noflash)
|
||||
sleep_modes:get_sleep_clock_icg_flags (noflash)
|
||||
if SOC_LIGHT_SLEEP_SUPPORTED = y:
|
||||
sleep_modes:esp_light_sleep_start (noflash)
|
||||
sleep_modes:esp_sleep_enable_timer_wakeup (noflash)
|
||||
sleep_modem:modem_domain_pd_allowed (noflash)
|
||||
sleep_modem:periph_inform_out_light_sleep_overhead (noflash)
|
||||
sleep_modem:sleep_modem_reject_triggers (noflash)
|
||||
if ESP_PHY_MAC_BB_PD = y:
|
||||
sleep_modem:mac_bb_power_down_cb_execute (noflash)
|
||||
sleep_modem:mac_bb_power_up_cb_execute (noflash)
|
||||
if GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL = y:
|
||||
sleep_gpio:gpio_sleep_mode_config_apply (noflash)
|
||||
if SOC_PM_SUPPORT_TOP_PD = y:
|
||||
sleep_clock:clock_domain_pd_allowed (noflash)
|
||||
sleep_system_peripheral:peripheral_domain_pd_allowed (noflash)
|
||||
if SOC_PM_CPU_RETENTION_BY_RTCCNTL = y && (PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP = y || SOC_PM_SUPPORT_TAGMEM_PD = y):
|
||||
sleep_cpu:sleep_enable_cpu_retention (noflash)
|
||||
if PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP = y || (SOC_CPU_IN_TOP_DOMAIN = y && PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP = y):
|
||||
sleep_cpu:cpu_domain_pd_allowed (noflash)
|
||||
if SOC_PM_MMU_TABLE_RETENTION_WHEN_TOP_PD = y && PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP = y:
|
||||
sleep_mmu:mmu_domain_pd_allowed (noflash)
|
||||
esp_clk:esp_clk_slowclk_cal_set (noflash)
|
||||
esp_clk:esp_clk_slowclk_cal_get (noflash)
|
||||
esp_clk:esp_rtc_get_time_us (noflash)
|
||||
esp_clk:esp_clk_private_lock (noflash)
|
||||
esp_clk:esp_clk_private_unlock (noflash)
|
||||
if SOC_RTC_MEM_SUPPORTED = y:
|
||||
esp_clk:calc_checksum (noflash)
|
||||
if SOC_SYSTIMER_SUPPORTED = y:
|
||||
systimer (noflash)
|
||||
if GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL = y:
|
||||
sleep_gpio:gpio_sleep_mode_config_apply (noflash)
|
||||
if SOC_PM_CPU_RETENTION_BY_RTCCNTL = y && (PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP = y || SOC_PM_SUPPORT_TAGMEM_PD = y):
|
||||
sleep_cpu:sleep_enable_cpu_retention (noflash)
|
||||
if PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP = y || (SOC_CPU_IN_TOP_DOMAIN = y && PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP = y):
|
||||
sleep_cpu:cpu_domain_pd_allowed (noflash)
|
||||
if SOC_PM_SUPPORT_TOP_PD = y:
|
||||
sleep_clock:clock_domain_pd_allowed (noflash)
|
||||
sleep_system_peripheral:peripheral_domain_pd_allowed (noflash)
|
||||
if SOC_PM_MMU_TABLE_RETENTION_WHEN_TOP_PD = y && PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP = y:
|
||||
sleep_mmu:mmu_domain_pd_allowed (noflash)
|
||||
sleep_modem:modem_domain_pd_allowed (noflash)
|
||||
sleep_modem:periph_inform_out_light_sleep_overhead (noflash)
|
||||
sar_periph_ctrl:sar_periph_ctrl_power_disable (noflash)
|
||||
if IDF_TARGET_ESP32H21 != y && IDF_TARGET_ESP32H4 != y:
|
||||
sar_periph_ctrl:sar_periph_ctrl_power_disable (noflash)
|
||||
if SOC_TEMP_SENSOR_SUPPORTED = y:
|
||||
sar_periph_ctrl_common:temperature_sensor_power_acquire (noflash)
|
||||
sar_periph_ctrl_common:temperature_sensor_power_release (noflash)
|
||||
sar_periph_ctrl_common:temperature_sensor_get_raw_value (noflash)
|
||||
sar_periph_ctrl_common:temp_sensor_get_raw_value (noflash)
|
||||
regi2c_ctrl:regi2c_saradc_enable (noflash)
|
||||
regi2c_ctrl:regi2c_saradc_disable (noflash)
|
||||
@@ -57,17 +58,6 @@ archive: libesp_system.a
|
||||
entries:
|
||||
if PM_RTOS_IDLE_OPT = y:
|
||||
freertos_hooks:esp_vApplicationIdleHook (noflash)
|
||||
if PM_SLP_IRAM_OPT = y:
|
||||
task_wdt:idle_hook_cb (noflash)
|
||||
task_wdt:task_wdt_timer_feed (noflash)
|
||||
task_wdt:find_entry_and_check_all_reset (noflash)
|
||||
task_wdt:find_entry_from_task_handle_and_check_all_reset (noflash)
|
||||
task_wdt:esp_task_wdt_reset (noflash)
|
||||
task_wdt:esp_task_wdt_reset_user (noflash)
|
||||
if ESP_TASK_WDT_USE_ESP_TIMER = y:
|
||||
task_wdt_impl_esp_timer:esp_task_wdt_impl_timer_feed (noflash)
|
||||
else:
|
||||
task_wdt_impl_timergroup:esp_task_wdt_impl_timer_feed (noflash)
|
||||
|
||||
[mapping:esp_timer_pm]
|
||||
archive: libesp_timer.a
|
||||
|
@@ -803,7 +803,7 @@ static inline void IRAM_ATTR other_core_should_skip_light_sleep(int core_id)
|
||||
#endif
|
||||
}
|
||||
|
||||
void IRAM_ATTR vApplicationSleep( TickType_t xExpectedIdleTime )
|
||||
void vApplicationSleep( TickType_t xExpectedIdleTime )
|
||||
{
|
||||
portENTER_CRITICAL(&s_switch_lock);
|
||||
int core_id = xPortGetCoreID();
|
||||
|
@@ -36,6 +36,12 @@
|
||||
#define BACKTRACE_MSG "backtrace"
|
||||
#endif
|
||||
|
||||
#if CONFIG_PM_RTOS_IDLE_OPT
|
||||
# define TASK_WDT_FN_ATTR IRAM_ATTR
|
||||
#else
|
||||
# define TASK_WDT_FN_ATTR
|
||||
#endif
|
||||
|
||||
/* We will use this function in order to simulate an `abort()` occurring in
|
||||
* a different context than the one it's called from. */
|
||||
extern void xt_unhandled_exception(void *frame);
|
||||
@@ -96,7 +102,7 @@ static char core_user_names[CONFIG_FREERTOS_NUMBER_OF_CORES][CORE_USER_NAME_LEN]
|
||||
* @brief Reset the timer and reset flags of each entry
|
||||
* When entering this function, the spinlock has already been taken, no need to take it back.
|
||||
*/
|
||||
static void task_wdt_timer_feed(void)
|
||||
static TASK_WDT_FN_ATTR void task_wdt_timer_feed(void)
|
||||
{
|
||||
esp_task_wdt_impl_timer_feed(p_twdt_obj->impl_ctx);
|
||||
|
||||
@@ -114,7 +120,7 @@ static void task_wdt_timer_feed(void)
|
||||
* @param[out] all_reset Whether all entries have been reset
|
||||
* @return Whether the user entry exists
|
||||
*/
|
||||
static bool find_entry_and_check_all_reset(twdt_entry_t *user_entry, bool *all_reset)
|
||||
static TASK_WDT_FN_ATTR bool find_entry_and_check_all_reset(twdt_entry_t *user_entry, bool *all_reset)
|
||||
{
|
||||
bool found_user_entry = false;
|
||||
bool found_non_reset = false;
|
||||
@@ -139,7 +145,7 @@ static bool find_entry_and_check_all_reset(twdt_entry_t *user_entry, bool *all_r
|
||||
* @param[out] all_reset Whether all entries have been reset
|
||||
* @return Task entry, or NULL if not found
|
||||
*/
|
||||
static twdt_entry_t *find_entry_from_task_handle_and_check_all_reset(TaskHandle_t handle, bool *all_reset)
|
||||
static TASK_WDT_FN_ATTR twdt_entry_t *find_entry_from_task_handle_and_check_all_reset(TaskHandle_t handle, bool *all_reset)
|
||||
{
|
||||
twdt_entry_t *target = NULL;
|
||||
bool found_non_reset = false;
|
||||
@@ -448,7 +454,7 @@ static void task_wdt_timeout_handling(int cores_fail, bool panic)
|
||||
*
|
||||
* @return Whether the idle tasks should continue idling
|
||||
*/
|
||||
static bool idle_hook_cb(void)
|
||||
static TASK_WDT_FN_ATTR bool idle_hook_cb(void)
|
||||
{
|
||||
#if CONFIG_FREERTOS_SMP
|
||||
esp_task_wdt_reset_user(core_user_handles[xPortGetCoreID()]);
|
||||
@@ -687,7 +693,7 @@ esp_err_t esp_task_wdt_add_user(const char *user_name, esp_task_wdt_user_handle_
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t esp_task_wdt_reset(void)
|
||||
esp_err_t TASK_WDT_FN_ATTR esp_task_wdt_reset(void)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(p_twdt_obj != NULL, ESP_ERR_INVALID_STATE, TAG, "TWDT was never initialized");
|
||||
esp_err_t ret;
|
||||
@@ -711,7 +717,7 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t esp_task_wdt_reset_user(esp_task_wdt_user_handle_t user_handle)
|
||||
esp_err_t TASK_WDT_FN_ATTR esp_task_wdt_reset_user(esp_task_wdt_user_handle_t user_handle)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(user_handle != NULL, ESP_ERR_INVALID_ARG, TAG, "Invalid arguments");
|
||||
ESP_RETURN_ON_FALSE(p_twdt_obj != NULL, ESP_ERR_INVALID_STATE, TAG, "TWDT was never initialized");
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -17,6 +17,12 @@
|
||||
#include "esp_timer.h"
|
||||
#include "esp_private/esp_task_wdt_impl.h"
|
||||
|
||||
#if CONFIG_PM_SLP_IRAM_OPT
|
||||
# define TASK_WDT_FN_ATTR IRAM_ATTR
|
||||
#else
|
||||
# define TASK_WDT_FN_ATTR
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Context for the software implementation of the Task WatchDog Timer.
|
||||
* This will be passed as a parameter to public functions below. */
|
||||
@@ -50,7 +56,7 @@ esp_err_t esp_task_wdt_impl_timer_allocate(const esp_task_wdt_config_t *config,
|
||||
esp_err_t ret = esp_timer_create(&timer_args, &ctx->sw_timer);
|
||||
ESP_GOTO_ON_FALSE((ret == ESP_OK), ret, reterr, TAG, "could not start periodic timer");
|
||||
|
||||
/* Configure it as a periodic timer, so that we check the Tasks everytime it is triggered.
|
||||
/* Configure it as a periodic timer, so that we check the Tasks every time it is triggered.
|
||||
* No need to start the timer here, it will be started later with `esp_task_wdt_impl_timer_restart` */
|
||||
ctx->period_ms = config->timeout_ms;
|
||||
|
||||
@@ -89,7 +95,7 @@ void esp_task_wdt_impl_timer_free(twdt_ctx_t obj)
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t esp_task_wdt_impl_timer_feed(twdt_ctx_t obj)
|
||||
esp_err_t TASK_WDT_FN_ATTR esp_task_wdt_impl_timer_feed(twdt_ctx_t obj)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
const twdt_ctx_soft_t* ctx = (twdt_ctx_soft_t*) obj;
|
||||
|
@@ -32,6 +32,12 @@
|
||||
#define TWDT_TIMER_GROUP 0
|
||||
#define TWDT_INTR_SOURCE SYS_TG0_WDT_INTR_SOURCE
|
||||
|
||||
#if CONFIG_PM_SLP_IRAM_OPT
|
||||
# define TASK_WDT_FN_ATTR IRAM_ATTR
|
||||
#else
|
||||
# define TASK_WDT_FN_ATTR
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Context for the software implementation of the Task WatchDog Timer.
|
||||
* This will be passed as a parameter to public functions below. */
|
||||
@@ -177,7 +183,7 @@ void esp_task_wdt_impl_timer_free(twdt_ctx_t obj)
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t esp_task_wdt_impl_timer_feed(twdt_ctx_t obj)
|
||||
esp_err_t TASK_WDT_FN_ATTR esp_task_wdt_impl_timer_feed(twdt_ctx_t obj)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
twdt_ctx_hard_t* ctx = (twdt_ctx_hard_t*) obj;
|
||||
|
@@ -343,7 +343,8 @@ menu "Wi-Fi"
|
||||
config ESP_WIFI_SLP_IRAM_OPT
|
||||
bool "WiFi SLP IRAM speed optimization"
|
||||
select PM_SLP_DEFAULT_PARAMS_OPT
|
||||
select PERIPH_CTRL_FUNC_IN_IRAM
|
||||
select PM_SLEEP_FUNC_IN_IRAM
|
||||
select ESP_PERIPH_CTRL_FUNC_IN_IRAM
|
||||
default y if SOC_WIFI_HE_SUPPORT
|
||||
help
|
||||
Select this option to place called Wi-Fi library TBTT process and receive beacon functions in IRAM.
|
||||
|
@@ -285,6 +285,28 @@ This section introduces the recommended configuration and configuration steps fo
|
||||
|
||||
Due to the shared power pins between flash and PSRAM, cutting power to PSRAM would result in data loss. Therefore, to ensure light sleep does not disrupt program execution, enabling this option requires that the system does not utilize PSRAM.
|
||||
|
||||
.. only:: esp32c2
|
||||
|
||||
- To reduce the on-chip RAM usage of the Power Management module (:ref:CONFIG_PM_SLEEP_FUNC_IN_IRAM), the options in the table below are used to control whether individual components of the Power Management module enable or disable on-chip RAM optimization when :ref:CONFIG_PM_SLEEP_FUNC_IN_IRAM is disabled.
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 30 60
|
||||
|
||||
* - Configuration Name
|
||||
- Configuration Description
|
||||
|
||||
* - :ref:`CONFIG_PM_SLP_IRAM_OPT`
|
||||
- When this option is enabled, the software flow for entering and exiting light/deep sleep is linked to on-chip RAM, which shortens the sleep transition time but consumes more on-chip RAM resources. When this option is disabled, the light/deep sleep software flow is compiled into flash memory instead, resulting in longer sleep transition time but saving on-chip RAM resources.
|
||||
|
||||
* - :ref:`CONFIG_PM_RTOS_IDLE_OPT`
|
||||
- In auto light sleep mode, when this option is enabled, the FreeRTOS system tick, IDLE task hook functions, and the FreeRTOS tickless idle software context are linked to on-chip RAM. Otherwise, they will be linked to flash memory.
|
||||
|
||||
* - :ref:`CONFIG_ESP_PERIPH_CTRL_FUNC_IN_IRAM`
|
||||
- When this option is enabled, the software implementation related to peripheral clock and reset control will be linked to on-chip RAM. Otherwise, it will be linked to flash memory.
|
||||
|
||||
* - :ref:`CONFIG_ESP_REGI2C_CTRL_FUNC_IN_IRAM`
|
||||
- When this option is enabled, the software implementation related to Analog I2C read/write access will be linked to on-chip RAM. Otherwise, it will be linked to flash memory.
|
||||
|
||||
Configuration Steps:
|
||||
|
||||
|
@@ -285,6 +285,28 @@ Light-sleep 模式配置
|
||||
|
||||
由于 flash 和 PSRAM 共用供电管脚,PSRAM 关闭供电将会导致数据丢失,因此,为保证 light sleep 不破坏程序运行状态,启用该选项的前提是系统没有使用 PSRAM。
|
||||
|
||||
.. only:: esp32c2
|
||||
|
||||
- 减少 Power Managemet 模块片内 RAM 内存资源使用量 (:ref:`CONFIG_PM_SLEEP_FUNC_IN_IRAM`),当 :ref:`CONFIG_PM_SLEEP_FUNC_IN_IRAM` 禁止时,下面表格中选项分别用于控制 Power Management 模块各部分组件启用或禁止片内 RAM 优化
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 60 30
|
||||
|
||||
* - 配置项
|
||||
- 描述
|
||||
|
||||
* - :ref:`CONFIG_PM_SLP_IRAM_OPT`
|
||||
- 使能该选项后执行 light / deep sleep 软件流程上下文被链接到片内 RAM 空间,这意味着系统进出睡眠时间变短,消耗更多的片内 RAM 资源;禁止该选项,light / deep sleep 软件流程上下文将被编译到 Flash 空间,这意味着系统进出睡眠时间变长,但会节约片内 RAM 资源。
|
||||
|
||||
* - :ref:`CONFIG_PM_RTOS_IDLE_OPT`
|
||||
- auto light sleep 模式下,使能该选项后,FreeRTOS 系统滴答,IDLE 任务回调函数及 FreeRTOS Tickless idle 软件上下文被链接到片内 RAM 空间,反之将被链接到 Flash 空间。
|
||||
|
||||
* - :ref:`CONFIG_ESP_PERIPH_CTRL_FUNC_IN_IRAM`
|
||||
- 使能该选项后外设时钟及复位控制相关的软件实现将被链接到片内 RAM 空间,反之将被链接到 Flash 空间。
|
||||
|
||||
* - :ref:`CONFIG_ESP_REGI2C_CTRL_FUNC_IN_IRAM`
|
||||
- 使能该选项后 Analog I2C 读写访问相关的软件实现将被链接到片内 RAM 空间,反之被链接到 Flash 空间。
|
||||
|
||||
配置方法:
|
||||
|
||||
|
@@ -19,3 +19,9 @@ CONFIG_SPI_FLASH_PLACE_FUNCTIONS_IN_IRAM=n
|
||||
CONFIG_ESP_INTR_IN_IRAM=n
|
||||
CONFIG_LOG_IN_IRAM=n
|
||||
CONFIG_ESP_ROM_PRINT_IN_IRAM=n
|
||||
# Low power related options
|
||||
CONFIG_PM_SLEEP_FUNC_IN_IRAM=n
|
||||
CONFIG_PM_SLP_IRAM_OPT=n
|
||||
CONFIG_PM_RTOS_IDLE_OPT=n
|
||||
CONFIG_ESP_PERIPH_CTRL_FUNC_IN_IRAM=n
|
||||
CONFIG_ESP_REGI2C_CTRL_FUNC_IN_IRAM=n
|
||||
|
Reference in New Issue
Block a user