• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015-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 <esp_types.h>
16 #include "esp_err.h"
17 #include "esp_osal/esp_osal.h"
18 #include "driver/gpio.h"
19 #include "driver/rtc_io.h"
20 #include "soc/soc.h"
21 #include "soc/periph_defs.h"
22 #if !CONFIG_FREERTOS_UNICORE
23 #include "esp_ipc.h"
24 #endif
25 
26 #include "soc/soc_caps.h"
27 #include "soc/gpio_periph.h"
28 #include "esp_log.h"
29 #include "hal/gpio_hal.h"
30 #include "esp_rom_gpio.h"
31 
32 static const char *GPIO_TAG = "gpio";
33 #define GPIO_CHECK(a, str, ret_val) \
34     if (!(a)) { \
35         ESP_LOGE(GPIO_TAG,"%s(%d): %s", __FUNCTION__, __LINE__, str); \
36         return (ret_val); \
37     }
38 
39 #define GPIO_ISR_CORE_ID_UNINIT    (3)
40 
41 //default value for SOC_GPIO_SUPPORT_RTC_INDEPENDENT is 0
42 #ifndef SOC_GPIO_SUPPORT_RTC_INDEPENDENT
43 #define SOC_GPIO_SUPPORT_RTC_INDEPENDENT 0
44 #endif
45 
46 typedef struct {
47     gpio_isr_t fn;   /*!< isr function */
48     void *args;      /*!< isr function args */
49 } gpio_isr_func_t;
50 
51 // Used by the IPC call to register the interrupt service routine.
52 typedef struct {
53     int source;               /*!< ISR source */
54     int intr_alloc_flags;     /*!< ISR alloc flag */
55     void (*fn)(void*);        /*!< ISR function */
56     void *arg;                /*!< ISR function args*/
57     void *handle;             /*!< ISR handle */
58     esp_err_t ret;
59 } gpio_isr_alloc_t;
60 
61 typedef struct {
62     gpio_hal_context_t *gpio_hal;
63     portMUX_TYPE gpio_spinlock;
64     uint32_t isr_core_id;
65     gpio_isr_func_t *gpio_isr_func;
66     gpio_isr_handle_t gpio_isr_handle;
67 } gpio_context_t;
68 
69 static gpio_hal_context_t _gpio_hal = {
70     .dev = GPIO_HAL_GET_HW(GPIO_PORT_0)
71 };
72 
73 static gpio_context_t gpio_context = {
74     .gpio_hal = &_gpio_hal,
75     .gpio_spinlock = portMUX_INITIALIZER_UNLOCKED,
76     .isr_core_id = GPIO_ISR_CORE_ID_UNINIT,
77     .gpio_isr_func = NULL,
78 };
79 
gpio_pullup_en(gpio_num_t gpio_num)80 esp_err_t gpio_pullup_en(gpio_num_t gpio_num)
81 {
82     GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
83 
84     if (!rtc_gpio_is_valid_gpio(gpio_num) || SOC_GPIO_SUPPORT_RTC_INDEPENDENT) {
85         portENTER_CRITICAL(&gpio_context.gpio_spinlock);
86         gpio_hal_pullup_en(gpio_context.gpio_hal, gpio_num);
87         portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
88     } else {
89 #if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
90         rtc_gpio_pullup_en(gpio_num);
91 #else
92         abort(); // This should be eliminated as unreachable, unless a programming error has occured
93 #endif
94     }
95 
96     return ESP_OK;
97 }
98 
gpio_pullup_dis(gpio_num_t gpio_num)99 esp_err_t gpio_pullup_dis(gpio_num_t gpio_num)
100 {
101     GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
102 
103     if (!rtc_gpio_is_valid_gpio(gpio_num) || SOC_GPIO_SUPPORT_RTC_INDEPENDENT) {
104         portENTER_CRITICAL(&gpio_context.gpio_spinlock);
105         gpio_hal_pullup_dis(gpio_context.gpio_hal, gpio_num);
106         portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
107     } else {
108 #if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
109         rtc_gpio_pullup_dis(gpio_num);
110 #else
111         abort(); // This should be eliminated as unreachable, unless a programming error has occured
112 #endif
113     }
114 
115     return ESP_OK;
116 }
117 
gpio_pulldown_en(gpio_num_t gpio_num)118 esp_err_t gpio_pulldown_en(gpio_num_t gpio_num)
119 {
120     GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
121 
122     if (!rtc_gpio_is_valid_gpio(gpio_num) || SOC_GPIO_SUPPORT_RTC_INDEPENDENT) {
123         portENTER_CRITICAL(&gpio_context.gpio_spinlock);
124         gpio_hal_pulldown_en(gpio_context.gpio_hal, gpio_num);
125         portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
126     } else {
127 #if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
128         rtc_gpio_pulldown_en(gpio_num);
129 #else
130         abort(); // This should be eliminated as unreachable, unless a programming error has occured
131 #endif
132     }
133 
134     return ESP_OK;
135 }
136 
gpio_pulldown_dis(gpio_num_t gpio_num)137 esp_err_t gpio_pulldown_dis(gpio_num_t gpio_num)
138 {
139     GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
140 
141     if (!rtc_gpio_is_valid_gpio(gpio_num) || SOC_GPIO_SUPPORT_RTC_INDEPENDENT) {
142         portENTER_CRITICAL(&gpio_context.gpio_spinlock);
143         gpio_hal_pulldown_dis(gpio_context.gpio_hal, gpio_num);
144         portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
145     } else {
146 #if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
147         rtc_gpio_pulldown_dis(gpio_num);
148 #else
149         abort(); // This should be eliminated as unreachable, unless a programming error has occured
150 #endif
151     }
152 
153     return ESP_OK;
154 }
155 
gpio_set_intr_type(gpio_num_t gpio_num,gpio_int_type_t intr_type)156 esp_err_t gpio_set_intr_type(gpio_num_t gpio_num, gpio_int_type_t intr_type)
157 {
158     GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
159     GPIO_CHECK(intr_type < GPIO_INTR_MAX, "GPIO interrupt type error", ESP_ERR_INVALID_ARG);
160 
161     portENTER_CRITICAL(&gpio_context.gpio_spinlock);
162     gpio_hal_set_intr_type(gpio_context.gpio_hal, gpio_num, intr_type);
163     portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
164     return ESP_OK;
165 }
166 
gpio_intr_enable_on_core(gpio_num_t gpio_num,uint32_t core_id)167 static esp_err_t gpio_intr_enable_on_core(gpio_num_t gpio_num, uint32_t core_id)
168 {
169     GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
170     gpio_hal_intr_enable_on_core(gpio_context.gpio_hal, gpio_num, core_id);
171     return ESP_OK;
172 }
173 
gpio_intr_enable(gpio_num_t gpio_num)174 esp_err_t gpio_intr_enable(gpio_num_t gpio_num)
175 {
176     GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
177     portENTER_CRITICAL(&gpio_context.gpio_spinlock);
178     if(gpio_context.isr_core_id == GPIO_ISR_CORE_ID_UNINIT) {
179         gpio_context.isr_core_id = xPortGetCoreID();
180     }
181     portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
182     return gpio_intr_enable_on_core (gpio_num, gpio_context.isr_core_id);
183 }
184 
gpio_intr_disable(gpio_num_t gpio_num)185 esp_err_t gpio_intr_disable(gpio_num_t gpio_num)
186 {
187     GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
188     gpio_hal_intr_disable(gpio_context.gpio_hal, gpio_num);
189     return ESP_OK;
190 }
191 
gpio_input_disable(gpio_num_t gpio_num)192 static esp_err_t gpio_input_disable(gpio_num_t gpio_num)
193 {
194     GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
195     gpio_hal_input_disable(gpio_context.gpio_hal, gpio_num);
196     return ESP_OK;
197 }
198 
gpio_input_enable(gpio_num_t gpio_num)199 static esp_err_t gpio_input_enable(gpio_num_t gpio_num)
200 {
201     GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
202     gpio_hal_input_enable(gpio_context.gpio_hal, gpio_num);
203     return ESP_OK;
204 }
205 
gpio_output_disable(gpio_num_t gpio_num)206 static esp_err_t gpio_output_disable(gpio_num_t gpio_num)
207 {
208     GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
209     gpio_hal_output_disable(gpio_context.gpio_hal, gpio_num);
210     return ESP_OK;
211 }
212 
gpio_output_enable(gpio_num_t gpio_num)213 static esp_err_t gpio_output_enable(gpio_num_t gpio_num)
214 {
215     GPIO_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "GPIO output gpio_num error", ESP_ERR_INVALID_ARG);
216     gpio_hal_output_enable(gpio_context.gpio_hal, gpio_num);
217     esp_rom_gpio_connect_out_signal(gpio_num, SIG_GPIO_OUT_IDX, false, false);
218     return ESP_OK;
219 }
220 
gpio_od_disable(gpio_num_t gpio_num)221 static esp_err_t gpio_od_disable(gpio_num_t gpio_num)
222 {
223     GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
224     gpio_hal_od_disable(gpio_context.gpio_hal, gpio_num);
225     return ESP_OK;
226 }
227 
gpio_od_enable(gpio_num_t gpio_num)228 static esp_err_t gpio_od_enable(gpio_num_t gpio_num)
229 {
230     GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
231     gpio_hal_od_enable(gpio_context.gpio_hal, gpio_num);
232     return ESP_OK;
233 }
234 
gpio_set_level(gpio_num_t gpio_num,uint32_t level)235 esp_err_t gpio_set_level(gpio_num_t gpio_num, uint32_t level)
236 {
237     GPIO_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "GPIO output gpio_num error", ESP_ERR_INVALID_ARG);
238     gpio_hal_set_level(gpio_context.gpio_hal, gpio_num, level);
239     return ESP_OK;
240 }
241 
gpio_get_level(gpio_num_t gpio_num)242 int gpio_get_level(gpio_num_t gpio_num)
243 {
244     return gpio_hal_get_level(gpio_context.gpio_hal, gpio_num);
245 }
246 
gpio_set_pull_mode(gpio_num_t gpio_num,gpio_pull_mode_t pull)247 esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull)
248 {
249     GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
250     GPIO_CHECK(pull <= GPIO_FLOATING, "GPIO pull mode error", ESP_ERR_INVALID_ARG);
251     esp_err_t ret = ESP_OK;
252 
253     switch (pull) {
254         case GPIO_PULLUP_ONLY:
255             gpio_pulldown_dis(gpio_num);
256             gpio_pullup_en(gpio_num);
257             break;
258 
259         case GPIO_PULLDOWN_ONLY:
260             gpio_pulldown_en(gpio_num);
261             gpio_pullup_dis(gpio_num);
262             break;
263 
264         case GPIO_PULLUP_PULLDOWN:
265             gpio_pulldown_en(gpio_num);
266             gpio_pullup_en(gpio_num);
267             break;
268 
269         case GPIO_FLOATING:
270             gpio_pulldown_dis(gpio_num);
271             gpio_pullup_dis(gpio_num);
272             break;
273 
274         default:
275             ESP_LOGE(GPIO_TAG, "Unknown pull up/down mode,gpio_num=%u,pull=%u", gpio_num, pull);
276             ret = ESP_ERR_INVALID_ARG;
277             break;
278     }
279 
280     return ret;
281 }
282 
gpio_set_direction(gpio_num_t gpio_num,gpio_mode_t mode)283 esp_err_t gpio_set_direction(gpio_num_t gpio_num, gpio_mode_t mode)
284 {
285     GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
286 
287     if ((GPIO_IS_VALID_OUTPUT_GPIO(gpio_num) != true) && (mode & GPIO_MODE_DEF_OUTPUT)) {
288         ESP_LOGE(GPIO_TAG, "io_num=%d can only be input", gpio_num);
289         return ESP_ERR_INVALID_ARG;
290     }
291 
292     esp_err_t ret = ESP_OK;
293 
294     if (mode & GPIO_MODE_DEF_INPUT) {
295         gpio_input_enable(gpio_num);
296     } else {
297         gpio_input_disable(gpio_num);
298     }
299 
300     if (mode & GPIO_MODE_DEF_OUTPUT) {
301         gpio_output_enable(gpio_num);
302     } else {
303         gpio_output_disable(gpio_num);
304     }
305 
306     if (mode & GPIO_MODE_DEF_OD) {
307         gpio_od_enable(gpio_num);
308     } else {
309         gpio_od_disable(gpio_num);
310     }
311 
312     return ret;
313 }
314 
gpio_config(const gpio_config_t * pGPIOConfig)315 esp_err_t gpio_config(const gpio_config_t *pGPIOConfig)
316 {
317     uint64_t gpio_pin_mask = (pGPIOConfig->pin_bit_mask);
318     uint32_t io_reg = 0;
319     uint32_t io_num = 0;
320     uint8_t input_en = 0;
321     uint8_t output_en = 0;
322     uint8_t od_en = 0;
323     uint8_t pu_en = 0;
324     uint8_t pd_en = 0;
325 
326     if (pGPIOConfig->pin_bit_mask == 0 ||
327         pGPIOConfig->pin_bit_mask & ~SOC_GPIO_VALID_GPIO_MASK) {
328         ESP_LOGE(GPIO_TAG, "GPIO_PIN mask error ");
329         return ESP_ERR_INVALID_ARG;
330     }
331 
332     if (pGPIOConfig->mode & GPIO_MODE_DEF_OUTPUT &&
333         pGPIOConfig->pin_bit_mask & ~SOC_GPIO_VALID_OUTPUT_GPIO_MASK) {
334         ESP_LOGE(GPIO_TAG, "GPIO can only be used as input mode");
335         return ESP_ERR_INVALID_ARG;
336     }
337 
338     do {
339         io_reg = GPIO_PIN_MUX_REG[io_num];
340 
341         if (((gpio_pin_mask >> io_num) & BIT(0))) {
342             assert(io_reg != (intptr_t)NULL);
343 
344 #if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
345             if (rtc_gpio_is_valid_gpio(io_num)) {
346                 rtc_gpio_deinit(io_num);
347             }
348 #endif
349 
350             if ((pGPIOConfig->mode) & GPIO_MODE_DEF_INPUT) {
351                 input_en = 1;
352                 gpio_input_enable(io_num);
353             } else {
354                 gpio_input_disable(io_num);
355             }
356 
357             if ((pGPIOConfig->mode) & GPIO_MODE_DEF_OD) {
358                 od_en = 1;
359                 gpio_od_enable(io_num);
360             } else {
361                 gpio_od_disable(io_num);
362             }
363 
364             if ((pGPIOConfig->mode) & GPIO_MODE_DEF_OUTPUT) {
365                 output_en = 1;
366                 gpio_output_enable(io_num);
367             } else {
368                 gpio_output_disable(io_num);
369             }
370 
371             if (pGPIOConfig->pull_up_en) {
372                 pu_en = 1;
373                 gpio_pullup_en(io_num);
374             } else {
375                 gpio_pullup_dis(io_num);
376             }
377 
378             if (pGPIOConfig->pull_down_en) {
379                 pd_en = 1;
380                 gpio_pulldown_en(io_num);
381             } else {
382                 gpio_pulldown_dis(io_num);
383             }
384 
385             gpio_set_intr_type(io_num, pGPIOConfig->intr_type);
386 
387             if (pGPIOConfig->intr_type) {
388                 gpio_intr_enable(io_num);
389             } else {
390                 gpio_intr_disable(io_num);
391             }
392 
393             /* By default, all the pins have to be configured as GPIO pins. */
394             gpio_hal_iomux_func_sel(io_reg, PIN_FUNC_GPIO);
395         }
396 
397         io_num++;
398     } while (io_num < GPIO_PIN_COUNT);
399 
400     return ESP_OK;
401 }
402 
gpio_reset_pin(gpio_num_t gpio_num)403 esp_err_t gpio_reset_pin(gpio_num_t gpio_num)
404 {
405     assert(gpio_num >= 0 && GPIO_IS_VALID_GPIO(gpio_num));
406     gpio_config_t cfg = {
407         .pin_bit_mask = BIT64(gpio_num),
408         .mode = GPIO_MODE_DISABLE,
409         //for powersave reasons, the GPIO should not be floating, select pullup
410         .pull_up_en = true,
411         .pull_down_en = false,
412         .intr_type = GPIO_INTR_DISABLE,
413     };
414     gpio_config(&cfg);
415     return ESP_OK;
416 }
417 
gpio_isr_loop(uint32_t status,const uint32_t gpio_num_start)418 static inline void IRAM_ATTR gpio_isr_loop(uint32_t status, const uint32_t gpio_num_start)
419 {
420     while (status) {
421         int nbit = __builtin_ffs(status) - 1;
422         status &= ~(1 << nbit);
423         int gpio_num = gpio_num_start + nbit;
424 
425         if (gpio_context.gpio_isr_func[gpio_num].fn != NULL) {
426             gpio_context.gpio_isr_func[gpio_num].fn(gpio_context.gpio_isr_func[gpio_num].args);
427         }
428     }
429 }
430 
gpio_intr_service(void * arg)431 static void IRAM_ATTR gpio_intr_service(void *arg)
432 {
433     //GPIO intr process
434     if (gpio_context.gpio_isr_func == NULL) {
435         return;
436     }
437 
438     //read status to get interrupt status for GPIO0-31
439     uint32_t gpio_intr_status;
440     gpio_hal_get_intr_status(gpio_context.gpio_hal, gpio_context.isr_core_id, &gpio_intr_status);
441 
442     if (gpio_intr_status) {
443         gpio_isr_loop(gpio_intr_status, 0);
444         gpio_hal_clear_intr_status(gpio_context.gpio_hal, gpio_intr_status);
445     }
446 
447     //read status1 to get interrupt status for GPIO32-39
448     uint32_t gpio_intr_status_h;
449     gpio_hal_get_intr_status_high(gpio_context.gpio_hal, gpio_context.isr_core_id, &gpio_intr_status_h);
450 
451     if (gpio_intr_status_h) {
452         gpio_isr_loop(gpio_intr_status_h, 32);
453         gpio_hal_clear_intr_status_high(gpio_context.gpio_hal, gpio_intr_status_h);
454     }
455 }
456 
gpio_install_isr_service(int intr_alloc_flags)457 esp_err_t gpio_install_isr_service(int intr_alloc_flags)
458 {
459     GPIO_CHECK(gpio_context.gpio_isr_func == NULL, "GPIO isr service already installed", ESP_ERR_INVALID_STATE);
460     esp_err_t ret;
461     portENTER_CRITICAL(&gpio_context.gpio_spinlock);
462     gpio_context.gpio_isr_func = (gpio_isr_func_t *) calloc(GPIO_NUM_MAX, sizeof(gpio_isr_func_t));
463     portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
464     if (gpio_context.gpio_isr_func == NULL) {
465         ret = ESP_ERR_NO_MEM;
466     } else {
467         ret = gpio_isr_register(gpio_intr_service, NULL, intr_alloc_flags, &gpio_context.gpio_isr_handle);
468     }
469 
470     return ret;
471 }
472 
gpio_isr_handler_add(gpio_num_t gpio_num,gpio_isr_t isr_handler,void * args)473 esp_err_t gpio_isr_handler_add(gpio_num_t gpio_num, gpio_isr_t isr_handler, void *args)
474 {
475     GPIO_CHECK(gpio_context.gpio_isr_func != NULL, "GPIO isr service is not installed, call gpio_install_isr_service() first", ESP_ERR_INVALID_STATE);
476     GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
477     portENTER_CRITICAL(&gpio_context.gpio_spinlock);
478     gpio_intr_disable(gpio_num);
479     if (gpio_context.gpio_isr_func) {
480         gpio_context.gpio_isr_func[gpio_num].fn = isr_handler;
481         gpio_context.gpio_isr_func[gpio_num].args = args;
482     }
483     gpio_intr_enable_on_core (gpio_num, esp_intr_get_cpu(gpio_context.gpio_isr_handle));
484     portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
485     return ESP_OK;
486 }
487 
gpio_isr_handler_remove(gpio_num_t gpio_num)488 esp_err_t gpio_isr_handler_remove(gpio_num_t gpio_num)
489 {
490     GPIO_CHECK(gpio_context.gpio_isr_func != NULL, "GPIO isr service is not installed, call gpio_install_isr_service() first", ESP_ERR_INVALID_STATE);
491     GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
492     portENTER_CRITICAL(&gpio_context.gpio_spinlock);
493     gpio_intr_disable(gpio_num);
494     if (gpio_context.gpio_isr_func) {
495         gpio_context.gpio_isr_func[gpio_num].fn = NULL;
496         gpio_context.gpio_isr_func[gpio_num].args = NULL;
497     }
498     portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
499     return ESP_OK;
500 }
501 
gpio_uninstall_isr_service(void)502 void gpio_uninstall_isr_service(void)
503 {
504     if (gpio_context.gpio_isr_func == NULL) {
505         return;
506     }
507     portENTER_CRITICAL(&gpio_context.gpio_spinlock);
508     esp_intr_free(gpio_context.gpio_isr_handle);
509     free(gpio_context.gpio_isr_func);
510     gpio_context.gpio_isr_func = NULL;
511     gpio_context.isr_core_id = GPIO_ISR_CORE_ID_UNINIT;
512     portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
513     return;
514 }
515 
516 
gpio_isr_register_on_core_static(void * param)517 static void gpio_isr_register_on_core_static(void *param)
518 {
519     gpio_isr_alloc_t *p = (gpio_isr_alloc_t *)param;
520     //We need to check the return value.
521     p->ret = esp_intr_alloc(p->source, p->intr_alloc_flags, p->fn, p->arg, p->handle);
522 }
523 
gpio_isr_register(void (* fn)(void *),void * arg,int intr_alloc_flags,gpio_isr_handle_t * handle)524 esp_err_t gpio_isr_register(void (*fn)(void *), void *arg, int intr_alloc_flags, gpio_isr_handle_t *handle)
525 {
526     GPIO_CHECK(fn, "GPIO ISR null", ESP_ERR_INVALID_ARG);
527     gpio_isr_alloc_t p;
528     p.source = ETS_GPIO_INTR_SOURCE;
529     p.intr_alloc_flags = intr_alloc_flags;
530     p.fn = fn;
531     p.arg = arg;
532     p.handle = handle;
533     portENTER_CRITICAL(&gpio_context.gpio_spinlock);
534     if(gpio_context.isr_core_id == GPIO_ISR_CORE_ID_UNINIT) {
535         gpio_context.isr_core_id = xPortGetCoreID();
536     }
537     portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
538     esp_err_t ret;
539 #if CONFIG_FREERTOS_UNICORE
540     gpio_isr_register_on_core_static(&p);
541     ret = ESP_OK;
542 #else /* CONFIG_FREERTOS_UNICORE */
543     ret = esp_ipc_call_blocking(gpio_context.isr_core_id, gpio_isr_register_on_core_static, (void *)&p);
544 #endif /* !CONFIG_FREERTOS_UNICORE */
545     if(ret != ESP_OK || p.ret != ESP_OK) {
546         return ESP_ERR_NOT_FOUND;
547     }
548     return ESP_OK;
549 }
550 
gpio_wakeup_enable(gpio_num_t gpio_num,gpio_int_type_t intr_type)551 esp_err_t gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type)
552 {
553     GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
554     esp_err_t ret = ESP_OK;
555 
556     if ((intr_type == GPIO_INTR_LOW_LEVEL) || (intr_type == GPIO_INTR_HIGH_LEVEL)) {
557 #if SOC_RTCIO_WAKE_SUPPORTED
558         if (rtc_gpio_is_valid_gpio(gpio_num)) {
559             ret = rtc_gpio_wakeup_enable(gpio_num, intr_type);
560         }
561 #endif
562         portENTER_CRITICAL(&gpio_context.gpio_spinlock);
563         gpio_hal_wakeup_enable(gpio_context.gpio_hal, gpio_num, intr_type);
564 #if SOC_GPIO_SUPPORT_SLP_SWITCH && CONFIG_ESP32C3_LIGHTSLEEP_GPIO_RESET_WORKAROUND
565         gpio_hal_sleep_sel_dis(gpio_context.gpio_hal, gpio_num);
566 #endif
567         portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
568     } else {
569         ESP_LOGE(GPIO_TAG, "GPIO wakeup only supports level mode, but edge mode set. gpio_num:%u", gpio_num);
570         ret = ESP_ERR_INVALID_ARG;
571     }
572 
573     return ret;
574 }
575 
gpio_wakeup_disable(gpio_num_t gpio_num)576 esp_err_t gpio_wakeup_disable(gpio_num_t gpio_num)
577 {
578     GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
579     esp_err_t ret = ESP_OK;
580 #if SOC_RTCIO_WAKE_SUPPORTED
581     if (rtc_gpio_is_valid_gpio(gpio_num)) {
582         ret = rtc_gpio_wakeup_disable(gpio_num);
583     }
584 #endif
585     portENTER_CRITICAL(&gpio_context.gpio_spinlock);
586     gpio_hal_wakeup_disable(gpio_context.gpio_hal, gpio_num);
587 #if SOC_GPIO_SUPPORT_SLP_SWITCH && CONFIG_ESP32C3_LIGHTSLEEP_GPIO_RESET_WORKAROUND
588     gpio_hal_sleep_sel_en(gpio_context.gpio_hal, gpio_num);
589 #endif
590     portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
591     return ret;
592 }
593 
gpio_set_drive_capability(gpio_num_t gpio_num,gpio_drive_cap_t strength)594 esp_err_t gpio_set_drive_capability(gpio_num_t gpio_num, gpio_drive_cap_t strength)
595 {
596     GPIO_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
597     GPIO_CHECK(strength < GPIO_DRIVE_CAP_MAX, "GPIO drive capability error", ESP_ERR_INVALID_ARG);
598     esp_err_t ret = ESP_OK;
599 
600     if (!rtc_gpio_is_valid_gpio(gpio_num) || SOC_GPIO_SUPPORT_RTC_INDEPENDENT) {
601         portENTER_CRITICAL(&gpio_context.gpio_spinlock);
602         gpio_hal_set_drive_capability(gpio_context.gpio_hal, gpio_num, strength);
603         portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
604     } else {
605 #if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
606         ret = rtc_gpio_set_drive_capability(gpio_num, strength);
607 #else
608         abort(); // This should be eliminated as unreachable, unless a programming error has occured
609 #endif
610     }
611 
612     return ret;
613 }
614 
gpio_get_drive_capability(gpio_num_t gpio_num,gpio_drive_cap_t * strength)615 esp_err_t gpio_get_drive_capability(gpio_num_t gpio_num, gpio_drive_cap_t *strength)
616 {
617     GPIO_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
618     GPIO_CHECK(strength != NULL, "GPIO drive capability pointer error", ESP_ERR_INVALID_ARG);
619     esp_err_t ret = ESP_OK;
620 
621     if (!rtc_gpio_is_valid_gpio(gpio_num) || SOC_GPIO_SUPPORT_RTC_INDEPENDENT) {
622         portENTER_CRITICAL(&gpio_context.gpio_spinlock);
623         gpio_hal_get_drive_capability(gpio_context.gpio_hal, gpio_num, strength);
624         portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
625     } else {
626 #if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
627         ret = rtc_gpio_get_drive_capability(gpio_num, strength);
628 #else
629         abort(); // This should be eliminated as unreachable, unless a programming error has occured
630 #endif
631     }
632 
633     return ret;
634 }
635 
gpio_hold_en(gpio_num_t gpio_num)636 esp_err_t gpio_hold_en(gpio_num_t gpio_num)
637 {
638     GPIO_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "Only output-capable GPIO support this function", ESP_ERR_NOT_SUPPORTED);
639     int ret = ESP_OK;
640 
641     if (rtc_gpio_is_valid_gpio(gpio_num)) {
642 #if SOC_RTCIO_HOLD_SUPPORTED
643         ret = rtc_gpio_hold_en(gpio_num);
644 #endif
645     } else if (GPIO_HOLD_MASK[gpio_num]) {
646         portENTER_CRITICAL(&gpio_context.gpio_spinlock);
647         gpio_hal_hold_en(gpio_context.gpio_hal, gpio_num);
648         portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
649     } else {
650         ret = ESP_ERR_NOT_SUPPORTED;
651     }
652 
653     return ret;
654 }
655 
gpio_hold_dis(gpio_num_t gpio_num)656 esp_err_t gpio_hold_dis(gpio_num_t gpio_num)
657 {
658     GPIO_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "Only output-capable GPIO support this function", ESP_ERR_NOT_SUPPORTED);
659     int ret = ESP_OK;
660 
661     if (rtc_gpio_is_valid_gpio(gpio_num)) {
662 #if SOC_RTCIO_HOLD_SUPPORTED
663         ret = rtc_gpio_hold_dis(gpio_num);
664 #endif
665     }else if (GPIO_HOLD_MASK[gpio_num]) {
666         portENTER_CRITICAL(&gpio_context.gpio_spinlock);
667         gpio_hal_hold_dis(gpio_context.gpio_hal, gpio_num);
668         portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
669     } else {
670         ret = ESP_ERR_NOT_SUPPORTED;
671     }
672 
673     return ret;
674 }
675 
gpio_deep_sleep_hold_en(void)676 void gpio_deep_sleep_hold_en(void)
677 {
678     portENTER_CRITICAL(&gpio_context.gpio_spinlock);
679     gpio_hal_deep_sleep_hold_en(gpio_context.gpio_hal);
680     portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
681 }
682 
gpio_deep_sleep_hold_dis(void)683 void gpio_deep_sleep_hold_dis(void)
684 {
685     portENTER_CRITICAL(&gpio_context.gpio_spinlock);
686     gpio_hal_deep_sleep_hold_dis(gpio_context.gpio_hal);
687     portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
688 }
689 
690 #if SOC_GPIO_SUPPORT_FORCE_HOLD
691 
gpio_force_hold_all()692 esp_err_t gpio_force_hold_all()
693 {
694 #if SOC_RTCIO_HOLD_SUPPORTED
695     rtc_gpio_force_hold_all();
696 #endif
697     portENTER_CRITICAL(&gpio_context.gpio_spinlock);
698     gpio_hal_force_hold_all(gpio_context.gpio_hal);
699     portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
700     return ESP_OK;
701 }
702 
gpio_force_unhold_all()703 esp_err_t gpio_force_unhold_all()
704 {
705 #if SOC_RTCIO_HOLD_SUPPORTED
706     rtc_gpio_force_hold_dis_all();
707 #endif
708     portENTER_CRITICAL(&gpio_context.gpio_spinlock);
709     gpio_hal_force_unhold_all();
710     portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
711     return ESP_OK;
712 }
713 #endif
714 
gpio_iomux_in(uint32_t gpio,uint32_t signal_idx)715 void gpio_iomux_in(uint32_t gpio, uint32_t signal_idx)
716 {
717     gpio_hal_iomux_in(gpio_context.gpio_hal, gpio, signal_idx);
718 }
719 
gpio_iomux_out(uint8_t gpio_num,int func,bool oen_inv)720 void gpio_iomux_out(uint8_t gpio_num, int func, bool oen_inv)
721 {
722     gpio_hal_iomux_out(gpio_context.gpio_hal, gpio_num, func, (uint32_t)oen_inv);
723 }
724 
725 #if SOC_GPIO_SUPPORT_SLP_SWITCH
gpio_sleep_pullup_en(gpio_num_t gpio_num)726 static esp_err_t gpio_sleep_pullup_en(gpio_num_t gpio_num)
727 {
728     GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
729 
730     portENTER_CRITICAL(&gpio_context.gpio_spinlock);
731     gpio_hal_sleep_pullup_en(gpio_context.gpio_hal, gpio_num);
732     portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
733 
734     return ESP_OK;
735 }
736 
gpio_sleep_pullup_dis(gpio_num_t gpio_num)737 static esp_err_t gpio_sleep_pullup_dis(gpio_num_t gpio_num)
738 {
739     GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
740 
741     portENTER_CRITICAL(&gpio_context.gpio_spinlock);
742     gpio_hal_sleep_pullup_dis(gpio_context.gpio_hal, gpio_num);
743     portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
744 
745     return ESP_OK;
746 }
747 
gpio_sleep_pulldown_en(gpio_num_t gpio_num)748 static esp_err_t gpio_sleep_pulldown_en(gpio_num_t gpio_num)
749 {
750     GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
751 
752     portENTER_CRITICAL(&gpio_context.gpio_spinlock);
753     gpio_hal_sleep_pulldown_en(gpio_context.gpio_hal, gpio_num);
754     portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
755 
756     return ESP_OK;
757 }
758 
gpio_sleep_pulldown_dis(gpio_num_t gpio_num)759 static esp_err_t gpio_sleep_pulldown_dis(gpio_num_t gpio_num)
760 {
761     GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
762 
763     portENTER_CRITICAL(&gpio_context.gpio_spinlock);
764     gpio_hal_sleep_pulldown_dis(gpio_context.gpio_hal, gpio_num);
765     portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
766 
767     return ESP_OK;
768 }
769 
gpio_sleep_input_disable(gpio_num_t gpio_num)770 static esp_err_t gpio_sleep_input_disable(gpio_num_t gpio_num)
771 {
772     GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
773     gpio_hal_sleep_input_disable(gpio_context.gpio_hal, gpio_num);
774     return ESP_OK;
775 }
776 
gpio_sleep_input_enable(gpio_num_t gpio_num)777 static esp_err_t gpio_sleep_input_enable(gpio_num_t gpio_num)
778 {
779     GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
780     gpio_hal_sleep_input_enable(gpio_context.gpio_hal, gpio_num);
781     return ESP_OK;
782 }
783 
gpio_sleep_output_disable(gpio_num_t gpio_num)784 static esp_err_t gpio_sleep_output_disable(gpio_num_t gpio_num)
785 {
786     GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
787     gpio_hal_sleep_output_disable(gpio_context.gpio_hal, gpio_num);
788     return ESP_OK;
789 }
790 
gpio_sleep_output_enable(gpio_num_t gpio_num)791 static esp_err_t gpio_sleep_output_enable(gpio_num_t gpio_num)
792 {
793     GPIO_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "GPIO output gpio_num error", ESP_ERR_INVALID_ARG);
794     gpio_hal_sleep_output_enable(gpio_context.gpio_hal, gpio_num);
795     return ESP_OK;
796 }
797 
gpio_sleep_set_direction(gpio_num_t gpio_num,gpio_mode_t mode)798 esp_err_t gpio_sleep_set_direction(gpio_num_t gpio_num, gpio_mode_t mode)
799 {
800     GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
801 
802     if ((GPIO_IS_VALID_OUTPUT_GPIO(gpio_num) != true) && (mode & GPIO_MODE_DEF_OUTPUT)) {
803         ESP_LOGE(GPIO_TAG, "io_num=%d can only be input", gpio_num);
804         return ESP_ERR_INVALID_ARG;
805     }
806 
807     esp_err_t ret = ESP_OK;
808 
809     if (mode & GPIO_MODE_DEF_INPUT) {
810         gpio_sleep_input_enable(gpio_num);
811     } else {
812         gpio_sleep_input_disable(gpio_num);
813     }
814 
815     if (mode & GPIO_MODE_DEF_OUTPUT) {
816         gpio_sleep_output_enable(gpio_num);
817     } else {
818         gpio_sleep_output_disable(gpio_num);
819     }
820 
821     return ret;
822 }
823 
gpio_sleep_set_pull_mode(gpio_num_t gpio_num,gpio_pull_mode_t pull)824 esp_err_t gpio_sleep_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull)
825 {
826     GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
827     GPIO_CHECK(pull <= GPIO_FLOATING, "GPIO pull mode error", ESP_ERR_INVALID_ARG);
828     esp_err_t ret = ESP_OK;
829 
830     switch (pull) {
831         case GPIO_PULLUP_ONLY:
832             gpio_sleep_pulldown_dis(gpio_num);
833             gpio_sleep_pullup_en(gpio_num);
834             break;
835 
836         case GPIO_PULLDOWN_ONLY:
837             gpio_sleep_pulldown_en(gpio_num);
838             gpio_sleep_pullup_dis(gpio_num);
839             break;
840 
841         case GPIO_PULLUP_PULLDOWN:
842             gpio_sleep_pulldown_en(gpio_num);
843             gpio_sleep_pullup_en(gpio_num);
844             break;
845 
846         case GPIO_FLOATING:
847             gpio_sleep_pulldown_dis(gpio_num);
848             gpio_sleep_pullup_dis(gpio_num);
849             break;
850 
851         default:
852             ESP_LOGE(GPIO_TAG, "Unknown pull up/down mode,gpio_num=%u,pull=%u", gpio_num, pull);
853             ret = ESP_ERR_INVALID_ARG;
854             break;
855     }
856 
857     return ret;
858 }
859 
gpio_sleep_sel_en(gpio_num_t gpio_num)860 esp_err_t gpio_sleep_sel_en(gpio_num_t gpio_num)
861 {
862     GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
863 
864     portENTER_CRITICAL(&gpio_context.gpio_spinlock);
865     gpio_hal_sleep_sel_en(gpio_context.gpio_hal, gpio_num);
866     portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
867 
868     return ESP_OK;
869 }
870 
gpio_sleep_sel_dis(gpio_num_t gpio_num)871 esp_err_t gpio_sleep_sel_dis(gpio_num_t gpio_num)
872 {
873     GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
874 
875     portENTER_CRITICAL(&gpio_context.gpio_spinlock);
876     gpio_hal_sleep_sel_dis(gpio_context.gpio_hal, gpio_num);
877     portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
878 
879     return ESP_OK;
880 }
881 
882 #if CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL
gpio_sleep_pupd_config_apply(gpio_num_t gpio_num)883 esp_err_t gpio_sleep_pupd_config_apply(gpio_num_t gpio_num)
884 {
885     GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
886     gpio_hal_sleep_pupd_config_apply(gpio_context.gpio_hal, gpio_num);
887     return ESP_OK;
888 }
889 
gpio_sleep_pupd_config_unapply(gpio_num_t gpio_num)890 esp_err_t gpio_sleep_pupd_config_unapply(gpio_num_t gpio_num)
891 {
892     GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
893     gpio_hal_sleep_pupd_config_unapply(gpio_context.gpio_hal, gpio_num);
894     return ESP_OK;
895 }
896 #endif // CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL
897 #endif // SOC_GPIO_SUPPORT_SLP_SWITCH
898 
899 #if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP
gpio_deep_sleep_wakeup_enable(gpio_num_t gpio_num,gpio_int_type_t intr_type)900 esp_err_t gpio_deep_sleep_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type)
901 {
902     if (!gpio_hal_is_valid_deepsleep_wakeup_gpio(gpio_num)) {
903         ESP_LOGE(GPIO_TAG, "GPIO %d does not support deep sleep wakeup", gpio_num);
904         return ESP_ERR_INVALID_ARG;
905     }
906     if ((intr_type != GPIO_INTR_LOW_LEVEL) && (intr_type != GPIO_INTR_HIGH_LEVEL)) {
907         ESP_LOGE(GPIO_TAG, "GPIO wakeup only supports level mode, but edge mode set. gpio_num:%u", gpio_num);
908         return ESP_ERR_INVALID_ARG;
909     }
910     portENTER_CRITICAL(&gpio_context.gpio_spinlock);
911     gpio_hal_deepsleep_wakeup_enable(gpio_context.gpio_hal, gpio_num, intr_type);
912 #if SOC_GPIO_SUPPORT_SLP_SWITCH && CONFIG_ESP32C3_LIGHTSLEEP_GPIO_RESET_WORKAROUND
913     gpio_hal_sleep_sel_dis(gpio_context.gpio_hal, gpio_num);
914 #endif
915     portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
916     return ESP_OK;
917 }
918 
gpio_deep_sleep_wakeup_disable(gpio_num_t gpio_num)919 esp_err_t gpio_deep_sleep_wakeup_disable(gpio_num_t gpio_num)
920 {
921     if (!gpio_hal_is_valid_deepsleep_wakeup_gpio(gpio_num)) {
922         ESP_LOGE(GPIO_TAG, "GPIO %d does not support deep sleep wakeup", gpio_num);
923         return ESP_ERR_INVALID_ARG;
924     }
925     portENTER_CRITICAL(&gpio_context.gpio_spinlock);
926     gpio_hal_deepsleep_wakeup_disable(gpio_context.gpio_hal, gpio_num);
927 #if SOC_GPIO_SUPPORT_SLP_SWITCH && CONFIG_ESP32C3_LIGHTSLEEP_GPIO_RESET_WORKAROUND
928     gpio_hal_sleep_sel_en(gpio_context.gpio_hal, gpio_num);
929 #endif
930     portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
931     return ESP_OK;
932 }
933 #endif // SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP
934