Skip to content

Commit eab9876

Browse files
committed
Merge branch 'feature/introduce_internal_sleep_sub_mode_configure_api' into 'master'
feat(esp_hw_support): introduce internal sleep sub mode configure api Closes PM-216 See merge request espressif/esp-idf!30687
2 parents c27614f + fd79c59 commit eab9876

File tree

11 files changed

+201
-76
lines changed

11 files changed

+201
-76
lines changed

components/esp_adc/adc_oneshot.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ esp_err_t adc_oneshot_new_unit(const adc_oneshot_unit_init_cfg_t *init_config, a
127127
sar_periph_ctrl_adc_oneshot_power_acquire();
128128
} else {
129129
#if SOC_LIGHT_SLEEP_SUPPORTED || SOC_DEEP_SLEEP_SUPPORTED
130-
esp_sleep_enable_adc_tsens_monitor(true);
130+
esp_sleep_sub_mode_config(ESP_SLEEP_USE_ADC_TSEN_MONITOR_MODE, true);
131131
#endif
132132
}
133133

@@ -230,7 +230,7 @@ esp_err_t adc_oneshot_del_unit(adc_oneshot_unit_handle_t handle)
230230
sar_periph_ctrl_adc_oneshot_power_release();
231231
} else {
232232
#if SOC_LIGHT_SLEEP_SUPPORTED || SOC_DEEP_SLEEP_SUPPORTED
233-
esp_sleep_enable_adc_tsens_monitor(false);
233+
esp_sleep_sub_mode_config(ESP_SLEEP_USE_ADC_TSEN_MONITOR_MODE, false);
234234
#endif
235235
}
236236

