Skip to content

Commit 321f628

Browse files
committed
feat(gpio): add a dump API to dump IO configurations
Closes #12176
1 parent 4356ded commit 321f628

File tree

17 files changed

+557
-13
lines changed

17 files changed

+557
-13
lines changed

components/driver/gpio/gpio.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "esp_check.h"
2323
#include "hal/gpio_hal.h"
2424
#include "esp_rom_gpio.h"
25+
#include "esp_private/esp_gpio_reserve.h"
2526

2627
#if (SOC_RTCIO_PIN_COUNT > 0)
2728
#include "hal/rtc_io_hal.h"
@@ -1006,3 +1007,45 @@ esp_err_t gpio_deep_sleep_wakeup_disable(gpio_num_t gpio_num)
10061007
return ESP_OK;
10071008
}
10081009
#endif // SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP
1010+
1011+
esp_err_t gpio_dump_io_configuration(FILE *out_stream, uint64_t io_bit_mask)
1012+
{
1013+
ESP_RETURN_ON_FALSE(out_stream, ESP_ERR_INVALID_ARG, GPIO_TAG, "out_stream error");
1014+
ESP_RETURN_ON_FALSE(!(io_bit_mask & ~SOC_GPIO_VALID_GPIO_MASK), ESP_ERR_INVALID_ARG, GPIO_TAG, "io_bit_mask error");
1015+
1016+
fprintf(out_stream, "================IO DUMP Start================\n");
1017+
while (io_bit_mask) {
1018+
uint32_t gpio_num = __builtin_ffsll(io_bit_mask) - 1;
1019+
io_bit_mask &= ~(1ULL << gpio_num);
1020+
1021+
bool pu, pd, ie, oe, od, slp_sel;
1022+
uint32_t drv, fun_sel, sig_out;
1023+
gpio_hal_get_io_config(gpio_context.gpio_hal, gpio_num, &pu, &pd, &ie, &oe, &od, &drv, &fun_sel, &sig_out, &slp_sel);
1024+
1025+
fprintf(out_stream, "IO[%"PRIu32"]%s -\n", gpio_num, esp_gpio_is_pin_reserved(gpio_num) ? " **RESERVED**" : "");
1026+
fprintf(out_stream, " Pullup: %d, Pulldown: %d, DriveCap: %"PRIu32"\n", pu, pd, drv);
1027+
fprintf(out_stream, " InputEn: %d, OutputEn: %d, OpenDrain: %d\n", ie, oe, od);
1028+
fprintf(out_stream, " FuncSel: %"PRIu32" (%s)\n", fun_sel, (fun_sel == PIN_FUNC_GPIO) ? "GPIO" : "IOMUX");
1029+
if (oe && fun_sel == PIN_FUNC_GPIO) {
1030+
fprintf(out_stream, " GPIO Matrix SigOut ID: %"PRIu32"%s\n", sig_out, (sig_out == SIG_GPIO_OUT_IDX) ? " (simple GPIO output)" : "");
1031+
}
1032+
if (ie && fun_sel == PIN_FUNC_GPIO) {
1033+
uint32_t cnt = 0;
1034+
fprintf(out_stream, " GPIO Matrix SigIn ID:");
1035+
for (int i = 0; i < SIG_GPIO_OUT_IDX; i++) {
1036+
if (gpio_hal_get_in_signal_connected_io(gpio_context.gpio_hal, i) == gpio_num) {
1037+
cnt++;
1038+
fprintf(out_stream, " %d", i);
1039+
}
1040+
}
1041+
if (cnt == 0) {
1042+
fprintf(out_stream, " (simple GPIO input)");
1043+
}
1044+
fprintf(out_stream, "\n");
1045+
}
1046+
fprintf(out_stream, " SleepSelEn: %d\n", slp_sel);
1047+
fprintf(out_stream, "\n");
1048+
}
1049+
fprintf(out_stream, "=================IO DUMP End==================\n");
1050+
return ESP_OK;
1051+
}

components/driver/gpio/include/driver/gpio.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
/*
2-
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

77
#pragma once
88

9+
#include <stdio.h>
910
#include <stdbool.h>
1011
#include "sdkconfig.h"
1112
#include "esp_err.h"
@@ -543,7 +544,19 @@ esp_err_t gpio_deep_sleep_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t int
543544
*/
544545
esp_err_t gpio_deep_sleep_wakeup_disable(gpio_num_t gpio_num);
545546

