1 /*
2  * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <stdint.h>
8 #include <stdlib.h>
9 #include "esp_attr.h"
10 #include "soc/soc.h"
11 #include "soc/rtc.h"
12 #include "soc/rtc_cntl_reg.h"
13 #include "soc/syscon_reg.h"
14 #include "soc/i2s_reg.h"
15 #include "soc/bb_reg.h"
16 #include "soc/nrx_reg.h"
17 #include "soc/fe_reg.h"
18 #include "soc/timer_group_reg.h"
19 #include "soc/system_reg.h"
20 #include "soc/chip_revision.h"
21 #include "esp32c3/rom/ets_sys.h"
22 #include "esp32c3/rom/rtc.h"
23 #include "regi2c_ctrl.h"
24 #include "soc/regi2c_dig_reg.h"
25 #include "soc/regi2c_lp_bias.h"
26 #include "hal/efuse_hal.h"
27 #if SOC_SLEEP_SYSTIMER_STALL_WORKAROUND
28 #include "soc/systimer_reg.h"
29 #endif
30 
31 static const DRAM_ATTR rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(1);
32 
33 /**
34  * Configure whether certain peripherals are powered down in deep sleep
35  * @param cfg power down flags as rtc_sleep_pu_config_t structure
36  */
rtc_sleep_pu(rtc_sleep_pu_config_t cfg)37 void rtc_sleep_pu(rtc_sleep_pu_config_t cfg)
38 {
39     REG_SET_FIELD(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_LSLP_MEM_FORCE_PU, cfg.dig_fpu);
40     REG_SET_FIELD(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_FASTMEM_FORCE_LPU, cfg.rtc_fpu);
41     REG_SET_FIELD(SYSCON_FRONT_END_MEM_PD_REG, SYSCON_DC_MEM_FORCE_PU, cfg.fe_fpu);
42     REG_SET_FIELD(SYSCON_FRONT_END_MEM_PD_REG, SYSCON_PBUS_MEM_FORCE_PU, cfg.fe_fpu);
43     REG_SET_FIELD(SYSCON_FRONT_END_MEM_PD_REG, SYSCON_AGC_MEM_FORCE_PU, cfg.fe_fpu);
44     REG_SET_FIELD(BBPD_CTRL, BB_FFT_FORCE_PU, cfg.bb_fpu);
45     REG_SET_FIELD(BBPD_CTRL, BB_DC_EST_FORCE_PU, cfg.bb_fpu);
46     REG_SET_FIELD(NRXPD_CTRL, NRX_RX_ROT_FORCE_PU, cfg.nrx_fpu);
47     REG_SET_FIELD(NRXPD_CTRL, NRX_VIT_FORCE_PU, cfg.nrx_fpu);
48     REG_SET_FIELD(NRXPD_CTRL, NRX_DEMAP_FORCE_PU, cfg.nrx_fpu);
49     REG_SET_FIELD(FE_GEN_CTRL, FE_IQ_EST_FORCE_PU, cfg.fe_fpu);
50     REG_SET_FIELD(FE2_TX_INTERP_CTRL, FE2_TX_INF_FORCE_PU, cfg.fe_fpu);
51     if (cfg.sram_fpu) {
52         REG_SET_FIELD(SYSCON_MEM_POWER_UP_REG, SYSCON_SRAM_POWER_UP, SYSCON_SRAM_POWER_UP);
53     } else {
54         REG_SET_FIELD(SYSCON_MEM_POWER_UP_REG, SYSCON_SRAM_POWER_UP, 0);
55     }
56     if (cfg.rom_ram_fpu) {
57         REG_SET_FIELD(SYSCON_MEM_POWER_UP_REG, SYSCON_ROM_POWER_UP, SYSCON_ROM_POWER_UP);
58     } else {
59         REG_SET_FIELD(SYSCON_MEM_POWER_UP_REG, SYSCON_ROM_POWER_UP, 0);
60     }
61 }
62 
rtc_sleep_get_default_config(uint32_t sleep_flags,rtc_sleep_config_t * out_config)63 void rtc_sleep_get_default_config(uint32_t sleep_flags, rtc_sleep_config_t *out_config)
64 {
65     *out_config = (rtc_sleep_config_t) {
66         .lslp_mem_inf_fpu = 0,
67         .rtc_mem_inf_follow_cpu = (sleep_flags & RTC_SLEEP_PD_RTC_MEM_FOLLOW_CPU) ? 1 : 0,
68         .rtc_fastmem_pd_en = (sleep_flags & RTC_SLEEP_PD_RTC_FAST_MEM) ? 1 : 0,
69         .rtc_slowmem_pd_en = (sleep_flags & RTC_SLEEP_PD_RTC_SLOW_MEM) ? 1 : 0,
70         .rtc_peri_pd_en = (sleep_flags & RTC_SLEEP_PD_RTC_PERIPH) ? 1 : 0,
71         .wifi_pd_en = (sleep_flags & RTC_SLEEP_PD_WIFI) ? 1 : 0,
72         .bt_pd_en = (sleep_flags & RTC_SLEEP_PD_BT) ? 1 : 0,
73         .cpu_pd_en = (sleep_flags & RTC_SLEEP_PD_CPU) ? 1 : 0,
74         .int_8m_pd_en = (sleep_flags & RTC_SLEEP_PD_INT_8M) ? 1 : 0,
75         .dig_peri_pd_en = (sleep_flags & RTC_SLEEP_PD_DIG_PERIPH) ? 1 : 0,
76         .deep_slp = (sleep_flags & RTC_SLEEP_PD_DIG) ? 1 : 0,
77         .wdt_flashboot_mod_en = 0,
78         .vddsdio_pd_en = (sleep_flags & RTC_SLEEP_PD_VDDSDIO) ? 1 : 0,
79         .xtal_fpu = (sleep_flags & RTC_SLEEP_PD_XTAL) ? 0 : 1,
80         .deep_slp_reject = 1,
81         .light_slp_reject = 1
82     };
83 
84     if (sleep_flags & RTC_SLEEP_PD_DIG) {
85         assert(sleep_flags & RTC_SLEEP_PD_XTAL);
86         bool eco2_workaround = false;
87     #if CONFIG_ESP32C3_REV_MIN_FULL < 3
88         if (!ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 3)) {
89             eco2_workaround = true; /* workaround for deep sleep issue in high temp on ECO2 and below */
90         }
91     #endif
92         if (!(sleep_flags & RTC_SLEEP_PD_INT_8M)) {
93             /*
94              * dbg_att_slp need to set to 0: rtc voltage is about 0.83v
95              * support all features:
96              * - 8MD256 as RTC slow clock src
97              * - RTC memory under high temperature
98              * - RTC IO as input
99              */
100             out_config->rtc_regulator_fpu = 1;
101             out_config->dbg_atten_slp = RTC_CNTL_DBG_ATTEN_DEEPSLEEP_NODROP;
102             out_config->rtc_dbias_slp = 0;
103         } else if (sleep_flags & RTC_SLEEP_NO_ULTRA_LOW) {
104             /*
105              * Default mode
106              * rtc voltage in sleep need stable and not less than 0.7v
107              * support features:
108              * - RTC memory under high temperature
109              * - RTC IO as input
110              */
111             out_config->rtc_regulator_fpu = 1;
112             out_config->dbg_atten_slp = eco2_workaround ? RTC_CNTL_DBG_ATTEN_DEEPSLEEP_NODROP: RTC_CNTL_DBG_ATTEN_DEEPSLEEP_DEFAULT;
113             out_config->rtc_dbias_slp = RTC_CNTL_RTC_DBIAS_DEEPSLEEP_0V7;
114         } else {
115             /*
116              * rtc regulator not opened and rtc voltage is about 0.66v (ultra low power):
117              * not support features:
118              * - RTC IO as input
119              * - RTC memory under high temperature
120              */
121             out_config->rtc_regulator_fpu = 0;
122             out_config->dbg_atten_slp = eco2_workaround ? RTC_CNTL_DBG_ATTEN_DEEPSLEEP_NODROP: RTC_CNTL_DBG_ATTEN_DEEPSLEEP_DEFAULT;
123             out_config->rtc_dbias_slp = 0;  /* not used */
124         }
125     } else {
126         out_config->rtc_regulator_fpu = 1;
127         // rtc & digital voltage from high to low
128         if ((sleep_flags & RTC_SLEEP_DIG_USE_8M) || !(sleep_flags & RTC_SLEEP_PD_XTAL)) {
129             /*
130              * digital voltage need to be >= 1.1v
131              * if 8MD256 select as RTC slow clock src, only need dbg_atten_slp set to 0
132              * Support all features:
133              * - XTAL
134              * - RC 8M used by digital system
135              * - 8MD256 as RTC slow clock src
136              */
137             out_config->dbg_atten_slp = RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_NODROP;
138             out_config->dig_dbias_slp = RTC_CNTL_DBIAS_1V10;
139             out_config->rtc_dbias_slp = RTC_CNTL_DBIAS_1V10;
140         } else if (!(sleep_flags & RTC_SLEEP_PD_INT_8M)){
141             /*
142              * dbg_att_slp need to set to 0: digital voltage is about 0.67v & rtc vol is about 0.83v
143              * Support features:
144              * - 8MD256 as RTC slow clock src
145             */
146             out_config->dbg_atten_slp = RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_NODROP;
147             out_config->dig_dbias_slp = 0;
148             out_config->rtc_dbias_slp = 0;
149         } else {
150             /*
151              * digital voltage not less than 0.6v.
152              * not support features:
153              * - XTAL
154              * - RC 8M used by digital system
155              * - 8MD256 as RTC slow clock src
156             */
157             out_config->dbg_atten_slp = RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_DEFAULT;
158             out_config->dig_dbias_slp = RTC_CNTL_DIG_DBIAS_LIGHTSLEEP_0V6;
159             out_config->rtc_dbias_slp = RTC_CNTL_RTC_DBIAS_LIGHTSLEEP_0V6;
160         }
161     }
162     if (!(sleep_flags & RTC_SLEEP_PD_XTAL)) {
163         out_config->bias_sleep_slp = RTC_CNTL_BIASSLP_SLEEP_ON;
164         out_config->pd_cur_slp = RTC_CNTL_PD_CUR_SLEEP_ON;
165     } else {
166         out_config->bias_sleep_slp = RTC_CNTL_BIASSLP_SLEEP_DEFAULT;
167         out_config->pd_cur_slp = RTC_CNTL_PD_CUR_SLEEP_DEFAULT;
168     }
169 }
170 
rtc_sleep_init(rtc_sleep_config_t cfg)171 void rtc_sleep_init(rtc_sleep_config_t cfg)
172 {
173     if (cfg.lslp_mem_inf_fpu) {
174         rtc_sleep_pu(pu_cfg);
175     }
176     if (cfg.wifi_pd_en) {
177         REG_CLR_BIT(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_WIFI_FORCE_NOISO);
178         REG_CLR_BIT(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_FORCE_PU);
179         SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_PD_EN);
180     } else {
181         CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_PD_EN);
182     }
183     if (cfg.bt_pd_en) {
184         REG_CLR_BIT(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_BT_FORCE_NOISO);
185         REG_CLR_BIT(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_BT_FORCE_PU);
186         SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_BT_PD_EN);
187     } else {
188         CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_BT_PD_EN);
189     }
190     if (cfg.cpu_pd_en) {
191         SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_CPU_TOP_PD_EN);
192     } else {
193         CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_CPU_TOP_PD_EN);
194     }
195     if (cfg.dig_peri_pd_en) {
196         SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_PERI_PD_EN);
197     } else {
198         CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_PERI_PD_EN);
199     }
200     REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DBG_ATTEN_MONITOR, RTC_CNTL_DBG_ATTEN_MONITOR_DEFAULT);
201     REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_BIAS_SLEEP_MONITOR, RTC_CNTL_BIASSLP_MONITOR_DEFAULT);
202     REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_PD_CUR_MONITOR, RTC_CNTL_PD_CUR_MONITOR_DEFAULT);
203 
204     assert(!cfg.pd_cur_slp || cfg.bias_sleep_slp);
205     REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG_SLEEP, cfg.rtc_dbias_slp);
206     REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG_SLEEP, cfg.dig_dbias_slp);
207     REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DBG_ATTEN_DEEP_SLP, cfg.dbg_atten_slp);
208     REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_BIAS_SLEEP_DEEP_SLP, cfg.bias_sleep_slp);
209     REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_PD_CUR_DEEP_SLP, cfg.pd_cur_slp);
210 
211     if (cfg.deep_slp) {
212         REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_FORCE_XPD_CK, 0);
213         SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_WRAP_PD_EN);
214         CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG,
215                             RTC_CNTL_CKGEN_I2C_PU | RTC_CNTL_PLL_I2C_PU |
216                             RTC_CNTL_RFRX_PBUS_PU | RTC_CNTL_TXRF_I2C_PU);
217         CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PU);
218     } else {
219         SET_PERI_REG_MASK(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DG_VDD_DRV_B_SLP_EN);
220         REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DG_VDD_DRV_B_SLP, RTC_CNTL_DG_VDD_DRV_B_SLP_DEFAULT);
221         CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_WRAP_PD_EN);
222     }
223     /* mem force pu */
224     SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_LSLP_MEM_FORCE_PU);
225     SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_FASTMEM_FORCE_LPU);
226 
227     REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_REGULATOR_FORCE_PU, cfg.rtc_regulator_fpu);
228     if (!cfg.int_8m_pd_en) {
229         SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU);
230         SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_NOGATING);
231     } else {
232         CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU);
233         CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_NOGATING);
234     }
235 
236     /* enable VDDSDIO control by state machine */
237     REG_CLR_BIT(RTC_CNTL_SDIO_CONF_REG, RTC_CNTL_SDIO_FORCE);
238     REG_SET_FIELD(RTC_CNTL_SDIO_CONF_REG, RTC_CNTL_SDIO_PD_EN, cfg.vddsdio_pd_en);
239 
240     REG_SET_FIELD(RTC_CNTL_SLP_REJECT_CONF_REG, RTC_CNTL_DEEP_SLP_REJECT_EN, cfg.deep_slp_reject);
241     REG_SET_FIELD(RTC_CNTL_SLP_REJECT_CONF_REG, RTC_CNTL_LIGHT_SLP_REJECT_EN, cfg.light_slp_reject);
242 
243     REG_SET_FIELD(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_XTL_FORCE_PU, cfg.xtal_fpu);
244     REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_XTAL_GLOBAL_FORCE_NOGATING, cfg.xtal_fpu);
245 }
246 
rtc_sleep_low_init(uint32_t slowclk_period)247 void rtc_sleep_low_init(uint32_t slowclk_period)
248 {
249     // set 5 PWC state machine times to fit in main state machine time
250     REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES);
251     REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_XTL_BUF_WAIT, rtc_time_us_to_slowclk(RTC_CNTL_XTL_BUF_WAIT_SLP_US, slowclk_period));
252     REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CNTL_CK8M_WAIT_SLP_CYCLES);
253 }
254 
255 static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu);
256 
rtc_sleep_start(uint32_t wakeup_opt,uint32_t reject_opt,uint32_t lslp_mem_inf_fpu)257 uint32_t rtc_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu)
258 {
259     REG_SET_FIELD(RTC_CNTL_WAKEUP_STATE_REG, RTC_CNTL_WAKEUP_ENA, wakeup_opt);
260     REG_SET_FIELD(RTC_CNTL_SLP_REJECT_CONF_REG, RTC_CNTL_SLEEP_REJECT_ENA, reject_opt);
261 
262     SET_PERI_REG_MASK(RTC_CNTL_INT_CLR_REG,
263                       RTC_CNTL_SLP_REJECT_INT_CLR | RTC_CNTL_SLP_WAKEUP_INT_CLR);
264 
265     /* Start entry into sleep mode */
266     SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_SLEEP_EN);
267 
268     while (GET_PERI_REG_MASK(RTC_CNTL_INT_RAW_REG,
269                              RTC_CNTL_SLP_REJECT_INT_RAW | RTC_CNTL_SLP_WAKEUP_INT_RAW) == 0) {
270         ;
271     }
272 
273     return rtc_sleep_finish(lslp_mem_inf_fpu);
274 }
275 
276 #define STR2(X) #X
277 #define STR(X) STR2(X)
278 
rtc_deep_sleep_start(uint32_t wakeup_opt,uint32_t reject_opt)279 uint32_t rtc_deep_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt)
280 {
281     REG_SET_FIELD(RTC_CNTL_WAKEUP_STATE_REG, RTC_CNTL_WAKEUP_ENA, wakeup_opt);
282     WRITE_PERI_REG(RTC_CNTL_SLP_REJECT_CONF_REG, reject_opt);
283 
284     SET_PERI_REG_MASK(RTC_CNTL_INT_CLR_REG,
285                       RTC_CNTL_SLP_REJECT_INT_CLR | RTC_CNTL_SLP_WAKEUP_INT_CLR);
286 
287     /* Calculate RTC Fast Memory CRC (for wake stub) & go to deep sleep
288 
289        Because we may be running from RTC memory as stack, we can't easily call any
290        functions to do this (as registers will spill to stack, corrupting the CRC).
291 
292        Instead, load all the values we need into registers then use register ops only to calculate
293        the CRC value, write it to the RTC CRC value register, and immediately go into deep sleep.
294      */
295 
296     /* Values used to set the SYSTEM_RTC_FASTMEM_CONFIG_REG value */
297     const unsigned CRC_START_ADDR = 0;
298     const unsigned CRC_LEN = 0x7ff;
299 
300     asm volatile(
301                  /* Start CRC calculation */
302                  "sw %1, 0(%0)\n" // set RTC_MEM_CRC_ADDR & RTC_MEM_CRC_LEN
303                  "or t0, %1, %2\n"
304                  "sw t0, 0(%0)\n" // set RTC_MEM_CRC_START
305 
306                  /* Wait for the CRC calculation to finish */
307                  ".Lwaitcrc:\n"
308                  "fence\n"
309                  "lw t0, 0(%0)\n"
310                  "li t1, "STR(SYSTEM_RTC_MEM_CRC_FINISH)"\n"
311                  "and t0, t0, t1\n"
312                  "beqz t0, .Lwaitcrc\n"
313                  "not %2, %2\n" // %2 -> ~DPORT_RTC_MEM_CRC_START
314                  "and t0, t0, %2\n"
315                  "sw t0, 0(%0)\n"  // clear RTC_MEM_CRC_START
316                  "fence\n"
317                  "not %2, %2\n" // %2 -> DPORT_RTC_MEM_CRC_START, probably unnecessary but gcc assumes inputs unchanged
318 
319                  /* Store the calculated value in RTC_MEM_CRC_REG */
320                  "lw t0, 0(%3)\n"
321                  "sw t0, 0(%4)\n"
322                  "fence\n"
323 
324                  /* Set register bit to go into deep sleep */
325                  "lw t0, 0(%5)\n"
326                  "or   t0, t0, %6\n"
327                  "sw t0, 0(%5)\n"
328                  "fence\n"
329 
330                  /* Wait for sleep reject interrupt (never finishes if successful) */
331                  ".Lwaitsleep:"
332                  "fence\n"
333                  "lw t0, 0(%7)\n"
334                  "and t0, t0, %8\n"
335                  "beqz t0, .Lwaitsleep\n"
336 
337                  :
338                  :
339                    "r" (SYSTEM_RTC_FASTMEM_CONFIG_REG), // %0
340                    "r" ( (CRC_START_ADDR << SYSTEM_RTC_MEM_CRC_START_S)
341                          | (CRC_LEN << SYSTEM_RTC_MEM_CRC_LEN_S)), // %1
342                    "r" (SYSTEM_RTC_MEM_CRC_START), // %2
343                    "r" (SYSTEM_RTC_FASTMEM_CRC_REG), // %3
344                    "r" (RTC_MEMORY_CRC_REG), // %4
345                    "r" (RTC_CNTL_STATE0_REG), // %5
346                    "r" (RTC_CNTL_SLEEP_EN), // %6
347                    "r" (RTC_CNTL_INT_RAW_REG), // %7
348                    "r" (RTC_CNTL_SLP_REJECT_INT_RAW | RTC_CNTL_SLP_WAKEUP_INT_RAW) // %8
349                  : "t0", "t1" // working registers
350                  );
351 
352     return rtc_sleep_finish(0);
353 }
354 
rtc_sleep_finish(uint32_t lslp_mem_inf_fpu)355 static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu)
356 {
357     /* In deep sleep mode, we never get here */
358     uint32_t reject = REG_GET_FIELD(RTC_CNTL_INT_RAW_REG, RTC_CNTL_SLP_REJECT_INT_RAW);
359     SET_PERI_REG_MASK(RTC_CNTL_INT_CLR_REG,
360                       RTC_CNTL_SLP_REJECT_INT_CLR | RTC_CNTL_SLP_WAKEUP_INT_CLR);
361 
362     /* restore config if it is a light sleep */
363     if (lslp_mem_inf_fpu) {
364         rtc_sleep_pu(pu_cfg);
365     }
366     return reject;
367 }
368