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