1 // Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <stddef.h>
16 #include <string.h>
17 #include <sys/lock.h>
18 #include <sys/param.h>
19
20 #include "esp_attr.h"
21 #include "esp_sleep.h"
22 #include "esp_private/esp_timer_private.h"
23 #include "esp_private/system_internal.h"
24 #include "esp_log.h"
25 #include "esp_newlib.h"
26 #include "esp_timer.h"
27 #include "esp_osal/esp_osal.h"
28 #include "esp_osal/task.h"
29 #include "soc/soc_caps.h"
30 #include "driver/rtc_io.h"
31 #include "hal/rtc_io_hal.h"
32
33 #include "driver/uart.h"
34
35 #include "soc/cpu.h"
36 #include "soc/rtc.h"
37
38 #include "hal/wdt_hal.h"
39 #include "hal/rtc_hal.h"
40 #include "hal/uart_hal.h"
41 #if SOC_TOUCH_SENSOR_NUM > 0
42 #include "hal/touch_sensor_hal.h"
43 #include "driver/touch_sensor.h"
44 #include "driver/touch_sensor_common.h"
45 #endif
46 #include "hal/clk_gate_ll.h"
47
48 #include "sdkconfig.h"
49 #include "esp_rom_uart.h"
50
51 #ifdef CONFIG_IDF_TARGET_ESP32
52 #include "esp32/rom/cache.h"
53 #include "esp32/clk.h"
54 #include "esp32/rom/rtc.h"
55 #include "esp_private/gpio.h"
56 #elif CONFIG_IDF_TARGET_ESP32S2
57 #include "esp32s2/clk.h"
58 #include "esp32s2/rom/cache.h"
59 #include "esp32s2/rom/rtc.h"
60 #include "esp32s2/brownout.h"
61 #include "soc/extmem_reg.h"
62 #include "esp_private/gpio.h"
63 #elif CONFIG_IDF_TARGET_ESP32S3
64 #include "esp32s3/clk.h"
65 #include "esp32s3/rom/cache.h"
66 #include "esp32s3/rom/rtc.h"
67 #include "soc/extmem_reg.h"
68 #elif CONFIG_IDF_TARGET_ESP32C3
69 #include "esp32c3/clk.h"
70 #include "esp32c3/rom/cache.h"
71 #include "esp32c3/rom/rtc.h"
72 #include "soc/extmem_reg.h"
73 #include "esp_heap_caps.h"
74 #endif
75
76 // If light sleep time is less than that, don't power down flash
77 #define FLASH_PD_MIN_SLEEP_TIME_US 2000
78
79 // Time from VDD_SDIO power up to first flash read in ROM code
80 #define VDD_SDIO_POWERUP_TO_FLASH_READ_US 700
81
82 // Cycles for RTC Timer clock source (internal oscillator) calibrate
83 #define RTC_CLK_SRC_CAL_CYCLES (10)
84
85 #ifdef CONFIG_IDF_TARGET_ESP32
86 #define DEFAULT_CPU_FREQ_MHZ CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ
87 #define DEFAULT_SLEEP_OUT_OVERHEAD_US (212)
88 #define DEFAULT_HARDWARE_OUT_OVERHEAD_US (60)
89 #elif CONFIG_IDF_TARGET_ESP32S2
90 #define DEFAULT_CPU_FREQ_MHZ CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ
91 #define DEFAULT_SLEEP_OUT_OVERHEAD_US (147)
92 #define DEFAULT_HARDWARE_OUT_OVERHEAD_US (28)
93 #elif CONFIG_IDF_TARGET_ESP32S3
94 #define DEFAULT_CPU_FREQ_MHZ CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ
95 #define DEFAULT_SLEEP_OUT_OVERHEAD_US (0)
96 #define DEFAULT_HARDWARE_OUT_OVERHEAD_US (0)
97 #elif CONFIG_IDF_TARGET_ESP32C3
98 #define DEFAULT_CPU_FREQ_MHZ CONFIG_ESP32C3_DEFAULT_CPU_FREQ_MHZ
99 #define DEFAULT_SLEEP_OUT_OVERHEAD_US (105)
100 #define DEFAULT_HARDWARE_OUT_OVERHEAD_US (37)
101 #endif
102
103 #define LIGHT_SLEEP_TIME_OVERHEAD_US DEFAULT_HARDWARE_OUT_OVERHEAD_US
104 #if defined(CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS) || \
105 defined(CONFIG_ESP32S2_RTC_CLK_SRC_EXT_CRYS) || \
106 defined(CONFIG_ESP32C3_RTC_CLK_SRC_EXT_CRYS) || \
107 defined(CONFIG_ESP32S3_RTC_CLK_SRC_EXT_CRYS)
108 #define DEEP_SLEEP_TIME_OVERHEAD_US (650 + 100 * 240 / DEFAULT_CPU_FREQ_MHZ)
109 #else
110 #define DEEP_SLEEP_TIME_OVERHEAD_US (250 + 100 * 240 / DEFAULT_CPU_FREQ_MHZ)
111 #endif
112
113 #if defined(CONFIG_IDF_TARGET_ESP32) && defined(CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY)
114 #define DEEP_SLEEP_WAKEUP_DELAY CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY
115 #else
116 #define DEEP_SLEEP_WAKEUP_DELAY 0
117 #endif
118
119 extern void periph_inform_out_light_sleep_overhead(uint32_t out_light_sleep_time);
120
121 // Minimal amount of time we can sleep for
122 #define LIGHT_SLEEP_MIN_TIME_US 200
123
124 #define RTC_MODULE_SLEEP_PREPARE_CYCLES (6)
125
126 #define CHECK_SOURCE(source, value, mask) ((s_config.wakeup_triggers & mask) && \
127 (source == value))
128
129 /**
130 * Internal structure which holds all requested deep sleep parameters
131 */
132 typedef struct {
133 esp_sleep_pd_option_t pd_options[ESP_PD_DOMAIN_MAX];
134 uint64_t sleep_duration;
135 uint32_t wakeup_triggers : 15;
136 uint32_t ext1_trigger_mode : 1;
137 uint32_t ext1_rtc_gpio_mask : 18;
138 uint32_t ext0_trigger_level : 1;
139 uint32_t ext0_rtc_gpio_num : 5;
140 uint32_t gpio_wakeup_mask : 6;
141 uint32_t gpio_trigger_mode : 6;
142 uint32_t sleep_time_adjustment;
143 uint32_t ccount_ticks_record;
144 uint32_t sleep_time_overhead_out;
145 uint32_t rtc_clk_cal_period;
146 uint64_t rtc_ticks_at_sleep_start;
147 #if SOC_PM_SUPPORT_CPU_PD
148 void *cpu_pd_mem;
149 #endif
150 } sleep_config_t;
151
152 static sleep_config_t s_config = {
153 .pd_options = { ESP_PD_OPTION_AUTO, ESP_PD_OPTION_AUTO, ESP_PD_OPTION_AUTO, ESP_PD_OPTION_AUTO, ESP_PD_OPTION_AUTO, ESP_PD_OPTION_AUTO },
154 .ccount_ticks_record = 0,
155 .sleep_time_overhead_out = DEFAULT_SLEEP_OUT_OVERHEAD_US,
156 .wakeup_triggers = 0
157 };
158
159 /* Internal variable used to track if light sleep wakeup sources are to be
160 expected when determining wakeup cause. */
161 static bool s_light_sleep_wakeup = false;
162
163 /* Updating RTC_MEMORY_CRC_REG register via set_rtc_memory_crc()
164 is not thread-safe, so we need to disable interrupts before going to deep sleep. */
165 static portMUX_TYPE spinlock_rtc_deep_sleep = portMUX_INITIALIZER_UNLOCKED;
166
167 static const char *TAG = "sleep";
168
169 static uint32_t get_power_down_flags(void);
170 #if SOC_PM_SUPPORT_EXT_WAKEUP
171 static void ext0_wakeup_prepare(void);
172 static void ext1_wakeup_prepare(void);
173 #endif
174 static void timer_wakeup_prepare(void);
175 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
176 static void touch_wakeup_prepare(void);
177 #endif
178 #if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP
179 static void esp_deep_sleep_wakeup_prepare(void);
180 #endif
181
182 #if CONFIG_MAC_BB_PD
183 #define MAC_BB_POWER_DOWN_CB_NO 2
184 #define MAC_BB_POWER_UP_CB_NO 2
185 static DRAM_ATTR mac_bb_power_down_cb_t s_mac_bb_power_down_cb[MAC_BB_POWER_DOWN_CB_NO];
186 static DRAM_ATTR mac_bb_power_up_cb_t s_mac_bb_power_up_cb[MAC_BB_POWER_UP_CB_NO];
187
esp_register_mac_bb_pd_callback(mac_bb_power_down_cb_t cb)188 esp_err_t esp_register_mac_bb_pd_callback(mac_bb_power_down_cb_t cb)
189 {
190 int index = MAC_BB_POWER_DOWN_CB_NO;
191 for (int i = MAC_BB_POWER_DOWN_CB_NO - 1; i >= 0; i--) {
192 if (s_mac_bb_power_down_cb[i] == cb) {
193 return ESP_OK;
194 }
195
196 if (s_mac_bb_power_down_cb[i] == NULL) {
197 index = i;
198 }
199 }
200
201 if (index < MAC_BB_POWER_DOWN_CB_NO) {
202 s_mac_bb_power_down_cb[index] = cb;
203 return ESP_OK;
204 }
205
206 return ESP_ERR_NO_MEM;
207 }
208
esp_unregister_mac_bb_pd_callback(mac_bb_power_down_cb_t cb)209 esp_err_t esp_unregister_mac_bb_pd_callback(mac_bb_power_down_cb_t cb)
210 {
211 for (int i = MAC_BB_POWER_DOWN_CB_NO - 1; i >= 0; i--) {
212 if (s_mac_bb_power_down_cb[i] == cb) {
213 s_mac_bb_power_down_cb[i] = NULL;
214 return ESP_OK;
215 }
216 }
217 return ESP_ERR_INVALID_STATE;
218 }
219
mac_bb_power_down_cb_execute(void)220 static IRAM_ATTR void mac_bb_power_down_cb_execute(void)
221 {
222 for (int i = 0; i < MAC_BB_POWER_DOWN_CB_NO; i++) {
223 if (s_mac_bb_power_down_cb[i]) {
224 s_mac_bb_power_down_cb[i]();
225 }
226 }
227 }
228
esp_register_mac_bb_pu_callback(mac_bb_power_up_cb_t cb)229 esp_err_t esp_register_mac_bb_pu_callback(mac_bb_power_up_cb_t cb)
230 {
231 int index = MAC_BB_POWER_UP_CB_NO;
232 for (int i = MAC_BB_POWER_UP_CB_NO - 1; i >= 0; i--) {
233 if (s_mac_bb_power_up_cb[i] == cb) {
234 return ESP_OK;
235 }
236
237 if (s_mac_bb_power_up_cb[i] == NULL) {
238 index = i;
239 }
240 }
241
242 if (index < MAC_BB_POWER_UP_CB_NO) {
243 s_mac_bb_power_up_cb[index] = cb;
244 return ESP_OK;
245 }
246
247 return ESP_ERR_NO_MEM;
248 }
249
esp_unregister_mac_bb_pu_callback(mac_bb_power_up_cb_t cb)250 esp_err_t esp_unregister_mac_bb_pu_callback(mac_bb_power_up_cb_t cb)
251 {
252 for (int i = MAC_BB_POWER_UP_CB_NO - 1; i >= 0; i--) {
253 if (s_mac_bb_power_up_cb[i] == cb) {
254 s_mac_bb_power_up_cb[i] = NULL;
255 return ESP_OK;
256 }
257 }
258 return ESP_ERR_INVALID_STATE;
259 }
260
mac_bb_power_up_cb_execute(void)261 static IRAM_ATTR void mac_bb_power_up_cb_execute(void)
262 {
263 for (int i = 0; i < MAC_BB_POWER_UP_CB_NO; i++) {
264 if (s_mac_bb_power_up_cb[i]) {
265 s_mac_bb_power_up_cb[i]();
266 }
267 }
268 }
269 #endif ///CONFIG_MAC_BB_PD
270
271 /* Wake from deep sleep stub
272 See esp_deepsleep.h esp_wake_deep_sleep() comments for details.
273 */
esp_get_deep_sleep_wake_stub(void)274 esp_deep_sleep_wake_stub_fn_t esp_get_deep_sleep_wake_stub(void)
275 {
276 esp_deep_sleep_wake_stub_fn_t stub_ptr = (esp_deep_sleep_wake_stub_fn_t) REG_READ(RTC_ENTRY_ADDR_REG);
277 if (!esp_ptr_executable(stub_ptr)) {
278 return NULL;
279 }
280 return stub_ptr;
281 }
282
esp_set_deep_sleep_wake_stub(esp_deep_sleep_wake_stub_fn_t new_stub)283 void esp_set_deep_sleep_wake_stub(esp_deep_sleep_wake_stub_fn_t new_stub)
284 {
285 REG_WRITE(RTC_ENTRY_ADDR_REG, (uint32_t)new_stub);
286 }
287
esp_default_wake_deep_sleep(void)288 void RTC_IRAM_ATTR esp_default_wake_deep_sleep(void)
289 {
290 /* Clear MMU for CPU 0 */
291 #if CONFIG_IDF_TARGET_ESP32
292 _DPORT_REG_WRITE(DPORT_PRO_CACHE_CTRL1_REG,
293 _DPORT_REG_READ(DPORT_PRO_CACHE_CTRL1_REG) | DPORT_PRO_CACHE_MMU_IA_CLR);
294 _DPORT_REG_WRITE(DPORT_PRO_CACHE_CTRL1_REG,
295 _DPORT_REG_READ(DPORT_PRO_CACHE_CTRL1_REG) & (~DPORT_PRO_CACHE_MMU_IA_CLR));
296 #if DEEP_SLEEP_WAKEUP_DELAY > 0
297 // ROM code has not started yet, so we need to set delay factor
298 // used by esp_rom_delay_us first.
299 ets_update_cpu_frequency_rom(ets_get_detected_xtal_freq() / 1000000);
300 // This delay is configured in menuconfig, it can be used to give
301 // the flash chip some time to become ready.
302 esp_rom_delay_us(DEEP_SLEEP_WAKEUP_DELAY);
303 #endif
304 #elif CONFIG_IDF_TARGET_ESP32S2
305 REG_SET_BIT(EXTMEM_CACHE_DBG_INT_ENA_REG, EXTMEM_CACHE_DBG_EN);
306 #endif
307 }
308
309 void __attribute__((weak, alias("esp_default_wake_deep_sleep"))) esp_wake_deep_sleep(void);
310
esp_deep_sleep(uint64_t time_in_us)311 void esp_deep_sleep(uint64_t time_in_us)
312 {
313 esp_sleep_enable_timer_wakeup(time_in_us);
314 esp_deep_sleep_start();
315 }
316
317 // [refactor-todo] provide target logic for body of uart functions below
flush_uarts(void)318 static void IRAM_ATTR flush_uarts(void)
319 {
320 for (int i = 0; i < SOC_UART_NUM; ++i) {
321 #ifdef CONFIG_IDF_TARGET_ESP32
322 esp_rom_uart_tx_wait_idle(i);
323 #else
324 if (periph_ll_periph_enabled(PERIPH_UART0_MODULE + i)) {
325 esp_rom_uart_tx_wait_idle(i);
326 }
327 #endif
328 }
329 }
330
suspend_uarts(void)331 static void IRAM_ATTR suspend_uarts(void)
332 {
333 for (int i = 0; i < SOC_UART_NUM; ++i) {
334 #ifndef CONFIG_IDF_TARGET_ESP32
335 if (!periph_ll_periph_enabled(PERIPH_UART0_MODULE + i)) {
336 continue;
337 }
338 #endif
339 uart_ll_force_xoff(i);
340 #if SOC_UART_SUPPORT_FSM_TX_WAIT_SEND
341 uint32_t uart_fsm = 0;
342 do {
343 uart_fsm = uart_ll_get_fsm_status(i);
344 } while (!(uart_fsm == UART_LL_FSM_IDLE || uart_fsm == UART_LL_FSM_TX_WAIT_SEND));
345 #else
346 while (uart_ll_get_fsm_status(i) != 0) {}
347 #endif
348 }
349 }
350
resume_uarts(void)351 static void IRAM_ATTR resume_uarts(void)
352 {
353 for (int i = 0; i < SOC_UART_NUM; ++i) {
354 #ifndef CONFIG_IDF_TARGET_ESP32
355 if (!periph_ll_periph_enabled(PERIPH_UART0_MODULE + i)) {
356 continue;
357 }
358 #endif
359 uart_ll_force_xon(i);
360 }
361 }
362
363 inline static uint32_t IRAM_ATTR call_rtc_sleep_start(uint32_t reject_triggers);
364
365 #if SOC_PM_SUPPORT_CPU_PD
esp_sleep_cpu_pd_low_init(bool enable)366 esp_err_t esp_sleep_cpu_pd_low_init(bool enable)
367 {
368 if (enable) {
369 if (s_config.cpu_pd_mem == NULL) {
370 void *buf = heap_caps_aligned_alloc(SOC_RTC_CNTL_CPU_PD_DMA_ADDR_ALIGN,
371 SOC_RTC_CNTL_CPU_PD_RETENTION_MEM_SIZE + RTC_HAL_DMA_LINK_NODE_SIZE,
372 MALLOC_CAP_RETENTION | MALLOC_CAP_DEFAULT);
373 if (buf) {
374 memset(buf, 0, SOC_RTC_CNTL_CPU_PD_RETENTION_MEM_SIZE + RTC_HAL_DMA_LINK_NODE_SIZE);
375 s_config.cpu_pd_mem = rtc_cntl_hal_dma_link_init(buf,
376 buf + RTC_HAL_DMA_LINK_NODE_SIZE, SOC_RTC_CNTL_CPU_PD_RETENTION_MEM_SIZE, NULL);
377 } else {
378 return ESP_ERR_NO_MEM;
379 }
380 }
381 } else {
382 if (s_config.cpu_pd_mem) {
383 heap_caps_free(s_config.cpu_pd_mem);
384 s_config.cpu_pd_mem = NULL;
385 }
386 }
387 return ESP_OK;
388 }
389 #endif // SOC_PM_SUPPORT_CPU_PD
390
391 #if SOC_GPIO_SUPPORT_SLP_SWITCH
392 #if CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL
gpio_sleep_mode_config_apply(void)393 static inline void gpio_sleep_mode_config_apply(void)
394 {
395 for (gpio_num_t gpio_num = GPIO_NUM_0; gpio_num < GPIO_NUM_MAX; gpio_num++) {
396 if (GPIO_IS_VALID_GPIO(gpio_num)) {
397 gpio_sleep_pupd_config_apply(gpio_num);
398 }
399 }
400 }
401
gpio_sleep_mode_config_unapply(void)402 static inline void gpio_sleep_mode_config_unapply(void)
403 {
404 for (gpio_num_t gpio_num = GPIO_NUM_0; gpio_num < GPIO_NUM_MAX; gpio_num++) {
405 if (GPIO_IS_VALID_GPIO(gpio_num)) {
406 gpio_sleep_pupd_config_unapply(gpio_num);
407 }
408 }
409 }
410 #endif
411
esp_sleep_config_gpio_isolate(void)412 void esp_sleep_config_gpio_isolate(void)
413 {
414 ESP_LOGI(TAG, "Configure to isolate all GPIO pins in sleep state");
415 for (gpio_num_t gpio_num = GPIO_NUM_0; gpio_num < GPIO_NUM_MAX; gpio_num++) {
416 if (GPIO_IS_VALID_GPIO(gpio_num)) {
417 gpio_sleep_set_direction(gpio_num, GPIO_MODE_DISABLE);
418 gpio_sleep_set_pull_mode(gpio_num, GPIO_FLOATING);
419 }
420 }
421 }
422
esp_sleep_enable_gpio_switch(bool enable)423 void esp_sleep_enable_gpio_switch(bool enable)
424 {
425 ESP_LOGI(TAG, "%s automatic switching of GPIO sleep configuration", enable ? "Enable" : "Disable");
426 for (gpio_num_t gpio_num = GPIO_NUM_0; gpio_num < GPIO_NUM_MAX; gpio_num++) {
427 if (GPIO_IS_VALID_GPIO(gpio_num)) {
428 if (enable) {
429 gpio_sleep_sel_en(gpio_num);
430 } else {
431 gpio_sleep_sel_dis(gpio_num);
432 }
433 }
434 }
435 }
436 #endif // SOC_GPIO_SUPPORT_SLP_SWITCH
437
438
esp_sleep_start(uint32_t pd_flags)439 static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags)
440 {
441 // Stop UART output so that output is not lost due to APB frequency change.
442 // For light sleep, suspend UART output — it will resume after wakeup.
443 // For deep sleep, wait for the contents of UART FIFO to be sent.
444 bool deep_sleep = pd_flags & RTC_SLEEP_PD_DIG;
445
446 #if !CONFIG_FREERTOS_UNICORE && CONFIG_IDF_TARGET_ESP32S3 && CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP
447 /* Currently only safe to use deep sleep wake stub & RTC memory as heap in single core mode.
448
449 For ESP32-S3, either disable ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP in config or find a way to set the
450 deep sleep wake stub to NULL.
451 */
452 assert(!deep_sleep || esp_get_deep_sleep_wake_stub() == NULL);
453 #endif
454
455 if (deep_sleep) {
456 flush_uarts();
457 } else {
458 suspend_uarts();
459 }
460
461 // Save current frequency and switch to XTAL
462 rtc_cpu_freq_config_t cpu_freq_config;
463 rtc_clk_cpu_freq_get_config(&cpu_freq_config);
464 rtc_clk_cpu_freq_set_xtal();
465
466 #if CONFIG_MAC_BB_PD
467 mac_bb_power_down_cb_execute();
468 #endif
469
470 #if SOC_PM_SUPPORT_EXT_WAKEUP
471 // Configure pins for external wakeup
472 if (s_config.wakeup_triggers & RTC_EXT0_TRIG_EN) {
473 ext0_wakeup_prepare();
474 }
475 if (s_config.wakeup_triggers & RTC_EXT1_TRIG_EN) {
476 ext1_wakeup_prepare();
477 }
478 #endif
479
480 #if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP
481 if (s_config.wakeup_triggers & RTC_GPIO_TRIG_EN) {
482 esp_deep_sleep_wakeup_prepare();
483 }
484 #endif
485
486 #ifdef CONFIG_IDF_TARGET_ESP32
487 // Enable ULP wakeup
488 if (s_config.wakeup_triggers & RTC_ULP_TRIG_EN) {
489 rtc_hal_ulp_wakeup_enable();
490 }
491 #if CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL
492 gpio_sleep_mode_config_apply();
493 #endif
494 #endif
495
496 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
497 if (deep_sleep) {
498 if (s_config.wakeup_triggers & RTC_TOUCH_TRIG_EN) {
499 touch_wakeup_prepare();
500 /* Workaround: In deep sleep, for ESP32S2, Power down the RTC_PERIPH will change the slope configuration of Touch sensor sleep pad.
501 * The configuration change will change the reading of the sleep pad, which will cause the touch wake-up sensor to trigger falsely.
502 */
503 pd_flags &= ~RTC_SLEEP_PD_RTC_PERIPH;
504 }
505 } else {
506 /* In light sleep, the RTC_PERIPH power domain should be in the power-on state (Power on the touch circuit in light sleep),
507 * otherwise the touch sensor FSM will be cleared, causing touch sensor false triggering.
508 */
509 if (touch_ll_get_fsm_state()) { // Check if the touch sensor is working properly.
510 pd_flags &= ~RTC_SLEEP_PD_RTC_PERIPH;
511 }
512 }
513 #endif
514 uint32_t reject_triggers = 0;
515 if ((pd_flags & RTC_SLEEP_PD_DIG) == 0 && (s_config.wakeup_triggers & RTC_GPIO_TRIG_EN)) {
516 /* Light sleep, enable sleep reject for faster return from this function,
517 * in case the wakeup is already triggerred.
518 */
519 #if CONFIG_IDF_TARGET_ESP32
520 reject_triggers = RTC_CNTL_LIGHT_SLP_REJECT_EN_M | RTC_CNTL_GPIO_REJECT_EN_M;
521 #else
522 reject_triggers = s_config.wakeup_triggers;
523 #endif
524 }
525
526 // Enter sleep
527 rtc_sleep_config_t config = RTC_SLEEP_CONFIG_DEFAULT(pd_flags);
528 rtc_sleep_init(config);
529 rtc_sleep_low_init(s_config.rtc_clk_cal_period);
530
531 // Set state machine time for light sleep
532 if (!deep_sleep) {
533 rtc_sleep_low_init(s_config.rtc_clk_cal_period);
534 }
535
536 // Configure timer wakeup
537 if ((s_config.wakeup_triggers & RTC_TIMER_TRIG_EN) &&
538 s_config.sleep_duration > 0) {
539 timer_wakeup_prepare();
540 }
541
542 uint32_t result;
543 if (deep_sleep) {
544 /* Disable interrupts in case another task writes to RTC memory while we
545 * calculate RTC memory CRC
546 *
547 * Note: for ESP32-S3 running in dual core mode this is currently not enough,
548 * see the assert at top of this function.
549 */
550 portENTER_CRITICAL(&spinlock_rtc_deep_sleep);
551
552 #if !CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP
553 /* If not possible stack is in RTC FAST memory, use the ROM function to calculate the CRC and save ~140 bytes IRAM */
554 set_rtc_memory_crc();
555 result = call_rtc_sleep_start(reject_triggers);
556 #else
557 /* Otherwise, need to call the dedicated soc function for this */
558 result = rtc_deep_sleep_start(s_config.wakeup_triggers, reject_triggers);
559 #endif
560
561 portEXIT_CRITICAL(&spinlock_rtc_deep_sleep);
562 } else {
563 result = call_rtc_sleep_start(reject_triggers);
564 }
565
566 // Restore CPU frequency
567 rtc_clk_cpu_freq_set_config(&cpu_freq_config);
568
569 if (!deep_sleep) {
570 s_config.ccount_ticks_record = cpu_ll_get_cycle_count();
571 }
572
573 #if SOC_PM_SUPPORT_CPU_PD
574 rtc_cntl_hal_disable_cpu_retention();
575 #endif
576
577 #if CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL
578 gpio_sleep_mode_config_unapply();
579 #endif
580
581 #if CONFIG_MAC_BB_PD
582 mac_bb_power_up_cb_execute();
583 #endif
584 // re-enable UART output
585 resume_uarts();
586
587 return result;
588 }
589
call_rtc_sleep_start(uint32_t reject_triggers)590 inline static uint32_t IRAM_ATTR call_rtc_sleep_start(uint32_t reject_triggers)
591 {
592 #ifdef CONFIG_IDF_TARGET_ESP32
593 return rtc_sleep_start(s_config.wakeup_triggers, reject_triggers);
594 #else
595 return rtc_sleep_start(s_config.wakeup_triggers, reject_triggers, 1);
596 #endif
597 }
598
esp_deep_sleep_start(void)599 void IRAM_ATTR esp_deep_sleep_start(void)
600 {
601 #if CONFIG_IDF_TARGET_ESP32S2
602 /* Due to hardware limitations, on S2 the brownout detector sometimes trigger during deep sleep
603 to circumvent this we disable the brownout detector before sleeping */
604 esp_brownout_disable();
605 #endif //CONFIG_IDF_TARGET_ESP32S2
606
607 // record current RTC time
608 s_config.rtc_ticks_at_sleep_start = rtc_time_get();
609
610 // record current RTC time
611 esp_sync_counters_rtc_and_frc();
612 // Configure wake stub
613 if (esp_get_deep_sleep_wake_stub() == NULL) {
614 esp_set_deep_sleep_wake_stub(esp_wake_deep_sleep);
615 }
616
617 // Decide which power domains can be powered down
618 uint32_t pd_flags = get_power_down_flags();
619
620 s_config.rtc_clk_cal_period = esp_clk_slowclk_cal_get();
621
622 // Correct the sleep time
623 s_config.sleep_time_adjustment = DEEP_SLEEP_TIME_OVERHEAD_US;
624
625 uint32_t force_pd_flags = RTC_SLEEP_PD_DIG | RTC_SLEEP_PD_VDDSDIO;
626
627 #if SOC_PM_SUPPORT_WIFI_PD
628 force_pd_flags |= RTC_SLEEP_PD_WIFI;
629 #endif
630
631 #if SOC_PM_SUPPORT_BT_PD
632 force_pd_flags |= RTC_SLEEP_PD_BT;
633 #endif
634
635 // Enter sleep
636 esp_sleep_start(force_pd_flags | pd_flags);
637
638 // Because RTC is in a slower clock domain than the CPU, it
639 // can take several CPU cycles for the sleep mode to start.
640 while (1) {
641 ;
642 }
643 }
644
645 /**
646 * Helper function which handles entry to and exit from light sleep
647 * Placed into IRAM as flash may need some time to be powered on.
648 */
649 static esp_err_t esp_light_sleep_inner(uint32_t pd_flags,
650 uint32_t flash_enable_time_us,
651 rtc_vddsdio_config_t vddsdio_config) IRAM_ATTR __attribute__((noinline));
652
esp_light_sleep_inner(uint32_t pd_flags,uint32_t flash_enable_time_us,rtc_vddsdio_config_t vddsdio_config)653 static esp_err_t esp_light_sleep_inner(uint32_t pd_flags,
654 uint32_t flash_enable_time_us,
655 rtc_vddsdio_config_t vddsdio_config)
656 {
657 // Enter sleep
658 esp_err_t err = esp_sleep_start(pd_flags);
659
660 // If VDDSDIO regulator was controlled by RTC registers before sleep,
661 // restore the configuration.
662 if (vddsdio_config.force) {
663 rtc_vddsdio_set_config(vddsdio_config);
664 }
665
666 // If SPI flash was powered down, wait for it to become ready
667 if (pd_flags & RTC_SLEEP_PD_VDDSDIO) {
668 // Wait for the flash chip to start up
669 esp_rom_delay_us(flash_enable_time_us);
670 }
671 return err;
672 }
673
esp_light_sleep_start(void)674 esp_err_t esp_light_sleep_start(void)
675 {
676 s_config.ccount_ticks_record = cpu_ll_get_cycle_count();
677 static portMUX_TYPE light_sleep_lock = portMUX_INITIALIZER_UNLOCKED;
678 portENTER_CRITICAL(&light_sleep_lock);
679 /* We will be calling esp_timer_private_advance inside DPORT access critical
680 * section. Make sure the code on the other CPU is not holding esp_timer
681 * lock, otherwise there will be deadlock.
682 */
683 esp_timer_private_lock();
684
685 s_config.rtc_ticks_at_sleep_start = rtc_time_get();
686 uint32_t ccount_at_sleep_start = cpu_ll_get_cycle_count();
687 uint64_t frc_time_at_start = esp_system_get_time();
688 uint32_t sleep_time_overhead_in = (ccount_at_sleep_start - s_config.ccount_ticks_record) / (esp_clk_cpu_freq() / 1000000ULL);
689
690 DPORT_STALL_OTHER_CPU_START();
691
692 // Decide which power domains can be powered down
693 uint32_t pd_flags = get_power_down_flags();
694
695 // Re-calibrate the RTC Timer clock
696 #if defined(CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS) || defined(CONFIG_ESP32S2_RTC_CLK_SRC_EXT_CRYS) || defined(CONFIG_ESP32C3_RTC_CLK_SRC_EXT_CRYS)
697 uint64_t time_per_us = 1000000ULL;
698 s_config.rtc_clk_cal_period = (time_per_us << RTC_CLK_CAL_FRACT) / rtc_clk_slow_freq_get_hz();
699 #elif defined(CONFIG_ESP32S2_RTC_CLK_SRC_INT_RC)
700 s_config.rtc_clk_cal_period = rtc_clk_cal_cycling(RTC_CAL_RTC_MUX, RTC_CLK_SRC_CAL_CYCLES);
701 esp_clk_slowclk_cal_set(s_config.rtc_clk_cal_period);
702 #else
703 s_config.rtc_clk_cal_period = rtc_clk_cal(RTC_CAL_RTC_MUX, RTC_CLK_SRC_CAL_CYCLES);
704 esp_clk_slowclk_cal_set(s_config.rtc_clk_cal_period);
705 #endif
706
707 /*
708 * Adjustment time consists of parts below:
709 * 1. Hardware time waiting for internal 8M oscilate clock and XTAL;
710 * 2. Hardware state swithing time of the rtc main state machine;
711 * 3. Code execution time when clock is not stable;
712 * 4. Code execution time which can be measured;
713 */
714
715 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);
716 s_config.sleep_time_adjustment = LIGHT_SLEEP_TIME_OVERHEAD_US + sleep_time_overhead_in + s_config.sleep_time_overhead_out
717 + 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);
718
719 // Decide if VDD_SDIO needs to be powered down;
720 // If it needs to be powered down, adjust sleep time.
721 const uint32_t flash_enable_time_us = VDD_SDIO_POWERUP_TO_FLASH_READ_US + DEEP_SLEEP_WAKEUP_DELAY;
722
723 /**
724 * If VDD_SDIO power domain is requested to be turned off, bit `RTC_SLEEP_PD_VDDSDIO`
725 * will be set in `pd_flags`.
726 */
727 if (pd_flags & RTC_SLEEP_PD_VDDSDIO) {
728 /*
729 * When VDD_SDIO power domain has to be turned off, the minimum sleep time of the
730 * system needs to meet the sum below:
731 * 1. Wait time for the flash power-on after waking up;
732 * 2. The execution time of codes between RTC Timer get start time
733 * with hardware starts to switch state to sleep;
734 * 3. The hardware state switching time of the rtc state machine during
735 * sleep and wake-up. This process requires 6 cycles to complete.
736 * The specific hardware state switching process and the cycles
737 * consumed are rtc_cpu_run_stall(1), cut_pll_rtl(2), cut_8m(1),
738 * min_protect(2);
739 * 4. All the adjustment time which is s_config.sleep_time_adjustment below.
740 */
741 const uint32_t vddsdio_pd_sleep_duration = MAX(FLASH_PD_MIN_SLEEP_TIME_US,
742 flash_enable_time_us + LIGHT_SLEEP_MIN_TIME_US + s_config.sleep_time_adjustment
743 + rtc_time_slowclk_to_us(RTC_MODULE_SLEEP_PREPARE_CYCLES, s_config.rtc_clk_cal_period));
744
745 if (s_config.sleep_duration > vddsdio_pd_sleep_duration) {
746 if (s_config.sleep_time_overhead_out < flash_enable_time_us) {
747 s_config.sleep_time_adjustment += flash_enable_time_us;
748 }
749 } else {
750 /**
751 * Minimum sleep time is not enough, then keep the VDD_SDIO power
752 * domain on.
753 */
754 pd_flags &= ~RTC_SLEEP_PD_VDDSDIO;
755 if (s_config.sleep_time_overhead_out > flash_enable_time_us) {
756 s_config.sleep_time_adjustment -= flash_enable_time_us;
757 }
758 }
759 }
760
761 periph_inform_out_light_sleep_overhead(s_config.sleep_time_adjustment - sleep_time_overhead_in);
762
763 #if SOC_PM_SUPPORT_CPU_PD
764 rtc_cntl_hal_enable_cpu_retention(s_config.cpu_pd_mem);
765 #endif
766
767 rtc_vddsdio_config_t vddsdio_config = rtc_vddsdio_get_config();
768
769 // Safety net: enable WDT in case exit from light sleep fails
770 wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &RTCCNTL};
771 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.
772 if (!wdt_was_enabled) {
773 wdt_hal_init(&rtc_wdt_ctx, WDT_RWDT, 0, false);
774 uint32_t stage_timeout_ticks = (uint32_t)(1000ULL * rtc_clk_slow_freq_get_hz() / 1000ULL);
775 wdt_hal_write_protect_disable(&rtc_wdt_ctx);
776 wdt_hal_config_stage(&rtc_wdt_ctx, WDT_STAGE0, stage_timeout_ticks, WDT_STAGE_ACTION_RESET_RTC);
777 wdt_hal_enable(&rtc_wdt_ctx);
778 wdt_hal_write_protect_enable(&rtc_wdt_ctx);
779 }
780
781 // Enter sleep, then wait for flash to be ready on wakeup
782 esp_err_t err = esp_light_sleep_inner(pd_flags,
783 flash_enable_time_us, vddsdio_config);
784
785 s_light_sleep_wakeup = true;
786
787 // FRC1 has been clock gated for the duration of the sleep, correct for that.
788 #ifdef CONFIG_IDF_TARGET_ESP32C3
789 /**
790 * On esp32c3, rtc_time_get() is non-blocking, esp_system_get_time() is
791 * blocking, and the measurement data shows that this order is better.
792 */
793 uint64_t frc_time_at_end = esp_system_get_time();
794 uint64_t rtc_ticks_at_end = rtc_time_get();
795 #else
796 uint64_t rtc_ticks_at_end = rtc_time_get();
797 uint64_t frc_time_at_end = esp_system_get_time();
798 #endif
799
800 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);
801 uint64_t frc_time_diff = frc_time_at_end - frc_time_at_start;
802
803 int64_t time_diff = rtc_time_diff - frc_time_diff;
804 /* Small negative values (up to 1 RTC_SLOW clock period) are possible,
805 * for very small values of sleep_duration. Ignore those to keep esp_timer
806 * monotonic.
807 */
808 if (time_diff > 0) {
809 esp_timer_private_advance(time_diff);
810 }
811 esp_set_time_from_rtc();
812
813 esp_timer_private_unlock();
814 DPORT_STALL_OTHER_CPU_END();
815 if (!wdt_was_enabled) {
816 wdt_hal_write_protect_disable(&rtc_wdt_ctx);
817 wdt_hal_disable(&rtc_wdt_ctx);
818 wdt_hal_write_protect_enable(&rtc_wdt_ctx);
819 }
820 portEXIT_CRITICAL(&light_sleep_lock);
821 s_config.sleep_time_overhead_out = (cpu_ll_get_cycle_count() - s_config.ccount_ticks_record) / (esp_clk_cpu_freq() / 1000000ULL);
822 return err;
823 }
824
esp_sleep_disable_wakeup_source(esp_sleep_source_t source)825 esp_err_t esp_sleep_disable_wakeup_source(esp_sleep_source_t source)
826 {
827 // For most of sources it is enough to set trigger mask in local
828 // configuration structure. The actual RTC wake up options
829 // will be updated by esp_sleep_start().
830 if (source == ESP_SLEEP_WAKEUP_ALL) {
831 s_config.wakeup_triggers = 0;
832 } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_TIMER, RTC_TIMER_TRIG_EN)) {
833 s_config.wakeup_triggers &= ~RTC_TIMER_TRIG_EN;
834 s_config.sleep_duration = 0;
835 #if SOC_PM_SUPPORT_EXT_WAKEUP
836 } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_EXT0, RTC_EXT0_TRIG_EN)) {
837 s_config.ext0_rtc_gpio_num = 0;
838 s_config.ext0_trigger_level = 0;
839 s_config.wakeup_triggers &= ~RTC_EXT0_TRIG_EN;
840 } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_EXT1, RTC_EXT1_TRIG_EN)) {
841 s_config.ext1_rtc_gpio_mask = 0;
842 s_config.ext1_trigger_mode = 0;
843 s_config.wakeup_triggers &= ~RTC_EXT1_TRIG_EN;
844 #endif
845 #if SOC_TOUCH_PAD_WAKE_SUPPORTED
846 } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_TOUCHPAD, RTC_TOUCH_TRIG_EN)) {
847 s_config.wakeup_triggers &= ~RTC_TOUCH_TRIG_EN;
848 #endif
849 } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_GPIO, RTC_GPIO_TRIG_EN)) {
850 s_config.wakeup_triggers &= ~RTC_GPIO_TRIG_EN;
851 } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_UART, (RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN))) {
852 s_config.wakeup_triggers &= ~(RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN);
853 }
854 #if defined(CONFIG_ESP32_ULP_COPROC_ENABLED) || defined(CONFIG_ESP32S2_ULP_COPROC_ENABLED)
855 else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_ULP, RTC_ULP_TRIG_EN)) {
856 s_config.wakeup_triggers &= ~RTC_ULP_TRIG_EN;
857 }
858 #endif
859 else {
860 ESP_LOGE(TAG, "Incorrect wakeup source (%d) to disable.", (int) source);
861 return ESP_ERR_INVALID_STATE;
862 }
863 return ESP_OK;
864 }
865
esp_sleep_enable_ulp_wakeup(void)866 esp_err_t esp_sleep_enable_ulp_wakeup(void)
867 {
868 #if CONFIG_IDF_TARGET_ESP32
869 #if ((defined CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT) || (defined CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT_V2))
870 ESP_LOGE(TAG, "Failed to enable wakeup when provide current to external 32kHz crystal");
871 return ESP_ERR_NOT_SUPPORTED;
872 #endif
873 #ifdef CONFIG_ESP32_ULP_COPROC_ENABLED
874 if (s_config.wakeup_triggers & RTC_EXT0_TRIG_EN) {
875 ESP_LOGE(TAG, "Conflicting wake-up trigger: ext0");
876 return ESP_ERR_INVALID_STATE;
877 }
878 s_config.wakeup_triggers |= RTC_ULP_TRIG_EN;
879 return ESP_OK;
880 #else // CONFIG_ESP32_ULP_COPROC_ENABLED
881 return ESP_ERR_INVALID_STATE;
882 #endif // CONFIG_ESP32_ULP_COPROC_ENABLED
883 #elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
884 s_config.wakeup_triggers |= (RTC_ULP_TRIG_EN | RTC_COCPU_TRIG_EN | RTC_COCPU_TRAP_TRIG_EN);
885 return ESP_OK;
886 #else
887 return ESP_ERR_NOT_SUPPORTED;
888 #endif
889 }
890
esp_sleep_enable_timer_wakeup(uint64_t time_in_us)891 esp_err_t esp_sleep_enable_timer_wakeup(uint64_t time_in_us)
892 {
893 s_config.wakeup_triggers |= RTC_TIMER_TRIG_EN;
894 s_config.sleep_duration = time_in_us;
895 return ESP_OK;
896 }
897
timer_wakeup_prepare(void)898 static void timer_wakeup_prepare(void)
899 {
900 int64_t sleep_duration = (int64_t) s_config.sleep_duration - (int64_t) s_config.sleep_time_adjustment;
901 if (sleep_duration < 0) {
902 sleep_duration = 0;
903 }
904
905 int64_t ticks = rtc_time_us_to_slowclk(sleep_duration, s_config.rtc_clk_cal_period);
906 rtc_hal_set_wakeup_timer(s_config.rtc_ticks_at_sleep_start + ticks);
907 }
908
909 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
910 /* In deep sleep mode, only the sleep channel is supported, and other touch channels should be turned off. */
touch_wakeup_prepare(void)911 static void touch_wakeup_prepare(void)
912 {
913 uint16_t sleep_cycle = 0;
914 uint16_t meas_times = 0;
915 touch_pad_t touch_num = TOUCH_PAD_NUM0;
916 touch_ll_sleep_get_channel_num(&touch_num); // Check if the sleep pad is enabled.
917 if ((touch_num > TOUCH_PAD_NUM0) && (touch_num < TOUCH_PAD_MAX) && touch_ll_get_fsm_state()) {
918 touch_ll_stop_fsm();
919 touch_ll_clear_channel_mask(TOUCH_PAD_BIT_MASK_ALL);
920 touch_ll_intr_clear(TOUCH_PAD_INTR_MASK_ALL); // Clear state from previous wakeup
921 touch_hal_sleep_channel_get_work_time(&sleep_cycle, &meas_times);
922 touch_ll_set_meas_times(meas_times);
923 touch_ll_set_sleep_time(sleep_cycle);
924 touch_ll_set_channel_mask(BIT(touch_num));
925 touch_ll_start_fsm();
926 }
927 }
928 #endif
929
930 #if SOC_TOUCH_SENSOR_NUM > 0
931
esp_sleep_enable_touchpad_wakeup(void)932 esp_err_t esp_sleep_enable_touchpad_wakeup(void)
933 {
934 #if ((defined CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT) || (defined CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT_V2))
935 ESP_LOGE(TAG, "Failed to enable wakeup when provide current to external 32kHz crystal");
936 return ESP_ERR_NOT_SUPPORTED;
937 #endif
938 if (s_config.wakeup_triggers & (RTC_EXT0_TRIG_EN)) {
939 ESP_LOGE(TAG, "Conflicting wake-up trigger: ext0");
940 return ESP_ERR_INVALID_STATE;
941 }
942 s_config.wakeup_triggers |= RTC_TOUCH_TRIG_EN;
943 return ESP_OK;
944 }
945
esp_sleep_get_touchpad_wakeup_status(void)946 touch_pad_t esp_sleep_get_touchpad_wakeup_status(void)
947 {
948 if (esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_TOUCHPAD) {
949 return TOUCH_PAD_MAX;
950 }
951 touch_pad_t pad_num;
952 esp_err_t ret = touch_pad_get_wakeup_status(&pad_num); //TODO 723diff commit id:fda9ada1b
953 assert(ret == ESP_OK && "wakeup reason is RTC_TOUCH_TRIG_EN but SENS_TOUCH_MEAS_EN is zero");
954 return pad_num;
955 }
956
957 #endif // SOC_TOUCH_SENSOR_NUM > 0
958
esp_sleep_is_valid_wakeup_gpio(gpio_num_t gpio_num)959 bool esp_sleep_is_valid_wakeup_gpio(gpio_num_t gpio_num)
960 {
961 #if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
962 return RTC_GPIO_IS_VALID_GPIO(gpio_num);
963 #else
964 return GPIO_IS_DEEP_SLEEP_WAKEUP_VALID_GPIO(gpio_num);
965 #endif // SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
966 }
967
968 #if SOC_PM_SUPPORT_EXT_WAKEUP
969
esp_sleep_enable_ext0_wakeup(gpio_num_t gpio_num,int level)970 esp_err_t esp_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level)
971 {
972 if (level < 0 || level > 1) {
973 return ESP_ERR_INVALID_ARG;
974 }
975 if (!esp_sleep_is_valid_wakeup_gpio(gpio_num)) {
976 return ESP_ERR_INVALID_ARG;
977 }
978 if (s_config.wakeup_triggers & (RTC_TOUCH_TRIG_EN | RTC_ULP_TRIG_EN)) {
979 ESP_LOGE(TAG, "Conflicting wake-up triggers: touch / ULP");
980 return ESP_ERR_INVALID_STATE;
981 }
982 s_config.ext0_rtc_gpio_num = rtc_io_number_get(gpio_num);
983 s_config.ext0_trigger_level = level;
984 s_config.wakeup_triggers |= RTC_EXT0_TRIG_EN;
985 return ESP_OK;
986 }
987
ext0_wakeup_prepare(void)988 static void ext0_wakeup_prepare(void)
989 {
990 int rtc_gpio_num = s_config.ext0_rtc_gpio_num;
991 rtcio_hal_ext0_set_wakeup_pin(rtc_gpio_num, s_config.ext0_trigger_level);
992 rtcio_hal_function_select(rtc_gpio_num, RTCIO_FUNC_RTC);
993 rtcio_hal_input_enable(rtc_gpio_num);
994 }
995
esp_sleep_enable_ext1_wakeup(uint64_t mask,esp_sleep_ext1_wakeup_mode_t mode)996 esp_err_t esp_sleep_enable_ext1_wakeup(uint64_t mask, esp_sleep_ext1_wakeup_mode_t mode)
997 {
998 if (mode > ESP_EXT1_WAKEUP_ANY_HIGH) {
999 return ESP_ERR_INVALID_ARG;
1000 }
1001 // Translate bit map of GPIO numbers into the bit map of RTC IO numbers
1002 uint32_t rtc_gpio_mask = 0;
1003 for (int gpio = 0; mask; ++gpio, mask >>= 1) {
1004 if ((mask & 1) == 0) {
1005 continue;
1006 }
1007 if (!esp_sleep_is_valid_wakeup_gpio(gpio)) {
1008 ESP_LOGE(TAG, "Not an RTC IO: GPIO%d", gpio);
1009 return ESP_ERR_INVALID_ARG;
1010 }
1011 rtc_gpio_mask |= BIT(rtc_io_number_get(gpio));
1012 }
1013 s_config.ext1_rtc_gpio_mask = rtc_gpio_mask;
1014 s_config.ext1_trigger_mode = mode;
1015 s_config.wakeup_triggers |= RTC_EXT1_TRIG_EN;
1016 return ESP_OK;
1017 }
1018
ext1_wakeup_prepare(void)1019 static void ext1_wakeup_prepare(void)
1020 {
1021 // Configure all RTC IOs selected as ext1 wakeup inputs
1022 uint32_t rtc_gpio_mask = s_config.ext1_rtc_gpio_mask;
1023 for (int gpio = 0; gpio < GPIO_PIN_COUNT && rtc_gpio_mask != 0; ++gpio) {
1024 int rtc_pin = rtc_io_number_get(gpio);
1025 if ((rtc_gpio_mask & BIT(rtc_pin)) == 0) {
1026 continue;
1027 }
1028 #if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
1029 // Route pad to RTC
1030 rtcio_hal_function_select(rtc_pin, RTCIO_FUNC_RTC);
1031 // set input enable in sleep mode
1032 rtcio_hal_input_enable(rtc_pin);
1033 #endif
1034
1035 // Pad configuration depends on RTC_PERIPH state in sleep mode
1036 if (s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] != ESP_PD_OPTION_ON) {
1037 #if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
1038 // RTC_PERIPH will be powered down, so RTC_IO_ registers will
1039 // loose their state. Lock pad configuration.
1040 // Pullups/pulldowns also need to be disabled.
1041 rtcio_hal_pullup_disable(rtc_pin);
1042 rtcio_hal_pulldown_disable(rtc_pin);
1043 #endif
1044 rtcio_hal_hold_enable(rtc_pin);
1045 }
1046 // Keep track of pins which are processed to bail out early
1047 rtc_gpio_mask &= ~BIT(rtc_pin);
1048 }
1049
1050 // Clear state from previous wakeup
1051 rtc_hal_ext1_clear_wakeup_pins();
1052 // Set RTC IO pins and mode (any high, all low) to be used for wakeup
1053 rtc_hal_ext1_set_wakeup_pins(s_config.ext1_rtc_gpio_mask, s_config.ext1_trigger_mode);
1054 }
1055
esp_sleep_get_ext1_wakeup_status(void)1056 uint64_t esp_sleep_get_ext1_wakeup_status(void)
1057 {
1058 if (esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_EXT1) {
1059 return 0;
1060 }
1061 uint32_t status = rtc_hal_ext1_get_wakeup_pins();
1062 // Translate bit map of RTC IO numbers into the bit map of GPIO numbers
1063 uint64_t gpio_mask = 0;
1064 for (int gpio = 0; gpio < GPIO_PIN_COUNT; ++gpio) {
1065 if (!esp_sleep_is_valid_wakeup_gpio(gpio)) {
1066 continue;
1067 }
1068 int rtc_pin = rtc_io_number_get(gpio);
1069 if ((status & BIT(rtc_pin)) == 0) {
1070 continue;
1071 }
1072 gpio_mask |= 1ULL << gpio;
1073 }
1074 return gpio_mask;
1075 }
1076
1077 #endif // SOC_PM_SUPPORT_EXT_WAKEUP
1078
1079 #if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP
esp_sleep_get_gpio_wakeup_status(void)1080 uint64_t esp_sleep_get_gpio_wakeup_status(void)
1081 {
1082 if (esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_GPIO) {
1083 return 0;
1084 }
1085
1086 return rtc_hal_gpio_get_wakeup_pins();
1087 }
1088
esp_deep_sleep_wakeup_prepare(void)1089 static void esp_deep_sleep_wakeup_prepare(void)
1090 {
1091 for (gpio_num_t gpio_idx = GPIO_NUM_0; gpio_idx < GPIO_NUM_MAX; gpio_idx++) {
1092 if (((1ULL << gpio_idx) & s_config.gpio_wakeup_mask) == 0) {
1093 continue;
1094 }
1095 if (s_config.gpio_trigger_mode & BIT(gpio_idx)) {
1096 ESP_ERROR_CHECK(gpio_pullup_dis(gpio_idx));
1097 ESP_ERROR_CHECK(gpio_pulldown_en(gpio_idx));
1098 } else {
1099 ESP_ERROR_CHECK(gpio_pullup_en(gpio_idx));
1100 ESP_ERROR_CHECK(gpio_pulldown_dis(gpio_idx));
1101 }
1102 rtc_hal_gpio_set_wakeup_pins();
1103 ESP_ERROR_CHECK(gpio_hold_en(gpio_idx));
1104 }
1105 }
1106
esp_deep_sleep_enable_gpio_wakeup(uint64_t gpio_pin_mask,esp_deepsleep_gpio_wake_up_mode_t mode)1107 esp_err_t esp_deep_sleep_enable_gpio_wakeup(uint64_t gpio_pin_mask, esp_deepsleep_gpio_wake_up_mode_t mode)
1108 {
1109 if (mode > ESP_GPIO_WAKEUP_GPIO_HIGH) {
1110 ESP_LOGE(TAG, "invalid mode");
1111 return ESP_ERR_INVALID_ARG;
1112 }
1113 gpio_int_type_t intr_type = ((mode == ESP_GPIO_WAKEUP_GPIO_LOW) ? GPIO_INTR_LOW_LEVEL : GPIO_INTR_HIGH_LEVEL);
1114 esp_err_t err = ESP_OK;
1115 for (gpio_num_t gpio_idx = GPIO_NUM_0; gpio_idx < GPIO_NUM_MAX; gpio_idx++, gpio_pin_mask >>= 1) {
1116 if ((gpio_pin_mask & 1) == 0) {
1117 continue;
1118 }
1119 if (!esp_sleep_is_valid_wakeup_gpio(gpio_idx)) {
1120 ESP_LOGE(TAG, "invalid mask, please ensure gpio number is no more than 5");
1121 return ESP_ERR_INVALID_ARG;
1122 }
1123 err = gpio_deep_sleep_wakeup_enable(gpio_idx, intr_type);
1124
1125 s_config.gpio_wakeup_mask |= BIT(gpio_idx);
1126 if (mode == ESP_GPIO_WAKEUP_GPIO_HIGH) {
1127 s_config.gpio_trigger_mode |= (mode << gpio_idx);
1128 } else {
1129 s_config.gpio_trigger_mode &= ~(mode << gpio_idx);
1130 }
1131 }
1132 s_config.wakeup_triggers |= RTC_GPIO_TRIG_EN;
1133 rtc_hal_gpio_clear_wakeup_pins();
1134 return err;
1135 }
1136
1137 #endif //SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP
1138
esp_sleep_enable_gpio_wakeup(void)1139 esp_err_t esp_sleep_enable_gpio_wakeup(void)
1140 {
1141 #if CONFIG_IDF_TARGET_ESP32
1142 if (s_config.wakeup_triggers & (RTC_TOUCH_TRIG_EN | RTC_ULP_TRIG_EN)) {
1143 ESP_LOGE(TAG, "Conflicting wake-up triggers: touch / ULP");
1144 return ESP_ERR_INVALID_STATE;
1145 }
1146 #endif
1147 s_config.wakeup_triggers |= RTC_GPIO_TRIG_EN;
1148 return ESP_OK;
1149 }
1150
esp_sleep_enable_uart_wakeup(int uart_num)1151 esp_err_t esp_sleep_enable_uart_wakeup(int uart_num)
1152 {
1153 if (uart_num == UART_NUM_0) {
1154 s_config.wakeup_triggers |= RTC_UART0_TRIG_EN;
1155 } else if (uart_num == UART_NUM_1) {
1156 s_config.wakeup_triggers |= RTC_UART1_TRIG_EN;
1157 } else {
1158 return ESP_ERR_INVALID_ARG;
1159 }
1160
1161 return ESP_OK;
1162 }
1163
esp_sleep_enable_wifi_wakeup(void)1164 esp_err_t esp_sleep_enable_wifi_wakeup(void)
1165 {
1166 #if SOC_PM_SUPPORT_WIFI_WAKEUP
1167 s_config.wakeup_triggers |= RTC_WIFI_TRIG_EN;
1168 return ESP_OK;
1169 #else
1170 return ESP_ERR_NOT_SUPPORTED;
1171 #endif
1172 }
1173
esp_sleep_disable_wifi_wakeup(void)1174 esp_err_t esp_sleep_disable_wifi_wakeup(void)
1175 {
1176 #if SOC_PM_SUPPORT_WIFI_WAKEUP
1177 s_config.wakeup_triggers &= (~RTC_WIFI_TRIG_EN);
1178 return ESP_OK;
1179 #else
1180 return ESP_ERR_NOT_SUPPORTED;
1181 #endif
1182 }
1183
esp_sleep_get_wakeup_cause(void)1184 esp_sleep_wakeup_cause_t esp_sleep_get_wakeup_cause(void)
1185 {
1186 if (rtc_get_reset_reason(0) != DEEPSLEEP_RESET && !s_light_sleep_wakeup) {
1187 return ESP_SLEEP_WAKEUP_UNDEFINED;
1188 }
1189
1190 #ifdef CONFIG_IDF_TARGET_ESP32
1191 uint32_t wakeup_cause = REG_GET_FIELD(RTC_CNTL_WAKEUP_STATE_REG, RTC_CNTL_WAKEUP_CAUSE);
1192 #else
1193 uint32_t wakeup_cause = REG_GET_FIELD(RTC_CNTL_SLP_WAKEUP_CAUSE_REG, RTC_CNTL_WAKEUP_CAUSE);
1194 #endif
1195
1196 if (wakeup_cause & RTC_TIMER_TRIG_EN) {
1197 return ESP_SLEEP_WAKEUP_TIMER;
1198 } else if (wakeup_cause & RTC_GPIO_TRIG_EN) {
1199 return ESP_SLEEP_WAKEUP_GPIO;
1200 } else if (wakeup_cause & (RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN)) {
1201 return ESP_SLEEP_WAKEUP_UART;
1202 #if SOC_PM_SUPPORT_EXT_WAKEUP
1203 } else if (wakeup_cause & RTC_EXT0_TRIG_EN) {
1204 return ESP_SLEEP_WAKEUP_EXT0;
1205 } else if (wakeup_cause & RTC_EXT1_TRIG_EN) {
1206 return ESP_SLEEP_WAKEUP_EXT1;
1207 #endif
1208 #if SOC_TOUCH_PAD_WAKE_SUPPORTED
1209 } else if (wakeup_cause & RTC_TOUCH_TRIG_EN) {
1210 return ESP_SLEEP_WAKEUP_TOUCHPAD;
1211 #endif
1212 #if SOC_ULP_SUPPORTED
1213 } else if (wakeup_cause & RTC_ULP_TRIG_EN) {
1214 return ESP_SLEEP_WAKEUP_ULP;
1215 #endif
1216 #if SOC_PM_SUPPORT_WIFI_WAKEUP
1217 } else if (wakeup_cause & RTC_WIFI_TRIG_EN) {
1218 return ESP_SLEEP_WAKEUP_WIFI;
1219 #endif
1220 #if SOC_PM_SUPPORT_BT_WAKEUP
1221 } else if (wakeup_cause & RTC_BT_TRIG_EN) {
1222 return ESP_SLEEP_WAKEUP_BT;
1223 #endif
1224 #if CONFIG_IDF_TARGET_ESP32S2
1225 } else if (wakeup_cause & RTC_COCPU_TRIG_EN) {
1226 return ESP_SLEEP_WAKEUP_ULP;
1227 } else if (wakeup_cause & RTC_COCPU_TRAP_TRIG_EN) {
1228 return ESP_SLEEP_WAKEUP_COCPU_TRAP_TRIG;
1229 #endif
1230 } else {
1231 return ESP_SLEEP_WAKEUP_UNDEFINED;
1232 }
1233 }
1234
esp_sleep_pd_config(esp_sleep_pd_domain_t domain,esp_sleep_pd_option_t option)1235 esp_err_t esp_sleep_pd_config(esp_sleep_pd_domain_t domain,
1236 esp_sleep_pd_option_t option)
1237 {
1238 if (domain >= ESP_PD_DOMAIN_MAX || option > ESP_PD_OPTION_AUTO) {
1239 return ESP_ERR_INVALID_ARG;
1240 }
1241 s_config.pd_options[domain] = option;
1242 return ESP_OK;
1243 }
1244
get_power_down_flags(void)1245 static uint32_t get_power_down_flags(void)
1246 {
1247 // Where needed, convert AUTO options to ON. Later interpret AUTO as OFF.
1248
1249 // RTC_SLOW_MEM is needed for the ULP, so keep RTC_SLOW_MEM powered up if ULP
1250 // is used and RTC_SLOW_MEM is Auto.
1251 // If there is any data placed into .rtc.data or .rtc.bss segments, and
1252 // RTC_SLOW_MEM is Auto, keep it powered up as well.
1253
1254 #if SOC_RTC_SLOW_MEM_SUPPORTED && SOC_ULP_SUPPORTED
1255 // Labels are defined in the linker script
1256 extern int _rtc_slow_length;
1257
1258 if ((s_config.pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM] == ESP_PD_OPTION_AUTO) &&
1259 ((size_t) &_rtc_slow_length > 0 ||
1260 (s_config.wakeup_triggers & RTC_ULP_TRIG_EN))) {
1261 s_config.pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM] = ESP_PD_OPTION_ON;
1262 }
1263 #endif
1264
1265 #if !CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP
1266 /* RTC_FAST_MEM is needed for deep sleep stub.
1267 If RTC_FAST_MEM is Auto, keep it powered on, so that deep sleep stub can run.
1268 In the new chip revision, deep sleep stub will be optional, and this can be changed. */
1269 if (s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM] == ESP_PD_OPTION_AUTO) {
1270 s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM] = ESP_PD_OPTION_ON;
1271 }
1272 #else
1273 /* If RTC_FAST_MEM is used for heap, force RTC_FAST_MEM to be powered on. */
1274 s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM] = ESP_PD_OPTION_ON;
1275 #endif
1276
1277 // RTC_PERIPH is needed for EXT0 wakeup and GPIO wakeup.
1278 // If RTC_PERIPH is auto, and EXT0/GPIO aren't enabled, power down RTC_PERIPH.
1279 if (s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] == ESP_PD_OPTION_AUTO) {
1280 #if SOC_TOUCH_PAD_WAKE_SUPPORTED
1281 uint32_t wakeup_source = RTC_TOUCH_TRIG_EN;
1282 #if SOC_ULP_SUPPORTED
1283 wakeup_source |= RTC_ULP_TRIG_EN;
1284 #endif
1285 if (s_config.wakeup_triggers & (RTC_EXT0_TRIG_EN | RTC_GPIO_TRIG_EN)) {
1286 s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] = ESP_PD_OPTION_ON;
1287 } else if (s_config.wakeup_triggers & wakeup_source) {
1288 // In both rev. 0 and rev. 1 of ESP32, forcing power up of RTC_PERIPH
1289 // prevents ULP timer and touch FSMs from working correctly.
1290 s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] = ESP_PD_OPTION_OFF;
1291 }
1292 #else
1293 if (s_config.wakeup_triggers & RTC_GPIO_TRIG_EN) {
1294 s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] = ESP_PD_OPTION_ON;
1295 } else {
1296 s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] = ESP_PD_OPTION_OFF;
1297 }
1298 #endif // SOC_TOUCH_PAD_WAKE_SUPPORTED
1299 }
1300
1301 #if SOC_PM_SUPPORT_CPU_PD
1302 if (s_config.cpu_pd_mem == NULL) {
1303 s_config.pd_options[ESP_PD_DOMAIN_CPU] = ESP_PD_OPTION_ON;
1304 }
1305 #else
1306 if (s_config.pd_options[ESP_PD_DOMAIN_CPU] != ESP_PD_OPTION_ON) {
1307 s_config.pd_options[ESP_PD_DOMAIN_CPU] = ESP_PD_OPTION_ON;
1308 }
1309 #endif
1310
1311 if (s_config.pd_options[ESP_PD_DOMAIN_XTAL] == ESP_PD_OPTION_AUTO) {
1312 s_config.pd_options[ESP_PD_DOMAIN_XTAL] = ESP_PD_OPTION_OFF;
1313 }
1314
1315 const char *option_str[] = {"OFF", "ON", "AUTO(OFF)" /* Auto works as OFF */};
1316 ESP_LOGD(TAG, "RTC_PERIPH: %s", option_str[s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH]]);
1317 #if SOC_RTC_SLOW_MEM_SUPPORTED
1318 ESP_LOGD(TAG, "RTC_SLOW_MEM: %s", option_str[s_config.pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM]]);
1319 #endif
1320 ESP_LOGD(TAG, "RTC_FAST_MEM: %s", option_str[s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM]]);
1321
1322 // Prepare flags based on the selected options
1323 uint32_t pd_flags = 0;
1324 if (s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM] != ESP_PD_OPTION_ON) {
1325 pd_flags |= RTC_SLEEP_PD_RTC_FAST_MEM;
1326 }
1327 #if SOC_RTC_SLOW_MEM_SUPPORTED
1328 if (s_config.pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM] != ESP_PD_OPTION_ON) {
1329 pd_flags |= RTC_SLEEP_PD_RTC_SLOW_MEM;
1330 }
1331 #endif
1332 if (s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] != ESP_PD_OPTION_ON) {
1333 pd_flags |= RTC_SLEEP_PD_RTC_PERIPH;
1334 }
1335
1336 #if SOC_PM_SUPPORT_CPU_PD
1337 if (s_config.pd_options[ESP_PD_DOMAIN_CPU] != ESP_PD_OPTION_ON) {
1338 pd_flags |= RTC_SLEEP_PD_CPU;
1339 }
1340 #endif
1341
1342 #ifdef CONFIG_IDF_TARGET_ESP32
1343 pd_flags |= RTC_SLEEP_PD_XTAL;
1344 #endif
1345
1346 /**
1347 * VDD_SDIO power domain shall be kept on during the light sleep
1348 * when CONFIG_ESP_SYSTEM_PD_FLASH is not set and off when it is set.
1349 * The application can still force the power domain to remain on by calling
1350 * `esp_sleep_pd_config` before getting into light sleep mode.
1351 *
1352 * In deep sleep mode, the power domain will be turned off, regardless the
1353 * value of this field.
1354 */
1355 if (s_config.pd_options[ESP_PD_DOMAIN_VDDSDIO] == ESP_PD_OPTION_AUTO) {
1356 #ifdef CONFIG_ESP_SYSTEM_PD_FLASH
1357 s_config.pd_options[ESP_PD_DOMAIN_VDDSDIO] = ESP_PD_OPTION_OFF;
1358 #else
1359 s_config.pd_options[ESP_PD_DOMAIN_VDDSDIO] = ESP_PD_OPTION_ON;
1360 #endif
1361 }
1362
1363 if (s_config.pd_options[ESP_PD_DOMAIN_VDDSDIO] != ESP_PD_OPTION_ON) {
1364 pd_flags |= RTC_SLEEP_PD_VDDSDIO;
1365 }
1366
1367 #if ((defined CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS) && (defined CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT))
1368 if ((s_config.wakeup_triggers & (RTC_TOUCH_TRIG_EN | RTC_ULP_TRIG_EN)) == 0) {
1369 // If enabled EXT1 only and enable the additional current by touch, should be keep RTC_PERIPH power on.
1370 pd_flags &= ~RTC_SLEEP_PD_RTC_PERIPH;
1371 }
1372 #endif
1373
1374 return pd_flags;
1375 }
1376
esp_deep_sleep_disable_rom_logging(void)1377 void esp_deep_sleep_disable_rom_logging(void)
1378 {
1379 esp_rom_disable_logging();
1380 }
1381