Skip to content

Commit bac996a

Browse files
committed
Merge branch 'feat/support_low_power_mode_in_monitor_state' into 'master'
feat(esp_hw_support): support enable analog lowpower mode by API Closes IDFGH-6208 See merge request espressif/esp-idf!38924
2 parents b971cf5 + e55d6d8 commit bac996a

File tree

7 files changed

+56
-5
lines changed

7 files changed

+56
-5
lines changed

components/esp_adc/adc_oneshot.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,10 @@ esp_err_t adc_oneshot_new_unit(const adc_oneshot_unit_init_cfg_t *init_config, a
163163
esp_sleep_sub_mode_config(ESP_SLEEP_USE_ADC_TSEN_MONITOR_MODE, true);
164164
#endif
165165
}
166+
#if CONFIG_IDF_TARGET_ESP32
167+
// SAR will be used in monitor state, forcibly disable analog lowpower mode to keep system functionality.
168+
esp_sleep_sub_mode_force_disable(ESP_SLEEP_ANALOG_LOW_POWER_MODE);
169+
#endif
166170

167171
ESP_LOGD(TAG, "new adc unit%"PRId32" is created", unit->unit_id);
168172
*ret_unit = unit;

components/esp_hw_support/include/esp_private/esp_sleep_internal.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ typedef enum {
4040
ESP_SLEEP_DIG_USE_XTAL_MODE, //!< The mode requested by digital peripherals to keep XTAL clock on during sleep (both HP_SLEEP and LP_SLEEP mode). (!!! Only valid for lightsleep, will override the XTAL domain config by esp_sleep_pd_config)
4141
ESP_SLEEP_LP_USE_XTAL_MODE, //!< The mode requested by lp peripherals to keep XTAL clock on during sleep. Only valid for lightsleep.
4242
ESP_SLEEP_VBAT_POWER_DEEPSLEEP_MODE, //!< The mode to switch power supply to VBAT during deep sleep.
43+
#if CONFIG_IDF_TARGET_ESP32
44+
ESP_SLEEP_ANALOG_LOW_POWER_MODE, //!< If analog-related peripherals(ADC, TSENS, TOUCH) is not used in monitor mode, analog low power mode can be enabled to reduce power consumption (~300uA) in monitor state.
45+
#endif
4346
ESP_SLEEP_MODE_MAX,
4447
} esp_sleep_sub_mode_t;
4548

components/esp_hw_support/include/esp_sleep.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -755,6 +755,16 @@ void esp_default_wake_deep_sleep(void);
755755
*/
756756
void esp_deep_sleep_disable_rom_logging(void);
757757

758+
#if CONFIG_IDF_TARGET_ESP32
759+
/**
760+
* @brief If analog-related peripherals(ADC, TOUCH) is not used in monitor mode, analog low power mode
761+
* can be enabled by this API to reduce power consumption in monitor state.
762+
*
763+
* @param enable Enable or disable lowpower analog mode
764+
*/
765+
void esp_sleep_enable_lowpower_analog_mode(bool enable);
766+
#endif
767+
758768
#if ESP_SLEEP_POWER_DOWN_CPU
759769

760770
#if SOC_PM_CPU_RETENTION_BY_RTCCNTL

components/esp_hw_support/port/esp32/include/soc/rtc.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,7 @@ typedef struct rtc_sleep_config_s {
508508
uint32_t dig_dbias_slp : 3; //!< set bias for digital domain, in sleep mode
509509
uint32_t rtc_dbias_wak : 3; //!< set bias for RTC domain, in active mode
510510
uint32_t rtc_dbias_slp : 3; //!< set bias for RTC domain, in sleep mode
511+
uint32_t dbias_follow_8m : 1; //!< raise voltage if RTC 8MCLK is enabled
511512
uint32_t lslp_meminf_pd : 1; //!< remove all peripheral force power up flags
512513
uint32_t vddsdio_pd_en : 1; //!< power down VDDSDIO regulator
513514
uint32_t xtal_fpu : 1; //!< keep main XTAL powered up in sleep
@@ -527,6 +528,9 @@ typedef struct rtc_sleep_config_s {
527528
#define RTC_SLEEP_PD_INT_8M BIT(8) //!< Power down Internal 8M oscillator
528529

529530
//These flags are not power domains, but will affect some sleep parameters
531+
#if CONFIG_IDF_TARGET_ESP32
532+
#define RTC_SLEEP_WITH_LOWPOWER_ANALOG BIT(15) //!< Setting analog low power mode in esp32 monitor state, in which analog-related peripherals(ADC, TOUCH) is not used.
533+
#endif
530534
#define RTC_SLEEP_DIG_USE_8M BIT(16)
531535
#define RTC_SLEEP_USE_ADC_TESEN_MONITOR BIT(17)
532536
#define RTC_SLEEP_NO_ULTRA_LOW BIT(18) //!< Avoid using ultra low power in deep sleep, in which RTCIO cannot be used as input, and RTCMEM can't work under high temperature

components/esp_hw_support/port/esp32/rtc_sleep.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,13 @@ void rtc_sleep_get_default_config(uint32_t sleep_flags, rtc_sleep_config_t *out_
116116
out_config->rtc_dbias_slp = !((sleep_flags) & RTC_SLEEP_PD_INT_8M) ? RTC_CNTL_DBIAS_1V10 : RTC_CNTL_DBIAS_0V90;
117117
out_config->dbg_atten_slp = RTC_CNTL_DBG_ATTEN_NODROP;
118118
}
119+
120+
if (sleep_flags & RTC_SLEEP_WITH_LOWPOWER_ANALOG) {
121+
out_config->dbias_follow_8m = 0;
122+
} else {
123+
// make sure voltage is raised when RTC 8MCLK is enabled
124+
out_config->dbias_follow_8m = 1;
125+
}
119126
}
120127

121128
void rtc_sleep_init(rtc_sleep_config_t cfg)
@@ -221,6 +228,16 @@ void rtc_sleep_init(rtc_sleep_config_t cfg)
221228
REG_CLR_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU);
222229
}
223230

