mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-31 19:24:33 +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
|
* @brief DCDC has taken over power supply, shut down LDO to save power consumption
|
||||||
*/
|
*/
|
||||||
void pmu_sleep_shutdown_ldo(void);
|
void pmu_sleep_shutdown_ldo(void);
|
||||||
#endif
|
#endif // SOC_DCDC_SUPPORTED
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enter deep or light sleep mode
|
* @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
|
* @brief Finish sleep process settings and get sleep reject status
|
||||||
|
* @param dslp True if sleep requests id deep-sleep
|
||||||
* @return return sleep reject status
|
* @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
|
* @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
|
#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),
|
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
|
#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),
|
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
|
#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),
|
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
|
#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),
|
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);
|
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);
|
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);
|
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.
|
value according to the model of external DCDC selected in your hardware solution.
|
||||||
|
|
||||||
For the DCDC chip model recommended by ESP, the recommended configuration
|
For the DCDC chip model recommended by ESP, the recommended configuration
|
||||||
valuesare listed below:
|
values are listed below:
|
||||||
- TI-TLV62569/TLV62569P: 14
|
|
||||||
|
- TI-TLV62569/TLV62569P: 14
|
||||||
endmenu
|
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_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_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_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_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_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);
|
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_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_G2) ? BIT(2) : 0;
|
||||||
iram_pd_flags |= (pd_flags & PMU_SLEEP_PD_MEM_G3) ? BIT(3) : 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) {
|
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);
|
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);
|
pmu_sleep_analog_config_t analog_default = PMU_SLEEP_ANALOG_DSLP_CONFIG_DEFAULT(pd_flags);
|
||||||
config->analog = analog_default;
|
config->analog = analog_default;
|
||||||
} else {
|
} else {
|
||||||
|
// Get light sleep digital_default
|
||||||
pmu_sleep_digital_config_t digital_default = PMU_SLEEP_DIGITAL_LSLP_CONFIG_DEFAULT(pd_flags);
|
pmu_sleep_digital_config_t digital_default = PMU_SLEEP_DIGITAL_LSLP_CONFIG_DEFAULT(pd_flags);
|
||||||
config->digital = digital_default;
|
config->digital = digital_default;
|
||||||
|
|
||||||
|
// Get light sleep analog default
|
||||||
pmu_sleep_analog_config_t analog_default = PMU_SLEEP_ANALOG_LSLP_CONFIG_DEFAULT(pd_flags);
|
pmu_sleep_analog_config_t analog_default = PMU_SLEEP_ANALOG_LSLP_CONFIG_DEFAULT(pd_flags);
|
||||||
#if CONFIG_SPIRAM
|
#if CONFIG_SPIRAM
|
||||||
analog_default.hp_sys.analog.pd_cur = 1;
|
analog_default.hp_sys.analog.pd_cur = 1;
|
||||||
analog_default.lp_sys[PMU_MODE_LP_SLEEP].analog.pd_cur = 1;
|
analog_default.lp_sys[PMU_MODE_LP_SLEEP].analog.pd_cur = 1;
|
||||||
#endif
|
#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->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;
|
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)
|
static void pmu_sleep_analog_init(pmu_context_t *ctx, const pmu_sleep_analog_config_t *analog, bool dslp)
|
||||||
{
|
{
|
||||||
assert(ctx->hal);
|
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_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_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);
|
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) {
|
void pmu_sleep_increase_ldo_volt(void) {
|
||||||
REG_SET_FIELD(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS, 30);
|
pmu_ll_hp_set_regulator_dbias(&PMU, PMU_MODE_HP_ACTIVE, 30);
|
||||||
REG_SET_BIT(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_XPD);
|
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.
|
// 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) {
|
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 CONFIG_ESP_SLEEP_KEEP_DCDC_ALWAYS_ON
|
||||||
if (pmu_ll_hp_is_sleep_reject(PMU_instance()->hal->dev)) {
|
if (!dslp) {
|
||||||
// If sleep is rejected, the hardware wake-up process that turns on DCDC
|
// Keep DCDC always on during light sleep, no need to adjust LDO.
|
||||||
// is skipped, and software is used to enable DCDC here.
|
} else
|
||||||
pmu_sleep_enable_dcdc();
|
#endif
|
||||||
esp_rom_delay_us(950);
|
{
|
||||||
|
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();
|
unsigned chip_version = efuse_hal_chip_revision();
|
||||||
if (!ESP_CHIP_REV_ABOVE(chip_version, 1)) {
|
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 {
|
typedef union {
|
||||||
struct {
|
struct {
|
||||||
uint32_t reserved0 : 21;
|
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_dslp : 1;
|
||||||
uint32_t mem_pd_en : 1;
|
uint32_t mem_pd_en : 1;
|
||||||
uint32_t reserved1 : 6;
|
uint32_t reserved1 : 6;
|
||||||
@@ -153,7 +153,9 @@ typedef union {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
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 xpd_bias : 1;
|
||||||
uint32_t dbg_atten : 4;
|
uint32_t dbg_atten : 4;
|
||||||
uint32_t pd_cur : 1;
|
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_PMU_SUPPORTED
|
||||||
|
|
||||||
#if SOC_DCDC_SUPPORTED
|
#if SOC_DCDC_SUPPORTED
|
||||||
s_config.rtc_ticks_at_ldo_prepare = rtc_time_get();
|
#if CONFIG_ESP_SLEEP_KEEP_DCDC_ALWAYS_ON
|
||||||
pmu_sleep_increase_ldo_volt();
|
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
|
#endif
|
||||||
|
|
||||||
pmu_sleep_config_t config;
|
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
|
#endif
|
||||||
|
|
||||||
#if SOC_DCDC_SUPPORTED
|
#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 CONFIG_ESP_SLEEP_KEEP_DCDC_ALWAYS_ON
|
||||||
if (ldo_increased_us < LDO_POWER_TAKEOVER_PREPARATION_TIME_US) {
|
if (!deep_sleep) {
|
||||||
esp_rom_delay_us(LDO_POWER_TAKEOVER_PREPARATION_TIME_US - ldo_increased_us);
|
// 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
|
#endif
|
||||||
|
|
||||||
#if SOC_PMU_SUPPORTED
|
#if SOC_PMU_SUPPORTED
|
||||||
|
Reference in New Issue
Block a user