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