mirror of
https://github.com/espressif/esp-idf.git
synced 2025-10-03 02:20:57 +02:00
Merge branch 'fix/controll_dcdc_switch_by_pmu_in_dslp' into 'master'
fix(esp_hw_support): control DCDC switch by PMU FSM while control DCDC_EN by software See merge request espressif/esp-idf!41310
This commit is contained in:
@@ -1,23 +1,10 @@
|
||||
menu "DCDC Regulator Configurations"
|
||||
depends on SOC_GP_LDO_SUPPORTED
|
||||
|
||||
config ESP_SLEEP_KEEP_DCDC_ALWAYS_ON
|
||||
bool "Keep DC-DC power always on during light-sleep"
|
||||
default y
|
||||
help
|
||||
ESP32P4 will switch the power supply to LDO before sleeping, and switch to DCDC after waking up.
|
||||
These two processes take a long time and may bring some risks for some short duration
|
||||
light sleep. (DCDC -> LDO: 2.5ms (max), LDO -> DCDC: 1.2 ms)
|
||||
Enabling this option will make chip powered by DCDC during light sleep to reduce some power switch
|
||||
risks, this will also increase the power consumption during the light sleep.
|
||||
|
||||
DO NOT DISABLE UNLESS YOU KNOW WHAT YOU ARE DOING.
|
||||
depends on SOC_DCDC_SUPPORTED
|
||||
|
||||
config ESP_SLEEP_DCM_VSET_VAL_IN_SLEEP
|
||||
int "DCDC voltage parameter during sleep"
|
||||
default 14
|
||||
range 0 31
|
||||
depends on ESP_SLEEP_KEEP_DCDC_ALWAYS_ON
|
||||
help
|
||||
This value determines the voltage of the DCDC chip during sleep. The same parameter value may
|
||||
correspond to different voltage values on different models of DCDC chips. Please update this
|
||||
|
@@ -169,7 +169,7 @@ const pmu_hp_system_digital_param_t * pmu_hp_system_digital_param_default(pmu_hp
|
||||
#define PMU_HP_SLEEP_ANALOG_CONFIG_DEFAULT() { \
|
||||
.bias = { \
|
||||
.dcm_vset = 0, \
|
||||
.dcm_mode = 0, \
|
||||
.dcm_mode = 1, \
|
||||
.xpd_bias = 0, \
|
||||
.dbg_atten = 0x0, \
|
||||
.pd_cur = 1, \
|
||||
|
@@ -43,6 +43,7 @@
|
||||
#define HP(state) (PMU_MODE_HP_ ## state)
|
||||
#define LP(state) (PMU_MODE_LP_ ## state)
|
||||
|
||||
#define DCDC_STARTUP_TIME_US (950)
|
||||
|
||||
static bool s_pmu_sleep_regdma_backup_enabled;
|
||||
|
||||
@@ -200,16 +201,9 @@ const pmu_sleep_config_t* pmu_sleep_config_default(
|
||||
analog_default.lp_sys[LP(SLEEP)].analog.pd_cur = PMU_PD_CUR_SLEEP_ON;
|
||||
analog_default.lp_sys[LP(SLEEP)].analog.bias_sleep = PMU_BIASSLP_SLEEP_ON;
|
||||
analog_default.lp_sys[LP(SLEEP)].analog.dbg_atten = PMU_DBG_ATTEN_ACTIVE_DEFAULT;
|
||||
#if !CONFIG_ESP_SLEEP_KEEP_DCDC_ALWAYS_ON
|
||||
analog_default.lp_sys[LP(SLEEP)].analog.dbias = LP_CALI_ACTIVE_DBIAS_DEFAULT;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if CONFIG_ESP_SLEEP_KEEP_DCDC_ALWAYS_ON
|
||||
power_default.hp_sys.dig_power.dcdc_switch_pd_en = 0;
|
||||
analog_default.hp_sys.analog.dcm_vset = CONFIG_ESP_SLEEP_DCM_VSET_VAL_IN_SLEEP;
|
||||
analog_default.hp_sys.analog.dcm_mode = 1;
|
||||
#endif
|
||||
if (sleep_flags & PMU_SLEEP_PD_VDDSDIO) {
|
||||
analog_default.hp_sys.analog.xpd_0p1a = 0;
|
||||
} else {
|
||||
@@ -281,6 +275,10 @@ static void pmu_sleep_digital_init(pmu_context_t *ctx, const pmu_sleep_digital_c
|
||||
static void pmu_sleep_analog_init(pmu_context_t *ctx, const pmu_sleep_analog_config_t *analog, bool dslp)
|
||||
{
|
||||
assert(ctx->hal);
|
||||
/* For deepsleep, DCDC_EN will be controlled by software to avoid DCDC working in a non-feedback state,
|
||||
which may cause input glitch voltage when waking up and switching to LDO. After chip wake up from deepsleep,
|
||||
set DCDC_EN in rtc_clk_init. */
|
||||
pmu_ll_hp_set_dcm_mode (ctx->hal->dev, HP(ACTIVE), dslp ? 0 : 1);
|
||||
pmu_ll_hp_set_dcm_mode (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.dcm_mode);
|
||||
pmu_ll_hp_set_dcm_vset (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.dcm_vset);
|
||||
pmu_ll_hp_set_current_power_off (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.pd_cur);
|
||||
@@ -346,7 +344,7 @@ void pmu_sleep_increase_ldo_volt(void) {
|
||||
}
|
||||
|
||||
void pmu_sleep_shutdown_dcdc(void) {
|
||||
pmu_ll_set_dcdc_switch_force_power_down(&PMU, true);
|
||||
// Keep dcdc_switch on, will be disabled by PMU when entered sleep.
|
||||
pmu_ll_set_dcdc_en(&PMU, false);
|
||||
// Decrease hp_ldo voltage.
|
||||
pmu_ll_hp_set_regulator_dbias(&PMU, PMU_MODE_HP_ACTIVE, HP_CALI_ACTIVE_DBIAS_DEFAULT);
|
||||
@@ -448,18 +446,13 @@ TCM_IRAM_ATTR uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt,
|
||||
|
||||
TCM_IRAM_ATTR bool pmu_sleep_finish(bool dslp)
|
||||
{
|
||||
#if CONFIG_ESP_SLEEP_KEEP_DCDC_ALWAYS_ON
|
||||
if (!dslp) {
|
||||
// Keep DCDC always on during light sleep, no need to adjust LDO.
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if (dslp) {
|
||||
pmu_ll_hp_set_dcm_vset(&PMU, PMU_MODE_HP_ACTIVE, HP_CALI_ACTIVE_DCM_VSET_DEFAULT);
|
||||
pmu_sleep_enable_dcdc();
|
||||
if (pmu_ll_hp_is_sleep_reject(&PMU)) {
|
||||
// If sleep is rejected, the hardware wake-up process that turns on DCDC
|
||||
// is skipped, and wait DCDC volt rise up by software here.
|
||||
esp_rom_delay_us(950);
|
||||
// If sleep is rejected or regdma restore is skipped, the hardware wake-up process that
|
||||
// turns on DCDC is skipped, and wait DCDC volt rise up by software here.
|
||||
esp_rom_delay_us(DCDC_STARTUP_TIME_US);
|
||||
}
|
||||
pmu_sleep_shutdown_ldo();
|
||||
}
|
||||
|
@@ -351,6 +351,7 @@ typedef struct {
|
||||
#define PMU_SLEEP_ANALOG_LSLP_CONFIG_DEFAULT(sleep_flags) { \
|
||||
.hp_sys = { \
|
||||
.analog = { \
|
||||
.dcm_mode = 1, \
|
||||
.drv_b = PMU_HP_DRVB_LIGHTSLEEP, \
|
||||
.pd_cur = PMU_PD_CUR_SLEEP_DEFAULT, \
|
||||
.bias_sleep = PMU_BIASSLP_SLEEP_DEFAULT, \
|
||||
@@ -385,6 +386,7 @@ typedef struct {
|
||||
#define PMU_SLEEP_ANALOG_DSLP_CONFIG_DEFAULT(sleep_flags) { \
|
||||
.hp_sys = { \
|
||||
.analog = { \
|
||||
.dcm_mode = 0, \
|
||||
.pd_cur = PMU_PD_CUR_SLEEP_DEFAULT, \
|
||||
.bias_sleep = PMU_BIASSLP_SLEEP_DEFAULT, \
|
||||
.xpd = PMU_HP_XPD_DEEPSLEEP, \
|
||||
@@ -503,7 +505,7 @@ typedef struct pmu_sleep_machine_constant {
|
||||
.system_dfs_up_work_time_us = 124, \
|
||||
.analog_wait_time_us = PMU_HP_ANA_WAIT_TIME_PD_TOP_US, \
|
||||
.power_supply_wait_time_us = 2, \
|
||||
.power_up_wait_time_us = 2, \
|
||||
.power_up_wait_time_us = 26, \
|
||||
.regdma_s2m_work_time_us = 172, \
|
||||
.regdma_s2a_work_time_us = PMU_REGDMA_S2A_WORK_TIME_US, \
|
||||
.regdma_m2a_work_time_us = 278, \
|
||||
|
@@ -931,14 +931,6 @@ static esp_err_t FORCE_IRAM_ATTR esp_sleep_start_safe(uint32_t sleep_flags, uint
|
||||
}
|
||||
#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);
|
||||
@@ -1114,14 +1106,8 @@ static esp_err_t SLEEP_FN_ATTR esp_sleep_start(uint32_t sleep_flags, uint32_t cl
|
||||
// Enter sleep
|
||||
esp_err_t result;
|
||||
#if SOC_PMU_SUPPORTED
|
||||
|
||||
#if SOC_DCDC_SUPPORTED
|
||||
#if CONFIG_ESP_SLEEP_KEEP_DCDC_ALWAYS_ON
|
||||
if (!deep_sleep) {
|
||||
// Keep DCDC always on during light sleep, no need to adjust LDO voltage.
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if (deep_sleep) {
|
||||
s_config.rtc_ticks_at_ldo_prepare = rtc_time_get();
|
||||
pmu_sleep_increase_ldo_volt();
|
||||
}
|
||||
|
Reference in New Issue
Block a user