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