546-
#endif
547+
#endif //SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP
548+
549+
/**
550+
* @brief Dump IO configuration information to console
551+
*
552+
* @param out_stream IO stream (e.g. stdout)
553+
* @param io_bit_mask IO pin bit mask, each bit maps to an IO
554+
*
555+
* @return
556+
* - ESP_OK Success
557+
* - ESP_ERR_INVALID_ARG Parameter error
558+
*/
559+
esp_err_t gpio_dump_io_configuration(FILE *out_stream, uint64_t io_bit_mask);
547560

548561
#ifdef __cplusplus
549562
}

components/hal/esp32/include/hal/gpio_ll.h

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -39,6 +39,39 @@ extern const uint8_t GPIO_PIN_MUX_REG_OFFSET[SOC_GPIO_PIN_COUNT];
3939
#define GPIO_LL_PRO_CPU_NMI_INTR_ENA (BIT(3))
4040
#define GPIO_LL_SDIO_EXT_INTR_ENA (BIT(4))
4141

42+
/**
43+
* @brief Get the configuration for an IO
44+
*
45+
* @param hw Peripheral GPIO hardware instance address.
46+
* @param gpio_num GPIO number
47+
* @param pu Pull-up enabled or not
48+
* @param pd Pull-down enabled or not
49+
* @param ie Input enabled or not
50+
* @param oe Output enabled or not
51+
* @param od Open-drain enabled or not
52+
* @param drv Drive strength value
53+
* @param fun_sel IOMUX function selection value
54+
* @param sig_out Outputting peripheral signal index
55+
* @param slp_sel Pin sleep mode enabled or not
56+
*/
57+
static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num,
58+
bool *pu, bool *pd, bool *ie, bool *oe, bool *od, uint32_t *drv,
59+
uint32_t *fun_sel, uint32_t *sig_out, bool *slp_sel)
60+
{
61+
uint32_t bit_shift = (gpio_num < 32) ? gpio_num : (gpio_num - 32);
62+
uint32_t bit_mask = 1 << bit_shift;
63+
uint32_t iomux_reg_val = REG_READ(GPIO_PIN_MUX_REG[gpio_num]);
64+
*pu = (iomux_reg_val & FUN_PU_M) >> FUN_PU_S;
65+
*pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S;
66+
*ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S;
67+
*oe = (((gpio_num < 32) ? hw->enable : hw->enable1.val) & bit_mask) >> bit_shift;
68+
*od = hw->pin[gpio_num].pad_driver;
69+
*drv = (iomux_reg_val & FUN_DRV_M) >> FUN_DRV_S;
70+
*fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S;
71+
*sig_out = hw->func_out_sel_cfg[gpio_num].func_sel;
72+
*slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S;
73+
}
74+
4275
/**
4376
* @brief Enable pull-up on GPIO.
4477
*
@@ -669,6 +702,23 @@ static inline void gpio_ll_iomux_out(gpio_dev_t *hw, uint8_t gpio_num, int func,
669702
gpio_ll_func_sel(hw, gpio_num, func);
670703
}
671704

705+
/**
706+
* @brief Get the GPIO number that is routed to the input peripheral signal through GPIO matrix.
707+
*
708+
* @param hw Peripheral GPIO hardware instance address.
709+
* @param in_sig_idx Peripheral signal index (tagged as input attribute).
710+
*
711+
* @return
712+
* - -1 Signal bypassed GPIO matrix
713+
* - Others GPIO number
714+
*/
715+
static inline int gpio_ll_get_in_signal_connected_io(gpio_dev_t *hw, uint32_t in_sig_idx)
716+
{
717+
typeof(hw->func_in_sel_cfg[in_sig_idx]) reg;
718+
reg.val = hw->func_in_sel_cfg[in_sig_idx].val;
719+
return (reg.sig_in_sel ? reg.func_sel : -1);
720+
}
721+
672722
#ifdef __cplusplus
673723
}
674724
#endif

