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