1 /*
2  * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /*******************************************************************************
8  * NOTICE
9  * The ll is not public api, don't use in application code.
10  * See readme.md in hal/include/hal/readme.md
11  ******************************************************************************/
12 
13 #pragma once
14 
15 #include <stdlib.h>
16 #include "soc/rtc_periph.h"
17 #include "hal/gpio_types.h"
18 
19 #define RTCIO_LL_PIN_FUNC     0
20 
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24 
25 typedef enum {
26     RTCIO_FUNC_RTC = 0x0,         /*!< The pin controled by RTC module. */
27     RTCIO_FUNC_DIGITAL = 0x1,     /*!< The pin controlled by DIGITAL module. */
28 } rtcio_ll_func_t;
29 
30 typedef enum {
31     RTCIO_WAKEUP_DISABLE    = 0,    /*!< Disable GPIO interrupt                             */
32     RTCIO_WAKEUP_LOW_LEVEL  = 0x4,  /*!< GPIO interrupt type : input low level trigger      */
33     RTCIO_WAKEUP_HIGH_LEVEL = 0x5,  /*!< GPIO interrupt type : input high level trigger     */
34 } rtcio_ll_wake_type_t;
35 
36 typedef enum {
37     RTCIO_OUTPUT_NORMAL = 0,    /*!< RTCIO output mode is normal. */
38     RTCIO_OUTPUT_OD = 0x1,      /*!< RTCIO output mode is open-drain. */
39 } rtcio_ll_out_mode_t;
40 
41 /**
42  * @brief Select the rtcio function.
43  *
44  * @note The RTC function must be selected before the pad analog function is enabled.
45  * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
46  * @param func Select pin function.
47  */
rtcio_ll_function_select(int rtcio_num,rtcio_ll_func_t func)48 static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func)
49 {
50     if (func == RTCIO_FUNC_RTC) {
51         // 0: GPIO connected to digital GPIO module. 1: GPIO connected to analog RTC module.
52         SET_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, (rtc_io_desc[rtcio_num].mux));
53         //0:RTC FUNCTION 1,2,3:Reserved
54         SET_PERI_REG_BITS(rtc_io_desc[rtcio_num].reg, RTC_IO_TOUCH_PAD1_FUN_SEL_V, RTCIO_LL_PIN_FUNC, rtc_io_desc[rtcio_num].func);
55     } else if (func == RTCIO_FUNC_DIGITAL) {
56         CLEAR_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, (rtc_io_desc[rtcio_num].mux));
57     }
58 }
59 
60 /**
61  * Enable rtcio output.
62  *
63  * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
64  */
rtcio_ll_output_enable(int rtcio_num)65 static inline void rtcio_ll_output_enable(int rtcio_num)
66 {
67     RTCIO.enable_w1ts.w1ts = (1U << rtcio_num);
68 }
69 
70 /**
71  * Disable rtcio output.
72  *
73  * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
74  */
rtcio_ll_output_disable(int rtcio_num)75 static inline void rtcio_ll_output_disable(int rtcio_num)
76 {
77     RTCIO.enable_w1tc.w1tc = (1U << rtcio_num);
78 }
79 
80 /**
81  * Set RTCIO output level.
82  *
83  * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
84  * @param level 0: output low; ~0: output high.
85  */
rtcio_ll_set_level(int rtcio_num,uint32_t level)86 static inline void rtcio_ll_set_level(int rtcio_num, uint32_t level)
87 {
88     if (level) {
89         RTCIO.out_w1ts.w1ts = (1U << rtcio_num);
90     } else {
91         RTCIO.out_w1tc.w1tc = (1U << rtcio_num);
92     }
93 }
94 
95 /**
96  * Enable rtcio input.
97  *
98  * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
99  */
rtcio_ll_input_enable(int rtcio_num)100 static inline void rtcio_ll_input_enable(int rtcio_num)
101 {
102     SET_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].ie);
103 }
104 
105 /**
106  * Disable rtcio input.
107  *
108  * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
109  */
rtcio_ll_input_disable(int rtcio_num)110 static inline void rtcio_ll_input_disable(int rtcio_num)
111 {
112     CLEAR_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].ie);
113 }
114 
115 /**
116  * Get RTCIO input level.
117  *
118  * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
119  * @return 0: input low; ~0: input high.
120  */
rtcio_ll_get_level(int rtcio_num)121 static inline uint32_t rtcio_ll_get_level(int rtcio_num)
122 {
123     return (uint32_t)(RTCIO.in_val.in >> rtcio_num) & 0x1;
124 }
125 
126 /**
127  * @brief Set RTC GPIO pad drive capability
128  *
129  * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
130  * @param strength Drive capability of the pad. Range: 0 ~ 3.
131  */
rtcio_ll_set_drive_capability(int rtcio_num,uint32_t strength)132 static inline void rtcio_ll_set_drive_capability(int rtcio_num, uint32_t strength)
133 {
134     if (rtc_io_desc[rtcio_num].drv_v) {
135         SET_PERI_REG_BITS(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].drv_v, strength, rtc_io_desc[rtcio_num].drv_s);
136     }
137 }
138 
139 /**
140  * @brief Get RTC GPIO pad drive capability.
141  *
142  * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
143  * @return Drive capability of the pad. Range: 0 ~ 3.
144  */
rtcio_ll_get_drive_capability(int rtcio_num)145 static inline uint32_t rtcio_ll_get_drive_capability(int rtcio_num)
146 {
147     return GET_PERI_REG_BITS2(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].drv_v, rtc_io_desc[rtcio_num].drv_s);
148 }
149 
150 /**
151  * @brief Set RTC GPIO pad output mode.
152  *
153  * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
154  * @return mode Output mode.
155  */
rtcio_ll_output_mode_set(int rtcio_num,rtcio_ll_out_mode_t mode)156 static inline void rtcio_ll_output_mode_set(int rtcio_num, rtcio_ll_out_mode_t mode)
157 {
158     RTCIO.pin[rtcio_num].pad_driver = mode;
159 }
160 
161 /**
162  * RTC GPIO pullup enable.
163  *
164  * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
165  */
rtcio_ll_pullup_enable(int rtcio_num)166 static inline void rtcio_ll_pullup_enable(int rtcio_num)
167 {
168     if (rtc_io_desc[rtcio_num].pullup) {
169         SET_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].pullup);
170     }
171 }
172 
173 /**
174  * RTC GPIO pullup disable.
175  *
176  * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
177  */
rtcio_ll_pullup_disable(int rtcio_num)178 static inline void rtcio_ll_pullup_disable(int rtcio_num)
179 {
180     if (rtc_io_desc[rtcio_num].pullup) {
181         CLEAR_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].pullup);
182     }
183 }
184 
185 /**
186  * RTC GPIO pulldown enable.
187  *
188  * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
189  */
rtcio_ll_pulldown_enable(int rtcio_num)190 static inline void rtcio_ll_pulldown_enable(int rtcio_num)
191 {
192     if (rtc_io_desc[rtcio_num].pulldown) {
193         SET_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].pulldown);
194     }
195 }
196 
197 /**
198  * RTC GPIO pulldown disable.
199  *
200  * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
201  */
rtcio_ll_pulldown_disable(int rtcio_num)202 static inline void rtcio_ll_pulldown_disable(int rtcio_num)
203 {
204     if (rtc_io_desc[rtcio_num].pulldown) {
205         CLEAR_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].pulldown);
206     }
207 }
208 
209 /**
210  * Enable force hold function on an RTC IO pad.
211  *
212  * Enabling HOLD function will cause the pad to lock current status, such as,
213  * input/output enable, input/output value, function, drive strength values.
214  * This function is useful when going into light or deep sleep mode to prevent
215  * the pin configuration from changing.
216  *
217  * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
218  */
rtcio_ll_force_hold_enable(int rtcio_num)219 static inline void rtcio_ll_force_hold_enable(int rtcio_num)
220 {
221     REG_SET_BIT(RTC_CNTL_HOLD_FORCE_REG, rtc_io_desc[rtcio_num].hold_force);
222     REG_SET_BIT(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].hold);
223 }
224 
225 /**
226  * Disable hold function on an RTC IO pad.
227  *
228  * @note If disable the pad hold, the status of pad maybe changed in sleep mode.
229  * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
230  */
rtcio_ll_force_hold_disable(int rtcio_num)231 static inline void rtcio_ll_force_hold_disable(int rtcio_num)
232 {
233     REG_CLR_BIT(RTC_CNTL_HOLD_FORCE_REG, rtc_io_desc[rtcio_num].hold_force);
234     REG_CLR_BIT(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].hold);
235 }
236 
237 /**
238  * Enable force hold function on all RTC IO pads.
239  *
240  * Enabling HOLD function will cause the pad to lock current status, such as,
241  * input/output enable, input/output value, function, drive strength values.
242  * This function is useful when going into light or deep sleep mode to prevent
243  * the pin configuration from changing.
244  *
245  * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
246  */
rtcio_ll_force_hold_all(void)247 static inline void rtcio_ll_force_hold_all(void)
248 {
249     SET_PERI_REG_BITS(RTC_CNTL_HOLD_FORCE_REG, 0x3FFFF, 0x3FFFF, 0);
250 }
251 
252 /**
253  * Disable hold function on all RTC IO pads.
254  *
255  * @note If disable the pad hold, the status of pad maybe changed in sleep mode.
256  * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
257  */
rtcio_ll_force_unhold_all(void)258 static inline void rtcio_ll_force_unhold_all(void)
259 {
260     SET_PERI_REG_BITS(RTC_CNTL_HOLD_FORCE_REG, 0x3FFFF, 0, 0);
261 }
262 
263 /**
264  * Enable wakeup function and set wakeup type from light sleep status for rtcio.
265  *
266  * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
267  * @param type  Wakeup on high level or low level.
268  */
rtcio_ll_wakeup_enable(int rtcio_num,rtcio_ll_wake_type_t type)269 static inline void rtcio_ll_wakeup_enable(int rtcio_num, rtcio_ll_wake_type_t type)
270 {
271     RTCIO.pin[rtcio_num].wakeup_enable = 0x1;
272     RTCIO.pin[rtcio_num].int_type = type;
273 }
274 
275 /**
276  * Disable wakeup function from light sleep status for rtcio.
277  *
278  * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
279  */
rtcio_ll_wakeup_disable(int rtcio_num)280 static inline void rtcio_ll_wakeup_disable(int rtcio_num)
281 {
282     RTCIO.pin[rtcio_num].wakeup_enable = 0;
283     RTCIO.pin[rtcio_num].int_type = RTCIO_WAKEUP_DISABLE;
284 }
285 
286 /**
287  * Enable rtc io output in deep sleep.
288  *
289  * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
290  */
rtcio_ll_enable_output_in_sleep(gpio_num_t gpio_num)291 static inline void rtcio_ll_enable_output_in_sleep(gpio_num_t gpio_num)
292 {
293     if (rtc_io_desc[gpio_num].slpoe) {
294         SET_PERI_REG_MASK(rtc_io_desc[gpio_num].reg, rtc_io_desc[gpio_num].slpoe);
295     }
296 }
297 
298 /**
299  * Disable rtc io output in deep sleep.
300  *
301  * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
302  */
rtcio_ll_disable_output_in_sleep(gpio_num_t gpio_num)303 static inline void rtcio_ll_disable_output_in_sleep(gpio_num_t gpio_num)
304 {
305     if (rtc_io_desc[gpio_num].slpoe) {
306         CLEAR_PERI_REG_MASK(rtc_io_desc[gpio_num].reg, rtc_io_desc[gpio_num].slpoe);
307     }
308 }
309 
310 /**
311  * Enable rtc io input in deep sleep.
312  *
313  * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
314  */
rtcio_ll_enable_input_in_sleep(gpio_num_t gpio_num)315 static inline void rtcio_ll_enable_input_in_sleep(gpio_num_t gpio_num)
316 {
317     SET_PERI_REG_MASK(rtc_io_desc[gpio_num].reg, rtc_io_desc[gpio_num].slpie);
318 }
319 
320 /**
321  * Disable rtc io input in deep sleep.
322  *
323  * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
324  */
rtcio_ll_disable_input_in_sleep(gpio_num_t gpio_num)325 static inline void rtcio_ll_disable_input_in_sleep(gpio_num_t gpio_num)
326 {
327     CLEAR_PERI_REG_MASK(rtc_io_desc[gpio_num].reg, rtc_io_desc[gpio_num].slpie);
328 }
329 
330 /**
331  * Enable rtc io keep another setting in deep sleep.
332  *
333  * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
334  */
rtcio_ll_enable_sleep_setting(gpio_num_t gpio_num)335 static inline void rtcio_ll_enable_sleep_setting(gpio_num_t gpio_num)
336 {
337     SET_PERI_REG_MASK(rtc_io_desc[gpio_num].reg, rtc_io_desc[gpio_num].slpsel);
338 }
339 
340 /**
341  * Disable rtc io keep another setting in deep sleep. (Default)
342  *
343  * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
344  */
rtcio_ll_disable_sleep_setting(gpio_num_t gpio_num)345 static inline void rtcio_ll_disable_sleep_setting(gpio_num_t gpio_num)
346 {
347     CLEAR_PERI_REG_MASK(rtc_io_desc[gpio_num].reg, rtc_io_desc[gpio_num].slpsel);
348 }
349 
350 /**
351  * Set specific logic level on an RTC IO pin as a wakeup trigger.
352  *
353  * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
354  * @param level Logic level (0)
355  */
rtcio_ll_ext0_set_wakeup_pin(int rtcio_num,int level)356 static inline void rtcio_ll_ext0_set_wakeup_pin(int rtcio_num, int level)
357 {
358     REG_SET_FIELD(RTC_IO_EXT_WAKEUP0_REG, RTC_IO_EXT_WAKEUP0_SEL, rtcio_num);
359     // Set level which will trigger wakeup
360     SET_PERI_REG_BITS(RTC_CNTL_EXT_WAKEUP_CONF_REG, 0x1,
361             level , RTC_CNTL_EXT_WAKEUP0_LV_S);
362 }
363 
364 #ifdef __cplusplus
365 }
366 #endif
367