components/esp_driver_ledc/src/ledc.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "driver/ledc.h"
2020
#include "esp_rom_gpio.h"
2121
#include "clk_ctrl_os.h"
22+
#include "esp_private/esp_sleep_internal.h"
2223
#include "esp_private/periph_ctrl.h"
2324
#include "esp_private/gpio.h"
2425
#include "esp_private/esp_gpio_reserve.h"
@@ -561,6 +562,16 @@ static esp_err_t ledc_set_timer_div(ledc_mode_t speed_mode, ledc_timer_t timer_n
561562
}
562563
p_ledc_obj[speed_mode]->glb_clk_is_acquired[timer_num] = true;
563564
if (p_ledc_obj[speed_mode]->glb_clk != glb_clk) {
565+
#if SOC_LIGHT_SLEEP_SUPPORTED
566+
/* keep ESP_PD_DOMAIN_RC_FAST on during light sleep */
567+
if (glb_clk == LEDC_SLOW_CLK_RC_FAST) {
568+
/* Keep ESP_PD_DOMAIN_RC_FAST on during light sleep */
569+
esp_sleep_sub_mode_config(ESP_SLEEP_DIG_USE_RC_FAST_MODE, true);
570+
} else if (p_ledc_obj[speed_mode]->glb_clk == LEDC_SLOW_CLK_RC_FAST) {
571+
/* No need to keep ESP_PD_DOMAIN_RC_FAST on during light sleep anymore */
572+
esp_sleep_sub_mode_config(ESP_SLEEP_DIG_USE_RC_FAST_MODE, false);
573+
}
574+
#endif
564575
// TODO: release old glb_clk (if not UNINIT), and acquire new glb_clk [clk_tree]
565576
p_ledc_obj[speed_mode]->glb_clk = glb_clk;
566577
LEDC_FUNC_CLOCK_ATOMIC() {
@@ -571,12 +582,6 @@ static esp_err_t ledc_set_timer_div(ledc_mode_t speed_mode, ledc_timer_t timer_n
571582
portEXIT_CRITICAL(&ledc_spinlock);
572583

573584
ESP_LOGD(LEDC_TAG, "In slow speed mode, global clk set: %d", glb_clk);
574-
575-
/* keep ESP_PD_DOMAIN_RC_FAST on during light sleep */
576-
#if SOC_LIGHT_SLEEP_SUPPORTED
577-
extern void esp_sleep_periph_use_8m(bool use_or_not);
578-
esp_sleep_periph_use_8m(glb_clk == LEDC_SLOW_CLK_RC_FAST);
579-
#endif
580585
}
581586

582587
/* The divisor is correct, we can write in the hardware. */

components/esp_driver_uart/test_apps/uart/main/test_app_main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#include "unity_test_utils.h"
1010
#include "esp_heap_caps.h"
1111

12-
#define TEST_MEMORY_LEAK_THRESHOLD (200)
12+
#define TEST_MEMORY_LEAK_THRESHOLD (212)
1313

1414
void setUp(void)
1515
{

components/esp_hw_support/include/esp_private/esp_sleep_internal.h

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,35 @@ typedef struct {
3131
void esp_sleep_set_sleep_context(esp_sleep_context_t *sleep_ctx);
3232
#endif
3333

34+
typedef enum {
35+
ESP_SLEEP_RTC_USE_RC_FAST_MODE, //!< The mode requested by RTC peripherals to keep RC_FAST clock on during sleep (both HP_SLEEP and LP_SLEEP mode). (Will override the RC_FAST domain config by esp_sleep_pd_config)
36+
ESP_SLEEP_DIG_USE_RC_FAST_MODE, //!< The mode requested by digital peripherals to keep RC_FAST clock on during sleep (both HP_SLEEP and LP_SLEEP mode). (!!! Only valid for lightsleep, will override the RC_FAST domain config by esp_sleep_pd_config)
37+
ESP_SLEEP_USE_ADC_TSEN_MONITOR_MODE, //!< Will enables the use of ADC and temperature sensor in monitor (ULP) mode.
38+
ESP_SLEEP_ULTRA_LOW_MODE, //!< In ultra low mode, 2uA is saved, but RTC memory can't use at high temperature, and RTCIO can't be used as INPUT.
39+
ESP_SLEEP_RTC_FAST_USE_XTAL_MODE, //!< The mode in which the crystal is used as the RTC_FAST clock source, need keep XTAL on in HP_SLEEP mode when ULP is working.
40+
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)
41+
ESP_SLEEP_MODE_MAX,
42+
} esp_sleep_sub_mode_t;
43+
3444
/**
35-
* @brief Enables the use of ADC and temperature sensor in monitor (ULP) mode
45+
* @brief Set sub-sleep power mode in sleep, mode enabled status is maintained by reference count.
46+
* This submode configuration will kept after deep sleep wakeup.
3647
*
37-
* @note This state is kept in RTC memory and will keep its value after a deep sleep wakeup
48+
* @param mode sub-sleep mode type
49+
* @param activate Activate or deactivate the sleep sub mode
3850
*
51+
* @return
52+
* - ESP_OK on success
53+
* - ESP_ERR_INVALID_ARG if either of the arguments is out of range
54+
*/
55+
esp_err_t esp_sleep_sub_mode_config(esp_sleep_sub_mode_t mode, bool activate);
56+
57+
/**
58+
* Dump the sub-sleep power mode enable status
59+
* @param stream The stream to dump to, if NULL then nothing will be dumped
60+
* @return return the reference count array pointer
3961
*/
40-
void esp_sleep_enable_adc_tsens_monitor(bool enable);
62+
int32_t* esp_sleep_sub_mode_dump_config(FILE *stream);
4163

4264
#if SOC_GPIO_SUPPORT_HOLD_IO_IN_DSLP && !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
4365
/**

components/esp_hw_support/port/esp32/rtc_clk.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <stdlib.h>
1111
#include "soc/rtc.h"
1212
#include "esp_private/rtc_clk.h"
13+
#include "esp_private/esp_sleep_internal.h"
1314
#include "soc/rtc_periph.h"
1415
#include "soc/sens_reg.h"
1516
#include "soc/soc_caps.h"
@@ -273,15 +274,23 @@ void rtc_clk_apll_coeff_set(uint32_t o_div, uint32_t sdm0, uint32_t sdm1, uint32
273274

274275
void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src)
275276
{
276-
clk_ll_rtc_slow_set_src(clk_src);
277+
#ifndef BOOTLOADER_BUILD
278+
soc_rtc_slow_clk_src_t clk_src_before_switch = clk_ll_rtc_slow_get_src();
279+
// Keep the RTC8M_CLK on in sleep if RTC clock is rc_fast_d256.
280+
if (clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 && clk_src_before_switch != SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) { // Switch to RC_FAST_D256
281+
esp_sleep_sub_mode_config(ESP_SLEEP_RTC_USE_RC_FAST_MODE, true);
282+
} else if (clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 && clk_src_before_switch == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) { // Switch away from RC_FAST_D256
283+
esp_sleep_sub_mode_config(ESP_SLEEP_RTC_USE_RC_FAST_MODE, false);
284+
}
285+
#endif
277286

287+
clk_ll_rtc_slow_set_src(clk_src);
278288
// The logic should be moved to BT driver
279289
if (clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
280290
clk_ll_xtal32k_digi_enable();
281291
} else {
282292
clk_ll_xtal32k_digi_disable();
283293
}
284-
285294
esp_rom_delay_us(SOC_DELAY_RTC_SLOW_CLK_SWITCH);
286295
}
287296

components/esp_hw_support/port/esp32c2/rtc_clk.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "esp32c2/rom/rtc.h"
1414
#include "esp32c2/rom/uart.h"
1515
#include "soc/rtc.h"
16+
#include "esp_private/esp_sleep_internal.h"
1617
#include "esp_private/rtc_clk.h"
1718
#include "soc/io_mux_reg.h"
1819
#include "soc/soc.h"
@@ -66,6 +67,16 @@ bool rtc_clk_8md256_enabled(void)
6667

6768
void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src)
6869
{
70+
#ifndef BOOTLOADER_BUILD
71+
soc_rtc_slow_clk_src_t clk_src_before_switch = clk_ll_rtc_slow_get_src();
72+
// Keep the RTC8M_CLK on in sleep if RTC clock is rc_fast_d256.
73+
if (clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 && clk_src_before_switch != SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) { // Switch to RC_FAST_D256
74+
esp_sleep_sub_mode_config(ESP_SLEEP_RTC_USE_RC_FAST_MODE, true);
75+
} else if (clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 && clk_src_before_switch == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) { // Switch away from RC_FAST_D256
76+
esp_sleep_sub_mode_config(ESP_SLEEP_RTC_USE_RC_FAST_MODE, false);
77+
}
78+
#endif
79+
6980
clk_ll_rtc_slow_set_src(clk_src);
7081

7182
/* Why we need to connect this clock to digital?
@@ -76,7 +87,6 @@ void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src)
7687
} else {
7788
clk_ll_xtal32k_digi_disable();
7889
}
79-
8090
esp_rom_delay_us(SOC_DELAY_RTC_SLOW_CLK_SWITCH);
8191
}
8292

components/esp_hw_support/port/esp32c3/rtc_clk.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "esp32c3/rom/rtc.h"
1414
#include "soc/rtc.h"
1515
#include "soc/io_mux_reg.h"
16+
#include "esp_private/esp_sleep_internal.h"
1617
#include "esp_private/rtc_clk.h"
1718
#include "esp_hw_log.h"
1819
#include "esp_rom_sys.h"
@@ -99,8 +100,17 @@ bool rtc_clk_8md256_enabled(void)
99100

100101
void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src)
101102
{
102-
clk_ll_rtc_slow_set_src(clk_src);
103+
#ifndef BOOTLOADER_BUILD
104+
soc_rtc_slow_clk_src_t clk_src_before_switch = clk_ll_rtc_slow_get_src();
105+
// Keep the RTC8M_CLK on in sleep if RTC clock is rc_fast_d256.
106+
if (clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 && clk_src_before_switch != SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) { // Switch to RC_FAST_D256
107+
esp_sleep_sub_mode_config(ESP_SLEEP_RTC_USE_RC_FAST_MODE, true);
108+
} else if (clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 && clk_src_before_switch == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) { // Switch away from RC_FAST_D256
109+
esp_sleep_sub_mode_config(ESP_SLEEP_RTC_USE_RC_FAST_MODE, false);
110+
}
111+
#endif
103112

113+
clk_ll_rtc_slow_set_src(clk_src);
104114
/* Why we need to connect this clock to digital?
105115
* Or maybe this clock should be connected to digital when xtal 32k clock is enabled instead?
106116
*/
@@ -109,7 +119,6 @@ void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src)
109119
} else {
110120
clk_ll_xtal32k_digi_disable();
111121
}
112-
113122
esp_rom_delay_us(SOC_DELAY_RTC_SLOW_CLK_SWITCH);
114123
}
115124

