change(esp_hw_support): support esp32h21eco1 sleep flow

This commit is contained in:
hebinglin
2026-03-11 15:38:23 +08:00
parent 8ce11e1608
commit c09aaa64bf
13 changed files with 143 additions and 95 deletions
@@ -134,6 +134,11 @@ FORCE_INLINE_ATTR void pmu_ll_hp_set_xtal_xpd(pmu_dev_t *hw, pmu_hp_mode_t mode,
hw->hp_sys[mode].xtal.xpd_xtal = xpd_xtal;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_xtalx2_xpd(pmu_dev_t *hw, pmu_hp_mode_t mode, bool xpd_xtalx2)
{
hw->hp_sys[mode].xtal.xpd_xtalx2 = xpd_xtalx2;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_discnnt_dig_rtc(pmu_dev_t *hw, pmu_hp_mode_t mode, bool discnnt)
{
hw->hp_sys[mode].bias.discnnt_dig_rtc = discnnt;
@@ -299,6 +304,12 @@ FORCE_INLINE_ATTR void pmu_ll_lp_set_xtal_xpd(pmu_dev_t *hw, pmu_lp_mode_t mode,
hw->lp_sys[mode].xtal.xpd_xtal = slp_xpd;
}
FORCE_INLINE_ATTR void pmu_ll_lp_set_xtalx2_xpd(pmu_dev_t *hw, pmu_lp_mode_t mode, bool xpd_xtalx2)
{
HAL_ASSERT(mode == PMU_MODE_LP_SLEEP);
hw->lp_sys[mode].xtal.xpd_xtalx2 = xpd_xtalx2;
}
FORCE_INLINE_ATTR void pmu_ll_lp_set_dig_power(pmu_dev_t *hw, pmu_lp_mode_t mode, uint32_t flag)
{
hw->lp_sys[mode].dig_power.val = flag;
@@ -320,6 +331,12 @@ FORCE_INLINE_ATTR void pmu_ll_lp_set_dcdc_ccm_enable(pmu_dev_t *hw, pmu_lp_mode_
hw->lp_sys[mode].bias.dcdc_ccm_enb = enable;
}
FORCE_INLINE_ATTR void pmu_ll_lp_set_dcdc_clear_ready(pmu_dev_t *hw, pmu_lp_mode_t mode, bool clear_rdy)
{
HAL_ASSERT(mode == PMU_MODE_LP_SLEEP);
hw->lp_sys[mode].bias.dcdc_clear_rdy = clear_rdy;
}
FORCE_INLINE_ATTR void pmu_ll_lp_set_dig_reg_dpcur_bias(pmu_dev_t *hw, pmu_lp_mode_t mode, uint32_t value)
{
HAL_ASSERT(mode == PMU_MODE_LP_SLEEP);
@@ -764,7 +781,8 @@ FORCE_INLINE_ATTR uint32_t pmu_ll_get_dcdc_boost_dreg(pmu_dev_t *hw)
FORCE_INLINE_ATTR void pmu_ll_set_ble_bandgap_ext_ocode(pmu_dev_t *hw, uint32_t ocode)
{
hw->ble_bandgap_ctrl.ext_ocode = ocode;
/* Field is 8 bits (see PMU_EXT_OCODE); mask matches REG_SET_FIELD(..., PMU_EXT_OCODE, x). */
hw->ble_bandgap_ctrl.ext_ocode = ocode & 0xFFU;
}
FORCE_INLINE_ATTR uint32_t pmu_ll_get_ble_bandgap_ext_ocode(pmu_dev_t *hw)
@@ -259,7 +259,7 @@ FORCE_INLINE_ATTR void pmu_ll_hp_set_regulator_power_detect_bypass(pmu_dev_t *hw
hw->hp_sys[mode].regulator0.power_det_bypass = bypass;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_regulator_dbias_sel(pmu_dev_t *hw, pmu_hp_mode_t mode, bool dbias_sel)
FORCE_INLINE_ATTR void pmu_ll_hp_set_regulator_dbias_select(pmu_dev_t *hw, pmu_hp_mode_t mode, bool dbias_sel)
{
HAL_ASSERT(mode == PMU_MODE_HP_ACTIVE);
hw->hp_sys[mode].regulator0.dbias_sel = dbias_sel;
@@ -843,6 +843,27 @@ FORCE_INLINE_ATTR void pmu_ll_set_dcdc_ccm_sw_en(pmu_dev_t *hw, bool en)
hw->dcm_ctrl.dcdc_ccm_sw_en = en;
}
FORCE_INLINE_ATTR void pmu_ll_set_ble_bandgap_ext_ocode(pmu_dev_t *hw, uint32_t ocode)
{
/* Field is 8 bits (see PMU_EXT_OCODE); mask matches REG_SET_FIELD(..., PMU_EXT_OCODE, x). */
hw->ble_bandgap_ctrl.ext_ocode = ocode & 0xFFU;
}
FORCE_INLINE_ATTR uint32_t pmu_ll_get_ble_bandgap_ext_ocode(pmu_dev_t *hw)
{
return hw->ble_bandgap_ctrl.ext_ocode;
}
FORCE_INLINE_ATTR void pmu_ll_set_ble_bandgap_ext_force_ocode(pmu_dev_t *hw, bool force)
{
hw->ble_bandgap_ctrl.ext_force_ocode = force;
}
FORCE_INLINE_ATTR bool pmu_ll_get_ble_bandgap_ext_force_ocode(pmu_dev_t *hw)
{
return hw->ble_bandgap_ctrl.ext_force_ocode;
}
#ifdef __cplusplus
}
#endif
@@ -61,6 +61,7 @@ typedef enum {
PMU_HP_PD_CPU = 2, /*!< Power domain of HP CPU */
PMU_HP_PD_RESERVED = 3, /*!< Reserved power domain */
PMU_HP_PD_WIFI = 4, /*!< Power domain of WIFI */
PMU_HP_PD_BT_154 = PMU_HP_PD_WIFI, /*!< Power domain of BT 154 */
} pmu_hp_power_domain_t;
#endif
@@ -84,6 +84,38 @@ static inline void regi2c_ctrl_ll_i2c_sar_periph_disable(void)
CLEAR_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_PERIF_I2C);
}
/**
* @brief Enable the RF TX I2C internal bus power domain
*/
static inline void regi2c_ctrl_ll_i2c_rftx_periph_enable(void)
{
SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_RFTX_I2C);
}
/**
* @brief Disable the RF TX I2C internal bus power domain
*/
static inline void regi2c_ctrl_ll_i2c_rftx_periph_disable(void)
{
CLEAR_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_RFTX_I2C);
}
/**
* @brief Enable the RF RX I2C internal bus power domain
*/
static inline void regi2c_ctrl_ll_i2c_rfrx_periph_enable(void)
{
SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_RFRX_I2C);
}
/**
* @brief Disable the RF RX I2C internal bus power domain
*/
static inline void regi2c_ctrl_ll_i2c_rfrx_periph_disable(void)
{
CLEAR_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_RFRX_I2C);
}
#ifdef __cplusplus
}
#endif
+1 -1
View File
@@ -47,7 +47,7 @@ entries:
pmu_param (noflash)
elif PM_SLP_IRAM_OPT = y && IDF_TARGET_ESP32P4 != y:
pmu_param:get_act_lp_dbias (noflash)
if IDF_TARGET_ESP32H4 = y:
if IDF_TARGET_ESP32H4 || IDF_TARGET_ESP32H21 = y:
pmu_param:get_act_hp_drvb (noflash)
else:
pmu_param:get_act_hp_dbias (noflash)
@@ -50,9 +50,6 @@ esp_err_t sleep_clock_modem_retention_init(void *arg)
const static sleep_retention_entries_config_t modem_regs_retention[] = {
[0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEMSYSCON_LINK(0), MODEM_SYSCON_TEST_CONF_REG, MODEM_SYSCON_TEST_CONF_REG, N_REGS_SYSCON(), 0, 0), .owner = ENTRY(0) | ENTRY(1) }, /* MODEM SYSCON */
#if SOC_PM_RETENTION_SW_TRIGGER_REGDMA
[1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEMLPCON_LINK(0), MODEM_LPCON_TEST_CONF_REG, MODEM_LPCON_TEST_CONF_REG, N_REGS_LPCON(), 0, 0), .owner = ENTRY(0) | ENTRY(1) } /* MODEM LPCON */
#endif
};
esp_err_t err = sleep_retention_entries_create(modem_regs_retention, ARRAY_SIZE(modem_regs_retention), REGDMA_LINK_PRI_MODEM_CLK, SLEEP_RETENTION_MODULE_CLOCK_MODEM);
@@ -14,11 +14,12 @@
#include "pmu_param.h"
#include "esp_private/esp_pmu.h"
#include "regi2c_ctrl.h"
#include "soc/rtc.h"
// #include "esp_private/ocode_init.h"
#include "esp_hw_log.h"
#include "soc/regi2c_lp_bias.h"
#include "soc/lp_aon_reg.h"
#include "hal/lp_aon_ll.h"
static __attribute__((unused)) const char *TAG = "pmu_init";
ESP_HW_LOG_ATTR_TAG(TAG, "pmu_init");
typedef struct {
const pmu_hp_system_power_param_t *power;
@@ -56,6 +57,7 @@ void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, const pmu_hp_sys
pmu_ll_hp_set_dig_power(ctx->hal->dev, mode, power->dig_power.val);
pmu_ll_hp_set_clk_power(ctx->hal->dev, mode, power->clk_power.val);
pmu_ll_hp_set_xtal_xpd (ctx->hal->dev, mode, power->xtal.xpd_xtal);
pmu_ll_hp_set_xtalx2_xpd (ctx->hal->dev, mode, power->xtal.xpd_xtalx2);
/* Default configuration of hp-system clock in active, modem and sleep modes */
pmu_ll_hp_set_icg_func (ctx->hal->dev, mode, clock->icg_func);
@@ -115,7 +117,23 @@ void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, const pmu_hp_sys
pmu_ll_hp_set_sleep_protect_mode(ctx->hal->dev, PMU_SLEEP_PROTECT_HP_LP_SLEEP);
/* set dcdc ccm mode software enable */
pmu_ll_set_dcdc_ccm_sw_en(&PMU, true);
pmu_ll_set_dcdc_ccm_sw_en(ctx->hal->dev, true);
//For dcdc ldo mode when VDD is low than about a certion value, eg 2.6v
lp_aon_ll_set_ldo_sw(15);
/* set ble bandgap ocode */
uint32_t ulp_ocode = 0;
#if !CONFIG_IDF_ENV_FPGA
bool ulp_force_flag = REGI2C_READ_MASK(I2C_ULP, I2C_ULP_IR_FORCE_CODE);
if (ulp_force_flag) {
ulp_ocode = REGI2C_READ_MASK(I2C_ULP, I2C_ULP_EXT_CODE);
} else {
ulp_ocode = REGI2C_READ_MASK(I2C_ULP, I2C_ULP_OCODE);
}
#endif
pmu_ll_set_ble_bandgap_ext_ocode(ctx->hal->dev, ulp_ocode);
pmu_ll_set_ble_bandgap_ext_force_ocode(ctx->hal->dev, true);
}
void pmu_lp_system_init(pmu_context_t *ctx, pmu_lp_mode_t mode, const pmu_lp_system_param_t *param)
@@ -128,11 +146,13 @@ void pmu_lp_system_init(pmu_context_t *ctx, pmu_lp_mode_t mode, const pmu_lp_sys
pmu_ll_lp_set_dig_power(ctx->hal->dev, mode, power->dig_power.val);
pmu_ll_lp_set_clk_power(ctx->hal->dev, mode, power->clk_power.val);
pmu_ll_lp_set_xtal_xpd (ctx->hal->dev, PMU_MODE_LP_SLEEP, power->xtal.xpd_xtal);
pmu_ll_lp_set_xtalx2_xpd (ctx->hal->dev, PMU_MODE_LP_SLEEP, power->xtal.xpd_xtalx2);
/* Default configuration of lp-system analog sub-system in active and
* sleep modes */
if (mode == PMU_MODE_LP_SLEEP) {
pmu_ll_lp_set_dcdc_ccm_enable (ctx->hal->dev, mode, anlg->bias.dcdc_ccm_enb);
pmu_ll_lp_set_dcdc_clear_ready (ctx->hal->dev, mode, anlg->bias.dcdc_clear_rdy);
pmu_ll_lp_set_dig_reg_dpcur_bias(ctx->hal->dev, mode, anlg->bias.dig_reg_dpcur_bias);
pmu_ll_lp_set_dig_reg_dsfmos (ctx->hal->dev, mode, anlg->bias.dig_reg_dsfmos);
pmu_ll_lp_set_dcm_vset (ctx->hal->dev, mode, anlg->bias.dcm_vset);
@@ -156,7 +176,7 @@ static inline void pmu_power_domain_force_default(pmu_context_t *ctx)
const pmu_hp_power_domain_t pmu_hp_domains[] = {
PMU_HP_PD_TOP,
PMU_HP_PD_CPU,
PMU_HP_PD_WIFI
PMU_HP_PD_BT_154
};
for (uint8_t idx = 0; idx < (sizeof(pmu_hp_domains) / sizeof(pmu_hp_power_domain_t)); idx++) {
@@ -191,7 +211,7 @@ static inline void pmu_hp_system_param_default(pmu_hp_mode_t mode, pmu_hp_system
*param->analog = *pmu_hp_system_analog_param_default(mode); //copy default value
param->retent = pmu_hp_system_retention_param_default(mode);
if (mode == PMU_MODE_HP_ACTIVE || mode == PMU_MODE_HP_MODEM) {
if (mode == PMU_MODE_HP_ACTIVE) {
param->analog->regulator1.drv_b = get_act_hp_drvb();
}
}
@@ -229,31 +249,12 @@ static void pmu_lp_system_init_default(pmu_context_t *ctx)
}
}
uint32_t get_ulp_ocode()
{
uint32_t ulp_ocode = 0;
bool ulp_force_flag = REGI2C_READ_MASK(I2C_ULP, I2C_ULP_IR_FORCE_CODE);
if (ulp_force_flag)
ulp_ocode = REGI2C_READ_MASK(I2C_ULP, I2C_ULP_EXT_CODE);
else
ulp_ocode = REGI2C_READ_MASK(I2C_ULP, I2C_ULP_OCODE);
return ulp_ocode;
}
void pmu_init(void)
{
WRITE_PERI_REG(PMU_POWER_PD_TOP_CNTL_REG, 0);
WRITE_PERI_REG(PMU_POWER_PD_HPAON_CNTL_REG, 0);
WRITE_PERI_REG(PMU_POWER_PD_HPCPU_CNTL_REG, 0);
WRITE_PERI_REG(PMU_POWER_PD_HPPERI_RESERVE_REG, 0);
WRITE_PERI_REG(PMU_POWER_PD_HPWIFI_CNTL_REG, 0);
WRITE_PERI_REG(PMU_POWER_PD_LPPERI_CNTL_REG, 0);
WRITE_PERI_REG(PMU_POWER_PD_MEM_CNTL_REG, 0);
/* Peripheral reg i2c power up */
SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_PERIF_I2C);
SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_RFTX_I2C);
SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_RFRX_I2C);
regi2c_ctrl_ll_i2c_sar_periph_enable();
regi2c_ctrl_ll_i2c_rftx_periph_enable();
regi2c_ctrl_ll_i2c_rfrx_periph_enable();
pmu_hp_system_init_default(PMU_instance());
pmu_lp_system_init_default(PMU_instance());
@@ -266,38 +267,4 @@ void pmu_init(void)
// esp_ocode_calib_init();
// }
// #endif
uint32_t ulp_ocode = get_ulp_ocode();
REG_SET_FIELD(PMU_BLE_BANDGAP_CTRL_REG, PMU_EXT_OCODE, ulp_ocode);
SET_PERI_REG_MASK(PMU_BLE_BANDGAP_CTRL_REG, PMU_EXT_FORCE_OCODE);
//For dcdc ldo mode when VDD is low than about a certion value, eg 2.6v
CLEAR_PERI_REG_MASK(LP_AON_DATE_REG, LP_AON_DREG_LDO_HW);
REG_SET_FIELD(LP_AON_DATE_REG, LP_AON_DREG_LDO_SW, 15);
// For sleep
bool hp_ana_wait_sel_sosc = 1;
uint32_t lp_wait_us = 154;
uint32_t hp_wait_us = 150;
uint32_t xtl_stable_wait = 200;
uint32_t slowclk_period = rtc_clk_cal(0, 128) * 4;
uint32_t fosc_period = rtc_clk_cal(3, 5000);
uint32_t lp_wait_cycle = rtc_time_us_to_slowclk(lp_wait_us, slowclk_period);
uint32_t xtl_wait_cycle = rtc_time_us_to_slowclk(xtl_stable_wait, fosc_period);
uint32_t hp_wait_cycle;
if (hp_ana_wait_sel_sosc)
{
REG_SET_BIT(PMU_SLP_WAKEUP_CNTL7_REG, PMU_ANA_WAIT_CLK_SEL); // hp_ana_wait_clk sel sosc
hp_wait_cycle = rtc_time_us_to_slowclk(hp_wait_us, slowclk_period);
} else {
REG_CLR_BIT(PMU_SLP_WAKEUP_CNTL7_REG, PMU_ANA_WAIT_CLK_SEL); // hp_ana_wait_clk sel fosc
hp_wait_cycle = rtc_time_us_to_slowclk(lp_wait_us, fosc_period);
}
REG_SET_FIELD(PMU_SLP_WAKEUP_CNTL5_REG, PMU_LP_ANA_WAIT_TARGET, lp_wait_cycle);
REG_SET_FIELD(PMU_SLP_WAKEUP_CNTL7_REG, PMU_ANA_WAIT_TARGET, hp_wait_cycle);
REG_SET_FIELD(PMU_POWER_CK_WAIT_CNTL_REG, PMU_WAIT_XTL_STABLE, xtl_wait_cycle);
}
@@ -50,7 +50,7 @@ ESP_HW_LOG_ATTR_TAG(TAG, "pmu_param");
.xpd_bbpll = 1 \
}, \
.xtal = { \
.xpd_xtalx2 = 0, \
.xpd_xtalx2 = 1, \
.xpd_xtal = 1 \
} \
}
@@ -65,7 +65,7 @@ ESP_HW_LOG_ATTR_TAG(TAG, "pmu_param");
*/
#define PMU_HP_SLEEP_POWER_CONFIG_DEFAULT() { \
.dig_power = { \
.vdd_flash_mode = 0, \
.vdd_flash_mode = 3, \
.mem_dslp = 0, \
.mem_pd_en = 0, \
.wifi_pd_en = 0, \
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -167,7 +167,7 @@ const pmu_sleep_config_t* pmu_sleep_config_default(
config->digital = digital_default;
pmu_sleep_analog_config_t analog_default = PMU_SLEEP_ANALOG_LSLP_CONFIG_DEFAULT(sleep_flags);
analog_default.hp_sys.analog.dbias = PMU_HP_DBIAS_LIGHTSLEEP_0V6_DEFAULT;
analog_default.hp_sys.analog.drv_b = PMU_HP_DRVB_LIGHTSLEEP;
analog_default.lp_sys[LP(SLEEP)].analog.dbias = get_slp_lp_dbias();
if (!(sleep_flags & PMU_SLEEP_PD_XTAL)){
analog_default.hp_sys.analog.xpd_trx = PMU_XPD_TRX_SLEEP_ON;
@@ -192,6 +192,7 @@ static void pmu_sleep_power_init(pmu_context_t *ctx, const pmu_sleep_power_confi
pmu_ll_hp_set_dig_power(ctx->hal->dev, HP(SLEEP), power->hp_sys.dig_power.val);
pmu_ll_hp_set_clk_power(ctx->hal->dev, HP(SLEEP), power->hp_sys.clk_power.val);
pmu_ll_hp_set_xtal_xpd (ctx->hal->dev, HP(SLEEP), power->hp_sys.xtal.xpd_xtal);
pmu_ll_hp_set_xtalx2_xpd (ctx->hal->dev, HP(SLEEP), power->hp_sys.xtal.xpd_xtalx2);
if (dslp) {
pmu_ll_hp_set_memory_power_on_mask(ctx->hal->dev, 0);
@@ -205,6 +206,7 @@ static void pmu_sleep_power_init(pmu_context_t *ctx, const pmu_sleep_power_confi
pmu_ll_lp_set_dig_power(ctx->hal->dev, LP(SLEEP), power->lp_sys[LP(SLEEP)].dig_power.val);
pmu_ll_lp_set_clk_power(ctx->hal->dev, LP(SLEEP), power->lp_sys[LP(SLEEP)].clk_power.val);
pmu_ll_lp_set_xtal_xpd (ctx->hal->dev, LP(SLEEP), power->lp_sys[LP(SLEEP)].xtal.xpd_xtal);
pmu_ll_lp_set_xtalx2_xpd (ctx->hal->dev, LP(SLEEP), power->lp_sys[LP(SLEEP)].xtal.xpd_xtalx2);
}
static void pmu_sleep_digital_init(pmu_context_t *ctx, const pmu_sleep_digital_config_t *dig, bool dslp)
@@ -220,12 +222,13 @@ 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);
// Core power supply (include DCDC, HP LDO, LP LDO) configuration
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_xpd (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.xpd);
pmu_ll_hp_set_regulator_dbias (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.dbias);
pmu_ll_hp_set_regulator_driver_bar (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.drv_b);
pmu_ll_hp_set_trx_xpd (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.xpd_trx);
pmu_ll_lp_set_current_power_off (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.pd_cur);
pmu_ll_lp_set_bias_sleep_enable (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.bias_sleep);
pmu_ll_lp_set_regulator_slp_xpd (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.slp_xpd);
@@ -233,6 +236,9 @@ static void pmu_sleep_analog_init(pmu_context_t *ctx, const pmu_sleep_analog_con
pmu_ll_lp_set_regulator_sleep_dbias (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.slp_dbias);
pmu_ll_lp_set_regulator_dbias (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.dbias);
pmu_ll_lp_set_regulator_driver_bar (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.drv_b);
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_lp_set_dcm_vset (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.dcm_vset);
pmu_ll_lp_set_dcm_mode (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.dcm_mode);
}
@@ -312,7 +312,7 @@ typedef struct {
}, \
.lp_sys[PMU_MODE_LP_ACTIVE] = { \
.dig_power = { \
.vdd_io_mode = 4, \
.vdd_io_mode = 0, \
.bod_source_sel = 0, \
.vddbat_mode = 0, \
.peri_pd_en = 0, \
@@ -327,7 +327,7 @@ typedef struct {
}, \
.lp_sys[PMU_MODE_LP_SLEEP] = { \
.dig_power = { \
.vdd_io_mode = 4, \
.vdd_io_mode = 3, \
.bod_source_sel = 0, \
.vddbat_mode = 1, \
.peri_pd_en = ((sleep_flags) & PMU_SLEEP_PD_LP_PERIPH) ? 1 : 0,\
@@ -548,8 +548,8 @@ typedef struct pmu_sleep_machine_constant {
#define PMU_SLEEP_MC_DEFAULT() { \
.lp = { \
.min_slp_time_us = 450, \
.analog_wait_time_us = 100, \
.xtal_wait_stable_time_us = 250, \
.analog_wait_time_us = 154, \
.xtal_wait_stable_time_us = 200, \
.clk_switch_cycle = 1, \
.clk_power_on_wait_cycle = 1, \
.isolate_wait_time_us = 1, \
@@ -559,14 +559,14 @@ typedef struct pmu_sleep_machine_constant {
}, \
.hp = { \
.min_slp_time_us = 450, \
.analog_wait_time_us = 1600, \
.analog_wait_time_us = 150, \
.isolate_wait_time_us = 1, \
.reset_wait_time_us = 1, \
.power_supply_wait_time_us = 2, \
.power_up_wait_time_us = 2, \
.regdma_s2a_work_time_us = PMU_REGDMA_S2A_WORK_TIME_US, \
.regdma_a2s_work_time_us = PMU_REGDMA_A2S_WORK_TIME_US, \
.xtal_wait_stable_time_us = 250, \
.xtal_wait_stable_time_us = 200, \
.pll_wait_stable_time_us = 1 \
} \
}
@@ -20,7 +20,7 @@
#include "soc/pmu_reg.h"
#include "pmu_param.h"
// ESP_HW_LOG_ATTR_TAG(TAG, "rtc_clk_init");
ESP_HW_LOG_ATTR_TAG(TAG, "rtc_clk_init");
void rtc_clk_init(rtc_clk_config_t cfg)
{
@@ -35,7 +35,7 @@ void rtc_clk_init(rtc_clk_config_t cfg)
* CLK_8M_DFREQ constant gives the best temperature characteristics.
*/
REG_SET_FIELD(LP_CLKRST_FOSC_CNTL_REG, LP_CLKRST_FOSC_DFREQ, cfg.clk_8m_dfreq);
REG_SET_FIELD(LP_CLKRST_RC32K_CNTL_REG, LP_CLKRST_RC32K_DFREQ, cfg.slow_clk_dcap); // h4 specific workaround (RC32K_DFREQ is used for RC_SLOW clock tuning) TODO: IDF-12313
REG_SET_FIELD(LP_CLKRST_RC32K_CNTL_REG, LP_CLKRST_RC32K_DFREQ, cfg.slow_clk_dcap); // h21 specific workaround (RC32K_DFREQ is used for RC_SLOW clock tuning) TODO: IDF-12313
// switch to ccm mode
@@ -90,8 +90,3 @@ void rtc_clk_init(rtc_clk_config_t cfg)
rtc_clk_fast_src_set(cfg.fast_clk_src);
rtc_clk_slow_src_set(cfg.slow_clk_src);
}
__attribute__((weak)) uint8_t i2c_readReg(uint8_t block, uint8_t host_id, uint8_t reg_add) {return 0;}
__attribute__((weak)) uint8_t i2c_readReg_Mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb) {return 0;}
__attribute__((weak)) void i2c_writeReg(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data) {};
__attribute__((weak)) void i2c_writeReg_Mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data) {};
@@ -20,8 +20,9 @@
#include "esp_rom_sys.h"
#include "soc/regi2c_ulp.h"
#include "hal/lp_aon_ll.h"
#include "esp_hw_log.h"
static __attribute__((unused)) const char *TAG = "pmu_init";
ESP_HW_LOG_ATTR_TAG(TAG, "pmu_init");
typedef struct {
const pmu_hp_system_power_param_t *power;
@@ -96,7 +97,7 @@ void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, const pmu_hp_sys
if (mode == PMU_MODE_HP_ACTIVE) {
pmu_ll_hp_set_regulator_lp_dbias_voltage(ctx->hal->dev, mode, anlg->regulator0.lp_dbias_vol);
pmu_ll_hp_set_regulator_hp_dbias_voltage(ctx->hal->dev, mode, anlg->regulator0.hp_dbias_vol);
pmu_ll_hp_set_regulator_dbias_sel (ctx->hal->dev, mode, anlg->regulator0.dbias_sel);
pmu_ll_hp_set_regulator_dbias_select (ctx->hal->dev, mode, anlg->regulator0.dbias_sel);
pmu_ll_hp_set_regulator_dbias_init (ctx->hal->dev, mode, anlg->regulator0.dbias_init);
}
pmu_ll_hp_set_regulator_power_detect_bypass(ctx->hal->dev, mode, anlg->regulator0.power_det_bypass);
@@ -122,6 +123,9 @@ void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, const pmu_hp_sys
/* set dcdc ccm mode software enable */
pmu_ll_set_dcdc_ccm_sw_en(ctx->hal->dev, true);
//For dcdc ldo mode when VDD is low than about a certion value, eg 2.6v
lp_aon_ll_set_ldo_sw(15);
/* set ble bandgap ocode */
uint32_t ulp_ocode = 0;
#if !CONFIG_IDF_ENV_FPGA
@@ -132,8 +136,8 @@ void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, const pmu_hp_sys
ulp_ocode = REGI2C_READ_MASK(I2C_ULP, I2C_ULP_OCODE);
}
#endif
REG_SET_FIELD(PMU_BLE_BANDGAP_CTRL_REG, PMU_EXT_OCODE, ulp_ocode);
SET_PERI_REG_MASK(PMU_BLE_BANDGAP_CTRL_REG, PMU_EXT_FORCE_OCODE);
pmu_ll_set_ble_bandgap_ext_ocode(ctx->hal->dev, ulp_ocode);
pmu_ll_set_ble_bandgap_ext_force_ocode(ctx->hal->dev, true);
}
void pmu_lp_system_init(pmu_context_t *ctx, pmu_lp_mode_t mode, const pmu_lp_system_param_t *param)
@@ -147,6 +151,7 @@ void pmu_lp_system_init(pmu_context_t *ctx, pmu_lp_mode_t mode, const pmu_lp_sys
pmu_ll_lp_set_clk_power(ctx->hal->dev, mode, power->clk_power.val);
pmu_ll_lp_set_xtal_xpd (ctx->hal->dev, PMU_MODE_LP_SLEEP, power->xtal.xpd_xtal);
pmu_ll_lp_set_xtalx2_xpd (ctx->hal->dev, PMU_MODE_LP_SLEEP, power->xtal.xpd_xtalx2);
/* Default configuration of lp-system analog sub-system in active and
* sleep modes */
if (mode == PMU_MODE_LP_SLEEP) {
@@ -176,16 +181,16 @@ static inline void pmu_power_domain_force_default(pmu_context_t *ctx)
PMU_HP_PD_TOP,
PMU_HP_PD_HP_AON,
PMU_HP_PD_CPU,
PMU_HP_PD_WIFI
PMU_HP_PD_BT_154
};
for (uint8_t idx = 0; idx < (sizeof(pmu_hp_domains) / sizeof(pmu_hp_power_domain_t)); idx++) {
pmu_ll_hp_set_power_force_power_up (ctx->hal->dev, pmu_hp_domains[idx], false);
pmu_ll_hp_set_power_force_reset (ctx->hal->dev, pmu_hp_domains[idx], false);
pmu_ll_hp_set_power_force_isolate (ctx->hal->dev, pmu_hp_domains[idx], false);
pmu_ll_hp_set_power_force_power_down(ctx->hal->dev, pmu_hp_domains[idx], false);
pmu_ll_hp_set_power_force_no_isolate(ctx->hal->dev, pmu_hp_domains[idx], false);
pmu_ll_hp_set_power_force_no_reset (ctx->hal->dev, pmu_hp_domains[idx], false);
pmu_ll_hp_set_power_force_power_down(ctx->hal->dev, pmu_hp_domains[idx], false);
pmu_ll_hp_set_power_force_isolate (ctx->hal->dev, pmu_hp_domains[idx], false);
pmu_ll_hp_set_power_force_reset (ctx->hal->dev, pmu_hp_domains[idx], false);
}
/* Isolate all memory banks while sleeping, avoid memory leakage current */
pmu_ll_hp_set_memory_no_isolate (ctx->hal->dev, 0);
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -84,6 +84,12 @@ static inline void lp_aon_ll_inform_wakeup_type(bool dslp)
}
}
static inline void lp_aon_ll_set_ldo_sw(uint32_t value)
{
CLEAR_PERI_REG_MASK(LP_AON_DATE_REG, LP_AON_DREG_LDO_HW);
REG_SET_FIELD(LP_AON_DATE_REG, LP_AON_DREG_LDO_SW, value);
}
#ifdef __cplusplus
}
#endif