1 /*
2 * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /*******************************************************************************
8 * NOTICE
9 * The hal is not public api, don't use in application code.
10 * See readme.md in hal/include/hal/readme.md
11 ******************************************************************************/
12
13 // The LL layer for ESP32 GPIO register operations
14
15 #pragma once
16
17 #include <stdbool.h>
18 #include "soc/soc.h"
19 #include "soc/gpio_periph.h"
20 #include "soc/gpio_struct.h"
21 #include "soc/rtc_cntl_reg.h"
22 #include "soc/rtc_io_reg.h"
23 #include "hal/gpio_types.h"
24 #include "hal/misc.h"
25
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29
30 // the address of esp32's IO_MUX_GPIOx_REGs are not incremented as the gpio number increments(address are out of order)
31 extern const uint8_t GPIO_PIN_MUX_REG_OFFSET[SOC_GPIO_PIN_COUNT];
32
33 // Get GPIO hardware instance with giving gpio num
34 #define GPIO_LL_GET_HW(num) (((num) == 0) ? (&GPIO) : NULL)
35
36 #define GPIO_LL_APP_CPU_INTR_ENA (BIT(0))
37 #define GPIO_LL_APP_CPU_NMI_INTR_ENA (BIT(1))
38 #define GPIO_LL_PRO_CPU_INTR_ENA (BIT(2))
39 #define GPIO_LL_PRO_CPU_NMI_INTR_ENA (BIT(3))
40 #define GPIO_LL_SDIO_EXT_INTR_ENA (BIT(4))
41
42 /**
43 * @brief Enable pull-up on GPIO.
44 *
45 * @param hw Peripheral GPIO hardware instance address.
46 * @param gpio_num GPIO number
47 */
gpio_ll_pullup_en(gpio_dev_t * hw,uint32_t gpio_num)48 static inline void gpio_ll_pullup_en(gpio_dev_t *hw, uint32_t gpio_num)
49 {
50 REG_SET_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PU);
51 }
52
53 /**
54 * @brief Disable pull-up on GPIO.
55 *
56 * @param hw Peripheral GPIO hardware instance address.
57 * @param gpio_num GPIO number
58 */
59 __attribute__((always_inline))
gpio_ll_pullup_dis(gpio_dev_t * hw,uint32_t gpio_num)60 static inline void gpio_ll_pullup_dis(gpio_dev_t *hw, uint32_t gpio_num)
61 {
62 REG_CLR_BIT(DR_REG_IO_MUX_BASE + GPIO_PIN_MUX_REG_OFFSET[gpio_num], FUN_PU);
63 }
64
65 /**
66 * @brief Return pull-up status on GPIO.
67 *
68 * @param hw Peripheral GPIO hardware instance address.
69 * @param gpio_num GPIO number
70 * @return if GPIO gpio_num`s FUN_PU is true
71 */
gpio_ll_pullup_is_enabled(gpio_dev_t * hw,uint32_t gpio_num)72 static inline bool gpio_ll_pullup_is_enabled(gpio_dev_t *hw, uint32_t gpio_num)
73 {
74 return REG_GET_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PU) ? true : false;
75 }
76
77 /**
78 * @brief Enable pull-down on GPIO.
79 *
80 * @param hw Peripheral GPIO hardware instance address.
81 * @param gpio_num GPIO number
82 */
gpio_ll_pulldown_en(gpio_dev_t * hw,uint32_t gpio_num)83 static inline void gpio_ll_pulldown_en(gpio_dev_t *hw, uint32_t gpio_num)
84 {
85 REG_SET_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PD);
86 }
87
88 /**
89 * @brief Disable pull-down on GPIO.
90 *
91 * @param hw Peripheral GPIO hardware instance address.
92 * @param gpio_num GPIO number
93 */
94 __attribute__((always_inline))
gpio_ll_pulldown_dis(gpio_dev_t * hw,uint32_t gpio_num)95 static inline void gpio_ll_pulldown_dis(gpio_dev_t *hw, uint32_t gpio_num)
96 {
97 REG_CLR_BIT(DR_REG_IO_MUX_BASE + GPIO_PIN_MUX_REG_OFFSET[gpio_num], FUN_PD);
98 }
99
100 /**
101 * @brief Return pull-down status on GPIO.
102 *
103 * @param hw Peripheral GPIO hardware instance address.
104 * @param gpio_num GPIO number
105 * @return if GPIO gpio_num`s FUN_PD is true
106 */
gpio_ll_pulldown_is_enabled(gpio_dev_t * hw,uint32_t gpio_num)107 static inline bool gpio_ll_pulldown_is_enabled(gpio_dev_t *hw, uint32_t gpio_num)
108 {
109 return REG_GET_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PD) ? true : false;
110 }
111
112 /**
113 * @brief Enable GPIO pin used for wakeup from sleep.
114 *
115 * @param hw Peripheral GPIO hardware instance address.
116 * @param gpio_num GPIO number
117 */
gpio_ll_sleep_sel_en(gpio_dev_t * hw,uint32_t gpio_num)118 static inline void gpio_ll_sleep_sel_en(gpio_dev_t *hw, uint32_t gpio_num)
119 {
120 PIN_SLP_SEL_ENABLE(GPIO_PIN_MUX_REG[gpio_num]);
121 }
122
123 /**
124 * @brief Disable GPIO pin used for wakeup from sleep.
125 *
126 * @param hw Peripheral GPIO hardware instance address.
127 * @param gpio_num GPIO number
128 */
gpio_ll_sleep_sel_dis(gpio_dev_t * hw,uint32_t gpio_num)129 static inline void gpio_ll_sleep_sel_dis(gpio_dev_t *hw, uint32_t gpio_num)
130 {
131 PIN_SLP_SEL_DISABLE(GPIO_PIN_MUX_REG[gpio_num]);
132 }
133
134 /**
135 * @brief Return slp-sel status on GPIO.
136 *
137 * @param hw Peripheral GPIO hardware instance address.
138 * @param gpio_num GPIO number
139 * @return if GPIO gpio_num`s SLP_SEL is true
140 */
gpio_ll_sleep_sel_is_enabled(gpio_dev_t * hw,uint32_t gpio_num)141 static inline bool gpio_ll_sleep_sel_is_enabled(gpio_dev_t *hw, uint32_t gpio_num)
142 {
143 return REG_GET_BIT(GPIO_PIN_MUX_REG[gpio_num], SLP_SEL) ? true : false;
144 }
145
146 /**
147 * @brief Disable GPIO pull-up in sleep mode.
148 *
149 * @param hw Peripheral GPIO hardware instance address.
150 * @param gpio_num GPIO number
151 */
gpio_ll_sleep_pullup_dis(gpio_dev_t * hw,uint32_t gpio_num)152 static inline void gpio_ll_sleep_pullup_dis(gpio_dev_t *hw, uint32_t gpio_num)
153 {
154 PIN_SLP_PULLUP_DISABLE(GPIO_PIN_MUX_REG[gpio_num]);
155 }
156
157 /**
158 * @brief Enable GPIO pull-up in sleep mode.
159 *
160 * @param hw Peripheral GPIO hardware instance address.
161 * @param gpio_num GPIO number
162 */
gpio_ll_sleep_pullup_en(gpio_dev_t * hw,uint32_t gpio_num)163 static inline void gpio_ll_sleep_pullup_en(gpio_dev_t *hw, uint32_t gpio_num)
164 {
165 PIN_SLP_PULLUP_ENABLE(GPIO_PIN_MUX_REG[gpio_num]);
166 }
167
168 /**
169 * @brief Return slp-pull-up status on GPIO.
170 *
171 * @param hw Peripheral GPIO hardware instance address.
172 * @param gpio_num GPIO number
173 * @return if GPIO gpio_num`s SLP_PU is true
174 */
gpio_ll_sleep_pullup_is_enabled(gpio_dev_t * hw,uint32_t gpio_num)175 static inline bool gpio_ll_sleep_pullup_is_enabled(gpio_dev_t *hw, uint32_t gpio_num)
176 {
177 return REG_GET_BIT(GPIO_PIN_MUX_REG[gpio_num], SLP_PU) ? true : false;
178 }
179
180 /**
181 * @brief Enable GPIO pull-down in sleep mode.
182 *
183 * @param hw Peripheral GPIO hardware instance address.
184 * @param gpio_num GPIO number
185 */
gpio_ll_sleep_pulldown_en(gpio_dev_t * hw,uint32_t gpio_num)186 static inline void gpio_ll_sleep_pulldown_en(gpio_dev_t *hw, uint32_t gpio_num)
187 {
188 PIN_SLP_PULLDOWN_ENABLE(GPIO_PIN_MUX_REG[gpio_num]);
189 }
190
191 /**
192 * @brief Disable GPIO pull-down in sleep mode.
193 *
194 * @param hw Peripheral GPIO hardware instance address.
195 * @param gpio_num GPIO number
196 */
gpio_ll_sleep_pulldown_dis(gpio_dev_t * hw,uint32_t gpio_num)197 static inline void gpio_ll_sleep_pulldown_dis(gpio_dev_t *hw, uint32_t gpio_num)
198 {
199 PIN_SLP_PULLDOWN_DISABLE(GPIO_PIN_MUX_REG[gpio_num]);
200 }
201
202 /**
203 * @brief Return slp-pull-down status on GPIO.
204 *
205 * @param hw Peripheral GPIO hardware instance address.
206 * @param gpio_num GPIO number
207 * @return if GPIO gpio_num`s SLP_PD is true
208 */
gpio_ll_sleep_pulldown_is_enabled(gpio_dev_t * hw,uint32_t gpio_num)209 static inline bool gpio_ll_sleep_pulldown_is_enabled(gpio_dev_t *hw, uint32_t gpio_num)
210 {
211 return REG_GET_BIT(GPIO_PIN_MUX_REG[gpio_num], SLP_PD) ? true : false;
212 }
213
214 /**
215 * @brief GPIO set interrupt trigger type
216 *
217 * @param hw Peripheral GPIO hardware instance address.
218 * @param gpio_num GPIO number. If you want to set the trigger type of e.g. of GPIO16, gpio_num should be GPIO_NUM_16 (16);
219 * @param intr_type Interrupt type, select from gpio_int_type_t
220 */
gpio_ll_set_intr_type(gpio_dev_t * hw,uint32_t gpio_num,gpio_int_type_t intr_type)221 static inline void gpio_ll_set_intr_type(gpio_dev_t *hw, uint32_t gpio_num, gpio_int_type_t intr_type)
222 {
223 hw->pin[gpio_num].int_type = intr_type;
224 }
225
226 /**
227 * @brief Get GPIO interrupt status
228 *
229 * @param hw Peripheral GPIO hardware instance address.
230 * @param core_id interrupt core id
231 * @param status interrupt status
232 */
233 __attribute__((always_inline))
gpio_ll_get_intr_status(gpio_dev_t * hw,uint32_t core_id,uint32_t * status)234 static inline void gpio_ll_get_intr_status(gpio_dev_t *hw, uint32_t core_id, uint32_t *status)
235 {
236 *status = (core_id == 0) ? hw->pcpu_int : hw->acpu_int;
237 }
238
239 /**
240 * @brief Get GPIO interrupt status high
241 *
242 * @param hw Peripheral GPIO hardware instance address.
243 * @param core_id interrupt core id
244 * @param status interrupt status high
245 */
246 __attribute__((always_inline))
gpio_ll_get_intr_status_high(gpio_dev_t * hw,uint32_t core_id,uint32_t * status)247 static inline void gpio_ll_get_intr_status_high(gpio_dev_t *hw, uint32_t core_id, uint32_t *status)
248 {
249 *status = (core_id == 0) ? HAL_FORCE_READ_U32_REG_FIELD(hw->pcpu_int1, intr) : HAL_FORCE_READ_U32_REG_FIELD(hw->acpu_int1, intr);
250 }
251
252 /**
253 * @brief Clear GPIO interrupt status
254 *
255 * @param hw Peripheral GPIO hardware instance address.
256 * @param mask interrupt status clear mask
257 */
258 __attribute__((always_inline))
gpio_ll_clear_intr_status(gpio_dev_t * hw,uint32_t mask)259 static inline void gpio_ll_clear_intr_status(gpio_dev_t *hw, uint32_t mask)
260 {
261 hw->status_w1tc = mask;
262 }
263
264 /**
265 * @brief Clear GPIO interrupt status high
266 *
267 * @param hw Peripheral GPIO hardware instance address.
268 * @param mask interrupt status high clear mask
269 */
270 __attribute__((always_inline))
gpio_ll_clear_intr_status_high(gpio_dev_t * hw,uint32_t mask)271 static inline void gpio_ll_clear_intr_status_high(gpio_dev_t *hw, uint32_t mask)
272 {
273 HAL_FORCE_MODIFY_U32_REG_FIELD(hw->status1_w1tc, intr_st, mask);
274 }
275
276 /**
277 * @brief Enable GPIO module interrupt signal
278 *
279 * @param hw Peripheral GPIO hardware instance address.
280 * @param core_id Interrupt enabled CPU to corresponding ID
281 * @param gpio_num GPIO number. If you want to enable the interrupt of e.g. GPIO16, gpio_num should be GPIO_NUM_16 (16);
282 */
283 __attribute__((always_inline))
gpio_ll_intr_enable_on_core(gpio_dev_t * hw,uint32_t core_id,uint32_t gpio_num)284 static inline void gpio_ll_intr_enable_on_core(gpio_dev_t *hw, uint32_t core_id, uint32_t gpio_num)
285 {
286 if (core_id == 0) {
287 hw->pin[gpio_num].int_ena = GPIO_LL_PRO_CPU_INTR_ENA; //enable pro cpu intr
288 } else {
289 hw->pin[gpio_num].int_ena = GPIO_LL_APP_CPU_INTR_ENA; //enable app cpu intr
290 }
291 }
292
293 /**
294 * @brief Disable GPIO module interrupt signal
295 *
296 * @param hw Peripheral GPIO hardware instance address.
297 * @param gpio_num GPIO number. If you want to disable the interrupt of e.g. GPIO16, gpio_num should be GPIO_NUM_16 (16);
298 */
299 __attribute__((always_inline))
gpio_ll_intr_disable(gpio_dev_t * hw,uint32_t gpio_num)300 static inline void gpio_ll_intr_disable(gpio_dev_t *hw, uint32_t gpio_num)
301 {
302 hw->pin[gpio_num].int_ena = 0; //disable GPIO intr
303 }
304
305 /**
306 * @brief Disable input mode on GPIO.
307 *
308 * @param hw Peripheral GPIO hardware instance address.
309 * @param gpio_num GPIO number
310 */
311 __attribute__((always_inline))
gpio_ll_input_disable(gpio_dev_t * hw,uint32_t gpio_num)312 static inline void gpio_ll_input_disable(gpio_dev_t *hw, uint32_t gpio_num)
313 {
314 PIN_INPUT_DISABLE(DR_REG_IO_MUX_BASE + GPIO_PIN_MUX_REG_OFFSET[gpio_num]);
315 }
316
317 /**
318 * @brief Enable input mode on GPIO.
319 *
320 * @param hw Peripheral GPIO hardware instance address.
321 * @param gpio_num GPIO number
322 */
gpio_ll_input_enable(gpio_dev_t * hw,uint32_t gpio_num)323 static inline void gpio_ll_input_enable(gpio_dev_t *hw, uint32_t gpio_num)
324 {
325 PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[gpio_num]);
326 }
327
328 /**
329 * @brief Disable output mode on GPIO.
330 *
331 * @param hw Peripheral GPIO hardware instance address.
332 * @param gpio_num GPIO number
333 */
334 __attribute__((always_inline))
gpio_ll_output_disable(gpio_dev_t * hw,uint32_t gpio_num)335 static inline void gpio_ll_output_disable(gpio_dev_t *hw, uint32_t gpio_num)
336 {
337 if (gpio_num < 32) {
338 hw->enable_w1tc = (0x1 << gpio_num);
339 } else {
340 HAL_FORCE_MODIFY_U32_REG_FIELD(hw->enable1_w1tc, data, (0x1 << (gpio_num - 32)));
341 }
342
343 // Ensure no other output signal is routed via GPIO matrix to this pin
344 REG_WRITE(GPIO_FUNC0_OUT_SEL_CFG_REG + (gpio_num * 4),
345 SIG_GPIO_OUT_IDX);
346 }
347
348 /**
349 * @brief Enable output mode on GPIO.
350 *
351 * @param hw Peripheral GPIO hardware instance address.
352 * @param gpio_num GPIO number
353 */
gpio_ll_output_enable(gpio_dev_t * hw,uint32_t gpio_num)354 static inline __attribute__((always_inline)) void gpio_ll_output_enable(gpio_dev_t *hw, uint32_t gpio_num)
355 {
356 if (gpio_num < 32) {
357 hw->enable_w1ts = (0x1 << gpio_num);
358 } else {
359 HAL_FORCE_MODIFY_U32_REG_FIELD(hw->enable1_w1ts, data, (0x1 << (gpio_num - 32)));
360 }
361 }
362
363 /**
364 * @brief Disable GPIO input in sleep mode.
365 *
366 * @param hw Peripheral GPIO hardware instance address.
367 * @param gpio_num GPIO number
368 */
gpio_ll_sleep_input_disable(gpio_dev_t * hw,uint32_t gpio_num)369 static inline void gpio_ll_sleep_input_disable(gpio_dev_t *hw, uint32_t gpio_num)
370 {
371 PIN_SLP_INPUT_DISABLE(GPIO_PIN_MUX_REG[gpio_num]);
372 }
373
374 /**
375 * @brief Enable GPIO input in sleep mode.
376 *
377 * @param hw Peripheral GPIO hardware instance address.
378 * @param gpio_num GPIO number
379 */
gpio_ll_sleep_input_enable(gpio_dev_t * hw,uint32_t gpio_num)380 static inline void gpio_ll_sleep_input_enable(gpio_dev_t *hw, uint32_t gpio_num)
381 {
382 PIN_SLP_INPUT_ENABLE(GPIO_PIN_MUX_REG[gpio_num]);
383 }
384
385 /**
386 * @brief Disable GPIO output in sleep mode.
387 *
388 * @param hw Peripheral GPIO hardware instance address.
389 * @param gpio_num GPIO number
390 */
gpio_ll_sleep_output_disable(gpio_dev_t * hw,uint32_t gpio_num)391 static inline void gpio_ll_sleep_output_disable(gpio_dev_t *hw, uint32_t gpio_num)
392 {
393 PIN_SLP_OUTPUT_DISABLE(GPIO_PIN_MUX_REG[gpio_num]);
394 }
395
396 /**
397 * @brief Enable GPIO output in sleep mode.
398 *
399 * @param hw Peripheral GPIO hardware instance address.
400 * @param gpio_num GPIO number
401 */
gpio_ll_sleep_output_enable(gpio_dev_t * hw,uint32_t gpio_num)402 static inline void gpio_ll_sleep_output_enable(gpio_dev_t *hw, uint32_t gpio_num)
403 {
404 PIN_SLP_OUTPUT_ENABLE(GPIO_PIN_MUX_REG[gpio_num]);
405 }
406
407 /**
408 * @brief Disable open-drain mode on GPIO.
409 *
410 * @param hw Peripheral GPIO hardware instance address.
411 * @param gpio_num GPIO number
412 */
gpio_ll_od_disable(gpio_dev_t * hw,uint32_t gpio_num)413 static inline __attribute__((always_inline)) void gpio_ll_od_disable(gpio_dev_t *hw, uint32_t gpio_num)
414 {
415 hw->pin[gpio_num].pad_driver = 0;
416 }
417
418 /**
419 * @brief Enable open-drain mode on GPIO.
420 *
421 * @param hw Peripheral GPIO hardware instance address.
422 * @param gpio_num GPIO number
423 */
gpio_ll_od_enable(gpio_dev_t * hw,uint32_t gpio_num)424 static inline void gpio_ll_od_enable(gpio_dev_t *hw, uint32_t gpio_num)
425 {
426 hw->pin[gpio_num].pad_driver = 1;
427 }
428
429 /**
430 * @brief Select a function for the pin in the IOMUX
431 *
432 * @param hw Peripheral GPIO hardware instance address.
433 * @param gpio_num GPIO number
434 * @param func Function to assign to the pin
435 */
gpio_ll_func_sel(gpio_dev_t * hw,uint8_t gpio_num,uint32_t func)436 static inline __attribute__((always_inline)) void gpio_ll_func_sel(gpio_dev_t *hw, uint8_t gpio_num, uint32_t func)
437 {
438 PIN_FUNC_SELECT(DR_REG_IO_MUX_BASE + GPIO_PIN_MUX_REG_OFFSET[gpio_num], func);
439 }
440
441 /**
442 * @brief GPIO set output level
443 *
444 * @param hw Peripheral GPIO hardware instance address.
445 * @param gpio_num GPIO number. If you want to set the output level of e.g. GPIO16, gpio_num should be GPIO_NUM_16 (16);
446 * @param level Output level. 0: low ; 1: high
447 */
448 __attribute__((always_inline))
gpio_ll_set_level(gpio_dev_t * hw,uint32_t gpio_num,uint32_t level)449 static inline void gpio_ll_set_level(gpio_dev_t *hw, uint32_t gpio_num, uint32_t level)
450 {
451 if (level) {
452 if (gpio_num < 32) {
453 hw->out_w1ts = (1 << gpio_num);
454 } else {
455 HAL_FORCE_MODIFY_U32_REG_FIELD(hw->out1_w1ts, data, (1 << (gpio_num - 32)));
456 }
457 } else {
458 if (gpio_num < 32) {
459 hw->out_w1tc = (1 << gpio_num);
460 } else {
461 HAL_FORCE_MODIFY_U32_REG_FIELD(hw->out1_w1tc, data, (1 << (gpio_num - 32)));
462 }
463 }
464 }
465
466 /**
467 * @brief GPIO get input level
468 *
469 * @warning If the pad is not configured for input (or input and output) the returned value is always 0.
470 *
471 * @param hw Peripheral GPIO hardware instance address.
472 * @param gpio_num GPIO number. If you want to get the logic level of e.g. pin GPIO16, gpio_num should be GPIO_NUM_16 (16);
473 *
474 * @return
475 * - 0 the GPIO input level is 0
476 * - 1 the GPIO input level is 1
477 */
gpio_ll_get_level(gpio_dev_t * hw,uint32_t gpio_num)478 static inline int gpio_ll_get_level(gpio_dev_t *hw, uint32_t gpio_num)
479 {
480 if (gpio_num < 32) {
481 return (hw->in >> gpio_num) & 0x1;
482 } else {
483 return (HAL_FORCE_READ_U32_REG_FIELD(hw->in1, data) >> (gpio_num - 32)) & 0x1;
484 }
485 }
486
487 /**
488 * @brief Enable GPIO wake-up function.
489 *
490 * @param hw Peripheral GPIO hardware instance address.
491 * @param gpio_num GPIO number.
492 */
gpio_ll_wakeup_enable(gpio_dev_t * hw,uint32_t gpio_num)493 static inline void gpio_ll_wakeup_enable(gpio_dev_t *hw, uint32_t gpio_num)
494 {
495 hw->pin[gpio_num].wakeup_enable = 0x1;
496 }
497
498 /**
499 * @brief Disable GPIO wake-up function.
500 *
501 * @param hw Peripheral GPIO hardware instance address.
502 * @param gpio_num GPIO number
503 */
gpio_ll_wakeup_disable(gpio_dev_t * hw,uint32_t gpio_num)504 static inline void gpio_ll_wakeup_disable(gpio_dev_t *hw, uint32_t gpio_num)
505 {
506 hw->pin[gpio_num].wakeup_enable = 0;
507 }
508
509 /**
510 * @brief Set GPIO pad drive capability
511 *
512 * @param hw Peripheral GPIO hardware instance address.
513 * @param gpio_num GPIO number, only support output GPIOs
514 * @param strength Drive capability of the pad
515 */
gpio_ll_set_drive_capability(gpio_dev_t * hw,uint32_t gpio_num,gpio_drive_cap_t strength)516 static inline void gpio_ll_set_drive_capability(gpio_dev_t *hw, uint32_t gpio_num, gpio_drive_cap_t strength)
517 {
518 SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[gpio_num], FUN_DRV_V, strength, FUN_DRV_S);
519 }
520
521 /**
522 * @brief Get GPIO pad drive capability
523 *
524 * @param hw Peripheral GPIO hardware instance address.
525 * @param gpio_num GPIO number, only support output GPIOs
526 * @param strength Pointer to accept drive capability of the pad
527 */
gpio_ll_get_drive_capability(gpio_dev_t * hw,uint32_t gpio_num,gpio_drive_cap_t * strength)528 static inline void gpio_ll_get_drive_capability(gpio_dev_t *hw, uint32_t gpio_num, gpio_drive_cap_t *strength)
529 {
530 *strength = (gpio_drive_cap_t)GET_PERI_REG_BITS2(GPIO_PIN_MUX_REG[gpio_num], FUN_DRV_V, FUN_DRV_S);
531 }
532
533 /**
534 * @brief Enable all digital gpio pad hold function during Deep-sleep.
535 *
536 * @param hw Peripheral GPIO hardware instance address.
537 */
gpio_ll_deep_sleep_hold_en(gpio_dev_t * hw)538 static inline void gpio_ll_deep_sleep_hold_en(gpio_dev_t *hw)
539 {
540 CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD);
541 SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M);
542 }
543
544 /**
545 * @brief Disable all digital gpio pad hold function during Deep-sleep.
546 *
547 * @param hw Peripheral GPIO hardware instance address.
548 */
gpio_ll_deep_sleep_hold_dis(gpio_dev_t * hw)549 static inline void gpio_ll_deep_sleep_hold_dis(gpio_dev_t *hw)
550 {
551 CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M);
552 }
553
554 /**
555 * @brief Get deep sleep hold status
556 *
557 * @param hw Peripheral GPIO hardware instance address.
558 *
559 * @return
560 * - true deep sleep hold is enabled
561 * - false deep sleep hold is disabled
562 */
563 __attribute__((always_inline))
gpio_ll_deep_sleep_hold_is_en(gpio_dev_t * hw)564 static inline bool gpio_ll_deep_sleep_hold_is_en(gpio_dev_t *hw)
565 {
566 return !GET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD) && GET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M);
567 }
568
569 /**
570 * @brief Enable gpio pad hold function.
571 *
572 * @param hw Peripheral GPIO hardware instance address.
573 * @param gpio_num GPIO number, only support output GPIOs
574 */
gpio_ll_hold_en(gpio_dev_t * hw,uint32_t gpio_num)575 static inline void gpio_ll_hold_en(gpio_dev_t *hw, uint32_t gpio_num)
576 {
577 SET_PERI_REG_MASK(RTC_IO_DIG_PAD_HOLD_REG, GPIO_HOLD_MASK[gpio_num]);
578 }
579
580 /**
581 * @brief Disable gpio pad hold function.
582 *
583 * @param hw Peripheral GPIO hardware instance address.
584 * @param gpio_num GPIO number, only support output GPIOs
585 */
gpio_ll_hold_dis(gpio_dev_t * hw,uint32_t gpio_num)586 static inline void gpio_ll_hold_dis(gpio_dev_t *hw, uint32_t gpio_num)
587 {
588 CLEAR_PERI_REG_MASK(RTC_IO_DIG_PAD_HOLD_REG, GPIO_HOLD_MASK[gpio_num]);
589 }
590
591 /**
592 * @brief Get digital gpio pad hold status.
593 *
594 * @param hw Peripheral GPIO hardware instance address.
595 * @param gpio_num GPIO number, only support output GPIOs
596 *
597 * @note caller must ensure that gpio_num is a digital io pad
598 *
599 * @return
600 * - true digital gpio pad is held
601 * - false digital gpio pad is unheld
602 */
603 __attribute__((always_inline))
gpio_ll_is_digital_io_hold(gpio_dev_t * hw,uint32_t gpio_num)604 static inline bool gpio_ll_is_digital_io_hold(gpio_dev_t *hw, uint32_t gpio_num)
605 {
606 uint32_t mask = 0;
607
608 switch (gpio_num) {
609 case 1: mask = BIT(1); break;
610 case 3: mask = BIT(0); break;
611 case 5: mask = BIT(8); break;
612 case 6 ... 11 : mask = BIT(gpio_num - 4); break;
613 case 16 ... 19:
614 case 21 ... 23: mask = BIT(gpio_num - 7); break;
615 default: break;
616 }
617
618 return GET_PERI_REG_MASK(RTC_IO_DIG_PAD_HOLD_REG, mask);
619 }
620
621 /**
622 * @brief Set pad input to a peripheral signal through the IOMUX.
623 *
624 * @param hw Peripheral GPIO hardware instance address.
625 * @param gpio_num GPIO number of the pad.
626 * @param signal_idx Peripheral signal id to input. One of the ``*_IN_IDX`` signals in ``soc/gpio_sig_map.h``.
627 */
628 __attribute__((always_inline))
gpio_ll_iomux_in(gpio_dev_t * hw,uint32_t gpio,uint32_t signal_idx)629 static inline void gpio_ll_iomux_in(gpio_dev_t *hw, uint32_t gpio, uint32_t signal_idx)
630 {
631 hw->func_in_sel_cfg[signal_idx].sig_in_sel = 0;
632 PIN_INPUT_ENABLE(DR_REG_IO_MUX_BASE + GPIO_PIN_MUX_REG_OFFSET[gpio]);
633 }
634
635 /**
636 * @brief Select a function for the pin in the IOMUX
637 *
638 * @param pin_name Pin name to configure
639 * @param func Function to assign to the pin
640 */
gpio_ll_iomux_func_sel(uint32_t pin_name,uint32_t func)641 static inline __attribute__((always_inline)) void gpio_ll_iomux_func_sel(uint32_t pin_name, uint32_t func)
642 {
643 PIN_FUNC_SELECT(pin_name, func);
644 }
645
646 /**
647 * @brief Control the pin in the IOMUX
648 *
649 * @param val Control value
650 */
gpio_ll_iomux_pin_ctrl(uint32_t val)651 static inline __attribute__((always_inline)) void gpio_ll_iomux_pin_ctrl(uint32_t val)
652 {
653 WRITE_PERI_REG(PIN_CTRL, val);
654 }
655
656 /**
657 * @brief Set peripheral output to an GPIO pad through the IOMUX.
658 *
659 * @param hw Peripheral GPIO hardware instance address.
660 * @param gpio_num gpio_num GPIO number of the pad.
661 * @param func The function number of the peripheral pin to output pin.
662 * One of the ``FUNC_X_*`` of specified pin (X) in ``soc/io_mux_reg.h``.
663 * @param oen_inv True if the output enable needs to be inverted, otherwise False.
664 */
gpio_ll_iomux_out(gpio_dev_t * hw,uint8_t gpio_num,int func,uint32_t oen_inv)665 static inline void gpio_ll_iomux_out(gpio_dev_t *hw, uint8_t gpio_num, int func, uint32_t oen_inv)
666 {
667 hw->func_out_sel_cfg[gpio_num].oen_sel = 0;
668 hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv;
669 gpio_ll_iomux_func_sel(GPIO_PIN_MUX_REG[gpio_num], func);
670 }
671
672 #ifdef __cplusplus
673 }
674 #endif
675