components/esp_hw_support/port/esp32s2/rtc_clk.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "esp32s2/rom/rtc.h"
1414
#include "soc/rtc.h"
1515
#include "esp_private/rtc_clk.h"
16+
#include "esp_private/esp_sleep_internal.h"
1617
#include "soc/rtc_cntl_reg.h"
1718
#include "soc/rtc_io_reg.h"
1819
#include "soc/soc_caps.h"
@@ -174,8 +175,17 @@ void rtc_clk_apll_coeff_set(uint32_t o_div, uint32_t sdm0, uint32_t sdm1, uint32
174175

175176
void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src)
176177
{
177-
clk_ll_rtc_slow_set_src(clk_src);
178+
#ifndef BOOTLOADER_BUILD
179+
soc_rtc_slow_clk_src_t clk_src_before_switch = clk_ll_rtc_slow_get_src();
180+
// Keep the RTC8M_CLK on in sleep if RTC clock is rc_fast_d256.
181+
if (clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 && clk_src_before_switch != SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) { // Switch to RC_FAST_D256
182+
esp_sleep_sub_mode_config(ESP_SLEEP_RTC_USE_RC_FAST_MODE, true);
183+
} else if (clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 && clk_src_before_switch == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) { // Switch away from RC_FAST_D256
184+
esp_sleep_sub_mode_config(ESP_SLEEP_RTC_USE_RC_FAST_MODE, false);
185+
}
186+
#endif
178187

188+
clk_ll_rtc_slow_set_src(clk_src);
179189
/* Why we need to connect this clock to digital?
180190
* Or maybe this clock should be connected to digital when xtal 32k clock is enabled instead?
181191
*/
@@ -184,7 +194,6 @@ void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src)
184194
} else {
185195
clk_ll_xtal32k_digi_disable();
186196
}
187-
188197
esp_rom_delay_us(SOC_DELAY_RTC_SLOW_CLK_SWITCH);
189198
}
190199