components/hal/esp32c2/include/hal/gpio_ll.h

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -31,6 +31,39 @@ extern "C" {
3131

3232
#define GPIO_LL_PRO_CPU_INTR_ENA (BIT(0))
3333
#define GPIO_LL_PRO_CPU_NMI_INTR_ENA (BIT(1))
34+
35+
/**
36+
* @brief Get the configuration for an IO
37+
*
38+
* @param hw Peripheral GPIO hardware instance address.
39+
* @param gpio_num GPIO number
40+
* @param pu Pull-up enabled or not
41+
* @param pd Pull-down enabled or not
42+
* @param ie Input enabled or not
43+
* @param oe Output enabled or not
44+
* @param od Open-drain enabled or not
45+
* @param drv Drive strength value
46+
* @param fun_sel IOMUX function selection value
47+
* @param sig_out Outputting peripheral signal index
48+
* @param slp_sel Pin sleep mode enabled or not
49+
*/
50+
static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num,
51+
bool *pu, bool *pd, bool *ie, bool *oe, bool *od, uint32_t *drv,
52+
uint32_t *fun_sel, uint32_t *sig_out, bool *slp_sel)
53+
{
54+
uint32_t bit_mask = 1 << gpio_num;
55+
uint32_t iomux_reg_val = REG_READ(GPIO_PIN_MUX_REG[gpio_num]);
56+
*pu = (iomux_reg_val & FUN_PU_M) >> FUN_PU_S;
57+
*pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S;
58+
*ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S;
59+
*oe = (hw->enable.val & bit_mask) >> gpio_num;
60+
*od = hw->pin[gpio_num].pad_driver;
61+
*drv = (iomux_reg_val & FUN_DRV_M) >> FUN_DRV_S;
62+
*fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S;
63+
*sig_out = hw->func_out_sel_cfg[gpio_num].func_sel;
64+
*slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S;
65+
}
66+
3467
/**
3568
* @brief Enable pull-up on GPIO.
3669
*
@@ -475,6 +508,23 @@ static inline void gpio_ll_iomux_out(gpio_dev_t *hw, uint8_t gpio_num, int func,
475508
gpio_ll_func_sel(hw, gpio_num, func);
476509
}
477510

511+
/**
512+
* @brief Get the GPIO number that is routed to the input peripheral signal through GPIO matrix.
513+
*
514+
* @param hw Peripheral GPIO hardware instance address.
515+
* @param in_sig_idx Peripheral signal index (tagged as input attribute).
516+
*
517+
* @return
518+
* - -1 Signal bypassed GPIO matrix
519+
* - Others GPIO number
520+
*/
521+
static inline int gpio_ll_get_in_signal_connected_io(gpio_dev_t *hw, uint32_t in_sig_idx)
522+
{
523+
gpio_func_in_sel_cfg_reg_t reg;
524+
reg.val = hw->func_in_sel_cfg[in_sig_idx].val;
525+
return (reg.sig_in_sel ? reg.func_sel : -1);
526+
}
527+
478528
/**
479529
* @brief Force hold all digital(VDD3P3_CPU) and rtc(VDD3P3_RTC) gpio pads.
480530
* @note GPIO force hold, whether the chip in sleep mode or wakeup mode.

components/hal/esp32c3/include/hal/gpio_ll.h

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,39 @@ extern "C" {
3333

3434
#define GPIO_LL_PRO_CPU_INTR_ENA (BIT(0))
3535
#define GPIO_LL_PRO_CPU_NMI_INTR_ENA (BIT(1))
36+
37+
/**
38+
* @brief Get the configuration for an IO
39+
*
40+
* @param hw Peripheral GPIO hardware instance address.
41+
* @param gpio_num GPIO number
42+
* @param pu Pull-up enabled or not
43+
* @param pd Pull-down enabled or not
44+
* @param ie Input enabled or not
45+
* @param oe Output enabled or not
46+
* @param od Open-drain enabled or not
47+
* @param drv Drive strength value
48+
* @param fun_sel IOMUX function selection value
49+
* @param sig_out Outputting peripheral signal index
50+
* @param slp_sel Pin sleep mode enabled or not
51+
*/
52+
static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num,
53+
bool *pu, bool *pd, bool *ie, bool *oe, bool *od, uint32_t *drv,
54+
uint32_t *fun_sel, uint32_t *sig_out, bool *slp_sel)
55+
{
56+
uint32_t bit_mask = 1 << gpio_num;
57+
uint32_t iomux_reg_val = REG_READ(GPIO_PIN_MUX_REG[gpio_num]);
58+
*pu = (iomux_reg_val & FUN_PU_M) >> FUN_PU_S;
59+
*pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S;
60+
*ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S;
61+
*oe = (hw->enable.val & bit_mask) >> gpio_num;
62+
*od = hw->pin[gpio_num].pad_driver;
63+
*drv = (iomux_reg_val & FUN_DRV_M) >> FUN_DRV_S;
64+
*fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S;
65+
*sig_out = hw->func_out_sel_cfg[gpio_num].func_sel;
66+
*slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S;
67+
}
68+
3669
/**
3770
* @brief Enable pull-up on GPIO.
3871
*
@@ -491,6 +524,23 @@ static inline void gpio_ll_iomux_out(gpio_dev_t *hw, uint8_t gpio_num, int func,
491524
gpio_ll_func_sel(hw, gpio_num, func);
492525
}
493526

527+
/**
528+
* @brief Get the GPIO number that is routed to the input peripheral signal through GPIO matrix.
529+
*
530+
* @param hw Peripheral GPIO hardware instance address.
531+
* @param in_sig_idx Peripheral signal index (tagged as input attribute).
532+
*
533+
* @return
534+
* - -1 Signal bypassed GPIO matrix
535+
* - Others GPIO number
536+
*/
537+
static inline int gpio_ll_get_in_signal_connected_io(gpio_dev_t *hw, uint32_t in_sig_idx)
538+
{
539+
typeof(hw->func_in_sel_cfg[in_sig_idx]) reg;
540+
reg.val = hw->func_in_sel_cfg[in_sig_idx].val;
541+
return (reg.sig_in_sel ? reg.func_sel : -1);
542+
}
543+
494544
/**
495545
* @brief Force hold all digital(VDD3P3_CPU) and rtc(VDD3P3_RTC) gpio pads.
496546
* @note GPIO force hold, whether the chip in sleep mode or wakeup mode.

components/hal/esp32c6/include/hal/gpio_ll.h

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,39 @@ extern "C" {
3838

3939
#define GPIO_LL_PRO_CPU_INTR_ENA (BIT(0))
4040
#define GPIO_LL_PRO_CPU_NMI_INTR_ENA (BIT(1))
41+
42+
/**
43+
* @brief Get the configuration for an IO
44+
*
45+
* @param hw Peripheral GPIO hardware instance address.
46+
* @param gpio_num GPIO number
47+
* @param pu Pull-up enabled or not
48+
* @param pd Pull-down enabled or not
49+
* @param ie Input enabled or not
50+
* @param oe Output enabled or not
51+
* @param od Open-drain enabled or not
52+
* @param drv Drive strength value
53+
* @param fun_sel IOMUX function selection value
54+
* @param sig_out Outputting peripheral signal index
55+
* @param slp_sel Pin sleep mode enabled or not
56+
*/
57+
static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num,
58+
bool *pu, bool *pd, bool *ie, bool *oe, bool *od, uint32_t *drv,
59+
uint32_t *fun_sel, uint32_t *sig_out, bool *slp_sel)
60+
{
61+
uint32_t bit_mask = 1 << gpio_num;
62+
uint32_t iomux_reg_val = REG_READ(GPIO_PIN_MUX_REG[gpio_num]);
63+
*pu = (iomux_reg_val & FUN_PU_M) >> FUN_PU_S;
64+
*pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S;
65+
*ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S;
66+
*oe = (hw->enable.val & bit_mask) >> gpio_num;
67+
*od = hw->pin[gpio_num].pad_driver;
68+
*drv = (iomux_reg_val & FUN_DRV_M) >> FUN_DRV_S;
69+
*fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S;
70+
*sig_out = hw->func_out_sel_cfg[gpio_num].out_sel;
71+
*slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S;
72+
}
73+
4174
/**
4275
* @brief Enable pull-up on GPIO.
4376
*
@@ -478,6 +511,23 @@ static inline void gpio_ll_iomux_set_clk_src(soc_module_clk_t src)
478511
}
479512
}
480513

514+
/**
515+
* @brief Get the GPIO number that is routed to the input peripheral signal through GPIO matrix.
516+
*
517+
* @param hw Peripheral GPIO hardware instance address.
518+
* @param in_sig_idx Peripheral signal index (tagged as input attribute).
519+
*
520+
* @return
521+
* - -1 Signal bypassed GPIO matrix
522+
* - Others GPIO number
523+
*/
524+
static inline int gpio_ll_get_in_signal_connected_io(gpio_dev_t *hw, uint32_t in_sig_idx)
525+
{
526+
gpio_func_in_sel_cfg_reg_t reg;
527+
reg.val = hw->func_in_sel_cfg[in_sig_idx].val;
528+
return (reg.sig_in_sel ? reg.in_sel : -1);
529+
}
530+
481531
/**
482532
* @brief Force hold digital io pad.
483533
* @note GPIO force hold, whether the chip in sleep mode or wakeup mode.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy