1 /*
2 * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8
9 #include <string.h>
10 #include "esp_log.h"
11 #include "esp_err.h"
12 #include "esp_check.h"
13 #include "driver/rtc_io.h"
14 #include "hal/rtc_io_hal.h"
15 #include "soc/soc_caps.h"
16
17 static const char __attribute__((__unused__)) *RTCIO_TAG = "RTCIO";
18
19 extern int rtc_spinlock;
20
21 #define RTCIO_ENTER_CRITICAL() do { rtc_spinlock = irq_lock(); } while(0)
22 #define RTCIO_EXIT_CRITICAL() irq_unlock(rtc_spinlock);
23
24 #if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
25
26 /*---------------------------------------------------------------
27 RTC IO
28 ---------------------------------------------------------------*/
rtc_gpio_init(gpio_num_t gpio_num)29 esp_err_t rtc_gpio_init(gpio_num_t gpio_num)
30 {
31 ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
32 RTCIO_ENTER_CRITICAL();
33 rtcio_hal_function_select(rtc_io_number_get(gpio_num), RTCIO_FUNC_RTC);
34 RTCIO_EXIT_CRITICAL();
35
36 return ESP_OK;
37 }
38
rtc_gpio_deinit(gpio_num_t gpio_num)39 esp_err_t rtc_gpio_deinit(gpio_num_t gpio_num)
40 {
41 ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
42 RTCIO_ENTER_CRITICAL();
43 // Select Gpio as Digital Gpio
44 rtcio_hal_function_select(rtc_io_number_get(gpio_num), RTCIO_FUNC_DIGITAL);
45 RTCIO_EXIT_CRITICAL();
46
47 return ESP_OK;
48 }
49
rtc_gpio_set_level(gpio_num_t gpio_num,uint32_t level)50 esp_err_t rtc_gpio_set_level(gpio_num_t gpio_num, uint32_t level)
51 {
52 ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
53 RTCIO_ENTER_CRITICAL();
54 rtcio_hal_set_level(rtc_io_number_get(gpio_num), level);
55 RTCIO_EXIT_CRITICAL();
56
57 return ESP_OK;
58 }
59
rtc_gpio_get_level(gpio_num_t gpio_num)60 uint32_t rtc_gpio_get_level(gpio_num_t gpio_num)
61 {
62 ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
63 return rtcio_hal_get_level(rtc_io_number_get(gpio_num));
64 }
65
rtc_gpio_set_drive_capability(gpio_num_t gpio_num,gpio_drive_cap_t strength)66 esp_err_t rtc_gpio_set_drive_capability(gpio_num_t gpio_num, gpio_drive_cap_t strength)
67 {
68 ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
69 ESP_RETURN_ON_FALSE(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "Output pad only");
70 ESP_RETURN_ON_FALSE(strength < GPIO_DRIVE_CAP_MAX, ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO drive capability error");
71 RTCIO_ENTER_CRITICAL();
72 rtcio_hal_set_drive_capability(rtc_io_number_get(gpio_num), strength);
73 RTCIO_EXIT_CRITICAL();
74
75 return ESP_OK;
76 }
77
rtc_gpio_get_drive_capability(gpio_num_t gpio_num,gpio_drive_cap_t * strength)78 esp_err_t rtc_gpio_get_drive_capability(gpio_num_t gpio_num, gpio_drive_cap_t *strength)
79 {
80 ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
81 ESP_RETURN_ON_FALSE(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "Output pad only");
82 ESP_RETURN_ON_FALSE(strength != NULL, ESP_ERR_INVALID_ARG, RTCIO_TAG, "GPIO drive pointer error");
83 *strength = (gpio_drive_cap_t)rtcio_hal_get_drive_capability(rtc_io_number_get(gpio_num));
84
85 return ESP_OK;
86 }
87
rtc_gpio_set_direction(gpio_num_t gpio_num,rtc_gpio_mode_t mode)88 esp_err_t rtc_gpio_set_direction(gpio_num_t gpio_num, rtc_gpio_mode_t mode)
89 {
90 ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
91 RTCIO_ENTER_CRITICAL();
92 rtcio_hal_set_direction(rtc_io_number_get(gpio_num), mode);
93 RTCIO_EXIT_CRITICAL();
94
95 return ESP_OK;
96 }
97
rtc_gpio_set_direction_in_sleep(gpio_num_t gpio_num,rtc_gpio_mode_t mode)98 esp_err_t rtc_gpio_set_direction_in_sleep(gpio_num_t gpio_num, rtc_gpio_mode_t mode)
99 {
100 ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
101 RTCIO_ENTER_CRITICAL();
102 rtcio_hal_set_direction_in_sleep(rtc_io_number_get(gpio_num), mode);
103 RTCIO_EXIT_CRITICAL();
104
105 return ESP_OK;
106 }
107
rtc_gpio_pullup_en(gpio_num_t gpio_num)108 esp_err_t rtc_gpio_pullup_en(gpio_num_t gpio_num)
109 {
110 ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
111 RTCIO_ENTER_CRITICAL();
112 rtcio_hal_pullup_enable(rtc_io_number_get(gpio_num));
113 RTCIO_EXIT_CRITICAL();
114
115 return ESP_OK;
116 }
117
rtc_gpio_pullup_dis(gpio_num_t gpio_num)118 esp_err_t rtc_gpio_pullup_dis(gpio_num_t gpio_num)
119 {
120 ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
121 RTCIO_ENTER_CRITICAL();
122 rtcio_hal_pullup_disable(rtc_io_number_get(gpio_num));
123 RTCIO_EXIT_CRITICAL();
124
125 return ESP_OK;
126 }
127
rtc_gpio_pulldown_en(gpio_num_t gpio_num)128 esp_err_t rtc_gpio_pulldown_en(gpio_num_t gpio_num)
129 {
130 ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
131 RTCIO_ENTER_CRITICAL();
132 rtcio_hal_pulldown_enable(rtc_io_number_get(gpio_num));
133 RTCIO_EXIT_CRITICAL();
134
135 return ESP_OK;
136 }
137
rtc_gpio_pulldown_dis(gpio_num_t gpio_num)138 esp_err_t rtc_gpio_pulldown_dis(gpio_num_t gpio_num)
139 {
140 ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
141 RTCIO_ENTER_CRITICAL();
142 rtcio_hal_pulldown_disable(rtc_io_number_get(gpio_num));
143 RTCIO_EXIT_CRITICAL();
144
145 return ESP_OK;
146 }
147
148 #endif // SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
149
150 #if SOC_RTCIO_HOLD_SUPPORTED
151
rtc_gpio_hold_en(gpio_num_t gpio_num)152 esp_err_t rtc_gpio_hold_en(gpio_num_t gpio_num)
153 {
154 ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
155 RTCIO_ENTER_CRITICAL();
156 rtcio_hal_hold_enable(rtc_io_number_get(gpio_num));
157 RTCIO_EXIT_CRITICAL();
158 return ESP_OK;
159 }
160
rtc_gpio_hold_dis(gpio_num_t gpio_num)161 esp_err_t rtc_gpio_hold_dis(gpio_num_t gpio_num)
162 {
163 ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
164 RTCIO_ENTER_CRITICAL();
165 rtcio_hal_hold_disable(rtc_io_number_get(gpio_num));
166 RTCIO_EXIT_CRITICAL();
167 return ESP_OK;
168 }
169
rtc_gpio_isolate(gpio_num_t gpio_num)170 esp_err_t rtc_gpio_isolate(gpio_num_t gpio_num)
171 {
172 ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
173 RTCIO_ENTER_CRITICAL();
174 rtcio_hal_isolate(rtc_io_number_get(gpio_num));
175 RTCIO_EXIT_CRITICAL();
176
177 return ESP_OK;
178 }
179
rtc_gpio_force_hold_en_all(void)180 esp_err_t rtc_gpio_force_hold_en_all(void)
181 {
182 RTCIO_ENTER_CRITICAL();
183 rtcio_hal_hold_all();
184 RTCIO_EXIT_CRITICAL();
185
186 return ESP_OK;
187 }
188
rtc_gpio_force_hold_dis_all(void)189 esp_err_t rtc_gpio_force_hold_dis_all(void)
190 {
191 RTCIO_ENTER_CRITICAL();
192 rtcio_hal_unhold_all();
193 RTCIO_EXIT_CRITICAL();
194
195 return ESP_OK;
196 }
197 #endif // SOC_RTCIO_HOLD_SUPPORTED
198
199 #if SOC_RTCIO_WAKE_SUPPORTED
200
rtc_gpio_wakeup_enable(gpio_num_t gpio_num,gpio_int_type_t intr_type)201 esp_err_t rtc_gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type)
202 {
203 ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
204 if (intr_type == GPIO_INTR_POSEDGE || intr_type == GPIO_INTR_NEGEDGE || intr_type == GPIO_INTR_ANYEDGE) {
205 return ESP_ERR_INVALID_ARG; // Dont support this mode.
206 }
207 RTCIO_ENTER_CRITICAL();
208 rtcio_hal_wakeup_enable(rtc_io_number_get(gpio_num), intr_type);
209 RTCIO_EXIT_CRITICAL();
210 return ESP_OK;
211 }
212
rtc_gpio_wakeup_disable(gpio_num_t gpio_num)213 esp_err_t rtc_gpio_wakeup_disable(gpio_num_t gpio_num)
214 {
215 ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
216 RTCIO_ENTER_CRITICAL();
217 rtcio_hal_wakeup_disable(rtc_io_number_get(gpio_num));
218 RTCIO_EXIT_CRITICAL();
219 return ESP_OK;
220 }
221
222 #endif // SOC_RTCIO_WAKE_SUPPORTED
223
rtc_gpio_is_valid_gpio(gpio_num_t gpio_num)224 bool rtc_gpio_is_valid_gpio(gpio_num_t gpio_num)
225 {
226 #if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
227 return (gpio_num < GPIO_PIN_COUNT && rtc_io_num_map[gpio_num] >= 0);
228 #else
229 return false;
230 #endif
231 }
232
233 #if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
rtc_io_number_get(gpio_num_t gpio_num)234 int rtc_io_number_get(gpio_num_t gpio_num)
235 {
236 return rtc_io_num_map[gpio_num];
237 }
238
239 #endif // SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
240