• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef __RTC_H__
15 #define __RTC_H__
16 
17 #pragma once
18 
19 #include <stdbool.h>
20 #include <stddef.h>
21 #include <stdint.h>
22 #include "soc/soc.h"
23 #include "soc/rtc_periph.h"
24 
25 #define MHZ (1000000)
26 
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif /* __cplusplus */
31 
32 /**
33  * @file rtc.h
34  * @brief Low-level RTC power, clock, and sleep functions.
35  *
36  * Functions in this file facilitate configuration of ESP32's RTC_CNTL peripheral.
37  * RTC_CNTL peripheral handles many functions:
38  * - enables/disables clocks and power to various parts of the chip; this is
39  *   done using direct register access (forcing power up or power down) or by
40  *   allowing state machines to control power and clocks automatically
41  * - handles sleep and wakeup functions
42  * - maintains a 48-bit counter which can be used for timekeeping
43  *
44  * These functions are not thread safe, and should not be viewed as high level
45  * APIs. For example, while this file provides a function which can switch
46  * CPU frequency, this function is on its own is not sufficient to implement
47  * frequency switching in ESP-IDF context: some coordination with RTOS,
48  * peripheral drivers, and WiFi/BT stacks is also required.
49  *
50  * These functions will normally not be used in applications directly.
51  * ESP-IDF provides, or will provide, drivers and other facilities to use
52  * RTC subsystem functionality.
53  *
54  * The functions are loosely split into the following groups:
55  * - rtc_clk: clock switching, calibration
56  * - rtc_time: reading RTC counter, conversion between counter values and time
57  * - rtc_sleep: entry into sleep modes
58  * - rtc_init: initialization
59  */
60 
61 
62 /**
63  * @brief Possible main XTAL frequency values.
64  *
65  * Enum values should be equal to frequency in MHz.
66  */
67 typedef enum {
68     RTC_XTAL_FREQ_AUTO = 0,     //!< Automatic XTAL frequency detection
69     RTC_XTAL_FREQ_40M = 40,     //!< 40 MHz XTAL
70     RTC_XTAL_FREQ_26M = 26,     //!< 26 MHz XTAL
71     RTC_XTAL_FREQ_24M = 24,     //!< 24 MHz XTAL
72 } rtc_xtal_freq_t;
73 
74 /**
75  * @brief CPU frequency values
76  */
77 typedef enum {
78     RTC_CPU_FREQ_XTAL = 0,      //!< Main XTAL frequency
79     RTC_CPU_FREQ_80M = 1,       //!< 80 MHz
80     RTC_CPU_FREQ_160M = 2,      //!< 160 MHz
81     RTC_CPU_FREQ_240M = 3,      //!< 240 MHz
82     RTC_CPU_FREQ_2M = 4,        //!< 2 MHz
83 } rtc_cpu_freq_t;
84 
85 /**
86  * @brief CPU clock source
87  */
88 typedef enum {
89     RTC_CPU_FREQ_SRC_XTAL,  //!< XTAL
90     RTC_CPU_FREQ_SRC_PLL,   //!< PLL (480M or 320M)
91     RTC_CPU_FREQ_SRC_8M,    //!< Internal 8M RTC oscillator
92     RTC_CPU_FREQ_SRC_APLL   //!< APLL
93 } rtc_cpu_freq_src_t;
94 
95 /**
96  * @brief CPU clock configuration structure
97  */
98 typedef struct rtc_cpu_freq_config_s {
99     rtc_cpu_freq_src_t source;      //!< The clock from which CPU clock is derived
100     uint32_t source_freq_mhz;       //!< Source clock frequency
101     uint32_t div;                   //!< Divider, freq_mhz = source_freq_mhz / div
102     uint32_t freq_mhz;              //!< CPU clock frequency
103 } rtc_cpu_freq_config_t;
104 
105 /**
106  * @brief RTC SLOW_CLK frequency values
107  */
108 typedef enum {
109     RTC_SLOW_FREQ_RTC = 0,      //!< Internal 150 kHz RC oscillator
110     RTC_SLOW_FREQ_32K_XTAL = 1, //!< External 32 kHz XTAL
111     RTC_SLOW_FREQ_8MD256 = 2,   //!< Internal 8 MHz RC oscillator, divided by 256
112 } rtc_slow_freq_t;
113 
114 /**
115  * @brief RTC FAST_CLK frequency values
116  */
117 typedef enum {
118     RTC_FAST_FREQ_XTALD4 = 0,   //!< Main XTAL, divided by 4
119     RTC_FAST_FREQ_8M = 1,       //!< Internal 8 MHz RC oscillator
120 } rtc_fast_freq_t;
121 
122 /* With the default value of CK8M_DFREQ, 8M clock frequency is 8.5 MHz +/- 7% */
123 #define RTC_FAST_CLK_FREQ_APPROX 8500000
124 
125 /**
126  * @brief Clock source to be calibrated using rtc_clk_cal function
127  */
128 typedef enum {
129     RTC_CAL_RTC_MUX = 0,       //!< Currently selected RTC SLOW_CLK
130     RTC_CAL_8MD256 = 1,        //!< Internal 8 MHz RC oscillator, divided by 256
131     RTC_CAL_32K_XTAL = 2       //!< External 32 kHz XTAL
132 } rtc_cal_sel_t;
133 
134 /**
135  * Initialization parameters for rtc_clk_init
136  */
137 typedef struct rtc_clk_config_s {
138     rtc_xtal_freq_t xtal_freq : 8;      //!< Main XTAL frequency
139     uint32_t cpu_freq_mhz : 10;         //!< CPU frequency to set, in MHz
140     rtc_fast_freq_t fast_freq : 1;      //!< RTC_FAST_CLK frequency to set
141     rtc_slow_freq_t slow_freq : 2;      //!< RTC_SLOW_CLK frequency to set
142     uint32_t clk_8m_div : 3;            //!< RTC 8M clock divider (division is by clk_8m_div+1, i.e. 0 means 8MHz frequency)
143     uint32_t slow_clk_dcap : 8;         //!< RTC 150k clock adjustment parameter (higher value leads to lower frequency)
144     uint32_t clk_8m_dfreq : 8;          //!< RTC 8m clock adjustment parameter (higher value leads to higher frequency)
145 } rtc_clk_config_t;
146 
147 /**
148  * Default initializer for rtc_clk_config_t
149  */
150 #define RTC_CLK_CONFIG_DEFAULT() { \
151     .xtal_freq = RTC_XTAL_FREQ_AUTO, \
152     .cpu_freq_mhz = 80, \
153     .fast_freq = RTC_FAST_FREQ_8M, \
154     .slow_freq = RTC_SLOW_FREQ_RTC, \
155     .clk_8m_div = 0, \
156     .slow_clk_dcap = RTC_CNTL_SCK_DCAP_DEFAULT, \
157     .clk_8m_dfreq = RTC_CNTL_CK8M_DFREQ_DEFAULT, \
158 }
159 
160 /**
161  * Initialize clocks and set CPU frequency
162  *
163  * If cfg.xtal_freq is set to RTC_XTAL_FREQ_AUTO, this function will attempt
164  * to auto detect XTAL frequency. Auto detection is performed by comparing
165  * XTAL frequency with the frequency of internal 8MHz oscillator. Note that at
166  * high temperatures the frequency of the internal 8MHz oscillator may drift
167  * enough for auto detection to be unreliable.
168  * Auto detection code will attempt to distinguish between 26MHz and 40MHz
169  * crystals. 24 MHz crystals are not supported by auto detection code.
170  * If XTAL frequency can not be auto detected, this 26MHz frequency will be used.
171  *
172  * @param cfg clock configuration as rtc_clk_config_t
173  */
174 void rtc_clk_init(rtc_clk_config_t cfg);
175 
176 /**
177  * @brief Get main XTAL frequency
178  *
179  * This is the value stored in RTC register RTC_XTAL_FREQ_REG by the bootloader. As passed to
180  * rtc_clk_init function, or if the value was RTC_XTAL_FREQ_AUTO, the detected
181  * XTAL frequency.
182  *
183  * @return XTAL frequency, one of rtc_xtal_freq_t
184  */
185 rtc_xtal_freq_t rtc_clk_xtal_freq_get(void);
186 
187 /**
188  * @brief Update XTAL frequency
189  *
190  * Updates the XTAL value stored in RTC_XTAL_FREQ_REG. Usually this value is ignored
191  * after startup.
192  *
193  * @param xtal_freq New frequency value
194  */
195 void rtc_clk_xtal_freq_update(rtc_xtal_freq_t xtal_freq);
196 
197 /**
198  * @brief Enable or disable 32 kHz XTAL oscillator
199  * @param en  true to enable, false to disable
200  */
201 void rtc_clk_32k_enable(bool en);
202 
203 /**
204  * @brief Configure 32 kHz XTAL oscillator to accept external clock signal
205  */
206 void rtc_clk_32k_enable_external(void);
207 
208 /**
209  * @brief Get the state of 32k XTAL oscillator
210  * @return true if 32k XTAL oscillator has been enabled
211  */
212 bool rtc_clk_32k_enabled(void);
213 
214 /**
215  * @brief Enable 32k oscillator, configuring it for fast startup time.
216  * Note: to achieve higher frequency stability, rtc_clk_32k_enable function
217  * must be called one the 32k XTAL oscillator has started up. This function
218  * will initially disable the 32k XTAL oscillator, so it should not be called
219  * when the system is using 32k XTAL as RTC_SLOW_CLK.
220  *
221  * @param cycle Number of 32kHz cycles to bootstrap external crystal.
222  *              If 0, no square wave will be used to bootstrap crystal oscillation.
223  */
224 void rtc_clk_32k_bootstrap(uint32_t cycle);
225 
226 /**
227  * @brief Enable or disable 8 MHz internal oscillator
228  *
229  * Output from 8 MHz internal oscillator is passed into a configurable
230  * divider, which by default divides the input clock frequency by 256.
231  * Output of the divider may be used as RTC_SLOW_CLK source.
232  * Output of the divider is referred to in register descriptions and code as
233  * 8md256 or simply d256. Divider values other than 256 may be configured, but
234  * this facility is not currently needed, so is not exposed in the code.
235  *
236  * When 8MHz/256 divided output is not needed, the divider should be disabled
237  * to reduce power consumption.
238  *
239  * @param clk_8m_en true to enable 8MHz generator
240  * @param d256_en true to enable /256 divider
241  */
242 void rtc_clk_8m_enable(bool clk_8m_en, bool d256_en);
243 
244 /**
245  * @brief Get the state of 8 MHz internal oscillator
246  * @return true if the oscillator is enabled
247  */
248 bool rtc_clk_8m_enabled(void);
249 
250 /**
251  * @brief Get the state of /256 divider which is applied to 8MHz clock
252  * @return true if the divided output is enabled
253  */
254 bool rtc_clk_8md256_enabled(void);
255 
256 /**
257  * @brief Enable or disable APLL
258  *
259  * Output frequency is given by the formula:
260  * apll_freq = xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536)/((o_div + 2) * 2)
261  *
262  * The dividend in this expression should be in the range of 240 - 600 MHz.
263  *
264  * In rev. 0 of ESP32, sdm0 and sdm1 are unused and always set to 0.
265  *
266  * @param enable  true to enable, false to disable
267  * @param sdm0  frequency adjustment parameter, 0..255
268  * @param sdm1  frequency adjustment parameter, 0..255
269  * @param sdm2  frequency adjustment parameter, 0..63
270  * @param o_div  frequency divider, 0..31
271  */
272 void rtc_clk_apll_enable(bool enable, uint32_t sdm0, uint32_t sdm1,
273         uint32_t sdm2, uint32_t o_div);
274 
275 /**
276  * @brief Select source for RTC_SLOW_CLK
277  * @param slow_freq clock source (one of rtc_slow_freq_t values)
278  */
279 void rtc_clk_slow_freq_set(rtc_slow_freq_t slow_freq);
280 
281 /**
282  * @brief Get the RTC_SLOW_CLK source
283  * @return currently selected clock source (one of rtc_slow_freq_t values)
284  */
285 rtc_slow_freq_t rtc_clk_slow_freq_get(void);
286 
287 /**
288  * @brief Get the approximate frequency of RTC_SLOW_CLK, in Hz
289  *
290  * - if RTC_SLOW_FREQ_RTC is selected, returns ~150000
291  * - if RTC_SLOW_FREQ_32K_XTAL is selected, returns 32768
292  * - if RTC_SLOW_FREQ_8MD256 is selected, returns ~33000
293  *
294  * rtc_clk_cal function can be used to get more precise value by comparing
295  * RTC_SLOW_CLK frequency to the frequency of main XTAL.
296  *
297  * @return RTC_SLOW_CLK frequency, in Hz
298  */
299 uint32_t rtc_clk_slow_freq_get_hz(void);
300 
301 /**
302  * @brief Select source for RTC_FAST_CLK
303  * @param fast_freq clock source (one of rtc_fast_freq_t values)
304  */
305 void rtc_clk_fast_freq_set(rtc_fast_freq_t fast_freq);
306 
307 /**
308  * @brief Get the RTC_FAST_CLK source
309  * @return currently selected clock source (one of rtc_fast_freq_t values)
310  */
311 rtc_fast_freq_t rtc_clk_fast_freq_get(void);
312 
313 /**
314  * @brief Get CPU frequency config corresponding to a rtc_cpu_freq_t value
315  * @param cpu_freq CPU frequency enumeration value
316  * @param[out] out_config  Output, CPU frequency configuration structure
317  */
318  void rtc_clk_cpu_freq_to_config(rtc_cpu_freq_t cpu_freq, rtc_cpu_freq_config_t* out_config);
319 
320  /**
321   * @brief Get CPU frequency config for a given frequency
322   * @param freq_mhz  Frequency in MHz
323   * @param[out] out_config Output, CPU frequency configuration structure
324   * @return true if frequency can be obtained, false otherwise
325   */
326  bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t* out_config);
327 
328  /**
329   * @brief Switch CPU frequency
330   *
331   * This function sets CPU frequency according to the given configuration
332   * structure. It enables PLLs, if necessary.
333   *
334   * @note This function in not intended to be called by applications in FreeRTOS
335   * environment. This is because it does not adjust various timers based on the
336   * new CPU frequency.
337   *
338   * @param config  CPU frequency configuration structure
339   */
340  void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t* config);
341 
342  /**
343   * @brief Switch CPU frequency (optimized for speed)
344   *
345   * This function is a faster equivalent of rtc_clk_cpu_freq_set_config.
346   * It works faster because it does not disable PLLs when switching from PLL to
347   * XTAL and does not enabled them when switching back. If PLL is not already
348   * enabled when this function is called to switch from XTAL to PLL frequency,
349   * or the PLL which is enabled is the wrong one, this function will fall back
350   * to calling rtc_clk_cpu_freq_set_config.
351   *
352   * Unlike rtc_clk_cpu_freq_set_config, this function relies on static data,
353   * so it is less safe to use it e.g. from a panic handler (when memory might
354   * be corrupted).
355   *
356   * @note This function in not intended to be called by applications in FreeRTOS
357   * environment. This is because it does not adjust various timers based on the
358   * new CPU frequency.
359   *
360   * @param config  CPU frequency configuration structure
361   */
362  void rtc_clk_cpu_freq_set_config_fast(const rtc_cpu_freq_config_t* config);
363 
364  /**
365   * @brief Get the currently used CPU frequency configuration
366   * @param[out] out_config  Output, CPU frequency configuration structure
367   */
368  void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t* out_config);
369 
370  /**
371   * @brief Switch CPU clock source to XTAL
372   *
373   * Short form for filling in rtc_cpu_freq_config_t structure and calling
374   * rtc_clk_cpu_freq_set_config when a switch to XTAL is needed.
375   * Assumes that XTAL frequency has been determined — don't call in startup code.
376   */
377  void rtc_clk_cpu_freq_set_xtal(void);
378 
379 
380 /**
381  * @brief Store new APB frequency value into RTC_APB_FREQ_REG
382  *
383  * This function doesn't change any hardware clocks.
384  *
385  * Functions which perform frequency switching and change APB frequency call
386  * this function to update the value of APB frequency stored in RTC_APB_FREQ_REG
387  * (one of RTC general purpose retention registers). This should not normally
388  * be called from application code.
389  *
390  * @param apb_freq  new APB frequency, in Hz
391  */
392 void rtc_clk_apb_freq_update(uint32_t apb_freq);
393 
394 /**
395  * @brief Get the current stored APB frequency.
396  * @return The APB frequency value as last set via rtc_clk_apb_freq_update(), in Hz.
397  */
398 uint32_t rtc_clk_apb_freq_get(void);
399 
400 #define RTC_CLK_CAL_FRACT  19  //!< Number of fractional bits in values returned by rtc_clk_cal
401 
402 /**
403  * @brief Measure RTC slow clock's period, based on main XTAL frequency
404  *
405  * This function will time out and return 0 if the time for the given number
406  * of cycles to be counted exceeds the expected time twice. This may happen if
407  * 32k XTAL is being calibrated, but the oscillator has not started up (due to
408  * incorrect loading capacitance, board design issue, or lack of 32 XTAL on board).
409  *
410  * @param cal_clk  clock to be measured
411  * @param slow_clk_cycles  number of slow clock cycles to average
412  * @return average slow clock period in microseconds, Q13.19 fixed point format,
413  *         or 0 if calibration has timed out
414  */
415 uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slow_clk_cycles);
416 
417 /**
418  * @brief Measure ratio between XTAL frequency and RTC slow clock frequency
419  * @param cal_clk slow clock to be measured
420  * @param slow_clk_cycles number of slow clock cycles to average
421  * @return average ratio between XTAL frequency and slow clock frequency,
422  *         Q13.19 fixed point format, or 0 if calibration has timed out.
423  */
424 uint32_t rtc_clk_cal_ratio(rtc_cal_sel_t cal_clk, uint32_t slow_clk_cycles);
425 
426 /**
427  * @brief Convert time interval from microseconds to RTC_SLOW_CLK cycles
428  * @param time_in_us Time interval in microseconds
429  * @param slow_clk_period  Period of slow clock in microseconds, Q13.19
430  *                         fixed point format (as returned by rtc_slowck_cali).
431  * @return number of slow clock cycles
432  */
433 uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period);
434 
435 /**
436  * @brief Convert time interval from RTC_SLOW_CLK to microseconds
437  * @param time_in_us Time interval in RTC_SLOW_CLK cycles
438  * @param slow_clk_period  Period of slow clock in microseconds, Q13.19
439  *                         fixed point format (as returned by rtc_slowck_cali).
440  * @return time interval in microseconds
441  */
442 uint64_t rtc_time_slowclk_to_us(uint64_t rtc_cycles, uint32_t period);
443 
444 /**
445  * @brief Get current value of RTC counter
446  *
447  * RTC has a 48-bit counter which is incremented by 2 every 2 RTC_SLOW_CLK
448  * cycles. Counter value is not writable by software. The value is not adjusted
449  * when switching to a different RTC_SLOW_CLK source.
450  *
451  * Note: this function may take up to 1 RTC_SLOW_CLK cycle to execute
452  *
453  * @return current value of RTC counter
454  */
455 uint64_t rtc_time_get(void);
456 
457 /**
458  * @brief Busy loop until next RTC_SLOW_CLK cycle
459  *
460  * This function returns not earlier than the next RTC_SLOW_CLK clock cycle.
461  * In some cases (e.g. when RTC_SLOW_CLK cycle is very close), it may return
462  * one RTC_SLOW_CLK cycle later.
463  */
464 void rtc_clk_wait_for_slow_cycle(void);
465 
466 /**
467  * @brief Enable the rtc digital 8M clock
468  *
469  * This function is used to enable the digital rtc 8M clock to support peripherals.
470  * For enabling the analog 8M clock, using `rtc_clk_8M_enable` function above.
471  */
472 void rtc_dig_clk8m_enable(void);
473 
474 /**
475  * @brief Disable the rtc digital 8M clock
476  *
477  * This function is used to disable the digital rtc 8M clock, which is only used to support peripherals.
478  */
479 void rtc_dig_clk8m_disable(void);
480 
481 /**
482  * @brief Calculate the real clock value after the clock calibration
483  *
484  * @param cal_val Average slow clock period in microseconds, fixed point value as returned from `rtc_clk_cal`
485  * @return Frequency of the clock in Hz
486  */
487 uint32_t rtc_clk_freq_cal(uint32_t cal_val);
488 
489 /**
490  * @brief sleep configuration for rtc_sleep_init function
491  */
492 typedef struct rtc_sleep_config_s {
493     uint32_t lslp_mem_inf_fpu : 1;      //!< force normal voltage in sleep mode (digital domain memory)
494     uint32_t rtc_mem_inf_fpu : 1;       //!< force normal voltage in sleep mode (RTC memory)
495     uint32_t rtc_mem_inf_follow_cpu : 1;//!< keep low voltage in sleep mode (even if ULP/touch is used)
496     uint32_t rtc_fastmem_pd_en : 1;     //!< power down RTC fast memory
497     uint32_t rtc_slowmem_pd_en : 1;     //!< power down RTC slow memory
498     uint32_t rtc_peri_pd_en : 1;        //!< power down RTC peripherals
499     uint32_t wifi_pd_en : 1;            //!< power down WiFi
500     uint32_t rom_mem_pd_en : 1;         //!< power down main RAM and ROM
501     uint32_t deep_slp : 1;              //!< power down digital domain
502     uint32_t wdt_flashboot_mod_en : 1;  //!< enable WDT flashboot mode
503     uint32_t dig_dbias_wak : 3;         //!< set bias for digital domain, in active mode
504     uint32_t dig_dbias_slp : 3;         //!< set bias for digital domain, in sleep mode
505     uint32_t rtc_dbias_wak : 3;         //!< set bias for RTC domain, in active mode
506     uint32_t rtc_dbias_slp : 3;         //!< set bias for RTC domain, in sleep mode
507     uint32_t lslp_meminf_pd : 1;        //!< remove all peripheral force power up flags
508     uint32_t vddsdio_pd_en : 1;         //!< power down VDDSDIO regulator
509     uint32_t xtal_fpu : 1;              //!< keep main XTAL powered up in sleep
510 } rtc_sleep_config_t;
511 
512 /**
513  * Default initializer for rtc_sleep_config_t
514  *
515  * This initializer sets all fields to "reasonable" values (e.g. suggested for
516  * production use) based on a combination of RTC_SLEEP_PD_x flags.
517  *
518  * @param RTC_SLEEP_PD_x flags combined using bitwise OR
519  */
520 #define RTC_SLEEP_CONFIG_DEFAULT(sleep_flags) { \
521     .lslp_mem_inf_fpu = 0, \
522     .rtc_mem_inf_fpu = 0, \
523     .rtc_mem_inf_follow_cpu = ((sleep_flags) & RTC_SLEEP_PD_RTC_MEM_FOLLOW_CPU) ? 1 : 0, \
524     .rtc_fastmem_pd_en = ((sleep_flags) & RTC_SLEEP_PD_RTC_FAST_MEM) ? 1 : 0, \
525     .rtc_slowmem_pd_en = ((sleep_flags) & RTC_SLEEP_PD_RTC_SLOW_MEM) ? 1 : 0, \
526     .rtc_peri_pd_en = ((sleep_flags) & RTC_SLEEP_PD_RTC_PERIPH) ? 1 : 0, \
527     .wifi_pd_en = 0, \
528     .rom_mem_pd_en = 0, \
529     .deep_slp = ((sleep_flags) & RTC_SLEEP_PD_DIG) ? 1 : 0, \
530     .wdt_flashboot_mod_en = 0, \
531     .dig_dbias_wak = RTC_CNTL_DBIAS_1V10, \
532     .dig_dbias_slp = RTC_CNTL_DBIAS_0V90, \
533     .rtc_dbias_wak = RTC_CNTL_DBIAS_1V10, \
534     .rtc_dbias_slp = RTC_CNTL_DBIAS_0V90, \
535     .lslp_meminf_pd = 1, \
536     .vddsdio_pd_en = ((sleep_flags) & RTC_SLEEP_PD_VDDSDIO) ? 1 : 0, \
537     .xtal_fpu = ((sleep_flags) & RTC_SLEEP_PD_XTAL) ? 0 : 1 \
538 };
539 
540 #define RTC_SLEEP_PD_DIG                BIT(0)  //!< Deep sleep (power down digital domain)
541 #define RTC_SLEEP_PD_RTC_PERIPH         BIT(1)  //!< Power down RTC peripherals
542 #define RTC_SLEEP_PD_RTC_SLOW_MEM       BIT(2)  //!< Power down RTC SLOW memory
543 #define RTC_SLEEP_PD_RTC_FAST_MEM       BIT(3)  //!< Power down RTC FAST memory
544 #define RTC_SLEEP_PD_RTC_MEM_FOLLOW_CPU BIT(4)  //!< RTC FAST and SLOW memories are automatically powered up and down along with the CPU
545 #define RTC_SLEEP_PD_VDDSDIO            BIT(5)  //!< Power down VDDSDIO regulator
546 #define RTC_SLEEP_PD_XTAL               BIT(6)  //!< Power down main XTAL
547 
548 /* Various delays to be programmed into power control state machines */
549 #define RTC_CNTL_XTL_BUF_WAIT_SLP_US        (500)
550 #define RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES    (1)
551 #define RTC_CNTL_CK8M_WAIT_SLP_CYCLES       (4)
552 #define RTC_CNTL_WAKEUP_DELAY_CYCLES        (7)
553 #define RTC_CNTL_OTHER_BLOCKS_POWERUP_CYCLES    (1)
554 #define RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES       (1)
555 
556 /**
557  * @brief Prepare the chip to enter sleep mode
558  *
559  * This function configures various power control state machines to handle
560  * entry into light sleep or deep sleep mode, switches APB and CPU clock source
561  * (usually to XTAL), and sets bias voltages for digital and RTC power domains.
562  *
563  * This function does not actually enter sleep mode; this is done using
564  * rtc_sleep_start function. Software may do some other actions between
565  * rtc_sleep_init and rtc_sleep_start, such as set wakeup timer and configure
566  * wakeup sources.
567  * @param cfg sleep mode configuration
568  */
569 void rtc_sleep_init(rtc_sleep_config_t cfg);
570 
571 /**
572  * @brief Low level initialize for rtc state machine waiting cycles after waking up
573  *
574  * This function configures the cycles chip need to wait for internal 8MHz
575  * oscillator and external 40MHz crystal. As we configure fixed time for waiting
576  * crystal, we need to pass period to calculate cycles. Now this function only
577  * used in lightsleep mode.
578  *
579  * @param slowclk_period re-calibrated slow clock period
580  */
581 void rtc_sleep_low_init(uint32_t slowclk_period);
582 
583 /**
584  * @brief Set target value of RTC counter for RTC_TIMER_TRIG_EN wakeup source
585  * @param t value of RTC counter at which wakeup from sleep will happen;
586  *          only the lower 48 bits are used
587  */
588 void rtc_sleep_set_wakeup_time(uint64_t t);
589 
590 
591 #define RTC_EXT0_TRIG_EN    BIT(0)  //!< EXT0 GPIO wakeup
592 #define RTC_EXT1_TRIG_EN    BIT(1)  //!< EXT1 GPIO wakeup
593 #define RTC_GPIO_TRIG_EN    BIT(2)  //!< GPIO wakeup (light sleep only)
594 #define RTC_TIMER_TRIG_EN   BIT(3)  //!< Timer wakeup
595 #define RTC_SDIO_TRIG_EN    BIT(4)  //!< SDIO wakeup (light sleep only)
596 #define RTC_MAC_TRIG_EN     BIT(5)  //!< MAC wakeup (light sleep only)
597 #define RTC_UART0_TRIG_EN   BIT(6)  //!< UART0 wakeup (light sleep only)
598 #define RTC_UART1_TRIG_EN   BIT(7)  //!< UART1 wakeup (light sleep only)
599 #define RTC_TOUCH_TRIG_EN   BIT(8)  //!< Touch wakeup
600 #define RTC_ULP_TRIG_EN     BIT(9)  //!< ULP wakeup
601 #define RTC_BT_TRIG_EN      BIT(10) //!< BT wakeup (light sleep only)
602 
603 /**
604  * @brief Enter deep or light sleep mode
605  *
606  * This function enters the sleep mode previously configured using rtc_sleep_init
607  * function. Before entering sleep, software should configure wake up sources
608  * appropriately (set up GPIO wakeup registers, timer wakeup registers,
609  * and so on).
610  *
611  * If deep sleep mode was configured using rtc_sleep_init, and sleep is not
612  * rejected by hardware (based on reject_opt flags), this function never returns.
613  * When the chip wakes up from deep sleep, CPU is reset and execution starts
614  * from ROM bootloader.
615  *
616  * If light sleep mode was configured using rtc_sleep_init, this function
617  * returns on wakeup, or if sleep is rejected by hardware.
618  *
619  * @param wakeup_opt  bit mask wake up reasons to enable (RTC_xxx_TRIG_EN flags
620  *                    combined with OR)
621  * @param reject_opt  bit mask of sleep reject reasons:
622  *                      - RTC_CNTL_GPIO_REJECT_EN
623  *                      - RTC_CNTL_SDIO_REJECT_EN
624  *                    These flags are used to prevent entering sleep when e.g.
625  *                    an external host is communicating via SDIO slave
626  * @return non-zero if sleep was rejected by hardware
627  */
628 uint32_t rtc_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt);
629 
630 /**
631  * @brief Enter deep sleep mode
632  *
633  * Similar to rtc_sleep_start(), but additionally uses hardware to calculate the CRC value
634  * of RTC FAST memory. On wake, this CRC is used to determine if a deep sleep wake
635  * stub is valid to execute (if a wake address is set).
636  *
637  * No RAM is accessed while calculating the CRC and going into deep sleep, which makes
638  * this function safe to use even if the caller's stack is in RTC FAST memory.
639  *
640  * @note If no deep sleep wake stub address is set then calling rtc_sleep_start() will
641  * have the same effect and takes less time as CRC calculation is skipped.
642  *
643  * @note This function should only be called after rtc_sleep_init() has been called to
644  * configure the system for deep sleep.
645  *
646  * @param wakeup_opt - same as for rtc_sleep_start
647  * @param reject_opt - same as for rtc_sleep_start
648  *
649  * @return non-zero if sleep was rejected by hardware
650  */
651 uint32_t rtc_deep_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt);
652 
653 /**
654  * RTC power and clock control initialization settings
655  */
656 typedef struct rtc_config_s {
657     uint32_t ck8m_wait : 8;         //!< Number of rtc_fast_clk cycles to wait for 8M clock to be ready
658     uint32_t xtal_wait : 8;         //!< Number of rtc_fast_clk cycles to wait for XTAL clock to be ready
659     uint32_t pll_wait : 8;          //!< Number of rtc_fast_clk cycles to wait for PLL to be ready
660     uint32_t clkctl_init : 1;       //!< Perform clock control related initialization
661     uint32_t pwrctl_init : 1;       //!< Perform power control related initialization
662     uint32_t rtc_dboost_fpd : 1;    //!< Force power down RTC_DBOOST
663 } rtc_config_t;
664 
665 /**
666  * Default initializer of rtc_config_t.
667  *
668  * This initializer sets all fields to "reasonable" values (e.g. suggested for
669  * production use).
670  */
671 #define RTC_CONFIG_DEFAULT() {\
672     .ck8m_wait = RTC_CNTL_CK8M_WAIT_DEFAULT, \
673     .xtal_wait = RTC_CNTL_XTL_BUF_WAIT_DEFAULT, \
674     .pll_wait  = RTC_CNTL_PLL_BUF_WAIT_DEFAULT, \
675     .clkctl_init = 1, \
676     .pwrctl_init = 1, \
677     .rtc_dboost_fpd = 1 \
678 }
679 
680 /**
681  * Initialize RTC clock and power control related functions
682  * @param cfg configuration options as rtc_config_t
683  */
684 void rtc_init(rtc_config_t cfg);
685 
686 #define RTC_VDDSDIO_TIEH_1_8V 0 //!< TIEH field value for 1.8V VDDSDIO
687 #define RTC_VDDSDIO_TIEH_3_3V 1 //!< TIEH field value for 3.3V VDDSDIO
688 
689 /**
690  * Structure describing vddsdio configuration
691  */
692 typedef struct rtc_vddsdio_config_s {
693     uint32_t force : 1;     //!< If 1, use configuration from RTC registers; if 0, use EFUSE/bootstrapping pins.
694     uint32_t enable : 1;    //!< Enable VDDSDIO regulator
695     uint32_t tieh  : 1;     //!< Select VDDSDIO voltage. One of RTC_VDDSDIO_TIEH_1_8V, RTC_VDDSDIO_TIEH_3_3V
696     uint32_t drefh : 2;     //!< Tuning parameter for VDDSDIO regulator
697     uint32_t drefm : 2;     //!< Tuning parameter for VDDSDIO regulator
698     uint32_t drefl : 2;     //!< Tuning parameter for VDDSDIO regulator
699 } rtc_vddsdio_config_t;
700 
701 /**
702  * Get current VDDSDIO configuration
703  * If VDDSDIO configuration is overridden by RTC, get values from RTC
704  * Otherwise, if VDDSDIO is configured by EFUSE, get values from EFUSE
705  * Otherwise, use default values and the level of MTDI bootstrapping pin.
706  * @return currently used VDDSDIO configuration
707  */
708 rtc_vddsdio_config_t rtc_vddsdio_get_config(void);
709 
710 /**
711  * Set new VDDSDIO configuration using RTC registers.
712  * If config.force == 1, this overrides configuration done using bootstrapping
713  * pins and EFUSE.
714  *
715  * @param config new VDDSDIO configuration
716  */
717 void rtc_vddsdio_set_config(rtc_vddsdio_config_t config);
718 
719 
720 #ifdef __cplusplus
721 }
722 #endif /* __cplusplus */
723 #endif /* __RTC_H__ */