sleep_modes.c
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 <sys/lock.h> 17 #include <sys/param.h> 18 19 #include "esp_attr.h" 20 #include "esp_sleep.h" 21 #include "esp_private/esp_timer_private.h" 22 #include "esp_private/system_internal.h" 23 #include "esp_log.h" 24 #include "esp_newlib.h" 25 #include "esp_timer.h" 26 #include "freertos/FreeRTOS.h" 27 #include "freertos/task.h" 28 #include "driver/touch_sensor.h" 29 #include "driver/touch_sensor_common.h" 30 #include "driver/rtc_io.h" 31 #include "driver/uart.h" 32 33 #include "soc/cpu.h" 34 #include "soc/rtc.h" 35 #include "soc/dport_reg.h" 36 #include "soc/soc_caps.h" 37 38 #include "hal/wdt_hal.h" 39 #include "hal/rtc_io_hal.h" 40 #include "hal/rtc_hal.h" 41 #include "hal/uart_hal.h" 42 #include "hal/touch_sensor_hal.h" 43 #include "hal/clk_gate_ll.h" 44 45 #include "sdkconfig.h" 46 #include "esp_rom_uart.h" 47 48 #ifdef CONFIG_IDF_TARGET_ESP32 49 #include "esp32/rom/cache.h" 50 #include "esp32/clk.h" 51 #include "esp32/rom/rtc.h" 52 #elif CONFIG_IDF_TARGET_ESP32S2 53 #include "esp32s2/clk.h" 54 #include "esp32s2/rom/cache.h" 55 #include "esp32s2/rom/rtc.h" 56 #include "soc/extmem_reg.h" 57 #elif CONFIG_IDF_TARGET_ESP32S3 58 #include "esp32s3/clk.h" 59 #include "esp32s3/rom/cache.h" 60 #include "esp32s3/rom/rtc.h" 61 #include "soc/extmem_reg.h" 62 #endif 63 64 // If light sleep time is less than that, don't power down flash 65 #define FLASH_PD_MIN_SLEEP_TIME_US 2000 66 67 // Time from VDD_SDIO power up to first flash read in ROM code 68 #define VDD_SDIO_POWERUP_TO_FLASH_READ_US 700 69 70 #ifdef CONFIG_IDF_TARGET_ESP32 71 #define DEFAULT_CPU_FREQ_MHZ CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ 72 #elif CONFIG_IDF_TARGET_ESP32S2 73 #define DEFAULT_CPU_FREQ_MHZ CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ 74 #elif CONFIG_IDF_TARGET_ESP32S3 75 #define DEFAULT_CPU_FREQ_MHZ CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ 76 #endif 77 78 #if defined(CONFIG_IDF_TARGET_ESP32) 79 #if defined(CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS) 80 #define LIGHT_SLEEP_TIME_OVERHEAD_US (650 + 30 * 240 / DEFAULT_CPU_FREQ_MHZ) 81 #define DEEP_SLEEP_TIME_OVERHEAD_US (650 + 100 * 240 / DEFAULT_CPU_FREQ_MHZ) 82 #else // CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS 83 #define LIGHT_SLEEP_TIME_OVERHEAD_US (250 + 30 * 240 / DEFAULT_CPU_FREQ_MHZ) 84 #define DEEP_SLEEP_TIME_OVERHEAD_US (250 + 100 * 240 / DEFAULT_CPU_FREQ_MHZ) 85 #endif // CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS 86 87 #elif defined(CONFIG_IDF_TARGET_ESP32S2) 88 #if defined(CONFIG_ESP32S2_RTC_CLK_SRC_EXT_CRYS) 89 #define LIGHT_SLEEP_TIME_OVERHEAD_US (1650 + 30 * 240 / DEFAULT_CPU_FREQ_MHZ) 90 #define DEEP_SLEEP_TIME_OVERHEAD_US (650 + 100 * 240 / DEFAULT_CPU_FREQ_MHZ) 91 #else // CONFIG_ESP32S2_RTC_CLK_SRC_EXT_CRYS 92 #define LIGHT_SLEEP_TIME_OVERHEAD_US (1250 + 30 * 240 / DEFAULT_CPU_FREQ_MHZ) 93 #define DEEP_SLEEP_TIME_OVERHEAD_US (250 + 100 * 240 / DEFAULT_CPU_FREQ_MHZ) 94 #endif // CONFIG_ESP32S2_RTC_CLK_SRC_EXT_CRYS 95 96 #else // other target 97 #define LIGHT_SLEEP_TIME_OVERHEAD_US 0 98 #define DEEP_SLEEP_TIME_OVERHEAD_US 0 99 #endif // CONFIG_IDF_TARGET_* 100 101 102 #if defined(CONFIG_IDF_TARGET_ESP32) && defined(CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY) 103 #define DEEP_SLEEP_WAKEUP_DELAY CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY 104 #else 105 #define DEEP_SLEEP_WAKEUP_DELAY 0 106 #endif 107 108 // Minimal amount of time we can sleep for 109 #define LIGHT_SLEEP_MIN_TIME_US 200 110 111 #define CHECK_SOURCE(source, value, mask) ((s_config.wakeup_triggers & mask) && \ 112 (source == value)) 113 114 /** 115 * Internal structure which holds all requested deep sleep parameters 116 */ 117 typedef struct { 118 esp_sleep_pd_option_t pd_options[ESP_PD_DOMAIN_MAX]; 119 uint64_t sleep_duration; 120 uint32_t wakeup_triggers : 11; 121 uint32_t ext1_trigger_mode : 1; 122 uint32_t ext1_rtc_gpio_mask : 18; 123 uint32_t ext0_trigger_level : 1; 124 uint32_t ext0_rtc_gpio_num : 5; 125 uint32_t sleep_time_adjustment; 126 uint64_t rtc_ticks_at_sleep_start; 127 } sleep_config_t; 128 129 static sleep_config_t s_config = { 130 .pd_options = { ESP_PD_OPTION_AUTO, ESP_PD_OPTION_AUTO, ESP_PD_OPTION_AUTO }, 131 .wakeup_triggers = 0 132 }; 133 134 /* Internal variable used to track if light sleep wakeup sources are to be 135 expected when determining wakeup cause. */ 136 static bool s_light_sleep_wakeup = false; 137 138 /* Updating RTC_MEMORY_CRC_REG register via set_rtc_memory_crc() 139 is not thread-safe, so we need to disable interrupts before going to deep sleep. */ 140 static portMUX_TYPE spinlock_rtc_deep_sleep = portMUX_INITIALIZER_UNLOCKED; 141 142 static const char* TAG = "sleep"; 143 144 static uint32_t get_power_down_flags(void); 145 static void ext0_wakeup_prepare(void); 146 static void ext1_wakeup_prepare(void); 147 static void timer_wakeup_prepare(void); 148 149 150 #ifdef CONFIG_IDF_TARGET_ESP32S2 151 static void touch_wakeup_prepare(void); 152 #endif 153 154 /* Wake from deep sleep stub 155 See esp_deepsleep.h esp_wake_deep_sleep() comments for details. 156 */ 157 esp_deep_sleep_wake_stub_fn_t esp_get_deep_sleep_wake_stub(void) 158 { 159 esp_deep_sleep_wake_stub_fn_t stub_ptr = (esp_deep_sleep_wake_stub_fn_t) REG_READ(RTC_ENTRY_ADDR_REG); 160 if (!esp_ptr_executable(stub_ptr)) { 161 return NULL; 162 } 163 return stub_ptr; 164 } 165 166 void esp_set_deep_sleep_wake_stub(esp_deep_sleep_wake_stub_fn_t new_stub) 167 { 168 REG_WRITE(RTC_ENTRY_ADDR_REG, (uint32_t)new_stub); 169 } 170 171 void RTC_IRAM_ATTR esp_default_wake_deep_sleep(void) { 172 /* Clear MMU for CPU 0 */ 173 #if CONFIG_IDF_TARGET_ESP32 174 _DPORT_REG_WRITE(DPORT_PRO_CACHE_CTRL1_REG, 175 _DPORT_REG_READ(DPORT_PRO_CACHE_CTRL1_REG) | DPORT_PRO_CACHE_MMU_IA_CLR); 176 _DPORT_REG_WRITE(DPORT_PRO_CACHE_CTRL1_REG, 177 _DPORT_REG_READ(DPORT_PRO_CACHE_CTRL1_REG) & (~DPORT_PRO_CACHE_MMU_IA_CLR)); 178 #if DEEP_SLEEP_WAKEUP_DELAY > 0 179 // ROM code has not started yet, so we need to set delay factor 180 // used by esp_rom_delay_us first. 181 ets_update_cpu_frequency_rom(ets_get_detected_xtal_freq() / 1000000); 182 // This delay is configured in menuconfig, it can be used to give 183 // the flash chip some time to become ready. 184 esp_rom_delay_us(DEEP_SLEEP_WAKEUP_DELAY); 185 #endif 186 #elif CONFIG_IDF_TARGET_ESP32S2 187 REG_SET_BIT(EXTMEM_CACHE_DBG_INT_ENA_REG, EXTMEM_CACHE_DBG_EN); 188 #endif 189 } 190 191 void __attribute__((weak, alias("esp_default_wake_deep_sleep"))) esp_wake_deep_sleep(void); 192 193 void esp_deep_sleep(uint64_t time_in_us) 194 { 195 esp_sleep_enable_timer_wakeup(time_in_us); 196 esp_deep_sleep_start(); 197 } 198 199 // [refactor-todo] provide target logic for body of uart functions below 200 static void IRAM_ATTR flush_uarts(void) 201 { 202 for (int i = 0; i < SOC_UART_NUM; ++i) { 203 #ifdef CONFIG_IDF_TARGET_ESP32 204 esp_rom_uart_tx_wait_idle(i); 205 #elif CONFIG_IDF_TARGET_ESP32S2 206 if (periph_ll_periph_enabled(PERIPH_UART0_MODULE + i)) { 207 esp_rom_uart_tx_wait_idle(i); 208 } 209 #endif 210 } 211 } 212 213 static void IRAM_ATTR suspend_uarts(void) 214 { 215 for (int i = 0; i < SOC_UART_NUM; ++i) { 216 #ifdef CONFIG_IDF_TARGET_ESP32 217 /* Note: Set `UART_FORCE_XOFF` can't stop new Tx request. */ 218 REG_SET_BIT(UART_FLOW_CONF_REG(i), UART_FORCE_XOFF); 219 while (REG_GET_FIELD(UART_STATUS_REG(i), UART_ST_UTX_OUT) != 0) { 220 ; 221 } 222 #elif CONFIG_IDF_TARGET_ESP32S2 223 if (periph_ll_periph_enabled(PERIPH_UART0_MODULE + i)) { 224 REG_CLR_BIT(UART_FLOW_CONF_REG(i), UART_FORCE_XON); 225 REG_SET_BIT(UART_FLOW_CONF_REG(i), UART_SW_FLOW_CON_EN | UART_FORCE_XOFF); 226 while (REG_GET_FIELD(UART_FSM_STATUS_REG(i), UART_ST_UTX_OUT) != 0) { 227 ; 228 } 229 } 230 #endif 231 } 232 } 233 234 static void IRAM_ATTR resume_uarts(void) 235 { 236 for (int i = 0; i < SOC_UART_NUM; ++i) { 237 #ifdef CONFIG_IDF_TARGET_ESP32 238 REG_CLR_BIT(UART_FLOW_CONF_REG(i), UART_FORCE_XOFF); 239 REG_SET_BIT(UART_FLOW_CONF_REG(i), UART_FORCE_XON); 240 REG_CLR_BIT(UART_FLOW_CONF_REG(i), UART_FORCE_XON); 241 #elif CONFIG_IDF_TARGET_ESP32S2 242 if (periph_ll_periph_enabled(PERIPH_UART0_MODULE + i)) { 243 REG_CLR_BIT(UART_FLOW_CONF_REG(i), UART_FORCE_XOFF); 244 REG_SET_BIT(UART_FLOW_CONF_REG(i), UART_FORCE_XON); 245 REG_CLR_BIT(UART_FLOW_CONF_REG(i), UART_SW_FLOW_CON_EN | UART_FORCE_XON); 246 } 247 #endif 248 } 249 } 250 251 inline static uint32_t IRAM_ATTR call_rtc_sleep_start(uint32_t reject_triggers); 252 253 static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags) 254 { 255 // Stop UART output so that output is not lost due to APB frequency change. 256 // For light sleep, suspend UART output — it will resume after wakeup. 257 // For deep sleep, wait for the contents of UART FIFO to be sent. 258 bool deep_sleep = pd_flags & RTC_SLEEP_PD_DIG; 259 260 #if !CONFIG_FREERTOS_UNICORE && ESP32S3_ALLOW_RTC_FAST_MEM_AS_HEAP 261 /* Currently only safe to use deep sleep wake stub & RTC memory as heap in single core mode. 262 263 For ESP32-S3, either disable ESP32S3_ALLOW_RTC_FAST_MEM_AS_HEAP in config or find a way to set the 264 deep sleep wake stub to NULL. 265 */ 266 assert(!deep_sleep || esp_get_deep_sleep_wake_stub() == NULL); 267 #endif 268 269 if (deep_sleep) { 270 flush_uarts(); 271 } else { 272 suspend_uarts(); 273 } 274 275 // Save current frequency and switch to XTAL 276 rtc_cpu_freq_config_t cpu_freq_config; 277 rtc_clk_cpu_freq_get_config(&cpu_freq_config); 278 rtc_clk_cpu_freq_set_xtal(); 279 280 // Configure pins for external wakeup 281 if (s_config.wakeup_triggers & RTC_EXT0_TRIG_EN) { 282 ext0_wakeup_prepare(); 283 } 284 if (s_config.wakeup_triggers & RTC_EXT1_TRIG_EN) { 285 ext1_wakeup_prepare(); 286 } 287 288 #ifdef CONFIG_IDF_TARGET_ESP32 289 // Enable ULP wakeup 290 if (s_config.wakeup_triggers & RTC_ULP_TRIG_EN) { 291 rtc_hal_ulp_wakeup_enable(); 292 } 293 #endif 294 295 #ifdef CONFIG_IDF_TARGET_ESP32S2 296 // Enable Touch wakeup 297 if (s_config.wakeup_triggers & RTC_TOUCH_TRIG_EN) { 298 touch_wakeup_prepare(); 299 } 300 #endif 301 302 uint32_t reject_triggers = 0; 303 if ((pd_flags & RTC_SLEEP_PD_DIG) == 0 && (s_config.wakeup_triggers & RTC_GPIO_TRIG_EN)) { 304 /* Light sleep, enable sleep reject for faster return from this function, 305 * in case the wakeup is already triggerred. 306 */ 307 #if CONFIG_IDF_TARGET_ESP32 308 reject_triggers = RTC_CNTL_LIGHT_SLP_REJECT_EN_M | RTC_CNTL_GPIO_REJECT_EN_M; 309 #elif CONFIG_IDF_TARGET_ESP32S2 310 reject_triggers = s_config.wakeup_triggers; 311 #endif 312 } 313 314 // Enter sleep 315 rtc_sleep_config_t config = RTC_SLEEP_CONFIG_DEFAULT(pd_flags); 316 rtc_sleep_init(config); 317 318 // Configure timer wakeup 319 if ((s_config.wakeup_triggers & RTC_TIMER_TRIG_EN) && 320 s_config.sleep_duration > 0) { 321 timer_wakeup_prepare(); 322 } 323 324 uint32_t result; 325 if (deep_sleep) { 326 /* Disable interrupts in case another task writes to RTC memory while we 327 * calculate RTC memory CRC 328 * 329 * Note: for ESP32-S3 running in dual core mode this is currently not enough, 330 * see the assert at top of this function. 331 */ 332 portENTER_CRITICAL(&spinlock_rtc_deep_sleep); 333 334 #if !CONFIG_ESP32_ALLOW_RTC_FAST_MEM_AS_HEAP && !CONFIG_ESP32S2_ALLOW_RTC_FAST_MEM_AS_HEAP && !CONFIG_ESP32S3_ALLOW_RTC_FAST_MEM_AS_HEAP 335 /* If not possible stack is in RTC FAST memory, use the ROM function to calculate the CRC and save ~140 bytes IRAM */ 336 set_rtc_memory_crc(); 337 result = call_rtc_sleep_start(reject_triggers); 338 #else 339 /* Otherwise, need to call the dedicated soc function for this */ 340 result = rtc_deep_sleep_start(s_config.wakeup_triggers, reject_triggers); 341 #endif 342 343 portEXIT_CRITICAL(&spinlock_rtc_deep_sleep); 344 } else { 345 result = call_rtc_sleep_start(reject_triggers); 346 } 347 348 // Restore CPU frequency 349 rtc_clk_cpu_freq_set_config(&cpu_freq_config); 350 351 // re-enable UART output 352 resume_uarts(); 353 354 return result; 355 } 356 357 inline static uint32_t IRAM_ATTR call_rtc_sleep_start(uint32_t reject_triggers) 358 { 359 #ifdef CONFIG_IDF_TARGET_ESP32 360 return rtc_sleep_start(s_config.wakeup_triggers, reject_triggers); 361 #else 362 return rtc_sleep_start(s_config.wakeup_triggers, reject_triggers, 1); 363 #endif 364 } 365 366 void IRAM_ATTR esp_deep_sleep_start(void) 367 { 368 // record current RTC time 369 s_config.rtc_ticks_at_sleep_start = rtc_time_get(); 370 371 // record current RTC time 372 esp_sync_counters_rtc_and_frc(); 373 // Configure wake stub 374 if (esp_get_deep_sleep_wake_stub() == NULL) { 375 esp_set_deep_sleep_wake_stub(esp_wake_deep_sleep); 376 } 377 378 // Decide which power domains can be powered down 379 uint32_t pd_flags = get_power_down_flags(); 380 381 // Correct the sleep time 382 s_config.sleep_time_adjustment = DEEP_SLEEP_TIME_OVERHEAD_US; 383 384 // Enter sleep 385 esp_sleep_start(RTC_SLEEP_PD_DIG | RTC_SLEEP_PD_VDDSDIO | pd_flags); 386 387 // Because RTC is in a slower clock domain than the CPU, it 388 // can take several CPU cycles for the sleep mode to start. 389 while (1) { 390 ; 391 } 392 } 393 394 /** 395 * Helper function which handles entry to and exit from light sleep 396 * Placed into IRAM as flash may need some time to be powered on. 397 */ 398 static esp_err_t esp_light_sleep_inner(uint32_t pd_flags, 399 uint32_t flash_enable_time_us, 400 rtc_vddsdio_config_t vddsdio_config) IRAM_ATTR __attribute__((noinline)); 401 402 static esp_err_t esp_light_sleep_inner(uint32_t pd_flags, 403 uint32_t flash_enable_time_us, 404 rtc_vddsdio_config_t vddsdio_config) 405 { 406 // Enter sleep 407 esp_err_t err = esp_sleep_start(pd_flags); 408 409 // If VDDSDIO regulator was controlled by RTC registers before sleep, 410 // restore the configuration. 411 if (vddsdio_config.force) { 412 rtc_vddsdio_set_config(vddsdio_config); 413 } 414 415 // If SPI flash was powered down, wait for it to become ready 416 if (pd_flags & RTC_SLEEP_PD_VDDSDIO) { 417 // Wait for the flash chip to start up 418 esp_rom_delay_us(flash_enable_time_us); 419 } 420 return err; 421 } 422 423 esp_err_t esp_light_sleep_start(void) 424 { 425 static portMUX_TYPE light_sleep_lock = portMUX_INITIALIZER_UNLOCKED; 426 portENTER_CRITICAL(&light_sleep_lock); 427 /* We will be calling esp_timer_private_advance inside DPORT access critical 428 * section. Make sure the code on the other CPU is not holding esp_timer 429 * lock, otherwise there will be deadlock. 430 */ 431 esp_timer_private_lock(); 432 s_config.rtc_ticks_at_sleep_start = rtc_time_get(); 433 uint64_t frc_time_at_start = esp_system_get_time(); 434 DPORT_STALL_OTHER_CPU_START(); 435 436 // Decide which power domains can be powered down 437 uint32_t pd_flags = get_power_down_flags(); 438 439 // Amount of time to subtract from actual sleep time. 440 // This is spent on entering and leaving light sleep. 441 s_config.sleep_time_adjustment = LIGHT_SLEEP_TIME_OVERHEAD_US; 442 443 // Decide if VDD_SDIO needs to be powered down; 444 // If it needs to be powered down, adjust sleep time. 445 const uint32_t flash_enable_time_us = VDD_SDIO_POWERUP_TO_FLASH_READ_US + DEEP_SLEEP_WAKEUP_DELAY; 446 447 #ifndef CONFIG_SPIRAM 448 const uint32_t vddsdio_pd_sleep_duration = MAX(FLASH_PD_MIN_SLEEP_TIME_US, 449 flash_enable_time_us + LIGHT_SLEEP_TIME_OVERHEAD_US + LIGHT_SLEEP_MIN_TIME_US); 450 451 if (s_config.sleep_duration > vddsdio_pd_sleep_duration) { 452 pd_flags |= RTC_SLEEP_PD_VDDSDIO; 453 s_config.sleep_time_adjustment += flash_enable_time_us; 454 } 455 #endif //CONFIG_SPIRAM 456 457 rtc_vddsdio_config_t vddsdio_config = rtc_vddsdio_get_config(); 458 459 // Safety net: enable WDT in case exit from light sleep fails 460 wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &RTCCNTL}; 461 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. 462 if (!wdt_was_enabled) { 463 wdt_hal_init(&rtc_wdt_ctx, WDT_RWDT, 0, false); 464 uint32_t stage_timeout_ticks = (uint32_t)(1000ULL * rtc_clk_slow_freq_get_hz() / 1000ULL); 465 wdt_hal_write_protect_disable(&rtc_wdt_ctx); 466 wdt_hal_config_stage(&rtc_wdt_ctx, WDT_STAGE0, stage_timeout_ticks, WDT_STAGE_ACTION_RESET_RTC); 467 wdt_hal_enable(&rtc_wdt_ctx); 468 wdt_hal_write_protect_enable(&rtc_wdt_ctx); 469 } 470 471 // Enter sleep, then wait for flash to be ready on wakeup 472 esp_err_t err = esp_light_sleep_inner(pd_flags, 473 flash_enable_time_us, vddsdio_config); 474 475 s_light_sleep_wakeup = true; 476 477 // FRC1 has been clock gated for the duration of the sleep, correct for that. 478 uint64_t rtc_ticks_at_end = rtc_time_get(); 479 uint64_t frc_time_at_end = esp_system_get_time(); 480 481 uint64_t rtc_time_diff = rtc_time_slowclk_to_us(rtc_ticks_at_end - s_config.rtc_ticks_at_sleep_start, 482 esp_clk_slowclk_cal_get()); 483 uint64_t frc_time_diff = frc_time_at_end - frc_time_at_start; 484 485 int64_t time_diff = rtc_time_diff - frc_time_diff; 486 /* Small negative values (up to 1 RTC_SLOW clock period) are possible, 487 * for very small values of sleep_duration. Ignore those to keep esp_timer 488 * monotonic. 489 */ 490 if (time_diff > 0) { 491 esp_timer_private_advance(time_diff); 492 } 493 esp_set_time_from_rtc(); 494 495 esp_timer_private_unlock(); 496 DPORT_STALL_OTHER_CPU_END(); 497 if (!wdt_was_enabled) { 498 wdt_hal_write_protect_disable(&rtc_wdt_ctx); 499 wdt_hal_disable(&rtc_wdt_ctx); 500 wdt_hal_write_protect_enable(&rtc_wdt_ctx); 501 } 502 portEXIT_CRITICAL(&light_sleep_lock); 503 return err; 504 } 505 506 esp_err_t esp_sleep_disable_wakeup_source(esp_sleep_source_t source) 507 { 508 // For most of sources it is enough to set trigger mask in local 509 // configuration structure. The actual RTC wake up options 510 // will be updated by esp_sleep_start(). 511 if (source == ESP_SLEEP_WAKEUP_ALL) { 512 s_config.wakeup_triggers = 0; 513 } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_TIMER, RTC_TIMER_TRIG_EN)) { 514 s_config.wakeup_triggers &= ~RTC_TIMER_TRIG_EN; 515 s_config.sleep_duration = 0; 516 } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_EXT0, RTC_EXT0_TRIG_EN)) { 517 s_config.ext0_rtc_gpio_num = 0; 518 s_config.ext0_trigger_level = 0; 519 s_config.wakeup_triggers &= ~RTC_EXT0_TRIG_EN; 520 } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_EXT1, RTC_EXT1_TRIG_EN)) { 521 s_config.ext1_rtc_gpio_mask = 0; 522 s_config.ext1_trigger_mode = 0; 523 s_config.wakeup_triggers &= ~RTC_EXT1_TRIG_EN; 524 } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_TOUCHPAD, RTC_TOUCH_TRIG_EN)) { 525 s_config.wakeup_triggers &= ~RTC_TOUCH_TRIG_EN; 526 } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_GPIO, RTC_GPIO_TRIG_EN)) { 527 s_config.wakeup_triggers &= ~RTC_GPIO_TRIG_EN; 528 } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_UART, (RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN))) { 529 s_config.wakeup_triggers &= ~(RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN); 530 } 531 #if defined(CONFIG_ESP32_ULP_COPROC_ENABLED) || defined(CONFIG_ESP32S2_ULP_COPROC_ENABLED) 532 else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_ULP, RTC_ULP_TRIG_EN)) { 533 s_config.wakeup_triggers &= ~RTC_ULP_TRIG_EN; 534 } 535 #endif 536 else { 537 ESP_LOGE(TAG, "Incorrect wakeup source (%d) to disable.", (int) source); 538 return ESP_ERR_INVALID_STATE; 539 } 540 return ESP_OK; 541 } 542 543 esp_err_t esp_sleep_enable_ulp_wakeup(void) 544 { 545 #if CONFIG_IDF_TARGET_ESP32 546 #ifdef CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT 547 return ESP_ERR_NOT_SUPPORTED; 548 #endif // CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT 549 #ifdef CONFIG_ESP32_ULP_COPROC_ENABLED 550 if(s_config.wakeup_triggers & RTC_EXT0_TRIG_EN) { 551 ESP_LOGE(TAG, "Conflicting wake-up trigger: ext0"); 552 return ESP_ERR_INVALID_STATE; 553 } 554 s_config.wakeup_triggers |= RTC_ULP_TRIG_EN; 555 return ESP_OK; 556 #else // CONFIG_ESP32_ULP_COPROC_ENABLED 557 return ESP_ERR_INVALID_STATE; 558 #endif // CONFIG_ESP32_ULP_COPROC_ENABLED 559 #elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 560 s_config.wakeup_triggers |= (RTC_ULP_TRIG_EN | RTC_COCPU_TRIG_EN | RTC_COCPU_TRAP_TRIG_EN); 561 return ESP_OK; 562 #endif 563 } 564 565 esp_err_t esp_sleep_enable_timer_wakeup(uint64_t time_in_us) 566 { 567 s_config.wakeup_triggers |= RTC_TIMER_TRIG_EN; 568 s_config.sleep_duration = time_in_us; 569 return ESP_OK; 570 } 571 572 static void timer_wakeup_prepare(void) 573 { 574 uint32_t period = esp_clk_slowclk_cal_get(); 575 int64_t sleep_duration = (int64_t) s_config.sleep_duration - (int64_t) s_config.sleep_time_adjustment; 576 if (sleep_duration < 0) { 577 sleep_duration = 0; 578 } 579 580 int64_t ticks = rtc_time_us_to_slowclk(sleep_duration, period); 581 rtc_hal_set_wakeup_timer(s_config.rtc_ticks_at_sleep_start + ticks); 582 } 583 584 585 #ifdef CONFIG_IDF_TARGET_ESP32S2 586 /* In deep sleep mode, only the sleep channel is supported, and other touch channels should be turned off. */ 587 static void touch_wakeup_prepare(void) 588 { 589 touch_pad_sleep_channel_t slp_config; 590 touch_pad_fsm_stop(); 591 touch_pad_clear_channel_mask(TOUCH_PAD_BIT_MASK_ALL); 592 touch_pad_sleep_channel_get_info(&slp_config); 593 touch_pad_set_channel_mask(BIT(slp_config.touch_num)); 594 touch_pad_fsm_start(); 595 } 596 #endif 597 598 esp_err_t esp_sleep_enable_touchpad_wakeup(void) 599 { 600 #ifdef CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT 601 return ESP_ERR_NOT_SUPPORTED; 602 #endif 603 if (s_config.wakeup_triggers & (RTC_EXT0_TRIG_EN)) { 604 ESP_LOGE(TAG, "Conflicting wake-up trigger: ext0"); 605 return ESP_ERR_INVALID_STATE; 606 } 607 s_config.wakeup_triggers |= RTC_TOUCH_TRIG_EN; 608 return ESP_OK; 609 } 610 611 touch_pad_t esp_sleep_get_touchpad_wakeup_status(void) 612 { 613 if (esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_TOUCHPAD) { 614 return TOUCH_PAD_MAX; 615 } 616 touch_pad_t pad_num; 617 esp_err_t ret = touch_pad_get_wakeup_status(&pad_num); //TODO 723diff commit id:fda9ada1b 618 assert(ret == ESP_OK && "wakeup reason is RTC_TOUCH_TRIG_EN but SENS_TOUCH_MEAS_EN is zero"); 619 return pad_num; 620 } 621 622 esp_err_t esp_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level) 623 { 624 if (level < 0 || level > 1) { 625 return ESP_ERR_INVALID_ARG; 626 } 627 if (!RTC_GPIO_IS_VALID_GPIO(gpio_num)) { 628 return ESP_ERR_INVALID_ARG; 629 } 630 if (s_config.wakeup_triggers & (RTC_TOUCH_TRIG_EN | RTC_ULP_TRIG_EN)) { 631 ESP_LOGE(TAG, "Conflicting wake-up triggers: touch / ULP"); 632 return ESP_ERR_INVALID_STATE; 633 } 634 s_config.ext0_rtc_gpio_num = rtc_io_number_get(gpio_num); 635 s_config.ext0_trigger_level = level; 636 s_config.wakeup_triggers |= RTC_EXT0_TRIG_EN; 637 return ESP_OK; 638 } 639 640 static void ext0_wakeup_prepare(void) 641 { 642 int rtc_gpio_num = s_config.ext0_rtc_gpio_num; 643 rtcio_hal_ext0_set_wakeup_pin(rtc_gpio_num, s_config.ext0_trigger_level); 644 rtcio_hal_function_select(rtc_gpio_num, RTCIO_FUNC_RTC); 645 rtcio_hal_input_enable(rtc_gpio_num); 646 } 647 648 esp_err_t esp_sleep_enable_ext1_wakeup(uint64_t mask, esp_sleep_ext1_wakeup_mode_t mode) 649 { 650 if (mode > ESP_EXT1_WAKEUP_ANY_HIGH) { 651 return ESP_ERR_INVALID_ARG; 652 } 653 // Translate bit map of GPIO numbers into the bit map of RTC IO numbers 654 uint32_t rtc_gpio_mask = 0; 655 for (int gpio = 0; mask; ++gpio, mask >>= 1) { 656 if ((mask & 1) == 0) { 657 continue; 658 } 659 if (!RTC_GPIO_IS_VALID_GPIO(gpio)) { 660 ESP_LOGE(TAG, "Not an RTC IO: GPIO%d", gpio); 661 return ESP_ERR_INVALID_ARG; 662 } 663 rtc_gpio_mask |= BIT(rtc_io_number_get(gpio)); 664 } 665 s_config.ext1_rtc_gpio_mask = rtc_gpio_mask; 666 s_config.ext1_trigger_mode = mode; 667 s_config.wakeup_triggers |= RTC_EXT1_TRIG_EN; 668 return ESP_OK; 669 } 670 671 static void ext1_wakeup_prepare(void) 672 { 673 // Configure all RTC IOs selected as ext1 wakeup inputs 674 uint32_t rtc_gpio_mask = s_config.ext1_rtc_gpio_mask; 675 for (int gpio = 0; gpio < GPIO_PIN_COUNT && rtc_gpio_mask != 0; ++gpio) { 676 int rtc_pin = rtc_io_number_get(gpio); 677 if ((rtc_gpio_mask & BIT(rtc_pin)) == 0) { 678 continue; 679 } 680 // Route pad to RTC 681 rtcio_hal_function_select(rtc_pin, RTCIO_FUNC_RTC); 682 // set input enable in sleep mode 683 rtcio_hal_input_enable(rtc_pin); 684 685 // Pad configuration depends on RTC_PERIPH state in sleep mode 686 if (s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] != ESP_PD_OPTION_ON) { 687 // RTC_PERIPH will be powered down, so RTC_IO_ registers will 688 // loose their state. Lock pad configuration. 689 // Pullups/pulldowns also need to be disabled. 690 rtcio_hal_pullup_disable(rtc_pin); 691 rtcio_hal_pulldown_disable(rtc_pin); 692 rtcio_hal_hold_enable(rtc_pin); 693 } 694 // Keep track of pins which are processed to bail out early 695 rtc_gpio_mask &= ~BIT(rtc_pin); 696 } 697 698 // Clear state from previous wakeup 699 rtc_hal_ext1_clear_wakeup_pins(); 700 // Set RTC IO pins and mode (any high, all low) to be used for wakeup 701 rtc_hal_ext1_set_wakeup_pins(s_config.ext1_rtc_gpio_mask, s_config.ext1_trigger_mode); 702 } 703 704 uint64_t esp_sleep_get_ext1_wakeup_status(void) 705 { 706 if (esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_EXT1) { 707 return 0; 708 } 709 uint32_t status = rtc_hal_ext1_get_wakeup_pins(); 710 // Translate bit map of RTC IO numbers into the bit map of GPIO numbers 711 uint64_t gpio_mask = 0; 712 for (int gpio = 0; gpio < GPIO_PIN_COUNT; ++gpio) { 713 if (!RTC_GPIO_IS_VALID_GPIO(gpio)) { 714 continue; 715 } 716 int rtc_pin = rtc_io_number_get(gpio); 717 if ((status & BIT(rtc_pin)) == 0) { 718 continue; 719 } 720 gpio_mask |= 1ULL << gpio; 721 } 722 return gpio_mask; 723 } 724 725 esp_err_t esp_sleep_enable_gpio_wakeup(void) 726 { 727 if (s_config.wakeup_triggers & (RTC_TOUCH_TRIG_EN | RTC_ULP_TRIG_EN)) { 728 ESP_LOGE(TAG, "Conflicting wake-up triggers: touch / ULP"); 729 return ESP_ERR_INVALID_STATE; 730 } 731 s_config.wakeup_triggers |= RTC_GPIO_TRIG_EN; 732 return ESP_OK; 733 } 734 735 esp_err_t esp_sleep_enable_uart_wakeup(int uart_num) 736 { 737 if (uart_num == UART_NUM_0) { 738 s_config.wakeup_triggers |= RTC_UART0_TRIG_EN; 739 } else if (uart_num == UART_NUM_1) { 740 s_config.wakeup_triggers |= RTC_UART1_TRIG_EN; 741 } else { 742 return ESP_ERR_INVALID_ARG; 743 } 744 745 return ESP_OK; 746 } 747 748 esp_err_t esp_sleep_enable_wifi_wakeup(void) 749 { 750 #if CONFIG_IDF_TARGET_ESP32 751 return ESP_ERR_NOT_SUPPORTED; 752 #elif CONFIG_IDF_TARGET_ESP32S2 753 s_config.wakeup_triggers |= RTC_WIFI_TRIG_EN; 754 return ESP_OK; 755 #elif CONFIG_IDF_TARGET_ESP32S3 756 s_config.wakeup_triggers |= RTC_MAC_TRIG_EN; 757 return ESP_OK; 758 #endif 759 } 760 761 762 esp_sleep_wakeup_cause_t esp_sleep_get_wakeup_cause(void) 763 { 764 if (rtc_get_reset_reason(0) != DEEPSLEEP_RESET && !s_light_sleep_wakeup) { 765 return ESP_SLEEP_WAKEUP_UNDEFINED; 766 } 767 768 #ifdef CONFIG_IDF_TARGET_ESP32 769 uint32_t wakeup_cause = REG_GET_FIELD(RTC_CNTL_WAKEUP_STATE_REG, RTC_CNTL_WAKEUP_CAUSE); 770 #elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 771 uint32_t wakeup_cause = REG_GET_FIELD(RTC_CNTL_SLP_WAKEUP_CAUSE_REG, RTC_CNTL_WAKEUP_CAUSE); 772 #endif 773 774 if (wakeup_cause & RTC_EXT0_TRIG_EN) { 775 return ESP_SLEEP_WAKEUP_EXT0; 776 } else if (wakeup_cause & RTC_EXT1_TRIG_EN) { 777 return ESP_SLEEP_WAKEUP_EXT1; 778 } else if (wakeup_cause & RTC_TIMER_TRIG_EN) { 779 return ESP_SLEEP_WAKEUP_TIMER; 780 } else if (wakeup_cause & RTC_TOUCH_TRIG_EN) { 781 return ESP_SLEEP_WAKEUP_TOUCHPAD; 782 } else if (wakeup_cause & RTC_ULP_TRIG_EN) { 783 return ESP_SLEEP_WAKEUP_ULP; 784 } else if (wakeup_cause & RTC_GPIO_TRIG_EN) { 785 return ESP_SLEEP_WAKEUP_GPIO; 786 } else if (wakeup_cause & (RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN)) { 787 return ESP_SLEEP_WAKEUP_UART; 788 #if CONFIG_IDF_TARGET_ESP32S2 789 } else if (wakeup_cause & RTC_WIFI_TRIG_EN) { 790 return ESP_SLEEP_WAKEUP_WIFI; 791 } else if (wakeup_cause & RTC_COCPU_TRIG_EN) { 792 return ESP_SLEEP_WAKEUP_ULP; 793 } else if (wakeup_cause & RTC_COCPU_TRAP_TRIG_EN) { 794 return ESP_SLEEP_WAKEUP_COCPU_TRAP_TRIG; 795 #endif 796 } else { 797 return ESP_SLEEP_WAKEUP_UNDEFINED; 798 } 799 } 800 801 esp_err_t esp_sleep_pd_config(esp_sleep_pd_domain_t domain, 802 esp_sleep_pd_option_t option) 803 { 804 if (domain >= ESP_PD_DOMAIN_MAX || option > ESP_PD_OPTION_AUTO) { 805 return ESP_ERR_INVALID_ARG; 806 } 807 s_config.pd_options[domain] = option; 808 return ESP_OK; 809 } 810 811 static uint32_t get_power_down_flags(void) 812 { 813 // Where needed, convert AUTO options to ON. Later interpret AUTO as OFF. 814 815 // RTC_SLOW_MEM is needed for the ULP, so keep RTC_SLOW_MEM powered up if ULP 816 // is used and RTC_SLOW_MEM is Auto. 817 // If there is any data placed into .rtc.data or .rtc.bss segments, and 818 // RTC_SLOW_MEM is Auto, keep it powered up as well. 819 820 // Labels are defined in the linker script 821 extern int _rtc_slow_length; 822 823 if ((s_config.pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM] == ESP_PD_OPTION_AUTO) && 824 ((size_t) &_rtc_slow_length > 0 || 825 (s_config.wakeup_triggers & RTC_ULP_TRIG_EN))) { 826 s_config.pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM] = ESP_PD_OPTION_ON; 827 } 828 829 // RTC_FAST_MEM is needed for deep sleep stub. 830 // If RTC_FAST_MEM is Auto, keep it powered on, so that deep sleep stub 831 // can run. 832 // In the new chip revision, deep sleep stub will be optional, 833 // and this can be changed. 834 if (s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM] == ESP_PD_OPTION_AUTO) { 835 s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM] = ESP_PD_OPTION_ON; 836 } 837 838 // RTC_PERIPH is needed for EXT0 wakeup and GPIO wakeup. 839 // If RTC_PERIPH is auto, and EXT0/GPIO aren't enabled, power down RTC_PERIPH. 840 if (s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] == ESP_PD_OPTION_AUTO) { 841 if (s_config.wakeup_triggers & (RTC_EXT0_TRIG_EN | RTC_GPIO_TRIG_EN)) { 842 s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] = ESP_PD_OPTION_ON; 843 } else if (s_config.wakeup_triggers & (RTC_TOUCH_TRIG_EN | RTC_ULP_TRIG_EN)) { 844 // In both rev. 0 and rev. 1 of ESP32, forcing power up of RTC_PERIPH 845 // prevents ULP timer and touch FSMs from working correctly. 846 s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] = ESP_PD_OPTION_OFF; 847 } 848 } 849 850 if (s_config.pd_options[ESP_PD_DOMAIN_XTAL] == ESP_PD_OPTION_AUTO) { 851 s_config.pd_options[ESP_PD_DOMAIN_XTAL] = ESP_PD_OPTION_OFF; 852 } 853 854 const char* option_str[] = {"OFF", "ON", "AUTO(OFF)" /* Auto works as OFF */}; 855 ESP_LOGD(TAG, "RTC_PERIPH: %s, RTC_SLOW_MEM: %s, RTC_FAST_MEM: %s", 856 option_str[s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH]], 857 option_str[s_config.pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM]], 858 option_str[s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM]]); 859 860 // Prepare flags based on the selected options 861 uint32_t pd_flags = 0; 862 if (s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM] != ESP_PD_OPTION_ON) { 863 pd_flags |= RTC_SLEEP_PD_RTC_FAST_MEM; 864 } 865 if (s_config.pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM] != ESP_PD_OPTION_ON) { 866 pd_flags |= RTC_SLEEP_PD_RTC_SLOW_MEM; 867 } 868 if (s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] != ESP_PD_OPTION_ON) { 869 pd_flags |= RTC_SLEEP_PD_RTC_PERIPH; 870 } 871 872 #ifdef CONFIG_IDF_TARGET_ESP32 873 pd_flags |= RTC_SLEEP_PD_XTAL; 874 #endif 875 876 #if ((defined CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS) && (defined CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT)) 877 if ((s_config.wakeup_triggers & (RTC_TOUCH_TRIG_EN | RTC_ULP_TRIG_EN)) == 0) { 878 // If enabled EXT1 only and enable the additional current by touch, should be keep RTC_PERIPH power on. 879 pd_flags &= ~RTC_SLEEP_PD_RTC_PERIPH; 880 } 881 #endif 882 883 return pd_flags; 884 } 885 886 void esp_deep_sleep_disable_rom_logging(void) 887 { 888 esp_rom_disable_logging(); 889 } 890