1 /*
2  * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #pragma once
8 
9 #include <stdint.h>
10 #include <stdbool.h>
11 #include "esp_err.h"
12 #include "soc/soc_caps.h"
13 #include "hal/rtc_io_types.h"
14 #include "driver/gpio.h"
15 
16 
17 #ifdef __cplusplus
18 extern "C" {
19 #endif
20 
21 /**
22  * @brief Determine if the specified GPIO is a valid RTC GPIO.
23  *
24  * @param gpio_num GPIO number
25  * @return true if GPIO is valid for RTC GPIO use. false otherwise.
26  */
27 bool rtc_gpio_is_valid_gpio(gpio_num_t gpio_num);
28 
29 #define RTC_GPIO_IS_VALID_GPIO(gpio_num) rtc_gpio_is_valid_gpio(gpio_num)
30 
31 #if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
32 /**
33  * @brief Get RTC IO index number by gpio number.
34  *
35  * @param gpio_num GPIO number
36  * @return
37  *        >=0: Index of rtcio.
38  *        -1 : The gpio is not rtcio.
39  */
40 int rtc_io_number_get(gpio_num_t gpio_num);
41 
42 /**
43  * @brief Init a GPIO as RTC GPIO
44  *
45  * This function must be called when initializing a pad for an analog function.
46  *
47  * @param  gpio_num GPIO number (e.g. GPIO_NUM_12)
48  *
49  * @return
50  *     - ESP_OK success
51  *     - ESP_ERR_INVALID_ARG GPIO is not an RTC IO
52  */
53 esp_err_t rtc_gpio_init(gpio_num_t gpio_num);
54 
55 /**
56  * @brief Init a GPIO as digital GPIO
57  *
58  * @param  gpio_num GPIO number (e.g. GPIO_NUM_12)
59  *
60  * @return
61  *     - ESP_OK success
62  *     - ESP_ERR_INVALID_ARG GPIO is not an RTC IO
63  */
64 esp_err_t rtc_gpio_deinit(gpio_num_t gpio_num);
65 
66 /**
67  * @brief Get the RTC IO input level
68  *
69  * @param  gpio_num GPIO number (e.g. GPIO_NUM_12)
70  *
71  * @return
72  *     - 1 High level
73  *     - 0 Low level
74  *     - ESP_ERR_INVALID_ARG GPIO is not an RTC IO
75  */
76 uint32_t rtc_gpio_get_level(gpio_num_t gpio_num);
77 
78 /**
79  * @brief Set the RTC IO output level
80  *
81  * @param  gpio_num GPIO number (e.g. GPIO_NUM_12)
82  * @param  level output level
83  *
84  * @return
85  *     - ESP_OK Success
86  *     - ESP_ERR_INVALID_ARG GPIO is not an RTC IO
87  */
88 esp_err_t rtc_gpio_set_level(gpio_num_t gpio_num, uint32_t level);
89 
90 /**
91  * @brief    RTC GPIO set direction
92  *
93  * Configure RTC GPIO direction, such as output only, input only,
94  * output and input.
95  *
96  * @param  gpio_num GPIO number (e.g. GPIO_NUM_12)
97  * @param  mode GPIO direction
98  *
99  * @return
100  *     - ESP_OK Success
101  *     - ESP_ERR_INVALID_ARG GPIO is not an RTC IO
102  */
103 esp_err_t rtc_gpio_set_direction(gpio_num_t gpio_num, rtc_gpio_mode_t mode);
104 
105 /**
106  * @brief RTC GPIO set direction in deep sleep mode or disable sleep status (default).
107  *        In some application scenarios, IO needs to have another states during deep sleep.
108  *
109  * NOTE: ESP32 support INPUT_ONLY mode.
110  *       ESP32S2 support INPUT_ONLY, OUTPUT_ONLY, INPUT_OUTPUT mode.
111  *
112  * @param  gpio_num GPIO number (e.g. GPIO_NUM_12)
113  * @param  mode GPIO direction
114  *
115  * @return
116  *     - ESP_OK Success
117  *     - ESP_ERR_INVALID_ARG GPIO is not an RTC IO
118  */
119 esp_err_t rtc_gpio_set_direction_in_sleep(gpio_num_t gpio_num, rtc_gpio_mode_t mode);
120 
121 /**
122  * @brief  RTC GPIO pullup enable
123  *
124  * This function only works for RTC IOs. In general, call gpio_pullup_en,
125  * which will work both for normal GPIOs and RTC IOs.
126  *
127  * @param  gpio_num GPIO number (e.g. GPIO_NUM_12)
128  *
129  * @return
130  *     - ESP_OK Success
131  *     - ESP_ERR_INVALID_ARG GPIO is not an RTC IO
132  */
133 esp_err_t rtc_gpio_pullup_en(gpio_num_t gpio_num);
134 
135 /**
136  * @brief  RTC GPIO pulldown enable
137  *
138  * This function only works for RTC IOs. In general, call gpio_pulldown_en,
139  * which will work both for normal GPIOs and RTC IOs.
140  *
141  * @param  gpio_num GPIO number (e.g. GPIO_NUM_12)
142  *
143  * @return
144  *     - ESP_OK Success
145  *     - ESP_ERR_INVALID_ARG GPIO is not an RTC IO
146  */
147 esp_err_t rtc_gpio_pulldown_en(gpio_num_t gpio_num);
148 
149 /**
150  * @brief  RTC GPIO pullup disable
151  *
152  * This function only works for RTC IOs. In general, call gpio_pullup_dis,
153  * which will work both for normal GPIOs and RTC IOs.
154  *
155  * @param  gpio_num GPIO number (e.g. GPIO_NUM_12)
156  *
157  * @return
158  *     - ESP_OK Success
159  *     - ESP_ERR_INVALID_ARG GPIO is not an RTC IO
160  */
161 esp_err_t rtc_gpio_pullup_dis(gpio_num_t gpio_num);
162 
163 /**
164  * @brief  RTC GPIO pulldown disable
165  *
166  * This function only works for RTC IOs. In general, call gpio_pulldown_dis,
167  * which will work both for normal GPIOs and RTC IOs.
168  *
169  * @param  gpio_num GPIO number (e.g. GPIO_NUM_12)
170  *
171  * @return
172  *     - ESP_OK Success
173  *     - ESP_ERR_INVALID_ARG GPIO is not an RTC IO
174  */
175 esp_err_t rtc_gpio_pulldown_dis(gpio_num_t gpio_num);
176 
177 /**
178  * @brief Set RTC GPIO pad drive capability
179  *
180  * @param gpio_num GPIO number, only support output GPIOs
181  * @param strength Drive capability of the pad
182  *
183  * @return
184  *     - ESP_OK Success
185  *     - ESP_ERR_INVALID_ARG Parameter error
186  */
187 esp_err_t rtc_gpio_set_drive_capability(gpio_num_t gpio_num, gpio_drive_cap_t strength);
188 
189 /**
190  * @brief Get RTC GPIO pad drive capability
191  *
192  * @param gpio_num GPIO number, only support output GPIOs
193  * @param strength Pointer to accept drive capability of the pad
194  *
195  * @return
196  *     - ESP_OK Success
197  *     - ESP_ERR_INVALID_ARG Parameter error
198  */
199 esp_err_t rtc_gpio_get_drive_capability(gpio_num_t gpio_num, gpio_drive_cap_t* strength);
200 
201 #endif // SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
202 
203 #if SOC_RTCIO_HOLD_SUPPORTED
204 
205 /**
206  * @brief Enable hold function on an RTC IO pad
207  *
208  * Enabling HOLD function will cause the pad to latch current values of
209  * input enable, output enable, output value, function, drive strength values.
210  * This function is useful when going into light or deep sleep mode to prevent
211  * the pin configuration from changing.
212  *
213  * @param gpio_num GPIO number (e.g. GPIO_NUM_12)
214  * @return
215  *     - ESP_OK Success
216  *     - ESP_ERR_INVALID_ARG GPIO is not an RTC IO
217  */
218 esp_err_t rtc_gpio_hold_en(gpio_num_t gpio_num);
219 
220 /**
221  * @brief Disable hold function on an RTC IO pad
222  *
223  * Disabling hold function will allow the pad receive the values of
224  * input enable, output enable, output value, function, drive strength from
225  * RTC_IO peripheral.
226  *
227  * @param gpio_num GPIO number (e.g. GPIO_NUM_12)
228  * @return
229  *     - ESP_OK Success
230  *     - ESP_ERR_INVALID_ARG GPIO is not an RTC IO
231  */
232 esp_err_t rtc_gpio_hold_dis(gpio_num_t gpio_num);
233 
234 /**
235  * @brief Helper function to disconnect internal circuits from an RTC IO
236  * This function disables input, output, pullup, pulldown, and enables
237  * hold feature for an RTC IO.
238  * Use this function if an RTC IO needs to be disconnected from internal
239  * circuits in deep sleep, to minimize leakage current.
240  *
241  * In particular, for ESP32-WROVER module, call
242  * rtc_gpio_isolate(GPIO_NUM_12) before entering deep sleep, to reduce
243  * deep sleep current.
244  *
245  * @param gpio_num GPIO number (e.g. GPIO_NUM_12).
246  * @return
247  *      - ESP_OK on success
248  *      - ESP_ERR_INVALID_ARG if GPIO is not an RTC IO
249  */
250 esp_err_t rtc_gpio_isolate(gpio_num_t gpio_num);
251 
252 /**
253  * @brief Enable force hold signal for all RTC IOs
254  *
255  * Each RTC pad has a "force hold" input signal from the RTC controller.
256  * If this signal is set, pad latches current values of input enable,
257  * function, output enable, and other signals which come from the RTC mux.
258  * Force hold signal is enabled before going into deep sleep for pins which
259  * are used for EXT1 wakeup.
260  */
261 esp_err_t rtc_gpio_force_hold_en_all(void);
262 
263 /**
264  * @brief Disable force hold signal for all RTC IOs
265  */
266 esp_err_t rtc_gpio_force_hold_dis_all(void);
267 
268 #endif // SOC_RTCIO_HOLD_SUPPORTED
269 
270 #if SOC_RTCIO_WAKE_SUPPORTED
271 
272 /**
273  * @brief Enable wakeup from sleep mode using specific GPIO
274  * @param gpio_num  GPIO number
275  * @param intr_type  Wakeup on high level (GPIO_INTR_HIGH_LEVEL) or low level
276  *                   (GPIO_INTR_LOW_LEVEL)
277  * @return
278  *      - ESP_OK on success
279  *      - ESP_ERR_INVALID_ARG if gpio_num is not an RTC IO, or intr_type is not
280  *        one of GPIO_INTR_HIGH_LEVEL, GPIO_INTR_LOW_LEVEL.
281  */
282 esp_err_t rtc_gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type);
283 
284 /**
285  * @brief Disable wakeup from sleep mode using specific GPIO
286  * @param gpio_num  GPIO number
287  * @return
288  *      - ESP_OK on success
289  *      - ESP_ERR_INVALID_ARG if gpio_num is not an RTC IO
290  */
291 esp_err_t rtc_gpio_wakeup_disable(gpio_num_t gpio_num);
292 
293 #endif // SOC_RTCIO_WAKE_SUPPORTED
294 
295 #ifdef __cplusplus
296 }
297 #endif
298