sleep_modes.c 34 KB

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