231+
if (cfg.dbias_follow_8m) {
232+
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BIAS_CORE_FOLW_8M);
233+
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BIAS_I2C_FOLW_8M);
234+
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BIAS_SLEEP_FOLW_8M);
235+
} else {
236+
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BIAS_CORE_FOLW_8M);
237+
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BIAS_I2C_FOLW_8M);
238+
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BIAS_SLEEP_FOLW_8M);
239+
}
240+
224241
/* enable VDDSDIO control by state machine */
225242
REG_CLR_BIT(RTC_CNTL_SDIO_CONF_REG, RTC_CNTL_SDIO_FORCE);
226243
REG_SET_FIELD(RTC_CNTL_SDIO_CONF_REG, RTC_CNTL_SDIO_PD_EN, cfg.vddsdio_pd_en);

components/esp_hw_support/sleep_modes.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2391,6 +2391,9 @@ int32_t* esp_sleep_sub_mode_dump_config(FILE *stream) {
23912391
[ESP_SLEEP_DIG_USE_XTAL_MODE] = "ESP_SLEEP_DIG_USE_XTAL_MODE",
23922392
[ESP_SLEEP_LP_USE_XTAL_MODE] = "ESP_SLEEP_LP_USE_XTAL_MODE",
23932393
[ESP_SLEEP_VBAT_POWER_DEEPSLEEP_MODE] = "ESP_SLEEP_VBAT_POWER_DEEPSLEEP_MODE",
2394+
#if CONFIG_IDF_TARGET_ESP32
2395+
[ESP_SLEEP_ANALOG_LOW_POWER_MODE] = "ESP_SLEEP_ANALOG_LOW_POWER_MODE",
2396+
#endif
23942397
}[mode],
23952398
s_sleep_sub_mode_ref_cnt[mode] ? "ENABLED" : "DISABLED",
23962399
s_sleep_sub_mode_ref_cnt[mode]);
@@ -2670,6 +2673,12 @@ static SLEEP_FN_ATTR uint32_t get_sleep_flags(uint32_t sleep_flags, bool deepsle
26702673
}
26712674
#endif
26722675

2676+
#if CONFIG_IDF_TARGET_ESP32
2677+
if (s_sleep_sub_mode_ref_cnt[ESP_SLEEP_ANALOG_LOW_POWER_MODE]) {
2678+
sleep_flags |= RTC_SLEEP_WITH_LOWPOWER_ANALOG;
2679+
}
2680+
#endif
2681+
26732682
#ifdef CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND
26742683
if (!deepsleep) {
26752684
sleep_flags &= ~RTC_SLEEP_PD_RTC_PERIPH;
@@ -2733,6 +2742,13 @@ esp_deep_sleep_disable_rom_logging(void)
27332742
rtc_suppress_rom_log();
27342743
}
27352744

2745+
#if CONFIG_IDF_TARGET_ESP32
2746+
void esp_sleep_enable_lowpower_analog_mode(bool enable)
2747+
{
2748+
esp_sleep_sub_mode_config(ESP_SLEEP_ANALOG_LOW_POWER_MODE, enable);
2749+
}
2750+
#endif
2751+
27362752
__attribute__((deprecated("Please use esp_sleep_sub_mode_config instead"))) void esp_sleep_periph_use_8m(bool use_or_not)
27372753
{
27382754
if (use_or_not) {

components/ulp/ulp_fsm/ulp.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2010-2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -74,10 +74,7 @@ esp_err_t ulp_run(uint32_t entry_point)
7474
CLEAR_PERI_REG_MASK(SENS_SAR_START_FORCE_REG, SENS_ULP_CP_FORCE_START_TOP_M);
7575
// set time until wakeup is allowed to the smallest possible
7676
REG_SET_FIELD(RTC_CNTL_TIMER5_REG, RTC_CNTL_MIN_SLP_VAL, RTC_CNTL_MIN_SLP_VAL_MIN);
77-
// make sure voltage is raised when RTC 8MCLK is enabled
78-
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BIAS_I2C_FOLW_8M);
79-
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BIAS_CORE_FOLW_8M);
80-
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BIAS_SLEEP_FOLW_8M);
77+
8178
// enable ULP timer
8279
SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN);
8380
#else

0 commit comments

Comments
 (0)