mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-30 02:37:19 +02:00
feat(esp_hw_support): support DCDC always on
This commit is contained in:
@ -270,7 +270,7 @@ void pmu_sleep_shutdown_dcdc(void);
|
||||
* @brief DCDC has taken over power supply, shut down LDO to save power consumption
|
||||
*/
|
||||
void pmu_sleep_shutdown_ldo(void);
|
||||
#endif
|
||||
#endif // SOC_DCDC_SUPPORTED
|
||||
|
||||
/**
|
||||
* @brief Enter deep or light sleep mode
|
||||
@ -302,9 +302,10 @@ uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp
|
||||
|
||||
/**
|
||||
* @brief Finish sleep process settings and get sleep reject status
|
||||
* @param dslp True if sleep requests id deep-sleep
|
||||
* @return return sleep reject status
|
||||
*/
|
||||
bool pmu_sleep_finish(void);
|
||||
bool pmu_sleep_finish(bool dslp);
|
||||
|
||||
/**
|
||||
* @brief Initialize PMU related power/clock/digital parameters and functions
|
||||
|
@ -435,7 +435,7 @@ static IRAM_ATTR esp_err_t do_cpu_retention(sleep_cpu_entry_cb_t goto_sleep,
|
||||
}
|
||||
#endif
|
||||
|
||||
return pmu_sleep_finish();
|
||||
return pmu_sleep_finish(dslp);
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR esp_sleep_cpu_retention(uint32_t (*goto_sleep)(uint32_t, uint32_t, uint32_t, bool),
|
||||
|
@ -475,7 +475,7 @@ static IRAM_ATTR esp_err_t do_cpu_retention(sleep_cpu_entry_cb_t goto_sleep,
|
||||
}
|
||||
#endif
|
||||
|
||||
return pmu_sleep_finish();
|
||||
return pmu_sleep_finish(dslp);
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR esp_sleep_cpu_retention(uint32_t (*goto_sleep)(uint32_t, uint32_t, uint32_t, bool),
|
||||
|
@ -475,7 +475,7 @@ static IRAM_ATTR esp_err_t do_cpu_retention(sleep_cpu_entry_cb_t goto_sleep,
|
||||
}
|
||||
#endif
|
||||
|
||||
return pmu_sleep_finish();
|
||||
return pmu_sleep_finish(dslp);
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR esp_sleep_cpu_retention(uint32_t (*goto_sleep)(uint32_t, uint32_t, uint32_t, bool),
|
||||
|
@ -429,7 +429,7 @@ static TCM_IRAM_ATTR esp_err_t do_cpu_retention(sleep_cpu_entry_cb_t goto_sleep,
|
||||
}
|
||||
#endif
|
||||
|
||||
return pmu_sleep_finish();
|
||||
return pmu_sleep_finish(dslp);
|
||||
}
|
||||
|
||||
esp_err_t TCM_IRAM_ATTR esp_sleep_cpu_retention(uint32_t (*goto_sleep)(uint32_t, uint32_t, uint32_t, bool),
|
||||
|
@ -274,11 +274,12 @@ uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp
|
||||
;
|
||||
}
|
||||
|
||||
return pmu_sleep_finish();
|
||||
return pmu_sleep_finish(dslp);
|
||||
}
|
||||
|
||||
bool pmu_sleep_finish(void)
|
||||
bool pmu_sleep_finish(bool dslp)
|
||||
{
|
||||
(void)dslp;
|
||||
return pmu_ll_hp_is_sleep_reject(PMU_instance()->hal->dev);
|
||||
}
|
||||
|
||||
|
@ -341,11 +341,12 @@ uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp
|
||||
;
|
||||
}
|
||||
|
||||
return pmu_sleep_finish();
|
||||
return pmu_sleep_finish(dslp);
|
||||
}
|
||||
|
||||
bool pmu_sleep_finish(void)
|
||||
bool pmu_sleep_finish(bool dslp)
|
||||
{
|
||||
(void)dslp;
|
||||
return pmu_ll_hp_is_sleep_reject(PMU_instance()->hal->dev);
|
||||
}
|
||||
|
||||
|
@ -258,11 +258,12 @@ uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp
|
||||
;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
return pmu_sleep_finish(dslp);
|
||||
}
|
||||
|
||||
bool pmu_sleep_finish(void)
|
||||
bool pmu_sleep_finish(bool dslp)
|
||||
{
|
||||
(void)dslp;
|
||||
return pmu_ll_hp_is_sleep_reject(PMU_instance()->hal->dev);
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,7 @@ menu "DCDC Regulator Configurations"
|
||||
value according to the model of external DCDC selected in your hardware solution.
|
||||
|
||||
For the DCDC chip model recommended by ESP, the recommended configuration
|
||||
valuesare listed below:
|
||||
- TI-TLV62569/TLV62569P: 14
|
||||
values are listed below:
|
||||
|
||||
- TI-TLV62569/TLV62569P: 14
|
||||
endmenu
|
||||
|
@ -79,7 +79,6 @@ void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, pmu_hp_system_pa
|
||||
pmu_ll_hp_set_bias_xpd (ctx->hal->dev, mode, anlg->bias.xpd_bias);
|
||||
pmu_ll_hp_set_dcm_mode (ctx->hal->dev, mode, anlg->bias.dcm_mode);
|
||||
pmu_ll_hp_set_dcm_vset (ctx->hal->dev, mode, anlg->bias.dcm_vset);
|
||||
pmu_ll_hp_set_bias_xpd (ctx->hal->dev, mode, anlg->bias.xpd_bias);
|
||||
pmu_ll_hp_set_dbg_atten (ctx->hal->dev, mode, anlg->bias.dbg_atten);
|
||||
pmu_ll_hp_set_current_power_off (ctx->hal->dev, mode, anlg->bias.pd_cur);
|
||||
pmu_ll_hp_set_bias_sleep_enable (ctx->hal->dev, mode, anlg->bias.bias_sleep);
|
||||
|
@ -149,26 +149,35 @@ const pmu_sleep_config_t* pmu_sleep_config_default(
|
||||
iram_pd_flags |= (pd_flags & PMU_SLEEP_PD_MEM_G1) ? BIT(1) : 0;
|
||||
iram_pd_flags |= (pd_flags & PMU_SLEEP_PD_MEM_G2) ? BIT(2) : 0;
|
||||
iram_pd_flags |= (pd_flags & PMU_SLEEP_PD_MEM_G3) ? BIT(3) : 0;
|
||||
config->power = power_default;
|
||||
|
||||
pmu_sleep_param_config_t param_default = PMU_SLEEP_PARAM_CONFIG_DEFAULT(pd_flags);
|
||||
config->param = *pmu_sleep_param_config_default(¶m_default, &power_default, pd_flags, adjustment, slowclk_period, fastclk_period);
|
||||
|
||||
if (dslp) {
|
||||
config->param.lp_sys.analog_wait_target_cycle = rtc_time_us_to_slowclk(PMU_LP_ANALOG_WAIT_TARGET_TIME_DSLP_US, slowclk_period);
|
||||
pmu_sleep_analog_config_t analog_default = PMU_SLEEP_ANALOG_DSLP_CONFIG_DEFAULT(pd_flags);
|
||||
config->analog = analog_default;
|
||||
} else {
|
||||
// Get light sleep digital_default
|
||||
pmu_sleep_digital_config_t digital_default = PMU_SLEEP_DIGITAL_LSLP_CONFIG_DEFAULT(pd_flags);
|
||||
config->digital = digital_default;
|
||||
|
||||
// Get light sleep analog default
|
||||
pmu_sleep_analog_config_t analog_default = PMU_SLEEP_ANALOG_LSLP_CONFIG_DEFAULT(pd_flags);
|
||||
#if CONFIG_SPIRAM
|
||||
analog_default.hp_sys.analog.pd_cur = 1;
|
||||
analog_default.lp_sys[PMU_MODE_LP_SLEEP].analog.pd_cur = 1;
|
||||
#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
|
||||
config->analog = analog_default;
|
||||
}
|
||||
|
||||
config->power = power_default;
|
||||
pmu_sleep_param_config_t param_default = PMU_SLEEP_PARAM_CONFIG_DEFAULT(pd_flags);
|
||||
config->param = *pmu_sleep_param_config_default(¶m_default, &power_default, pd_flags, adjustment, slowclk_period, fastclk_period);
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
@ -194,6 +203,8 @@ 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);
|
||||
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);
|
||||
pmu_ll_hp_set_bias_sleep_enable (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.bias_sleep);
|
||||
pmu_ll_hp_set_regulator_sleep_memory_xpd (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.slp_mem_xpd);
|
||||
@ -250,10 +261,10 @@ void pmu_sleep_init(const pmu_sleep_config_t *config, bool dslp)
|
||||
}
|
||||
|
||||
void pmu_sleep_increase_ldo_volt(void) {
|
||||
REG_SET_FIELD(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS, 30);
|
||||
REG_SET_BIT(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_XPD);
|
||||
pmu_ll_hp_set_regulator_dbias(&PMU, PMU_MODE_HP_ACTIVE, 30);
|
||||
pmu_ll_hp_set_regulator_xpd(&PMU, PMU_MODE_HP_ACTIVE, 1);
|
||||
// Decrease the DCDC voltage to reduce the voltage difference between the DCDC and the LDO to avoid overshooting the DCDC voltage during wake-up.
|
||||
REG_SET_FIELD(PMU_HP_ACTIVE_BIAS_REG, PMU_HP_ACTIVE_DCM_VSET, 24);
|
||||
pmu_ll_hp_set_dcm_vset(&PMU, PMU_MODE_HP_ACTIVE, 24);
|
||||
}
|
||||
|
||||
void pmu_sleep_shutdown_dcdc(void) {
|
||||
@ -301,19 +312,26 @@ TCM_IRAM_ATTR uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt,
|
||||
;
|
||||
}
|
||||
|
||||
return pmu_sleep_finish();
|
||||
return pmu_sleep_finish(dslp);
|
||||
}
|
||||
|
||||
TCM_IRAM_ATTR bool pmu_sleep_finish(void)
|
||||
TCM_IRAM_ATTR bool pmu_sleep_finish(bool dslp)
|
||||
{
|
||||
REG_SET_FIELD(PMU_HP_ACTIVE_BIAS_REG, PMU_HP_ACTIVE_DCM_VSET, 27);
|
||||
if (pmu_ll_hp_is_sleep_reject(PMU_instance()->hal->dev)) {
|
||||
// If sleep is rejected, the hardware wake-up process that turns on DCDC
|
||||
// is skipped, and software is used to enable DCDC here.
|
||||
pmu_sleep_enable_dcdc();
|
||||
esp_rom_delay_us(950);
|
||||
#if CONFIG_ESP_SLEEP_KEEP_DCDC_ALWAYS_ON
|
||||
if (!dslp) {
|
||||
// Keep DCDC always on during light sleep, no need to adjust LDO.
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
pmu_ll_hp_set_dcm_vset(&PMU, PMU_MODE_HP_ACTIVE, 27);
|
||||
if (pmu_ll_hp_is_sleep_reject(PMU_instance()->hal->dev)) {
|
||||
// If sleep is rejected, the hardware wake-up process that turns on DCDC
|
||||
// is skipped, and software is used to enable DCDC here.
|
||||
pmu_sleep_enable_dcdc();
|
||||
esp_rom_delay_us(950);
|
||||
}
|
||||
pmu_sleep_shutdown_ldo();
|
||||
}
|
||||
pmu_sleep_shutdown_ldo();
|
||||
|
||||
unsigned chip_version = efuse_hal_chip_revision();
|
||||
if (!ESP_CHIP_REV_ABOVE(chip_version, 1)) {
|
||||
|
@ -105,7 +105,7 @@ const pmu_lp_system_analog_param_t* pmu_lp_system_analog_param_default(pmu_lp_mo
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t reserved0 : 21;
|
||||
uint32_t dcdc_switch_pd_en: 1;
|
||||
uint32_t dcdc_switch_pd_en: 1;
|
||||
uint32_t mem_dslp : 1;
|
||||
uint32_t mem_pd_en : 1;
|
||||
uint32_t reserved1 : 6;
|
||||
@ -153,7 +153,9 @@ typedef union {
|
||||
|
||||
typedef struct {
|
||||
struct {
|
||||
uint32_t reserved0 : 25;
|
||||
uint32_t reserved0 : 18;
|
||||
uint32_t dcm_vset : 5;
|
||||
uint32_t dcm_mode : 2;
|
||||
uint32_t xpd_bias : 1;
|
||||
uint32_t dbg_atten : 4;
|
||||
uint32_t pd_cur : 1;
|
||||
|
@ -896,8 +896,15 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
|
||||
#if SOC_PMU_SUPPORTED
|
||||
|
||||
#if SOC_DCDC_SUPPORTED
|
||||
s_config.rtc_ticks_at_ldo_prepare = rtc_time_get();
|
||||
pmu_sleep_increase_ldo_volt();
|
||||
#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
|
||||
{
|
||||
s_config.rtc_ticks_at_ldo_prepare = rtc_time_get();
|
||||
pmu_sleep_increase_ldo_volt();
|
||||
}
|
||||
#endif
|
||||
|
||||
pmu_sleep_config_t config;
|
||||
@ -982,11 +989,18 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
|
||||
#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);
|
||||
#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
|
||||
{
|
||||
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();
|
||||
}
|
||||
pmu_sleep_shutdown_dcdc();
|
||||
#endif
|
||||
|
||||
#if SOC_PMU_SUPPORTED
|
||||
|
Reference in New Issue
Block a user