1 /*
2 * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <string.h>
8 #include "esp_log.h"
9 #include "esp_err.h"
10 #include "esp_check.h"
11 #include "freertos/FreeRTOS.h"
12 #include "freertos/semphr.h"
13 #include "freertos/timers.h"
14 #include "driver/rtc_io.h"
15 #include "hal/rtc_io_hal.h"
16
17 static const char __attribute__((__unused__)) *RTCIO_TAG = "RTCIO";
18
19 extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate position after the rtc module is finished.
20 #define RTCIO_ENTER_CRITICAL() portENTER_CRITICAL(&rtc_spinlock)
21 #define RTCIO_EXIT_CRITICAL() portEXIT_CRITICAL(&rtc_spinlock)
22
23 #if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
24
25 /*---------------------------------------------------------------
26 RTC IO
27 ---------------------------------------------------------------*/
rtc_gpio_init(gpio_num_t gpio_num)28 esp_err_t rtc_gpio_init(gpio_num_t gpio_num)
29 {
30 ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
31 RTCIO_ENTER_CRITICAL();
32 rtcio_hal_function_select(rtc_io_number_get(gpio_num), RTCIO_FUNC_RTC);
33 RTCIO_EXIT_CRITICAL();
34
35 return ESP_OK;
36 }
37
rtc_gpio_deinit(gpio_num_t gpio_num)38 esp_err_t rtc_gpio_deinit(gpio_num_t gpio_num)
39 {
40 ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
41 RTCIO_ENTER_CRITICAL();
42 // Select Gpio as Digital Gpio
43 rtcio_hal_function_select(rtc_io_number_get(gpio_num), RTCIO_FUNC_DIGITAL);
44 RTCIO_EXIT_CRITICAL();
45
46 return ESP_OK;
47 }
48
rtc_gpio_set_level(gpio_num_t gpio_num,uint32_t level)49 esp_err_t rtc_gpio_set_level(gpio_num_t gpio_num, uint32_t level)
50 {
51 ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
52 RTCIO_ENTER_CRITICAL();
53 rtcio_hal_set_level(rtc_io_number_get(gpio_num), level);
54 RTCIO_EXIT_CRITICAL();
55
56 return ESP_OK;
57 }
58
rtc_gpio_get_level(gpio_num_t gpio_num)59 uint32_t rtc_gpio_get_level(gpio_num_t gpio_num)
60 {
61 ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
62 return rtcio_hal_get_level(rtc_io_number_get(gpio_num));
63 }
64
rtc_gpio_set_drive_capability(gpio_num_t gpio_num,gpio_drive_cap_t strength)65 esp_err_t rtc_gpio_set_drive_capability(gpio_num_t gpio_num, gpio_drive_cap_t strength)
66 {
67 ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
68 ESP_RETURN_ON_FALSE(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "Output pad only");
69 ESP_RETURN_ON_FALSE(strength < GPIO_DRIVE_CAP_MAX, ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO drive capability error");
70 RTCIO_ENTER_CRITICAL();
71 rtcio_hal_set_drive_capability(rtc_io_number_get(gpio_num), strength);
72 RTCIO_EXIT_CRITICAL();
73
74 return ESP_OK;
75 }
76
rtc_gpio_get_drive_capability(gpio_num_t gpio_num,gpio_drive_cap_t * strength)77 esp_err_t rtc_gpio_get_drive_capability(gpio_num_t gpio_num, gpio_drive_cap_t *strength)
78 {
79 ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
80 ESP_RETURN_ON_FALSE(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "Output pad only");
81 ESP_RETURN_ON_FALSE(strength != NULL, ESP_ERR_INVALID_ARG, RTCIO_TAG, "GPIO drive pointer error");
82 *strength = (gpio_drive_cap_t)rtcio_hal_get_drive_capability(rtc_io_number_get(gpio_num));
83
84 return ESP_OK;
85 }
86
rtc_gpio_set_direction(gpio_num_t gpio_num,rtc_gpio_mode_t mode)87 esp_err_t rtc_gpio_set_direction(gpio_num_t gpio_num, rtc_gpio_mode_t mode)
88 {
89 ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
90 RTCIO_ENTER_CRITICAL();
91 rtcio_hal_set_direction(rtc_io_number_get(gpio_num), mode);
92 RTCIO_EXIT_CRITICAL();
93
94 return ESP_OK;
95 }
96
rtc_gpio_set_direction_in_sleep(gpio_num_t gpio_num,rtc_gpio_mode_t mode)97 esp_err_t rtc_gpio_set_direction_in_sleep(gpio_num_t gpio_num, rtc_gpio_mode_t mode)
98 {
99 ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
100 RTCIO_ENTER_CRITICAL();
101 rtcio_hal_set_direction_in_sleep(rtc_io_number_get(gpio_num), mode);
102 RTCIO_EXIT_CRITICAL();
103
104 return ESP_OK;
105 }
106
rtc_gpio_pullup_en(gpio_num_t gpio_num)107 esp_err_t rtc_gpio_pullup_en(gpio_num_t gpio_num)
108 {
109 ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
110 RTCIO_ENTER_CRITICAL();
111 rtcio_hal_pullup_enable(rtc_io_number_get(gpio_num));
112 RTCIO_EXIT_CRITICAL();
113
114 return ESP_OK;
115 }
116
rtc_gpio_pullup_dis(gpio_num_t gpio_num)117 esp_err_t rtc_gpio_pullup_dis(gpio_num_t gpio_num)
118 {
119 ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
120 RTCIO_ENTER_CRITICAL();
121 rtcio_hal_pullup_disable(rtc_io_number_get(gpio_num));
122 RTCIO_EXIT_CRITICAL();
123
124 return ESP_OK;
125 }
126
rtc_gpio_pulldown_en(gpio_num_t gpio_num)127 esp_err_t rtc_gpio_pulldown_en(gpio_num_t gpio_num)
128 {
129 ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
130 RTCIO_ENTER_CRITICAL();
131 rtcio_hal_pulldown_enable(rtc_io_number_get(gpio_num));
132 RTCIO_EXIT_CRITICAL();
133
134 return ESP_OK;
135 }
136
rtc_gpio_pulldown_dis(gpio_num_t gpio_num)137 esp_err_t rtc_gpio_pulldown_dis(gpio_num_t gpio_num)
138 {
139 ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
140 RTCIO_ENTER_CRITICAL();
141 rtcio_hal_pulldown_disable(rtc_io_number_get(gpio_num));
142 RTCIO_EXIT_CRITICAL();
143
144 return ESP_OK;
145 }
146
147 #endif // SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
148
149 #if SOC_RTCIO_HOLD_SUPPORTED
150
rtc_gpio_hold_en(gpio_num_t gpio_num)151 esp_err_t rtc_gpio_hold_en(gpio_num_t gpio_num)
152 {
153 ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
154 RTCIO_ENTER_CRITICAL();
155 rtcio_hal_hold_enable(rtc_io_number_get(gpio_num));
156 RTCIO_EXIT_CRITICAL();
157 return ESP_OK;
158 }
159
rtc_gpio_hold_dis(gpio_num_t gpio_num)160 esp_err_t rtc_gpio_hold_dis(gpio_num_t gpio_num)
161 {
162 ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
163 RTCIO_ENTER_CRITICAL();
164 rtcio_hal_hold_disable(rtc_io_number_get(gpio_num));
165 RTCIO_EXIT_CRITICAL();
166 return ESP_OK;
167 }
168
rtc_gpio_isolate(gpio_num_t gpio_num)169 esp_err_t rtc_gpio_isolate(gpio_num_t gpio_num)
170 {
171 ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
172 RTCIO_ENTER_CRITICAL();
173 rtcio_hal_isolate(rtc_io_number_get(gpio_num));
174 RTCIO_EXIT_CRITICAL();
175
176 return ESP_OK;
177 }
178
rtc_gpio_force_hold_en_all(void)179 esp_err_t rtc_gpio_force_hold_en_all(void)
180 {
181 RTCIO_ENTER_CRITICAL();
182 rtcio_hal_hold_all();
183 RTCIO_EXIT_CRITICAL();
184
185 return ESP_OK;
186 }
187
rtc_gpio_force_hold_dis_all(void)188 esp_err_t rtc_gpio_force_hold_dis_all(void)
189 {
190 RTCIO_ENTER_CRITICAL();
191 rtcio_hal_unhold_all();
192 RTCIO_EXIT_CRITICAL();
193
194 return ESP_OK;
195 }
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