1 /*
2 * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8 #include <zephyr/drivers/timer/system_timer.h>
9
10 #include <stddef.h>
11 #include <string.h>
12 #include <sys/lock.h>
13 #include <sys/param.h>
14
15 #include "esp_attr.h"
16 #include "esp_memory_utils.h"
17 #include "esp_sleep.h"
18 #include "esp_private/esp_sleep_internal.h"
19 #include "esp_private/esp_timer_private.h"
20 #include "esp_private/system_internal.h"
21 #include "esp_log.h"
22 #include "esp_cpu.h"
23 #include "esp_timer.h"
24 #include "soc/soc_caps.h"
25 #include "driver/rtc_io.h"
26 #include "hal/rtc_io_hal.h"
27
28 #if SOC_PM_SUPPORT_PMU_MODEM_STATE
29 #include "esp_private/pm_impl.h"
30 #endif
31
32 #if SOC_LP_AON_SUPPORTED
33 #include "hal/lp_aon_hal.h"
34 #else
35 #if !CONFIG_IDF_TARGET_ESP32H2
36 #include "hal/rtc_cntl_ll.h"
37 #include "hal/rtc_hal.h"
38 #endif
39 #endif
40
41 #include "driver/uart.h"
42
43 #include "soc/rtc.h"
44 #include "soc/soc_caps.h"
45 #include "regi2c_ctrl.h" //For `REGI2C_ANA_CALI_PD_WORKAROUND`, temp
46
47 #include "hal/cache_hal.h"
48 #include "hal/wdt_hal.h"
49 #include "hal/uart_hal.h"
50 #if SOC_TOUCH_SENSOR_SUPPORTED
51 #include "hal/touch_sensor_hal.h"
52 #include "driver/touch_sensor.h"
53 #include "driver/touch_sensor_common.h"
54 #endif
55 #include "hal/clk_gate_ll.h"
56
57 #include "sdkconfig.h"
58 #include "esp_rom_uart.h"
59 #include "esp_rom_sys.h"
60 #include "esp_private/brownout.h"
61 #include "esp_private/sleep_cpu.h"
62 #include "esp_private/sleep_modem.h"
63 #include "esp_private/esp_clk.h"
64 #include "esp_private/esp_task_wdt.h"
65 #include "esp_private/spi_flash_os.h"
66 #include "esp_private/sar_periph_ctrl.h"
67
68 #ifdef CONFIG_IDF_TARGET_ESP32
69 #include "esp32/rom/cache.h"
70 #include "esp32/rom/rtc.h"
71 #include "esp_private/gpio.h"
72 #include "esp_private/sleep_gpio.h"
73 #elif CONFIG_IDF_TARGET_ESP32S2
74 #include "esp32s2/rom/rtc.h"
75 #include "soc/extmem_reg.h"
76 #include "esp_private/gpio.h"
77 #elif CONFIG_IDF_TARGET_ESP32S3
78 #include "esp32s3/rom/rtc.h"
79 #include "esp_private/mspi_timing_tuning.h"
80 #elif CONFIG_IDF_TARGET_ESP32C3
81 #include "esp32c3/rom/rtc.h"
82 #elif CONFIG_IDF_TARGET_ESP32C2
83 #include "esp32c2/rom/rtc.h"
84 #elif CONFIG_IDF_TARGET_ESP32C6
85 #include "esp32c6/rom/rtc.h"
86 #include "hal/lp_timer_hal.h"
87 #include "hal/gpio_ll.h"
88 #elif CONFIG_IDF_TARGET_ESP32H2
89 #include "esp32h2/rom/rtc.h"
90 #include "esp32h2/rom/cache.h"
91 #include "esp32h2/rom/rtc.h"
92 #include "soc/extmem_reg.h"
93 #endif
94
95 #if SOC_LP_TIMER_SUPPORTED
96 #include "hal/lp_timer_hal.h"
97 #endif
98
99 #if SOC_PMU_SUPPORTED
100 #include "esp_private/esp_pmu.h"
101 #include "esp_private/sleep_sys_periph.h"
102 #include "esp_private/sleep_clock.h"
103 #endif
104
105 #if SOC_PM_RETENTION_HAS_REGDMA_POWER_BUG
106 #include "esp_private/sleep_retention.h"
107 #endif
108
109 #if (CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND) && !CONFIG_IDF_TARGET_ESP32H2
110 #include "hal/cache_hal.h"
111 #endif
112
113 // If light sleep time is less than that, don't power down flash
114 #define FLASH_PD_MIN_SLEEP_TIME_US 2000
115
116 // Time from VDD_SDIO power up to first flash read in ROM code
117 #define VDD_SDIO_POWERUP_TO_FLASH_READ_US 700
118
119 // Cycles for RTC Timer clock source (internal oscillator) calibrate
120 #define RTC_CLK_SRC_CAL_CYCLES (10)
121 #define FAST_CLK_SRC_CAL_CYCLES (2048) /* ~ 127.4 us */
122
123 #ifdef CONFIG_IDF_TARGET_ESP32
124 #define DEFAULT_SLEEP_OUT_OVERHEAD_US (212)
125 #define DEFAULT_HARDWARE_OUT_OVERHEAD_US (60)
126 #elif CONFIG_IDF_TARGET_ESP32S2
127 #define DEFAULT_SLEEP_OUT_OVERHEAD_US (147)
128 #define DEFAULT_HARDWARE_OUT_OVERHEAD_US (28)
129 #elif CONFIG_IDF_TARGET_ESP32S3
130 #define DEFAULT_SLEEP_OUT_OVERHEAD_US (382)
131 #define DEFAULT_HARDWARE_OUT_OVERHEAD_US (133)
132 #elif CONFIG_IDF_TARGET_ESP32C3
133 #define DEFAULT_SLEEP_OUT_OVERHEAD_US (105)
134 #define DEFAULT_HARDWARE_OUT_OVERHEAD_US (37)
135 #elif CONFIG_IDF_TARGET_ESP32C2
136 #define DEFAULT_SLEEP_OUT_OVERHEAD_US (118)
137 #define DEFAULT_HARDWARE_OUT_OVERHEAD_US (9)
138 #elif CONFIG_IDF_TARGET_ESP32C6
139 #define DEFAULT_SLEEP_OUT_OVERHEAD_US (318)
140 #define DEFAULT_HARDWARE_OUT_OVERHEAD_US (56)
141 #elif CONFIG_IDF_TARGET_ESP32H2
142 #define DEFAULT_SLEEP_OUT_OVERHEAD_US (118)// TODO: IDF-6267
143 #define DEFAULT_HARDWARE_OUT_OVERHEAD_US (9)
144 #endif
145
146 // Actually costs 80us, using the fastest slow clock 150K calculation takes about 16 ticks
147 #define SLEEP_TIMER_ALARM_TO_SLEEP_TICKS (16)
148
149 #define SLEEP_UART_FLUSH_DONE_TO_SLEEP_US (450)
150
151 #if SOC_PM_SUPPORT_TOP_PD
152 // IDF console uses 8 bits data mode without parity, so each char occupy 8(data)+1(start)+1(stop)=10bits
153 #define UART_FLUSH_US_PER_CHAR (10*1000*1000 / CONFIG_ESP_CONSOLE_UART_BAUDRATE)
154 #define CONCATENATE_HELPER(x, y) (x##y)
155 #define CONCATENATE(x, y) CONCATENATE_HELPER(x, y)
156 #define CONSOLE_UART_DEV (&CONCATENATE(UART, CONFIG_ESP_CONSOLE_UART_NUM))
157 #endif
158
159 #define LIGHT_SLEEP_TIME_OVERHEAD_US DEFAULT_HARDWARE_OUT_OVERHEAD_US
160 #ifdef CONFIG_ESP_SYSTEM_RTC_EXT_XTAL
161 #define DEEP_SLEEP_TIME_OVERHEAD_US (650 + 100 * 240 / CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ)
162 #else
163 #define DEEP_SLEEP_TIME_OVERHEAD_US (250 + 100 * 240 / CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ)
164 #endif
165
166 #if CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY
167 #define DEEP_SLEEP_WAKEUP_DELAY CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY
168 #else
169 #define DEEP_SLEEP_WAKEUP_DELAY 0
170 #endif
171
172 // Minimal amount of time we can sleep for
173 #define LIGHT_SLEEP_MIN_TIME_US 200
174
175 #define RTC_MODULE_SLEEP_PREPARE_CYCLES (6)
176
177 #define CHECK_SOURCE(source, value, mask) ((s_config.wakeup_triggers & mask) && \
178 (source == value))
179
180 #define MAX_DSLP_HOOKS 3
181
182 static esp_deep_sleep_cb_t s_dslp_cb[MAX_DSLP_HOOKS]={0};
183
184 /**
185 * Internal structure which holds all requested deep sleep parameters
186 */
187 typedef struct {
188 struct {
189 esp_sleep_pd_option_t pd_option;
190 int16_t refs;
191 uint16_t reserved; /* reserved for 4 bytes aligned */
192 } domain[ESP_PD_DOMAIN_MAX];
193 int lock;
194 uint64_t sleep_duration;
195 uint32_t wakeup_triggers : 15;
196 #if SOC_PM_SUPPORT_EXT1_WAKEUP
197 uint32_t ext1_trigger_mode : 1;
198 uint32_t ext1_rtc_gpio_mask : 22; // 22 is the maximum RTCIO number in all chips
199 #endif
200 #if SOC_PM_SUPPORT_EXT0_WAKEUP
201 uint32_t ext0_trigger_level : 1;
202 uint32_t ext0_rtc_gpio_num : 5;
203 #endif
204 uint32_t gpio_wakeup_mask : 8; // 8 is the maximum RTCIO number in all chips that support GPIO wakeup
205 uint32_t gpio_trigger_mode : 8;
206 uint32_t sleep_time_adjustment;
207 uint32_t ccount_ticks_record;
208 uint32_t sleep_time_overhead_out;
209 uint32_t rtc_clk_cal_period;
210 uint32_t fast_clk_cal_period;
211 uint64_t rtc_ticks_at_sleep_start;
212 } sleep_config_t;
213
214
215 _Static_assert(22 >= SOC_RTCIO_PIN_COUNT, "Chip has more RTCIOs than 22, should increase ext1_rtc_gpio_mask field size");
216
217 static sleep_config_t s_config = {
218 .domain = {
219 [0 ... ESP_PD_DOMAIN_MAX - 1] = {
220 .pd_option = ESP_PD_OPTION_AUTO,
221 .refs = 0
222 }
223 },
224 .ccount_ticks_record = 0,
225 .sleep_time_overhead_out = DEFAULT_SLEEP_OUT_OVERHEAD_US,
226 .wakeup_triggers = 0
227 };
228
229 /* Internal variable used to track if light sleep wakeup sources are to be
230 expected when determining wakeup cause. */
231 static bool s_light_sleep_wakeup = false;
232
233 /* Updating RTC_MEMORY_CRC_REG register via set_rtc_memory_crc()
234 is not thread-safe, so we need to disable interrupts before going to deep sleep. */
235 static int spinlock_rtc_deep_sleep;
236 #define RTC_DEEP_SLEEP_ENTER_CRITICAL() do { spinlock_rtc_deep_sleep = irq_lock(); } while(0)
237 #define RTC_DEEP_SLEEP_EXIT_CRITICAL() irq_unlock(spinlock_rtc_deep_sleep);
238
239 static const char *TAG = "sleep";
240 static RTC_FAST_ATTR bool s_adc_tsen_enabled = false;
241 //in this mode, 2uA is saved, but RTC memory can't use at high temperature, and RTCIO can't be used as INPUT.
242 static bool s_ultra_low_enabled = false;
243
244 static bool s_periph_use_8m_flag = false;
245
esp_sleep_periph_use_8m(bool use_or_not)246 void esp_sleep_periph_use_8m(bool use_or_not)
247 {
248 s_periph_use_8m_flag = use_or_not;
249 }
250
251 static uint32_t get_power_down_flags(void);
252 #if SOC_PM_SUPPORT_EXT0_WAKEUP
253 static void ext0_wakeup_prepare(void);
254 #endif
255 #if SOC_PM_SUPPORT_EXT1_WAKEUP
256 static void ext1_wakeup_prepare(void);
257 #endif
258 static esp_err_t timer_wakeup_prepare(int64_t sleep_duration);
259 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
260 static void touch_wakeup_prepare(void);
261 #endif
262 #if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP
263 static void gpio_deep_sleep_wakeup_prepare(void);
264 #endif
265
266 #if !CONFIG_IDF_TARGET_ESP32H2
267 #if SOC_RTC_FAST_MEM_SUPPORTED
268 #if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
269 static RTC_FAST_ATTR esp_deep_sleep_wake_stub_fn_t wake_stub_fn_handler = NULL;
270
esp_wake_stub_start(void)271 static void RTC_IRAM_ATTR __attribute__((used, noinline)) esp_wake_stub_start(void)
272 {
273 if (wake_stub_fn_handler) {
274 (*wake_stub_fn_handler)();
275 }
276 }
277
278 /* We must have a default deep sleep wake stub entry function, which must be
279 * located at the start address of the RTC fast memory, and its implementation
280 * must be simple enough to ensure that there is no litteral data before the
281 * wake stub entry, otherwise, the litteral data before the wake stub entry
282 * will not be CRC checked. */
esp_wake_stub_entry(void)283 static void __attribute__((section(".rtc.entry.text"))) esp_wake_stub_entry(void)
284 {
285 #define _SYM2STR(s) # s
286 #define SYM2STR(s) _SYM2STR(s)
287
288 #ifdef __riscv
289 __asm__ __volatile__ (
290 "addi sp, sp, -16 \n"
291 "sw ra, 0(sp) \n"
292 "jal ra, " SYM2STR(esp_wake_stub_start) "\n"
293 "lw ra, 0(sp) \n"
294 "addi sp, sp, 16 \n"
295 );
296 #else
297 // call4 has a larger effective addressing range (-524284 to 524288 bytes),
298 // which is sufficient for instruction addressing in RTC fast memory.
299 __asm__ __volatile__ ("call4 " SYM2STR(esp_wake_stub_start) "\n");
300 #endif
301
302 }
303
esp_set_deep_sleep_wake_stub_default_entry(void)304 void RTC_IRAM_ATTR esp_set_deep_sleep_wake_stub_default_entry(void)
305 {
306 extern char _rtc_text_start[];
307 #if CONFIG_ESP32S3_RTCDATA_IN_FAST_MEM
308 extern char _rtc_noinit_end[];
309 size_t rtc_fast_length = (size_t)_rtc_noinit_end - (size_t)_rtc_text_start;
310 #else
311 extern char _rtc_force_fast_end[];
312 size_t rtc_fast_length = (size_t)_rtc_force_fast_end - (size_t)_rtc_text_start;
313 #endif
314 esp_rom_set_rtc_wake_addr((esp_rom_wake_func_t)esp_wake_stub_entry, rtc_fast_length);
315 }
316 #endif // SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
317
318 /* Wake from deep sleep stub
319 See esp_deepsleep.h esp_wake_deep_sleep() comments for details.
320 */
esp_get_deep_sleep_wake_stub(void)321 esp_deep_sleep_wake_stub_fn_t esp_get_deep_sleep_wake_stub(void)
322 {
323 #if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
324 esp_deep_sleep_wake_stub_fn_t stub_ptr = wake_stub_fn_handler;
325 #else
326 esp_deep_sleep_wake_stub_fn_t stub_ptr = (esp_deep_sleep_wake_stub_fn_t) REG_READ(RTC_ENTRY_ADDR_REG);
327 #endif
328 if (!esp_ptr_executable(stub_ptr)) {
329 return NULL;
330 }
331 return stub_ptr;
332 }
333
334 #if CONFIG_IDF_TARGET_ESP32
335 /* APP core of esp32 can't access to RTC FAST MEMORY, do not define it with RTC_IRAM_ATTR */
336 void
337 #else
338 void RTC_IRAM_ATTR
339 #endif
esp_set_deep_sleep_wake_stub(esp_deep_sleep_wake_stub_fn_t new_stub)340 esp_set_deep_sleep_wake_stub(esp_deep_sleep_wake_stub_fn_t new_stub)
341 {
342 #if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
343 wake_stub_fn_handler = new_stub;
344 #else
345 REG_WRITE(RTC_ENTRY_ADDR_REG, (uint32_t)new_stub);
346 #endif
347 }
348
esp_default_wake_deep_sleep(void)349 void RTC_IRAM_ATTR esp_default_wake_deep_sleep(void)
350 {
351 /* Clear MMU for CPU 0 */
352 #if CONFIG_IDF_TARGET_ESP32
353 _DPORT_REG_WRITE(DPORT_PRO_CACHE_CTRL1_REG,
354 _DPORT_REG_READ(DPORT_PRO_CACHE_CTRL1_REG) | DPORT_PRO_CACHE_MMU_IA_CLR);
355 _DPORT_REG_WRITE(DPORT_PRO_CACHE_CTRL1_REG,
356 _DPORT_REG_READ(DPORT_PRO_CACHE_CTRL1_REG) & (~DPORT_PRO_CACHE_MMU_IA_CLR));
357 #if DEEP_SLEEP_WAKEUP_DELAY > 0
358 // ROM code has not started yet, so we need to set delay factor
359 // used by esp_rom_delay_us first.
360 ets_update_cpu_frequency_rom(ets_get_detected_xtal_freq() / 1000000);
361 // This delay is configured in menuconfig, it can be used to give
362 // the flash chip some time to become ready.
363 esp_rom_delay_us(DEEP_SLEEP_WAKEUP_DELAY);
364 #endif
365 #elif CONFIG_IDF_TARGET_ESP32S2
366 REG_SET_BIT(EXTMEM_CACHE_DBG_INT_ENA_REG, EXTMEM_CACHE_DBG_EN);
367 #endif
368 }
369
370 void __attribute__((weak, alias("esp_default_wake_deep_sleep"))) esp_wake_deep_sleep(void);
371 #endif // SOC_RTC_FAST_MEM_SUPPORTED
372 #endif // !CONFIG_IDF_TARGET_ESP32H2
373
esp_deep_sleep(uint64_t time_in_us)374 void esp_deep_sleep(uint64_t time_in_us)
375 {
376 esp_sleep_enable_timer_wakeup(time_in_us);
377 esp_deep_sleep_start();
378 }
379
esp_deep_sleep_register_hook(esp_deep_sleep_cb_t new_dslp_cb)380 esp_err_t esp_deep_sleep_register_hook(esp_deep_sleep_cb_t new_dslp_cb)
381 {
382 RTC_DEEP_SLEEP_ENTER_CRITICAL();
383 for(int n = 0; n < MAX_DSLP_HOOKS; n++){
384 if (s_dslp_cb[n]==NULL || s_dslp_cb[n]==new_dslp_cb) {
385 s_dslp_cb[n]=new_dslp_cb;
386 RTC_DEEP_SLEEP_EXIT_CRITICAL();
387 return ESP_OK;
388 }
389 }
390 RTC_DEEP_SLEEP_EXIT_CRITICAL();
391 ESP_LOGE(TAG, "Registered deepsleep callbacks exceeds MAX_DSLP_HOOKS");
392 return ESP_ERR_NO_MEM;
393 }
394
esp_deep_sleep_deregister_hook(esp_deep_sleep_cb_t old_dslp_cb)395 void esp_deep_sleep_deregister_hook(esp_deep_sleep_cb_t old_dslp_cb)
396 {
397 RTC_DEEP_SLEEP_ENTER_CRITICAL();
398 for(int n = 0; n < MAX_DSLP_HOOKS; n++){
399 if(s_dslp_cb[n] == old_dslp_cb) {
400 s_dslp_cb[n] = NULL;
401 }
402 }
403 RTC_DEEP_SLEEP_EXIT_CRITICAL();
404 }
405
406 // [refactor-todo] provide target logic for body of uart functions below
flush_uarts(void)407 static void IRAM_ATTR flush_uarts(void)
408 {
409 for (int i = 0; i < SOC_UART_NUM; ++i) {
410 #ifdef CONFIG_IDF_TARGET_ESP32
411 esp_rom_uart_tx_wait_idle(i);
412 #else
413 if (periph_ll_periph_enabled(PERIPH_UART0_MODULE + i)) {
414 esp_rom_uart_tx_wait_idle(i);
415 }
416 #endif
417 }
418 }
419
420 static uint32_t s_suspended_uarts_bmap = 0;
421
422 /**
423 * Suspend enabled uarts and return suspended uarts bit map
424 */
suspend_uarts(void)425 static IRAM_ATTR void suspend_uarts(void)
426 {
427 s_suspended_uarts_bmap = 0;
428 for (int i = 0; i < SOC_UART_NUM; ++i) {
429 #ifndef CONFIG_IDF_TARGET_ESP32
430 if (!periph_ll_periph_enabled(PERIPH_UART0_MODULE + i)) {
431 continue;
432 }
433 #endif
434 uart_ll_force_xoff(i);
435 s_suspended_uarts_bmap |= BIT(i);
436 #if SOC_UART_SUPPORT_FSM_TX_WAIT_SEND
437 uint32_t uart_fsm = 0;
438 do {
439 uart_fsm = uart_ll_get_fsm_status(i);
440 } while (!(uart_fsm == UART_LL_FSM_IDLE || uart_fsm == UART_LL_FSM_TX_WAIT_SEND));
441 #else
442 while (uart_ll_get_fsm_status(i) != 0) {}
443 #endif
444 }
445 }
446
resume_uarts(void)447 static void IRAM_ATTR resume_uarts(void)
448 {
449 for (int i = 0; i < SOC_UART_NUM; ++i) {
450 if (s_suspended_uarts_bmap & 0x1) {
451 uart_ll_force_xon(i);
452 }
453 s_suspended_uarts_bmap >>= 1;
454 }
455 }
456
457 /*
458 UART prepare strategy in sleep:
459 Deepsleep : flush the fifo before enter sleep to avoid data loss
460
461 Lightsleep:
462 Chips not support PD_TOP: Suspend uart before cpu freq switch
463
464 Chips support PD_TOP:
465 For sleep which will not power down the TOP domain (uart belongs it), we can just suspend the UART.
466
467 For sleep which will power down the TOP domain, we need to consider whether the uart flushing will
468 block the sleep process and cause the rtos target tick to be missed upon waking up. It's need to
469 estimate the flush time based on the number of bytes in the uart FIFO, if the predicted flush
470 completion time has exceeded the wakeup time, we should abandon the flush, skip the sleep and
471 return ESP_ERR_SLEEP_REJECT.
472 */
light_sleep_uart_prepare(uint32_t pd_flags,int64_t sleep_duration)473 static bool light_sleep_uart_prepare(uint32_t pd_flags, int64_t sleep_duration)
474 {
475 bool should_skip_sleep = false;
476 #if !SOC_PM_SUPPORT_TOP_PD
477 suspend_uarts();
478 #else
479 if (pd_flags & PMU_SLEEP_PD_TOP) {
480 if ((s_config.wakeup_triggers & RTC_TIMER_TRIG_EN) &&
481 // +1 is for cover the last charactor flush time
482 (sleep_duration < (int64_t)((UART_LL_FIFO_DEF_LEN - uart_ll_get_txfifo_len(CONSOLE_UART_DEV) + 1) * UART_FLUSH_US_PER_CHAR) + SLEEP_UART_FLUSH_DONE_TO_SLEEP_US)) {
483 should_skip_sleep = true;
484 } else {
485 /* Only flush the uart_num configured to console, the transmission integrity of
486 other uarts is guaranteed by the UART driver */
487 esp_rom_uart_tx_wait_idle(CONFIG_ESP_CONSOLE_UART_NUM);
488 }
489 } else {
490 suspend_uarts();
491 }
492 #endif
493 return should_skip_sleep;
494 }
495
496 /**
497 * These save-restore workaround should be moved to lower layer
498 */
misc_modules_sleep_prepare(bool deep_sleep)499 inline static void IRAM_ATTR misc_modules_sleep_prepare(bool deep_sleep)
500 {
501 if (deep_sleep){
502 for (int n = 0; n < MAX_DSLP_HOOKS; n++) {
503 if (s_dslp_cb[n] != NULL) {
504 s_dslp_cb[n]();
505 }
506 }
507 } else {
508 #if CONFIG_MAC_BB_PD
509 mac_bb_power_down_cb_execute();
510 #endif
511 #if CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL
512 gpio_sleep_mode_config_apply();
513 #endif
514 #if SOC_PM_SUPPORT_CPU_PD && SOC_PM_CPU_RETENTION_BY_RTCCNTL
515 sleep_enable_cpu_retention();
516 #endif
517 #if REGI2C_ANA_CALI_PD_WORKAROUND
518 regi2c_analog_cali_reg_read();
519 #endif
520 #if SOC_PM_RETENTION_HAS_REGDMA_POWER_BUG
521 sleep_retention_do_system_retention(true);
522 #endif
523 }
524
525 // TODO: IDF-7370
526 if (!(deep_sleep && s_adc_tsen_enabled)){
527 sar_periph_ctrl_power_disable();
528 }
529 }
530
531 /**
532 * These save-restore workaround should be moved to lower layer
533 */
misc_modules_wake_prepare(void)534 inline static void IRAM_ATTR misc_modules_wake_prepare(void)
535 {
536 #if SOC_PM_RETENTION_HAS_REGDMA_POWER_BUG
537 sleep_retention_do_system_retention(false);
538 #endif
539 sar_periph_ctrl_power_enable();
540 #if SOC_PM_SUPPORT_CPU_PD && SOC_PM_CPU_RETENTION_BY_RTCCNTL
541 sleep_disable_cpu_retention();
542 #endif
543 #if CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL
544 gpio_sleep_mode_config_unapply();
545 #endif
546 #if CONFIG_MAC_BB_PD
547 mac_bb_power_up_cb_execute();
548 #endif
549 #if REGI2C_ANA_CALI_PD_WORKAROUND
550 regi2c_analog_cali_reg_write();
551 #endif
552 }
553
554 inline static uint32_t call_rtc_sleep_start(uint32_t reject_triggers, uint32_t lslp_mem_inf_fpu, bool dslp);
555
esp_sleep_start(uint32_t pd_flags,esp_sleep_mode_t mode)556 static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t mode)
557 {
558 // Stop UART output so that output is not lost due to APB frequency change.
559 // For light sleep, suspend UART output — it will resume after wakeup.
560 // For deep sleep, wait for the contents of UART FIFO to be sent.
561 bool deep_sleep = (mode == ESP_SLEEP_MODE_DEEP_SLEEP);
562 bool should_skip_sleep = false;
563
564 int64_t sleep_duration = (int64_t) s_config.sleep_duration - (int64_t) s_config.sleep_time_adjustment;
565
566 #if SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256
567 //Keep the RTC8M_CLK on if RTC clock is rc_fast_d256.
568 bool rtc_using_8md256 = (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256);
569 #else
570 bool rtc_using_8md256 = false;
571 #endif
572 //Keep the RTC8M_CLK on if the ledc low-speed channel is clocked by RTC8M_CLK in lightsleep mode
573 bool periph_using_8m = !deep_sleep && s_periph_use_8m_flag;
574
575 //Override user-configured power modes.
576 if (rtc_using_8md256 || periph_using_8m) {
577 pd_flags &= ~RTC_SLEEP_PD_INT_8M;
578 }
579
580 // Will switch to XTAL turn down MSPI speed
581 #if SOC_SPI_MEM_SUPPORT_TIME_TUNING
582 mspi_timing_change_speed_mode_cache_safe(true);
583 #endif
584
585 // Set mspi clock to a low-power one.
586 #if SOC_MEMSPI_CLOCK_IS_INDEPENDENT
587 spi_flash_set_clock_src(MSPI_CLK_SRC_ROM_DEFAULT);
588 #endif
589
590 // Sleep UART prepare
591 if (deep_sleep) {
592 flush_uarts();
593 } else {
594 should_skip_sleep = light_sleep_uart_prepare(pd_flags, sleep_duration);
595 }
596
597 // Save current frequency and switch to XTAL
598 rtc_cpu_freq_config_t cpu_freq_config;
599 rtc_clk_cpu_freq_get_config(&cpu_freq_config);
600 rtc_clk_cpu_freq_set_xtal();
601
602 #if SOC_PM_SUPPORT_EXT0_WAKEUP
603 // Configure pins for external wakeup
604 if (s_config.wakeup_triggers & RTC_EXT0_TRIG_EN) {
605 ext0_wakeup_prepare();
606 }
607 #endif
608 #if SOC_PM_SUPPORT_EXT1_WAKEUP
609 if (s_config.wakeup_triggers & RTC_EXT1_TRIG_EN) {
610 ext1_wakeup_prepare();
611 }
612 #endif
613
614 #if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP
615 if (deep_sleep && (s_config.wakeup_triggers & RTC_GPIO_TRIG_EN)) {
616 gpio_deep_sleep_wakeup_prepare();
617 }
618 #endif
619
620 #if CONFIG_ULP_COPROC_TYPE_FSM
621 // Enable ULP wakeup
622 if (s_config.wakeup_triggers & RTC_ULP_TRIG_EN) {
623 #ifdef CONFIG_IDF_TARGET_ESP32
624 rtc_hal_ulp_wakeup_enable();
625 #else
626 rtc_hal_ulp_int_clear();
627 #endif
628 }
629 #endif
630
631 misc_modules_sleep_prepare(deep_sleep);
632
633 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
634 if (deep_sleep) {
635 if (s_config.wakeup_triggers & RTC_TOUCH_TRIG_EN) {
636 touch_wakeup_prepare();
637 #if CONFIG_IDF_TARGET_ESP32S2
638 /* Workaround: In deep sleep, for ESP32S2, Power down the RTC_PERIPH will change the slope configuration of Touch sensor sleep pad.
639 * The configuration change will change the reading of the sleep pad, which will cause the touch wake-up sensor to trigger falsely.
640 */
641 pd_flags &= ~RTC_SLEEP_PD_RTC_PERIPH;
642 #endif
643 }
644 } else {
645 /* In light sleep, the RTC_PERIPH power domain should be in the power-on state (Power on the touch circuit in light sleep),
646 * otherwise the touch sensor FSM will be cleared, causing touch sensor false triggering.
647 */
648 if (touch_ll_get_fsm_state()) { // Check if the touch sensor is working properly.
649 pd_flags &= ~RTC_SLEEP_PD_RTC_PERIPH;
650 }
651 }
652 #endif
653
654 /* Enable sleep reject for faster return from this function,
655 * in case the wakeup is already triggerred.
656 */
657 uint32_t reject_triggers = (s_config.wakeup_triggers & RTC_SLEEP_REJECT_MASK) | sleep_modem_reject_triggers();
658
659 //Append some flags in addition to power domains
660 uint32_t sleep_flags = pd_flags;
661 if (s_adc_tsen_enabled) {
662 sleep_flags |= RTC_SLEEP_USE_ADC_TESEN_MONITOR;
663 }
664 if (!s_ultra_low_enabled) {
665 sleep_flags |= RTC_SLEEP_NO_ULTRA_LOW;
666 }
667 if (periph_using_8m) {
668 sleep_flags |= RTC_SLEEP_DIG_USE_8M;
669 }
670
671 // Enter sleep
672 esp_err_t result;
673 #if SOC_PMU_SUPPORTED
674 pmu_sleep_config_t config;
675 pmu_sleep_init(pmu_sleep_config_default(&config, pd_flags, s_config.sleep_time_adjustment,
676 s_config.rtc_clk_cal_period, s_config.fast_clk_cal_period,
677 deep_sleep), deep_sleep);
678 #else
679 rtc_sleep_config_t config;
680 rtc_sleep_get_default_config(sleep_flags, &config);
681 rtc_sleep_init(config);
682
683 // Set state machine time for light sleep
684 if (!deep_sleep) {
685 rtc_sleep_low_init(s_config.rtc_clk_cal_period);
686 }
687 #endif
688
689 // Configure timer wakeup
690 if (!should_skip_sleep && (s_config.wakeup_triggers & RTC_TIMER_TRIG_EN)) {
691 if (timer_wakeup_prepare(sleep_duration) != ESP_OK) {
692 should_skip_sleep = true;
693 }
694 }
695
696 #if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND
697 if (!(pd_flags & RTC_SLEEP_PD_XTAL)) {
698 rtc_sleep_systimer_enable(false);
699 }
700 #endif
701
702 if (should_skip_sleep) {
703 result = ESP_ERR_SLEEP_REJECT;
704 } else {
705 if (deep_sleep) {
706 #if !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
707 esp_sleep_isolate_digital_gpio();
708 #endif
709
710 #if !CONFIG_IDF_TARGET_ESP32H2 // TODO: IDF-6268
711 #if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
712 // Enter Deep Sleep
713 #if SOC_PMU_SUPPORTED
714 result = call_rtc_sleep_start(reject_triggers, config.power.hp_sys.dig_power.mem_dslp, deep_sleep);
715 #else
716 result = call_rtc_sleep_start(reject_triggers, config.lslp_mem_inf_fpu, deep_sleep);
717 #endif
718 #else
719 #if !CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP
720 /* If not possible stack is in RTC FAST memory, use the ROM function to calculate the CRC and save ~140 bytes IRAM */
721 #if SOC_RTC_FAST_MEM_SUPPORTED
722 set_rtc_memory_crc();
723 #endif
724 result = call_rtc_sleep_start(reject_triggers, config.lslp_mem_inf_fpu, deep_sleep);
725 #else
726 /* Otherwise, need to call the dedicated soc function for this */
727 result = rtc_deep_sleep_start(s_config.wakeup_triggers, reject_triggers);
728 #endif
729 #endif // SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
730 #else // !CONFIG_IDF_TARGET_ESP32H2
731 result = ESP_OK;
732 #endif // !CONFIG_IDF_TARGET_ESP32H2
733 } else {
734 /* On esp32c6, only the lp_aon pad hold function can only hold the GPIO state in the active mode.
735 In order to avoid the leakage of the SPI cs pin, hold it here */
736 #if (CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND)
737 #if !CONFIG_IDF_TARGET_ESP32H2 // ESP32H2 TODO IDF-7359: related rtcio ll func not supported yet
738 if(!(pd_flags & PMU_SLEEP_PD_VDDSDIO)) {
739 cache_hal_freeze(CACHE_TYPE_ALL);
740 gpio_ll_hold_en(&GPIO, SPI_CS0_GPIO_NUM);
741 }
742 #endif
743 #endif
744
745 #if SOC_PMU_SUPPORTED
746 #if SOC_PM_CPU_RETENTION_BY_SW
747 if (pd_flags & PMU_SLEEP_PD_CPU) {
748 result = esp_sleep_cpu_retention(pmu_sleep_start, s_config.wakeup_triggers, reject_triggers, config.power.hp_sys.dig_power.mem_dslp, deep_sleep);
749 } else {
750 #endif
751 result = call_rtc_sleep_start(reject_triggers, config.power.hp_sys.dig_power.mem_dslp, deep_sleep);
752 }
753 #else
754 result = call_rtc_sleep_start(reject_triggers, config.lslp_mem_inf_fpu, deep_sleep);
755 #endif
756
757 /* Unhold the SPI CS pin */
758 #if (CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND)
759 #if !CONFIG_IDF_TARGET_ESP32H2 // ESP32H2 TODO IDF-7359: related rtcio ll func not supported yet
760 if(!(pd_flags & PMU_SLEEP_PD_VDDSDIO)) {
761 gpio_ll_hold_dis(&GPIO, SPI_CS0_GPIO_NUM);
762 cache_hal_unfreeze(CACHE_TYPE_ALL);
763 }
764 #endif
765 #endif
766 }
767
768 #if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND
769 if (!(pd_flags & RTC_SLEEP_PD_XTAL)) {
770 rtc_sleep_systimer_enable(true);
771 }
772 #endif
773 }
774
775 // Restore CPU frequency
776 #if SOC_PM_SUPPORT_PMU_MODEM_STATE
777 if (pmu_sleep_pll_already_enabled()) {
778 rtc_clk_cpu_freq_to_pll_and_pll_lock_release(esp_pm_impl_get_cpu_freq(PM_MODE_CPU_MAX));
779 } else
780 #endif
781 {
782 rtc_clk_cpu_freq_set_config(&cpu_freq_config);
783 }
784
785 // Set mspi clock to ROM default one.
786 if (cpu_freq_config.source == SOC_CPU_CLK_SRC_PLL) {
787 #if SOC_MEMSPI_CLOCK_IS_INDEPENDENT
788 spi_flash_set_clock_src(MSPI_CLK_SRC_DEFAULT);
789 #endif
790 #if SOC_SPI_MEM_SUPPORT_TIME_TUNING
791 // Turn up MSPI speed if switch to PLL
792 mspi_timing_change_speed_mode_cache_safe(false);
793 #endif
794 }
795
796 if (!deep_sleep) {
797 s_config.ccount_ticks_record = esp_cpu_get_cycle_count();
798 misc_modules_wake_prepare();
799 }
800
801 // re-enable UART output
802 resume_uarts();
803 return result ? ESP_ERR_SLEEP_REJECT : ESP_OK;
804 }
805
call_rtc_sleep_start(uint32_t reject_triggers,uint32_t lslp_mem_inf_fpu,bool dslp)806 inline static uint32_t IRAM_ATTR call_rtc_sleep_start(uint32_t reject_triggers, uint32_t lslp_mem_inf_fpu, bool dslp)
807 {
808 #ifdef CONFIG_IDF_TARGET_ESP32
809 return rtc_sleep_start(s_config.wakeup_triggers, reject_triggers);
810 #elif SOC_PMU_SUPPORTED
811 return pmu_sleep_start(s_config.wakeup_triggers, reject_triggers, lslp_mem_inf_fpu, dslp);
812 #else
813 return rtc_sleep_start(s_config.wakeup_triggers, reject_triggers, lslp_mem_inf_fpu);
814 #endif
815 }
816
esp_deep_sleep_start(void)817 void IRAM_ATTR esp_deep_sleep_start(void)
818 {
819 #if CONFIG_IDF_TARGET_ESP32S2
820 /* Due to hardware limitations, on S2 the brownout detector sometimes trigger during deep sleep
821 to circumvent this we disable the brownout detector before sleeping */
822 esp_brownout_disable();
823 #endif //CONFIG_IDF_TARGET_ESP32S2
824
825 /* Disable interrupts and stall another core in case another task writes
826 * to RTC memory while we calculate RTC memory CRC.
827 */
828 RTC_DEEP_SLEEP_ENTER_CRITICAL();
829
830 // record current RTC time
831 s_config.rtc_ticks_at_sleep_start = rtc_time_get();
832
833 // Decide which power domains can be powered down
834 uint32_t pd_flags = get_power_down_flags();
835
836 s_config.rtc_clk_cal_period = esp_clk_slowclk_cal_get();
837
838 // Correct the sleep time
839 s_config.sleep_time_adjustment = DEEP_SLEEP_TIME_OVERHEAD_US;
840
841 #if SOC_PMU_SUPPORTED
842 uint32_t force_pd_flags = PMU_SLEEP_PD_TOP | PMU_SLEEP_PD_VDDSDIO | PMU_SLEEP_PD_MODEM | PMU_SLEEP_PD_HP_PERIPH \
843 | PMU_SLEEP_PD_CPU | PMU_SLEEP_PD_MEM | PMU_SLEEP_PD_XTAL;
844 #else
845 uint32_t force_pd_flags = RTC_SLEEP_PD_DIG | RTC_SLEEP_PD_VDDSDIO | RTC_SLEEP_PD_INT_8M | RTC_SLEEP_PD_XTAL;
846 #endif
847 /**
848 * If all wireless modules share one power domain, we name this power domain "modem".
849 * If wireless modules have their own power domain, we give these power domains separate
850 * names.
851 */
852 #if SOC_PM_SUPPORT_MODEM_PD
853 force_pd_flags |= RTC_SLEEP_PD_MODEM;
854 #endif
855
856 #if SOC_PM_SUPPORT_WIFI_PD
857 force_pd_flags |= RTC_SLEEP_PD_WIFI;
858 #endif
859
860 #if SOC_PM_SUPPORT_BT_PD
861 force_pd_flags |= RTC_SLEEP_PD_BT;
862 #endif
863
864 // Enter sleep
865 if (esp_sleep_start(force_pd_flags | pd_flags, ESP_SLEEP_MODE_DEEP_SLEEP) == ESP_ERR_SLEEP_REJECT) {
866 ESP_EARLY_LOGW(TAG, "Deep sleep request is rejected");
867 }
868
869 // Because RTC is in a slower clock domain than the CPU, it
870 // can take several CPU cycles for the sleep mode to start.
871 while (1) {
872 ;
873 }
874 // Never returns here
875 RTC_DEEP_SLEEP_EXIT_CRITICAL();
876 }
877
878 /**
879 * Helper function which handles entry to and exit from light sleep
880 * Placed into IRAM as flash may need some time to be powered on.
881 */
882 static esp_err_t esp_light_sleep_inner(uint32_t pd_flags,
883 uint32_t flash_enable_time_us) IRAM_ATTR __attribute__((noinline));
884
esp_light_sleep_inner(uint32_t pd_flags,uint32_t flash_enable_time_us)885 static esp_err_t esp_light_sleep_inner(uint32_t pd_flags,
886 uint32_t flash_enable_time_us)
887 {
888 // Enter sleep
889 esp_err_t reject = esp_sleep_start(pd_flags, ESP_SLEEP_MODE_LIGHT_SLEEP);
890
891 #if SOC_CONFIGURABLE_VDDSDIO_SUPPORTED
892 rtc_vddsdio_config_t vddsdio_config = rtc_vddsdio_get_config();
893 // If VDDSDIO regulator was controlled by RTC registers before sleep,
894 // restore the configuration.
895 if (vddsdio_config.force) {
896 rtc_vddsdio_set_config(vddsdio_config);
897 }
898 #endif
899
900 // If SPI flash was powered down, wait for it to become ready
901 if (pd_flags & RTC_SLEEP_PD_VDDSDIO) {
902 // Wait for the flash chip to start up
903 esp_rom_delay_us(flash_enable_time_us);
904 }
905
906 return reject;
907 }
908
909 /**
910 * vddsdio is used for power supply of spi flash
911 *
912 * pd flash via menuconfig | pd flash via `esp_sleep_pd_config` | result
913 * ---------------------------------------------------------------------------------------------------
914 * 0 | 0 | no pd flash
915 * x | 1 | pd flash with relaxed conditions(force_pd)
916 * 1 | 0 | pd flash with strict conditions(safe_pd)
917 */
can_power_down_vddsdio(uint32_t pd_flags,const uint32_t vddsdio_pd_sleep_duration)918 static inline bool can_power_down_vddsdio(uint32_t pd_flags, const uint32_t vddsdio_pd_sleep_duration)
919 {
920 bool force_pd = !(s_config.wakeup_triggers & RTC_TIMER_TRIG_EN) || (s_config.sleep_duration > vddsdio_pd_sleep_duration);
921 bool safe_pd = (s_config.wakeup_triggers == RTC_TIMER_TRIG_EN) && (s_config.sleep_duration > vddsdio_pd_sleep_duration);
922 return (pd_flags & RTC_SLEEP_PD_VDDSDIO) ? force_pd : safe_pd;
923 }
924
esp_light_sleep_start(void)925 esp_err_t esp_light_sleep_start(void)
926 {
927 s_config.ccount_ticks_record = esp_cpu_get_cycle_count();
928 #if CONFIG_ESP_TASK_WDT_USE_ESP_TIMER
929 esp_err_t timerret = ESP_OK;
930
931 /* If a task watchdog timer is running, we have to stop it. */
932 timerret = esp_task_wdt_stop();
933 #endif // CONFIG_ESP_TASK_WDT_USE_ESP_TIMER
934
935 s_config.lock = irq_lock();
936 /*
937 Note: We are about to stall the other CPU via the esp_ipc_isr_stall_other_cpu(). However, there is a chance of
938 deadlock if after stalling the other CPU, we attempt to take spinlocks already held by the other CPU that is.
939
940 Thus any functions that we call after stalling the other CPU will need to have the locks taken first to avoid
941 deadlock.
942
943 Todo: IDF-5257
944 */
945
946 /* We will be calling esp_timer_private_set inside DPORT access critical
947 * section. Make sure the code on the other CPU is not holding esp_timer
948 * lock, otherwise there will be deadlock.
949 */
950 esp_timer_private_lock();
951
952 /* We will be calling esp_rtc_get_time_us() below. Make sure the code on the other CPU is not holding the
953 * esp_rtc_get_time_us() lock, otherwise there will be deadlock. esp_rtc_get_time_us() is called via:
954 *
955 * - esp_clk_slowclk_cal_set() -> esp_rtc_get_time_us()
956 */
957 esp_clk_private_lock();
958
959 #if SOC_LP_TIMER_SUPPORTED
960 s_config.rtc_ticks_at_sleep_start = lp_timer_hal_get_cycle_count();
961 #else
962 s_config.rtc_ticks_at_sleep_start = rtc_time_get();
963 #endif
964 uint32_t ccount_at_sleep_start = esp_cpu_get_cycle_count();
965 uint64_t high_res_time_at_start = esp_timer_get_time();
966 uint32_t sleep_time_overhead_in = (ccount_at_sleep_start - s_config.ccount_ticks_record) / (esp_clk_cpu_freq() / 1000000ULL);
967
968 // Decide which power domains can be powered down
969 uint32_t pd_flags = get_power_down_flags();
970
971
972 #if CONFIG_SOC_SERIES_ESP32 || CONFIG_SOC_SERIES_ESP32S2 || CONFIG_SOC_SERIES_ESP32S3
973 pd_flags &= ~RTC_SLEEP_PD_RTC_PERIPH;
974 #endif
975
976 // Re-calibrate the RTC Timer clock
977 #ifdef CONFIG_ESP_SYSTEM_RTC_EXT_XTAL
978 if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
979 uint64_t time_per_us = 1000000ULL;
980 s_config.rtc_clk_cal_period = (time_per_us << RTC_CLK_CAL_FRACT) / rtc_clk_slow_freq_get_hz();
981 } else {
982 // If the external 32 kHz XTAL does not exist, use the internal 150 kHz RC oscillator
983 // as the RTC slow clock source.
984 s_config.rtc_clk_cal_period = rtc_clk_cal(RTC_CAL_RTC_MUX, RTC_CLK_SRC_CAL_CYCLES);
985 esp_clk_slowclk_cal_set(s_config.rtc_clk_cal_period);
986 }
987 #elif CONFIG_RTC_CLK_SRC_INT_RC && CONFIG_IDF_TARGET_ESP32S2
988 s_config.rtc_clk_cal_period = rtc_clk_cal_cycling(RTC_CAL_RTC_MUX, RTC_CLK_SRC_CAL_CYCLES);
989 esp_clk_slowclk_cal_set(s_config.rtc_clk_cal_period);
990 #else
991 s_config.rtc_clk_cal_period = rtc_clk_cal(RTC_CAL_RTC_MUX, RTC_CLK_SRC_CAL_CYCLES);
992 esp_clk_slowclk_cal_set(s_config.rtc_clk_cal_period);
993 #endif
994
995 /*
996 * Adjustment time consists of parts below:
997 * 1. Hardware time waiting for internal 8M oscilate clock and XTAL;
998 * 2. Hardware state swithing time of the rtc main state machine;
999 * 3. Code execution time when clock is not stable;
1000 * 4. Code execution time which can be measured;
1001 */
1002
1003 #if SOC_PMU_SUPPORTED
1004 s_config.fast_clk_cal_period = rtc_clk_cal(RTC_CAL_RC_FAST, FAST_CLK_SRC_CAL_CYCLES);
1005 int sleep_time_sw_adjustment = LIGHT_SLEEP_TIME_OVERHEAD_US + sleep_time_overhead_in + s_config.sleep_time_overhead_out;
1006 int sleep_time_hw_adjustment = pmu_sleep_calculate_hw_wait_time(pd_flags, s_config.rtc_clk_cal_period, s_config.fast_clk_cal_period);
1007 s_config.sleep_time_adjustment = sleep_time_sw_adjustment + sleep_time_hw_adjustment;
1008 #else
1009 uint32_t rtc_cntl_xtl_buf_wait_slp_cycles = rtc_time_us_to_slowclk(RTC_CNTL_XTL_BUF_WAIT_SLP_US, s_config.rtc_clk_cal_period);
1010 s_config.sleep_time_adjustment = LIGHT_SLEEP_TIME_OVERHEAD_US + sleep_time_overhead_in + s_config.sleep_time_overhead_out
1011 + rtc_time_slowclk_to_us(rtc_cntl_xtl_buf_wait_slp_cycles + RTC_CNTL_CK8M_WAIT_SLP_CYCLES + RTC_CNTL_WAKEUP_DELAY_CYCLES, s_config.rtc_clk_cal_period);
1012 #endif
1013
1014 #if CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-6930
1015 const uint32_t flash_enable_time_us = 0;
1016 #else
1017 // Decide if VDD_SDIO needs to be powered down;
1018 // If it needs to be powered down, adjust sleep time.
1019 const uint32_t flash_enable_time_us = VDD_SDIO_POWERUP_TO_FLASH_READ_US + DEEP_SLEEP_WAKEUP_DELAY;
1020
1021 /**
1022 * If VDD_SDIO power domain is requested to be turned off, bit `RTC_SLEEP_PD_VDDSDIO`
1023 * will be set in `pd_flags`.
1024 */
1025 if (pd_flags & RTC_SLEEP_PD_VDDSDIO) {
1026 /*
1027 * When VDD_SDIO power domain has to be turned off, the minimum sleep time of the
1028 * system needs to meet the sum below:
1029 * 1. Wait time for the flash power-on after waking up;
1030 * 2. The execution time of codes between RTC Timer get start time
1031 * with hardware starts to switch state to sleep;
1032 * 3. The hardware state switching time of the rtc state machine during
1033 * sleep and wake-up. This process requires 6 cycles to complete.
1034 * The specific hardware state switching process and the cycles
1035 * consumed are rtc_cpu_run_stall(1), cut_pll_rtl(2), cut_8m(1),
1036 * min_protect(2);
1037 * 4. All the adjustment time which is s_config.sleep_time_adjustment below.
1038 */
1039 const uint32_t vddsdio_pd_sleep_duration = MAX(FLASH_PD_MIN_SLEEP_TIME_US,
1040 flash_enable_time_us + LIGHT_SLEEP_MIN_TIME_US + s_config.sleep_time_adjustment
1041 + rtc_time_slowclk_to_us(RTC_MODULE_SLEEP_PREPARE_CYCLES, s_config.rtc_clk_cal_period));
1042
1043 if (can_power_down_vddsdio(pd_flags, vddsdio_pd_sleep_duration)) {
1044 if (s_config.sleep_time_overhead_out < flash_enable_time_us) {
1045 s_config.sleep_time_adjustment += flash_enable_time_us;
1046 }
1047 } else {
1048 /**
1049 * Minimum sleep time is not enough, then keep the VDD_SDIO power
1050 * domain on.
1051 */
1052 pd_flags &= ~RTC_SLEEP_PD_VDDSDIO;
1053 if (s_config.sleep_time_overhead_out > flash_enable_time_us) {
1054 s_config.sleep_time_adjustment -= flash_enable_time_us;
1055 }
1056 }
1057 }
1058 #endif
1059
1060 periph_inform_out_light_sleep_overhead(s_config.sleep_time_adjustment - sleep_time_overhead_in);
1061
1062 // Safety net: enable WDT in case exit from light sleep fails
1063 wdt_hal_context_t rtc_wdt_ctx = RWDT_HAL_CONTEXT_DEFAULT();
1064 bool wdt_was_enabled = wdt_hal_is_enabled(&rtc_wdt_ctx); // If WDT was enabled in the user code, then do not change it here.
1065 if (!wdt_was_enabled) {
1066 wdt_hal_init(&rtc_wdt_ctx, WDT_RWDT, 0, false);
1067 uint32_t stage_timeout_ticks = (uint32_t)(1000ULL * rtc_clk_slow_freq_get_hz() / 1000ULL);
1068 wdt_hal_write_protect_disable(&rtc_wdt_ctx);
1069 wdt_hal_config_stage(&rtc_wdt_ctx, WDT_STAGE0, stage_timeout_ticks, WDT_STAGE_ACTION_RESET_RTC);
1070 wdt_hal_enable(&rtc_wdt_ctx);
1071 wdt_hal_write_protect_enable(&rtc_wdt_ctx);
1072 }
1073
1074 esp_err_t err = ESP_OK;
1075 int64_t final_sleep_duration_us = (int64_t)s_config.sleep_duration - (int64_t)s_config.sleep_time_adjustment;
1076 int64_t min_sleep_duration_us = rtc_time_slowclk_to_us(RTC_CNTL_MIN_SLP_VAL_MIN, s_config.rtc_clk_cal_period);
1077
1078 // reset light sleep wakeup flag before a new light sleep
1079 s_light_sleep_wakeup = false;
1080
1081 // if rtc timer wakeup source is enabled, need to compare final sleep duration and min sleep duration to avoid late wakeup
1082 if ((s_config.wakeup_triggers & RTC_TIMER_TRIG_EN) && (final_sleep_duration_us <= min_sleep_duration_us)) {
1083 err = ESP_ERR_SLEEP_TOO_SHORT_SLEEP_DURATION;
1084 } else {
1085 // Enter sleep, then wait for flash to be ready on wakeup
1086 err = esp_light_sleep_inner(pd_flags, flash_enable_time_us);
1087 }
1088
1089 // light sleep wakeup flag only makes sense after a successful light sleep
1090 s_light_sleep_wakeup = (err == ESP_OK);
1091
1092 // System timer has been stopped for the duration of the sleep, correct for that.
1093 #if SOC_LP_TIMER_SUPPORTED
1094 uint64_t rtc_ticks_at_end = lp_timer_hal_get_cycle_count();
1095 #else
1096 uint64_t rtc_ticks_at_end = rtc_time_get();
1097 #endif
1098 uint64_t rtc_time_diff = rtc_time_slowclk_to_us(rtc_ticks_at_end - s_config.rtc_ticks_at_sleep_start, s_config.rtc_clk_cal_period);
1099
1100 /**
1101 * If sleep duration is too small(less than 1 rtc_slow_clk cycle), rtc_time_diff will be zero.
1102 * In this case, just ignore the time compensation and keep esp_timer monotonic.
1103 */
1104 if (rtc_time_diff > 0) {
1105 esp_timer_private_set(high_res_time_at_start + rtc_time_diff);
1106 sys_clock_announce((rtc_time_diff * CONFIG_SYS_CLOCK_TICKS_PER_SEC) / USEC_PER_SEC);
1107 }
1108
1109 esp_clk_private_unlock();
1110 esp_timer_private_unlock();
1111
1112 if (!wdt_was_enabled) {
1113 wdt_hal_write_protect_disable(&rtc_wdt_ctx);
1114 wdt_hal_disable(&rtc_wdt_ctx);
1115 wdt_hal_write_protect_enable(&rtc_wdt_ctx);
1116 }
1117 irq_unlock(s_config.lock);
1118
1119 #if CONFIG_ESP_TASK_WDT_USE_ESP_TIMER
1120 /* Restart the Task Watchdog timer as it was stopped before sleeping. */
1121 if (timerret == ESP_OK) {
1122 esp_task_wdt_restart();
1123 }
1124 #endif // CONFIG_ESP_TASK_WDT_USE_ESP_TIMER
1125
1126 s_config.sleep_time_overhead_out = (esp_cpu_get_cycle_count() - s_config.ccount_ticks_record) / (esp_clk_cpu_freq() / 1000000ULL);
1127 return err;
1128 }
1129
esp_sleep_disable_wakeup_source(esp_sleep_source_t source)1130 esp_err_t esp_sleep_disable_wakeup_source(esp_sleep_source_t source)
1131 {
1132 // For most of sources it is enough to set trigger mask in local
1133 // configuration structure. The actual RTC wake up options
1134 // will be updated by esp_sleep_start().
1135 if (source == ESP_SLEEP_WAKEUP_ALL) {
1136 s_config.wakeup_triggers = 0;
1137 } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_TIMER, RTC_TIMER_TRIG_EN)) {
1138 s_config.wakeup_triggers &= ~RTC_TIMER_TRIG_EN;
1139 s_config.sleep_duration = 0;
1140 #if SOC_PM_SUPPORT_EXT0_WAKEUP
1141 } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_EXT0, RTC_EXT0_TRIG_EN)) {
1142 s_config.ext0_rtc_gpio_num = 0;
1143 s_config.ext0_trigger_level = 0;
1144 s_config.wakeup_triggers &= ~RTC_EXT0_TRIG_EN;
1145 #endif
1146 #if SOC_PM_SUPPORT_EXT1_WAKEUP
1147 } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_EXT1, RTC_EXT1_TRIG_EN)) {
1148 s_config.ext1_rtc_gpio_mask = 0;
1149 s_config.ext1_trigger_mode = 0;
1150 s_config.wakeup_triggers &= ~RTC_EXT1_TRIG_EN;
1151 #endif
1152 #if SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP
1153 } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_TOUCHPAD, RTC_TOUCH_TRIG_EN)) {
1154 s_config.wakeup_triggers &= ~RTC_TOUCH_TRIG_EN;
1155 #endif
1156 } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_GPIO, RTC_GPIO_TRIG_EN)) {
1157 s_config.wakeup_triggers &= ~RTC_GPIO_TRIG_EN;
1158 } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_UART, (RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN))) {
1159 s_config.wakeup_triggers &= ~(RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN);
1160 }
1161 #if CONFIG_ULP_COPROC_TYPE_FSM
1162 else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_ULP, RTC_ULP_TRIG_EN)) {
1163 s_config.wakeup_triggers &= ~RTC_ULP_TRIG_EN;
1164 }
1165 #endif
1166 else {
1167 ESP_LOGE(TAG, "Incorrect wakeup source (%d) to disable.", (int) source);
1168 return ESP_ERR_INVALID_STATE;
1169 }
1170 return ESP_OK;
1171 }
1172
esp_sleep_enable_ulp_wakeup(void)1173 esp_err_t esp_sleep_enable_ulp_wakeup(void)
1174 {
1175 #ifndef CONFIG_ULP_COPROC_ENABLED
1176 return ESP_ERR_INVALID_STATE;
1177 #endif // CONFIG_ULP_COPROC_ENABLED
1178 #if CONFIG_IDF_TARGET_ESP32
1179 #if ((defined CONFIG_RTC_EXT_CRYST_ADDIT_CURRENT) || (defined CONFIG_RTC_EXT_CRYST_ADDIT_CURRENT_V2))
1180 ESP_LOGE(TAG, "Failed to enable wakeup when provide current to external 32kHz crystal");
1181 return ESP_ERR_NOT_SUPPORTED;
1182 #endif
1183 if (s_config.wakeup_triggers & RTC_EXT0_TRIG_EN) {
1184 ESP_LOGE(TAG, "Conflicting wake-up trigger: ext0");
1185 return ESP_ERR_INVALID_STATE;
1186 }
1187 #endif //CONFIG_IDF_TARGET_ESP32
1188
1189 #if CONFIG_ULP_COPROC_TYPE_FSM
1190 s_config.wakeup_triggers |= RTC_ULP_TRIG_EN;
1191 return ESP_OK;
1192 #elif CONFIG_ULP_COPROC_TYPE_RISCV
1193 s_config.wakeup_triggers |= (RTC_COCPU_TRIG_EN | RTC_COCPU_TRAP_TRIG_EN);
1194 return ESP_OK;
1195 #elif CONFIG_ULP_COPROC_TYPE_LP_CORE
1196 s_config.wakeup_triggers |= RTC_LP_CORE_TRIG_EN;
1197 return ESP_OK;
1198 #else
1199 return ESP_ERR_NOT_SUPPORTED;
1200 #endif //CONFIG_ULP_COPROC_TYPE_FSM
1201 }
1202
esp_sleep_enable_timer_wakeup(uint64_t time_in_us)1203 esp_err_t esp_sleep_enable_timer_wakeup(uint64_t time_in_us)
1204 {
1205 s_config.wakeup_triggers |= RTC_TIMER_TRIG_EN;
1206 s_config.sleep_duration = time_in_us;
1207 return ESP_OK;
1208 }
1209
timer_wakeup_prepare(int64_t sleep_duration)1210 static esp_err_t timer_wakeup_prepare(int64_t sleep_duration)
1211 {
1212 if (sleep_duration < 0) {
1213 sleep_duration = 0;
1214 }
1215
1216 int64_t ticks = rtc_time_us_to_slowclk(sleep_duration, s_config.rtc_clk_cal_period);
1217 int64_t target_wakeup_tick = s_config.rtc_ticks_at_sleep_start + ticks;
1218
1219 #if SOC_LP_TIMER_SUPPORTED
1220 #if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
1221 // Last timer wake-up validity check
1222 if ((sleep_duration == 0) || \
1223 (target_wakeup_tick < lp_timer_hal_get_cycle_count() + SLEEP_TIMER_ALARM_TO_SLEEP_TICKS)) {
1224 // Treat too short sleep duration setting as timer reject
1225 return ESP_ERR_SLEEP_REJECT;
1226 }
1227 #endif
1228 lp_timer_hal_set_alarm_target(0, target_wakeup_tick);
1229 #else
1230 rtc_hal_set_wakeup_timer(target_wakeup_tick);
1231 #endif
1232
1233 return ESP_OK;
1234 }
1235
1236 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
1237 /* In deep sleep mode, only the sleep channel is supported, and other touch channels should be turned off. */
touch_wakeup_prepare(void)1238 static void touch_wakeup_prepare(void)
1239 {
1240 uint16_t sleep_cycle = 0;
1241 uint16_t meas_times = 0;
1242 touch_pad_t touch_num = TOUCH_PAD_NUM0;
1243 touch_ll_sleep_get_channel_num(&touch_num); // Check if the sleep pad is enabled.
1244 if ((touch_num > TOUCH_PAD_NUM0) && (touch_num < TOUCH_PAD_MAX) && touch_ll_get_fsm_state()) {
1245 touch_ll_stop_fsm();
1246 touch_ll_clear_channel_mask(TOUCH_PAD_BIT_MASK_ALL);
1247 touch_ll_intr_clear(TOUCH_PAD_INTR_MASK_ALL); // Clear state from previous wakeup
1248 touch_hal_sleep_channel_get_work_time(&sleep_cycle, &meas_times);
1249 touch_ll_set_meas_times(meas_times);
1250 touch_ll_set_sleep_time(sleep_cycle);
1251 touch_ll_set_channel_mask(BIT(touch_num));
1252 touch_ll_start_fsm();
1253 }
1254 }
1255 #endif
1256
1257 #if SOC_TOUCH_SENSOR_SUPPORTED
1258
esp_sleep_enable_touchpad_wakeup(void)1259 esp_err_t esp_sleep_enable_touchpad_wakeup(void)
1260 {
1261 #if CONFIG_IDF_TARGET_ESP32
1262 #if ((defined CONFIG_RTC_EXT_CRYST_ADDIT_CURRENT) || (defined CONFIG_RTC_EXT_CRYST_ADDIT_CURRENT_V2))
1263 ESP_LOGE(TAG, "Failed to enable wakeup when provide current to external 32kHz crystal");
1264 return ESP_ERR_NOT_SUPPORTED;
1265 #endif
1266 if (s_config.wakeup_triggers & (RTC_EXT0_TRIG_EN)) {
1267 ESP_LOGE(TAG, "Conflicting wake-up trigger: ext0");
1268 return ESP_ERR_INVALID_STATE;
1269 }
1270 #endif //CONFIG_IDF_TARGET_ESP32
1271
1272 s_config.wakeup_triggers |= RTC_TOUCH_TRIG_EN;
1273 return ESP_OK;
1274 }
1275
esp_sleep_get_touchpad_wakeup_status(void)1276 touch_pad_t esp_sleep_get_touchpad_wakeup_status(void)
1277 {
1278 if (esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_TOUCHPAD) {
1279 return TOUCH_PAD_MAX;
1280 }
1281 touch_pad_t pad_num;
1282 esp_err_t ret = touch_pad_get_wakeup_status(&pad_num); //TODO 723diff commit id:fda9ada1b
1283 assert(ret == ESP_OK && "wakeup reason is RTC_TOUCH_TRIG_EN but SENS_TOUCH_MEAS_EN is zero");
1284 return (ret == ESP_OK) ? pad_num : TOUCH_PAD_MAX;
1285 }
1286
1287 #endif // SOC_TOUCH_SENSOR_SUPPORTED
1288
esp_sleep_is_valid_wakeup_gpio(gpio_num_t gpio_num)1289 bool esp_sleep_is_valid_wakeup_gpio(gpio_num_t gpio_num)
1290 {
1291 #if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
1292 return RTC_GPIO_IS_VALID_GPIO(gpio_num);
1293 #else
1294 return GPIO_IS_DEEP_SLEEP_WAKEUP_VALID_GPIO(gpio_num);
1295 #endif // SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
1296 }
1297
1298 #if SOC_PM_SUPPORT_EXT0_WAKEUP
esp_sleep_enable_ext0_wakeup(gpio_num_t gpio_num,int level)1299 esp_err_t esp_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level)
1300 {
1301 if (level < 0 || level > 1) {
1302 return ESP_ERR_INVALID_ARG;
1303 }
1304 if (!esp_sleep_is_valid_wakeup_gpio(gpio_num)) {
1305 return ESP_ERR_INVALID_ARG;
1306 }
1307 #if CONFIG_IDF_TARGET_ESP32
1308 if (s_config.wakeup_triggers & (RTC_TOUCH_TRIG_EN | RTC_ULP_TRIG_EN)) {
1309 ESP_LOGE(TAG, "Conflicting wake-up triggers: touch / ULP");
1310 return ESP_ERR_INVALID_STATE;
1311 }
1312 #endif //CONFIG_IDF_TARGET_ESP32
1313
1314 s_config.ext0_rtc_gpio_num = rtc_io_number_get(gpio_num);
1315 s_config.ext0_trigger_level = level;
1316 s_config.wakeup_triggers |= RTC_EXT0_TRIG_EN;
1317 return ESP_OK;
1318 }
1319
ext0_wakeup_prepare(void)1320 static void ext0_wakeup_prepare(void)
1321 {
1322 int rtc_gpio_num = s_config.ext0_rtc_gpio_num;
1323 rtcio_hal_ext0_set_wakeup_pin(rtc_gpio_num, s_config.ext0_trigger_level);
1324 rtcio_hal_function_select(rtc_gpio_num, RTCIO_FUNC_RTC);
1325 rtcio_hal_input_enable(rtc_gpio_num);
1326 }
1327 #endif // SOC_PM_SUPPORT_EXT0_WAKEUP
1328
1329 #if SOC_PM_SUPPORT_EXT1_WAKEUP
esp_sleep_enable_ext1_wakeup(uint64_t mask,esp_sleep_ext1_wakeup_mode_t mode)1330 esp_err_t esp_sleep_enable_ext1_wakeup(uint64_t mask, esp_sleep_ext1_wakeup_mode_t mode)
1331 {
1332 if (mode > ESP_EXT1_WAKEUP_ANY_HIGH) {
1333 return ESP_ERR_INVALID_ARG;
1334 }
1335 // Translate bit map of GPIO numbers into the bit map of RTC IO numbers
1336 uint32_t rtc_gpio_mask = 0;
1337 for (int gpio = 0; mask; ++gpio, mask >>= 1) {
1338 if ((mask & 1) == 0) {
1339 continue;
1340 }
1341 if (!esp_sleep_is_valid_wakeup_gpio(gpio)) {
1342 ESP_LOGE(TAG, "Not an RTC IO: GPIO%d", gpio);
1343 return ESP_ERR_INVALID_ARG;
1344 }
1345 rtc_gpio_mask |= BIT(rtc_io_number_get(gpio));
1346 }
1347 s_config.ext1_rtc_gpio_mask = rtc_gpio_mask;
1348 s_config.ext1_trigger_mode = mode;
1349 s_config.wakeup_triggers |= RTC_EXT1_TRIG_EN;
1350 return ESP_OK;
1351 }
1352
ext1_wakeup_prepare(void)1353 static void ext1_wakeup_prepare(void)
1354 {
1355 // Configure all RTC IOs selected as ext1 wakeup inputs
1356 uint32_t rtc_gpio_mask = s_config.ext1_rtc_gpio_mask;
1357 for (int gpio = 0; gpio < GPIO_PIN_COUNT && rtc_gpio_mask != 0; ++gpio) {
1358 int rtc_pin = rtc_io_number_get(gpio);
1359 if ((rtc_gpio_mask & BIT(rtc_pin)) == 0) {
1360 continue;
1361 }
1362 #if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
1363 // Route pad to RTC
1364 rtcio_hal_function_select(rtc_pin, RTCIO_FUNC_RTC);
1365 // set input enable in sleep mode
1366 rtcio_hal_input_enable(rtc_pin);
1367 #endif
1368
1369 #if SOC_PM_SUPPORT_RTC_PERIPH_PD
1370 // Pad configuration depends on RTC_PERIPH state in sleep mode
1371 if (s_config.domain[ESP_PD_DOMAIN_RTC_PERIPH].pd_option != ESP_PD_OPTION_ON) {
1372 #if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
1373 // RTC_PERIPH will be powered down, so RTC_IO_ registers will
1374 // loose their state. Lock pad configuration.
1375 // Pullups/pulldowns also need to be disabled.
1376 rtcio_hal_pullup_disable(rtc_pin);
1377 rtcio_hal_pulldown_disable(rtc_pin);
1378 #endif
1379 rtcio_hal_hold_enable(rtc_pin);
1380 }
1381 #endif
1382 // Keep track of pins which are processed to bail out early
1383 rtc_gpio_mask &= ~BIT(rtc_pin);
1384 }
1385
1386 // Clear state from previous wakeup
1387 rtc_hal_ext1_clear_wakeup_status();
1388 // Set RTC IO pins and mode (any high, all low) to be used for wakeup
1389 rtc_hal_ext1_set_wakeup_pins(s_config.ext1_rtc_gpio_mask, s_config.ext1_trigger_mode);
1390 }
1391
esp_sleep_get_ext1_wakeup_status(void)1392 uint64_t esp_sleep_get_ext1_wakeup_status(void)
1393 {
1394 if (esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_EXT1) {
1395 return 0;
1396 }
1397 uint32_t status = rtc_hal_ext1_get_wakeup_status();
1398 // Translate bit map of RTC IO numbers into the bit map of GPIO numbers
1399 uint64_t gpio_mask = 0;
1400 for (int gpio = 0; gpio < GPIO_PIN_COUNT; ++gpio) {
1401 if (!esp_sleep_is_valid_wakeup_gpio(gpio)) {
1402 continue;
1403 }
1404 int rtc_pin = rtc_io_number_get(gpio);
1405 if ((status & BIT(rtc_pin)) == 0) {
1406 continue;
1407 }
1408 gpio_mask |= 1ULL << gpio;
1409 }
1410 return gpio_mask;
1411 }
1412
1413 #endif // SOC_PM_SUPPORT_EXT1_WAKEUP
1414
1415 #if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP
esp_sleep_get_gpio_wakeup_status(void)1416 uint64_t esp_sleep_get_gpio_wakeup_status(void)
1417 {
1418 #if CONFIG_IDF_TARGET_ESP32H2 // TODO: IDF-6268
1419 return 0;
1420 #else
1421 if (esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_GPIO) {
1422 return 0;
1423 }
1424
1425 return rtc_hal_gpio_get_wakeup_status();
1426 #endif // !CONFIG_IDF_TARGET_ESP32H2
1427 }
1428
gpio_deep_sleep_wakeup_prepare(void)1429 static void gpio_deep_sleep_wakeup_prepare(void)
1430 {
1431 #if !CONFIG_IDF_TARGET_ESP32H2 // TODO: IDF-6268
1432 for (gpio_num_t gpio_idx = GPIO_NUM_0; gpio_idx < GPIO_NUM_MAX; gpio_idx++) {
1433 if (((1ULL << gpio_idx) & s_config.gpio_wakeup_mask) == 0) {
1434 continue;
1435 }
1436 if (s_config.gpio_trigger_mode & BIT(gpio_idx)) {
1437 ESP_ERROR_CHECK(gpio_pullup_dis(gpio_idx));
1438 ESP_ERROR_CHECK(gpio_pulldown_en(gpio_idx));
1439 } else {
1440 ESP_ERROR_CHECK(gpio_pullup_en(gpio_idx));
1441 ESP_ERROR_CHECK(gpio_pulldown_dis(gpio_idx));
1442 }
1443 ESP_ERROR_CHECK(gpio_hold_en(gpio_idx));
1444 }
1445 // Clear state from previous wakeup
1446 rtc_hal_gpio_clear_wakeup_status();
1447 #endif // !CONFIG_IDF_TARGET_ESP32H2
1448 }
1449
esp_deep_sleep_enable_gpio_wakeup(uint64_t gpio_pin_mask,esp_deepsleep_gpio_wake_up_mode_t mode)1450 esp_err_t esp_deep_sleep_enable_gpio_wakeup(uint64_t gpio_pin_mask, esp_deepsleep_gpio_wake_up_mode_t mode)
1451 {
1452 if (mode > ESP_GPIO_WAKEUP_GPIO_HIGH) {
1453 ESP_LOGE(TAG, "invalid mode");
1454 return ESP_ERR_INVALID_ARG;
1455 }
1456 gpio_int_type_t intr_type = ((mode == ESP_GPIO_WAKEUP_GPIO_LOW) ? GPIO_INTR_LOW_LEVEL : GPIO_INTR_HIGH_LEVEL);
1457 esp_err_t err = ESP_OK;
1458 for (gpio_num_t gpio_idx = GPIO_NUM_0; gpio_idx < GPIO_NUM_MAX; gpio_idx++, gpio_pin_mask >>= 1) {
1459 if ((gpio_pin_mask & 1) == 0) {
1460 continue;
1461 }
1462 if (!esp_sleep_is_valid_wakeup_gpio(gpio_idx)) {
1463 ESP_LOGE(TAG, "gpio %d is an invalid deep sleep wakeup IO", gpio_idx);
1464 return ESP_ERR_INVALID_ARG;
1465 }
1466 err = gpio_deep_sleep_wakeup_enable(gpio_idx, intr_type);
1467
1468 s_config.gpio_wakeup_mask |= BIT(gpio_idx);
1469 if (mode == ESP_GPIO_WAKEUP_GPIO_HIGH) {
1470 s_config.gpio_trigger_mode |= (mode << gpio_idx);
1471 } else {
1472 s_config.gpio_trigger_mode &= ~(mode << gpio_idx);
1473 }
1474 }
1475 s_config.wakeup_triggers |= RTC_GPIO_TRIG_EN;
1476 return err;
1477 }
1478
1479 #endif //SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP
1480
esp_sleep_enable_gpio_wakeup(void)1481 esp_err_t esp_sleep_enable_gpio_wakeup(void)
1482 {
1483 #if CONFIG_IDF_TARGET_ESP32
1484 if (s_config.wakeup_triggers & (RTC_TOUCH_TRIG_EN | RTC_ULP_TRIG_EN)) {
1485 ESP_LOGE(TAG, "Conflicting wake-up triggers: touch / ULP");
1486 return ESP_ERR_INVALID_STATE;
1487 }
1488 #endif
1489 s_config.wakeup_triggers |= RTC_GPIO_TRIG_EN;
1490 return ESP_OK;
1491 }
1492
esp_sleep_enable_uart_wakeup(int uart_num)1493 esp_err_t esp_sleep_enable_uart_wakeup(int uart_num)
1494 {
1495 if (uart_num == UART_NUM_0) {
1496 s_config.wakeup_triggers |= RTC_UART0_TRIG_EN;
1497 } else if (uart_num == UART_NUM_1) {
1498 s_config.wakeup_triggers |= RTC_UART1_TRIG_EN;
1499 } else {
1500 return ESP_ERR_INVALID_ARG;
1501 }
1502
1503 return ESP_OK;
1504 }
1505
esp_sleep_enable_wifi_wakeup(void)1506 esp_err_t esp_sleep_enable_wifi_wakeup(void)
1507 {
1508 #if SOC_PM_SUPPORT_WIFI_WAKEUP
1509 s_config.wakeup_triggers |= RTC_WIFI_TRIG_EN;
1510 return ESP_OK;
1511 #else
1512 return ESP_ERR_NOT_SUPPORTED;
1513 #endif
1514 }
1515
esp_sleep_disable_wifi_wakeup(void)1516 esp_err_t esp_sleep_disable_wifi_wakeup(void)
1517 {
1518 #if SOC_PM_SUPPORT_WIFI_WAKEUP
1519 s_config.wakeup_triggers &= (~RTC_WIFI_TRIG_EN);
1520 return ESP_OK;
1521 #else
1522 return ESP_ERR_NOT_SUPPORTED;
1523 #endif
1524 }
1525
esp_sleep_enable_wifi_beacon_wakeup(void)1526 esp_err_t esp_sleep_enable_wifi_beacon_wakeup(void)
1527 {
1528 #if SOC_PM_SUPPORT_BEACON_WAKEUP
1529 s_config.wakeup_triggers |= PMU_WIFI_BEACON_WAKEUP_EN;
1530 return ESP_OK;
1531 #else
1532 return ESP_ERR_NOT_SUPPORTED;
1533 #endif
1534 }
1535
esp_sleep_disable_wifi_beacon_wakeup(void)1536 esp_err_t esp_sleep_disable_wifi_beacon_wakeup(void)
1537 {
1538 #if SOC_PM_SUPPORT_BEACON_WAKEUP
1539 s_config.wakeup_triggers &= (~PMU_WIFI_BEACON_WAKEUP_EN);
1540 return ESP_OK;
1541 #else
1542 return ESP_ERR_NOT_SUPPORTED;
1543 #endif
1544 }
1545
esp_sleep_enable_bt_wakeup(void)1546 esp_err_t esp_sleep_enable_bt_wakeup(void)
1547 {
1548 #if SOC_PM_SUPPORT_BT_WAKEUP
1549 s_config.wakeup_triggers |= RTC_BT_TRIG_EN;
1550 return ESP_OK;
1551 #else
1552 return ESP_ERR_NOT_SUPPORTED;
1553 #endif
1554 }
1555
esp_sleep_disable_bt_wakeup(void)1556 esp_err_t esp_sleep_disable_bt_wakeup(void)
1557 {
1558 #if SOC_PM_SUPPORT_BT_WAKEUP
1559 s_config.wakeup_triggers &= (~RTC_BT_TRIG_EN);
1560 return ESP_OK;
1561 #else
1562 return ESP_ERR_NOT_SUPPORTED;
1563 #endif
1564 }
1565
esp_sleep_get_wakeup_cause(void)1566 esp_sleep_wakeup_cause_t esp_sleep_get_wakeup_cause(void)
1567 {
1568 if (esp_rom_get_reset_reason(0) != RESET_REASON_CORE_DEEP_SLEEP && !s_light_sleep_wakeup) {
1569 return ESP_SLEEP_WAKEUP_UNDEFINED;
1570 }
1571
1572 #if SOC_PMU_SUPPORTED
1573 uint32_t wakeup_cause = pmu_ll_hp_get_wakeup_cause(&PMU);
1574 #else
1575 uint32_t wakeup_cause = rtc_cntl_ll_get_wakeup_cause();
1576 #endif
1577
1578 if (wakeup_cause & RTC_TIMER_TRIG_EN) {
1579 return ESP_SLEEP_WAKEUP_TIMER;
1580 } else if (wakeup_cause & RTC_GPIO_TRIG_EN) {
1581 return ESP_SLEEP_WAKEUP_GPIO;
1582 } else if (wakeup_cause & (RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN)) {
1583 return ESP_SLEEP_WAKEUP_UART;
1584 #if SOC_PM_SUPPORT_EXT0_WAKEUP
1585 } else if (wakeup_cause & RTC_EXT0_TRIG_EN) {
1586 return ESP_SLEEP_WAKEUP_EXT0;
1587 #endif
1588 #if SOC_PM_SUPPORT_EXT1_WAKEUP
1589 } else if (wakeup_cause & RTC_EXT1_TRIG_EN) {
1590 return ESP_SLEEP_WAKEUP_EXT1;
1591 #endif
1592 #if SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP
1593 } else if (wakeup_cause & RTC_TOUCH_TRIG_EN) {
1594 return ESP_SLEEP_WAKEUP_TOUCHPAD;
1595 #endif
1596 #if SOC_ULP_FSM_SUPPORTED
1597 } else if (wakeup_cause & RTC_ULP_TRIG_EN) {
1598 return ESP_SLEEP_WAKEUP_ULP;
1599 #endif
1600 #if SOC_PM_SUPPORT_WIFI_WAKEUP
1601 } else if (wakeup_cause & RTC_WIFI_TRIG_EN) {
1602 return ESP_SLEEP_WAKEUP_WIFI;
1603 #endif
1604 #if SOC_PM_SUPPORT_BT_WAKEUP
1605 } else if (wakeup_cause & RTC_BT_TRIG_EN) {
1606 return ESP_SLEEP_WAKEUP_BT;
1607 #endif
1608 #if SOC_RISCV_COPROC_SUPPORTED
1609 } else if (wakeup_cause & RTC_COCPU_TRIG_EN) {
1610 return ESP_SLEEP_WAKEUP_ULP;
1611 } else if (wakeup_cause & RTC_COCPU_TRAP_TRIG_EN) {
1612 return ESP_SLEEP_WAKEUP_COCPU_TRAP_TRIG;
1613 #endif
1614 #if SOC_LP_CORE_SUPPORTED
1615 } else if (wakeup_cause & RTC_LP_CORE_TRIG_EN) {
1616 return ESP_SLEEP_WAKEUP_ULP;
1617 #endif
1618 } else {
1619 return ESP_SLEEP_WAKEUP_UNDEFINED;
1620 }
1621 }
1622
esp_sleep_pd_config(esp_sleep_pd_domain_t domain,esp_sleep_pd_option_t option)1623 esp_err_t esp_sleep_pd_config(esp_sleep_pd_domain_t domain, esp_sleep_pd_option_t option)
1624 {
1625 if (domain >= ESP_PD_DOMAIN_MAX || option > ESP_PD_OPTION_AUTO) {
1626 return ESP_ERR_INVALID_ARG;
1627 }
1628 s_config.lock = irq_lock();
1629
1630 int refs = (option == ESP_PD_OPTION_ON) ? s_config.domain[domain].refs++ \
1631 : (option == ESP_PD_OPTION_OFF) ? --s_config.domain[domain].refs \
1632 : s_config.domain[domain].refs;
1633 if (refs == 0) {
1634 s_config.domain[domain].pd_option = option;
1635 }
1636 irq_unlock(s_config.lock);
1637 assert(refs >= 0);
1638 return ESP_OK;
1639 }
1640
1641 /**
1642 * The modules in the CPU and modem power domains still depend on the top power domain.
1643 * To be safe, the CPU and Modem power domains must also be powered off and saved when
1644 * the TOP is powered off. If not power down XTAL, power down TOP is meaningless, and
1645 * the XTAL clock control of some chips(esp32c6/esp32h2) depends on the top domain.
1646 */
1647 #if SOC_PM_SUPPORT_TOP_PD
top_domain_pd_allowed(void)1648 static inline bool top_domain_pd_allowed(void) {
1649 return (cpu_domain_pd_allowed() && \
1650 clock_domain_pd_allowed() && \
1651 peripheral_domain_pd_allowed() && \
1652 modem_domain_pd_allowed() && \
1653 s_config.domain[ESP_PD_DOMAIN_XTAL].pd_option != ESP_PD_OPTION_ON);
1654 }
1655 #endif
1656
get_power_down_flags(void)1657 static uint32_t get_power_down_flags(void)
1658 {
1659 // Where needed, convert AUTO options to ON. Later interpret AUTO as OFF.
1660
1661 // RTC_SLOW_MEM is needed for the ULP, so keep RTC_SLOW_MEM powered up if ULP
1662 // is used and RTC_SLOW_MEM is Auto.
1663 // If there is any data placed into .rtc.data or .rtc.bss segments, and
1664 // RTC_SLOW_MEM is Auto, keep it powered up as well.
1665
1666 #if SOC_PM_SUPPORT_RTC_SLOW_MEM_PD && SOC_ULP_SUPPORTED
1667 // Labels are defined in the linker script
1668 extern int _rtc_slow_length;
1669 int _rtc_reserved_length = 0;
1670 /**
1671 * Compiler considers "(size_t) &_rtc_slow_length > 0" to always be true.
1672 * So use a volatile variable to prevent compiler from doing this optimization.
1673 */
1674 volatile size_t rtc_slow_mem_used = (size_t)&_rtc_slow_length + (size_t)&_rtc_reserved_length;
1675
1676 if ((s_config.domain[ESP_PD_DOMAIN_RTC_SLOW_MEM].pd_option == ESP_PD_OPTION_AUTO) &&
1677 (rtc_slow_mem_used > 0 || (s_config.wakeup_triggers & RTC_ULP_TRIG_EN))) {
1678 s_config.domain[ESP_PD_DOMAIN_RTC_SLOW_MEM].pd_option = ESP_PD_OPTION_ON;
1679 }
1680 #endif
1681
1682 #if SOC_PM_SUPPORT_RTC_FAST_MEM_PD
1683 #if !CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP
1684 /* RTC_FAST_MEM is needed for deep sleep stub.
1685 If RTC_FAST_MEM is Auto, keep it powered on, so that deep sleep stub can run.
1686 In the new chip revision, deep sleep stub will be optional, and this can be changed. */
1687 if (s_config.domain[ESP_PD_DOMAIN_RTC_FAST_MEM].pd_option == ESP_PD_OPTION_AUTO) {
1688 s_config.domain[ESP_PD_DOMAIN_RTC_FAST_MEM].pd_option = ESP_PD_OPTION_ON;
1689 }
1690 #else
1691 /* If RTC_FAST_MEM is used for heap, force RTC_FAST_MEM to be powered on. */
1692 s_config.domain[ESP_PD_DOMAIN_RTC_FAST_MEM].pd_option = ESP_PD_OPTION_ON;
1693 #endif
1694 #endif
1695
1696 #if SOC_PM_SUPPORT_RTC_PERIPH_PD
1697 // RTC_PERIPH is needed for EXT0 wakeup and GPIO wakeup.
1698 // If RTC_PERIPH is left auto (EXT0/GPIO aren't enabled), RTC_PERIPH will be powered off by default.
1699 if (s_config.domain[ESP_PD_DOMAIN_RTC_PERIPH].pd_option == ESP_PD_OPTION_AUTO) {
1700 if (s_config.wakeup_triggers & (RTC_EXT0_TRIG_EN | RTC_GPIO_TRIG_EN)) {
1701 s_config.domain[ESP_PD_DOMAIN_RTC_PERIPH].pd_option = ESP_PD_OPTION_ON;
1702 }
1703 #if CONFIG_IDF_TARGET_ESP32
1704 else if (s_config.wakeup_triggers & (RTC_TOUCH_TRIG_EN | RTC_ULP_TRIG_EN)) {
1705 // On ESP32, forcing power up of RTC_PERIPH
1706 // prevents ULP timer and touch FSMs from working correctly.
1707 s_config.domain[ESP_PD_DOMAIN_RTC_PERIPH].pd_option = ESP_PD_OPTION_OFF;
1708 }
1709 #endif //CONFIG_IDF_TARGET_ESP32
1710 #if SOC_LP_CORE_SUPPORTED
1711 else if (s_config.wakeup_triggers & RTC_LP_CORE_TRIG_EN) {
1712 // Need to keep RTC_PERIPH on to allow lp core to wakeup during sleep (e.g. from lp timer)
1713 s_config.domain[ESP_PD_DOMAIN_RTC_PERIPH].pd_option = ESP_PD_OPTION_ON;
1714 }
1715 #endif //CONFIG_IDF_TARGET_ESP32
1716 }
1717 #endif // SOC_PM_SUPPORT_RTC_PERIPH_PD
1718
1719 /**
1720 * VDD_SDIO power domain shall be kept on during the light sleep
1721 * when CONFIG_ESP_SLEEP_POWER_DOWN_FLASH is not set and off when it is set.
1722 * The application can still force the power domain to remain on by calling
1723 * `esp_sleep_pd_config` before getting into light sleep mode.
1724 *
1725 * In deep sleep mode, the power domain will be turned off, regardless the
1726 * value of this field.
1727 */
1728 #if SOC_PM_SUPPORT_VDDSDIO_PD
1729 if (s_config.domain[ESP_PD_DOMAIN_VDDSDIO].pd_option == ESP_PD_OPTION_AUTO) {
1730 #ifndef CONFIG_ESP_SLEEP_POWER_DOWN_FLASH
1731 s_config.domain[ESP_PD_DOMAIN_VDDSDIO].pd_option = ESP_PD_OPTION_ON;
1732 #endif
1733 }
1734 #endif
1735
1736
1737 #ifdef CONFIG_IDF_TARGET_ESP32
1738 s_config.domain[ESP_PD_DOMAIN_XTAL].pd_option = ESP_PD_OPTION_OFF;
1739 #endif
1740
1741 const __attribute__((unused)) char *option_str[] = {"OFF", "ON", "AUTO(OFF)" /* Auto works as OFF */};
1742 /* This function is called from a critical section, log with ESP_EARLY_LOGD. */
1743 #if SOC_PM_SUPPORT_RTC_PERIPH_PD
1744 ESP_EARLY_LOGD(TAG, "RTC_PERIPH: %s", option_str[s_config.domain[ESP_PD_DOMAIN_RTC_PERIPH].pd_option]);
1745 #endif
1746 #if SOC_PM_SUPPORT_RTC_SLOW_MEM_PD
1747 ESP_EARLY_LOGD(TAG, "RTC_SLOW_MEM: %s", option_str[s_config.domain[ESP_PD_DOMAIN_RTC_SLOW_MEM].pd_option]);
1748 #endif
1749 #if SOC_PM_SUPPORT_RTC_FAST_MEM_PD
1750 ESP_EARLY_LOGD(TAG, "RTC_FAST_MEM: %s", option_str[s_config.domain[ESP_PD_DOMAIN_RTC_FAST_MEM].pd_option]);
1751 #endif
1752
1753 // Prepare flags based on the selected options
1754 uint32_t pd_flags = 0;
1755 #if SOC_PM_SUPPORT_RTC_FAST_MEM_PD
1756 if (s_config.domain[ESP_PD_DOMAIN_RTC_FAST_MEM].pd_option != ESP_PD_OPTION_ON) {
1757 pd_flags |= RTC_SLEEP_PD_RTC_FAST_MEM;
1758 }
1759 #endif
1760 #if SOC_PM_SUPPORT_RTC_SLOW_MEM_PD
1761 if (s_config.domain[ESP_PD_DOMAIN_RTC_SLOW_MEM].pd_option != ESP_PD_OPTION_ON) {
1762 pd_flags |= RTC_SLEEP_PD_RTC_SLOW_MEM;
1763 }
1764 #endif
1765 #if SOC_PM_SUPPORT_RTC_PERIPH_PD
1766 if (s_config.domain[ESP_PD_DOMAIN_RTC_PERIPH].pd_option != ESP_PD_OPTION_ON) {
1767 pd_flags |= RTC_SLEEP_PD_RTC_PERIPH;
1768 }
1769 #endif
1770
1771 #if SOC_PM_SUPPORT_CPU_PD
1772 if ((s_config.domain[ESP_PD_DOMAIN_CPU].pd_option != ESP_PD_OPTION_ON) && cpu_domain_pd_allowed()) {
1773 pd_flags |= RTC_SLEEP_PD_CPU;
1774 }
1775 #endif
1776 #if SOC_PM_SUPPORT_XTAL32K_PD
1777 if (s_config.domain[ESP_PD_DOMAIN_XTAL32K].pd_option != ESP_PD_OPTION_ON) {
1778 pd_flags |= PMU_SLEEP_PD_XTAL32K;
1779 }
1780 #endif
1781 #if SOC_PM_SUPPORT_RC32K_PD
1782 if (s_config.domain[ESP_PD_DOMAIN_RC32K].pd_option != ESP_PD_OPTION_ON) {
1783 pd_flags |= PMU_SLEEP_PD_RC32K;
1784 }
1785 #endif
1786 #if SOC_PM_SUPPORT_RC_FAST_PD
1787 if (s_config.domain[ESP_PD_DOMAIN_RC_FAST].pd_option != ESP_PD_OPTION_ON) {
1788 pd_flags |= RTC_SLEEP_PD_INT_8M;
1789 }
1790 #endif
1791 if (s_config.domain[ESP_PD_DOMAIN_XTAL].pd_option != ESP_PD_OPTION_ON) {
1792 pd_flags |= RTC_SLEEP_PD_XTAL;
1793 }
1794 #if SOC_PM_SUPPORT_TOP_PD
1795 if ((s_config.domain[ESP_PD_DOMAIN_TOP].pd_option != ESP_PD_OPTION_ON) && top_domain_pd_allowed()) {
1796 pd_flags |= PMU_SLEEP_PD_TOP;
1797 }
1798 #endif
1799
1800 #if SOC_PM_SUPPORT_MODEM_PD
1801 if ((s_config.domain[ESP_PD_DOMAIN_MODEM].pd_option != ESP_PD_OPTION_ON) && modem_domain_pd_allowed()) {
1802 pd_flags |= RTC_SLEEP_PD_MODEM;
1803 }
1804 #endif
1805
1806 #if SOC_PM_SUPPORT_VDDSDIO_PD
1807 if (s_config.domain[ESP_PD_DOMAIN_VDDSDIO].pd_option != ESP_PD_OPTION_ON) {
1808 pd_flags |= RTC_SLEEP_PD_VDDSDIO;
1809 }
1810 #endif
1811
1812 #if ((defined CONFIG_RTC_CLK_SRC_EXT_CRYS) && (defined CONFIG_RTC_EXT_CRYST_ADDIT_CURRENT) && (SOC_PM_SUPPORT_RTC_PERIPH_PD))
1813 if ((s_config.wakeup_triggers & (RTC_TOUCH_TRIG_EN | RTC_ULP_TRIG_EN)) == 0) {
1814 // If enabled EXT1 only and enable the additional current by touch, should be keep RTC_PERIPH power on.
1815 pd_flags &= ~RTC_SLEEP_PD_RTC_PERIPH;
1816 }
1817 #endif
1818
1819 return pd_flags;
1820 }
1821
1822 #if CONFIG_IDF_TARGET_ESP32
1823 /* APP core of esp32 can't access to RTC FAST MEMORY, do not define it with RTC_IRAM_ATTR */
1824 void
1825 #else
1826 void RTC_IRAM_ATTR
1827 #endif
esp_deep_sleep_disable_rom_logging(void)1828 esp_deep_sleep_disable_rom_logging(void)
1829 {
1830 rtc_suppress_rom_log();
1831 }
1832
esp_sleep_enable_adc_tsens_monitor(bool enable)1833 void esp_sleep_enable_adc_tsens_monitor(bool enable)
1834 {
1835 s_adc_tsen_enabled = enable;
1836 }
1837
rtc_sleep_enable_ultra_low(bool enable)1838 void rtc_sleep_enable_ultra_low(bool enable)
1839 {
1840 s_ultra_low_enabled = enable;
1841 }
1842