components/esp_hw_support/port/esp32s3/rtc_clk.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "esp32s3/rom/rtc.h"
1414
#include "soc/rtc.h"
1515
#include "soc/io_mux_reg.h"
16+
#include "esp_private/esp_sleep_internal.h"
1617
#include "esp_private/rtc_clk.h"
1718
#include "soc/rtc_io_reg.h"
1819
#include "esp_rom_sys.h"
@@ -114,8 +115,17 @@ bool rtc_clk_8md256_enabled(void)
114115

115116
void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src)
116117
{
117-
clk_ll_rtc_slow_set_src(clk_src);
118+
#ifndef BOOTLOADER_BUILD
119+
soc_rtc_slow_clk_src_t clk_src_before_switch = clk_ll_rtc_slow_get_src();
120+
// Keep the RTC8M_CLK on in sleep if RTC clock is rc_fast_d256.
121+
if (clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 && clk_src_before_switch != SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) { // Switch to RC_FAST_D256
122+
esp_sleep_sub_mode_config(ESP_SLEEP_RTC_USE_RC_FAST_MODE, true);
123+
} else if (clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 && clk_src_before_switch == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) { // Switch away from RC_FAST_D256
124+
esp_sleep_sub_mode_config(ESP_SLEEP_RTC_USE_RC_FAST_MODE, false);
125+
}
126+
#endif
118127

128+
clk_ll_rtc_slow_set_src(clk_src);
119129
/* Why we need to connect this clock to digital?
120130
* Or maybe this clock should be connected to digital when xtal 32k clock is enabled instead?
121131
*/
@@ -124,7 +134,6 @@ void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src)
124134
} else {
125135
clk_ll_xtal32k_digi_disable();
126136
}
127-
128137
esp_rom_delay_us(SOC_DELAY_RTC_SLOW_CLK_SWITCH);
129138
}
130139

0 commit comments

Comments
 (0)