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