From 6cffc5c9944f5f32714ff09999ee99a754c8f495 Mon Sep 17 00:00:00 2001 From: Song Ruo Jing Date: Thu, 13 Mar 2025 21:10:20 +0800 Subject: [PATCH 1/5] fix(gpio): fix pu, pd, drv value incorrect from gpio_dump_io_configuration on esp32 Closes https://github.com/espressif/esp-idf/issues/14931 --- components/esp_driver_gpio/src/gpio.c | 27 ++++++-- components/esp_hw_support/esp_gpio_reserve.c | 2 +- components/hal/esp32/include/hal/gpio_ll.h | 2 +- components/hal/esp32/include/hal/rtc_io_ll.h | 35 +++++++++- components/hal/esp32c2/include/hal/gpio_ll.h | 2 +- components/hal/esp32c3/include/hal/gpio_ll.h | 66 +++++++++--------- components/hal/esp32c5/include/hal/gpio_ll.h | 3 +- .../hal/esp32c5/include/hal/rtc_io_ll.h | 24 ++++++- components/hal/esp32c6/include/hal/gpio_ll.h | 2 +- .../hal/esp32c6/include/hal/rtc_io_ll.h | 24 ++++++- components/hal/esp32c61/include/hal/gpio_ll.h | 2 +- .../hal/esp32c61/include/hal/rtc_io_ll.h | 24 ++++++- components/hal/esp32h2/include/hal/gpio_ll.h | 2 +- components/hal/esp32p4/include/hal/gpio_ll.h | 2 +- .../hal/esp32p4/include/hal/rtc_io_ll.h | 24 ++++++- components/hal/esp32s2/include/hal/gpio_ll.h | 2 +- .../hal/esp32s2/include/hal/rtc_io_ll.h | 31 +++++++++ components/hal/esp32s3/include/hal/gpio_ll.h | 68 +++++++++---------- .../hal/esp32s3/include/hal/rtc_io_ll.h | 31 +++++++++ components/hal/include/hal/rtc_io_hal.h | 18 ++++- 20 files changed, 301 insertions(+), 90 deletions(-) diff --git a/components/esp_driver_gpio/src/gpio.c b/components/esp_driver_gpio/src/gpio.c index a63ab11375..be6a1ecc35 100644 --- a/components/esp_driver_gpio/src/gpio.c +++ b/components/esp_driver_gpio/src/gpio.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -75,7 +75,7 @@ static gpio_context_t gpio_context = { esp_err_t gpio_pullup_en(gpio_num_t gpio_num) { - GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); + GPIO_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "GPIO number error (input-only pad has no internal PU)", ESP_ERR_INVALID_ARG); if (!rtc_gpio_is_valid_gpio(gpio_num) || SOC_GPIO_SUPPORT_RTC_INDEPENDENT) { portENTER_CRITICAL(&gpio_context.gpio_spinlock); @@ -113,7 +113,7 @@ esp_err_t gpio_pullup_dis(gpio_num_t gpio_num) esp_err_t gpio_pulldown_en(gpio_num_t gpio_num) { - GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); + GPIO_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "GPIO number error (input-only pad has no internal PD)", ESP_ERR_INVALID_ARG); if (!rtc_gpio_is_valid_gpio(gpio_num) || SOC_GPIO_SUPPORT_RTC_INDEPENDENT) { portENTER_CRITICAL(&gpio_context.gpio_spinlock); @@ -1027,9 +1027,24 @@ esp_err_t gpio_dump_io_configuration(FILE *out_stream, uint64_t io_bit_mask) uint32_t gpio_num = __builtin_ffsll(io_bit_mask) - 1; io_bit_mask &= ~(1ULL << gpio_num); - bool pu, pd, ie, oe, od, slp_sel; - uint32_t drv, fun_sel, sig_out; + bool pu = 0; + bool pd = 0; + bool ie = 0; + bool oe = 0; + bool od = 0; + bool slp_sel = 0; + uint32_t drv = 0; + uint32_t fun_sel = 0; + uint32_t sig_out = 0; gpio_hal_get_io_config(gpio_context.gpio_hal, gpio_num, &pu, &pd, &ie, &oe, &od, &drv, &fun_sel, &sig_out, &slp_sel); +#if !SOC_GPIO_SUPPORT_RTC_INDEPENDENT && SOC_RTCIO_PIN_COUNT > 0 + if (rtc_gpio_is_valid_gpio(gpio_num)) { + int rtcio_num = rtc_io_number_get(gpio_num); + pu = rtcio_hal_is_pullup_enabled(rtcio_num); + pd = rtcio_hal_is_pulldown_enabled(rtcio_num); + drv = rtcio_hal_get_drive_capability(rtcio_num); + } +#endif fprintf(out_stream, "IO[%"PRIu32"]%s -\n", gpio_num, esp_gpio_is_reserved(BIT64(gpio_num)) ? " **RESERVED**" : ""); fprintf(out_stream, " Pullup: %d, Pulldown: %d, DriveCap: %"PRIu32"\n", pu, pd, drv); @@ -1055,7 +1070,7 @@ esp_err_t gpio_dump_io_configuration(FILE *out_stream, uint64_t io_bit_mask) fprintf(out_stream, " SleepSelEn: %d\n", slp_sel); fprintf(out_stream, "\n"); } - fprintf(out_stream, "=================IO DUMP End==================\n"); + fprintf(out_stream, "=================IO DUMP End=================\n"); return ESP_OK; } diff --git a/components/esp_hw_support/esp_gpio_reserve.c b/components/esp_hw_support/esp_gpio_reserve.c index b7891c879d..c2e5ec71c0 100644 --- a/components/esp_hw_support/esp_gpio_reserve.c +++ b/components/esp_hw_support/esp_gpio_reserve.c @@ -10,7 +10,7 @@ #include "esp_bit_defs.h" #include "esp_private/esp_gpio_reserve.h" -static _Atomic uint64_t s_reserved_pin_mask = ATOMIC_VAR_INIT(~(SOC_GPIO_VALID_OUTPUT_GPIO_MASK)); +static _Atomic uint64_t s_reserved_pin_mask = ATOMIC_VAR_INIT(~(SOC_GPIO_VALID_GPIO_MASK)); uint64_t esp_gpio_reserve(uint64_t gpio_mask) { diff --git a/components/hal/esp32/include/hal/gpio_ll.h b/components/hal/esp32/include/hal/gpio_ll.h index e304327402..128334c51e 100644 --- a/components/hal/esp32/include/hal/gpio_ll.h +++ b/components/hal/esp32/include/hal/gpio_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/components/hal/esp32/include/hal/rtc_io_ll.h b/components/hal/esp32/include/hal/rtc_io_ll.h index 78a71c3d05..cae6e69072 100644 --- a/components/hal/esp32/include/hal/rtc_io_ll.h +++ b/components/hal/esp32/include/hal/rtc_io_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -12,6 +12,7 @@ #pragma once +#include #include #include "soc/rtc_io_struct.h" #include "soc/rtc_io_reg.h" @@ -24,7 +25,7 @@ extern "C" { #endif typedef enum { - RTCIO_LL_FUNC_RTC = 0x0, /*!< The pin controled by RTC module. */ + RTCIO_LL_FUNC_RTC = 0x0, /*!< The pin controlled by RTC module. */ RTCIO_LL_FUNC_DIGITAL = 0x1, /*!< The pin controlled by DIGITAL module. */ } rtcio_ll_func_t; @@ -194,6 +195,21 @@ static inline void rtcio_ll_pullup_disable(int rtcio_num) } } +/** + * @brief Get RTC GPIO pad pullup status. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @return Whether the pullup of the pad is enabled or not. + */ +static inline bool rtcio_ll_is_pullup_enabled(int rtcio_num) +{ + if (rtc_io_desc[rtcio_num].pullup) { + return GET_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].pullup); + } else { + return false; + } +} + /** * RTC GPIO pulldown enable. * @@ -218,6 +234,21 @@ static inline void rtcio_ll_pulldown_disable(int rtcio_num) } } +/** + * @brief Get RTC GPIO pad pulldown status. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @return Whether the pulldown of the pad is enabled or not. + */ +static inline bool rtcio_ll_is_pulldown_enabled(int rtcio_num) +{ + if (rtc_io_desc[rtcio_num].pulldown) { + return GET_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].pulldown); + } else { + return false; + } +} + /** * Enable force hold function on an RTC IO pad. * diff --git a/components/hal/esp32c2/include/hal/gpio_ll.h b/components/hal/esp32c2/include/hal/gpio_ll.h index 6af3747eac..b4a1a199fc 100644 --- a/components/hal/esp32c2/include/hal/gpio_ll.h +++ b/components/hal/esp32c2/include/hal/gpio_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/components/hal/esp32c3/include/hal/gpio_ll.h b/components/hal/esp32c3/include/hal/gpio_ll.h index 8cc89f9221..e0096a0edc 100644 --- a/components/hal/esp32c3/include/hal/gpio_ll.h +++ b/components/hal/esp32c3/include/hal/gpio_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -34,38 +34,6 @@ extern "C" { #define GPIO_LL_PRO_CPU_INTR_ENA (BIT(0)) #define GPIO_LL_PRO_CPU_NMI_INTR_ENA (BIT(1)) -/** - * @brief Get the configuration for an IO - * - * @param hw Peripheral GPIO hardware instance address. - * @param gpio_num GPIO number - * @param pu Pull-up enabled or not - * @param pd Pull-down enabled or not - * @param ie Input enabled or not - * @param oe Output enabled or not - * @param od Open-drain enabled or not - * @param drv Drive strength value - * @param fun_sel IOMUX function selection value - * @param sig_out Outputting peripheral signal index - * @param slp_sel Pin sleep mode enabled or not - */ -static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, - bool *pu, bool *pd, bool *ie, bool *oe, bool *od, uint32_t *drv, - uint32_t *fun_sel, uint32_t *sig_out, bool *slp_sel) -{ - uint32_t bit_mask = 1 << gpio_num; - uint32_t iomux_reg_val = REG_READ(GPIO_PIN_MUX_REG[gpio_num]); - *pu = (iomux_reg_val & FUN_PU_M) >> FUN_PU_S; - *pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S; - *ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S; - *oe = (hw->enable.val & bit_mask) >> gpio_num; - *od = hw->pin[gpio_num].pad_driver; - *drv = (iomux_reg_val & FUN_DRV_M) >> FUN_DRV_S; - *fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S; - *sig_out = hw->func_out_sel_cfg[gpio_num].func_sel; - *slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S; -} - /** * @brief Enable pull-up on GPIO. * @@ -770,6 +738,38 @@ static inline bool gpio_ll_deepsleep_wakeup_is_enabled(gpio_dev_t *hw, uint32_t return GET_PERI_REG_MASK(RTC_CNTL_GPIO_WAKEUP_REG, 1 << (RTC_CNTL_GPIO_PIN0_WAKEUP_ENABLE_S - gpio_num)); } +/** + * @brief Get the configuration for an IO + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + * @param pu Pull-up enabled or not + * @param pd Pull-down enabled or not + * @param ie Input enabled or not + * @param oe Output enabled or not + * @param od Open-drain enabled or not + * @param drv Drive strength value + * @param fun_sel IOMUX function selection value + * @param sig_out Outputting peripheral signal index + * @param slp_sel Pin sleep mode enabled or not + */ +static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, + bool *pu, bool *pd, bool *ie, bool *oe, bool *od, uint32_t *drv, + uint32_t *fun_sel, uint32_t *sig_out, bool *slp_sel) +{ + uint32_t bit_mask = 1 << gpio_num; + uint32_t iomux_reg_val = REG_READ(GPIO_PIN_MUX_REG[gpio_num]); + *pu = (iomux_reg_val & FUN_PU_M) >> FUN_PU_S; + *pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S; + *ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S; + *oe = (hw->enable.val & bit_mask) >> gpio_num; + *od = hw->pin[gpio_num].pad_driver; + gpio_ll_get_drive_capability(hw, gpio_num, (gpio_drive_cap_t *)drv); // specific workaround in the LL + *fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S; + *sig_out = hw->func_out_sel_cfg[gpio_num].func_sel; + *slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S; +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32c5/include/hal/gpio_ll.h b/components/hal/esp32c5/include/hal/gpio_ll.h index abc199001a..c9de0b5dc7 100644 --- a/components/hal/esp32c5/include/hal/gpio_ll.h +++ b/components/hal/esp32c5/include/hal/gpio_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -37,7 +37,6 @@ extern "C" { #define GPIO_LL_GET_HW(num) (((num) == 0) ? (&GPIO) : NULL) #define GPIO_LL_PRO_CPU_INTR_ENA (BIT(0)) -#define GPIO_LL_PRO_CPU_NMI_INTR_ENA (BIT(1)) /** * @brief Get the configuration for an IO diff --git a/components/hal/esp32c5/include/hal/rtc_io_ll.h b/components/hal/esp32c5/include/hal/rtc_io_ll.h index 7b3d10819c..ce6e7c511e 100644 --- a/components/hal/esp32c5/include/hal/rtc_io_ll.h +++ b/components/hal/esp32c5/include/hal/rtc_io_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -229,6 +229,17 @@ static inline void rtcio_ll_pullup_disable(int rtcio_num) LP_IO_MUX.gpion[rtcio_num].gpion_fun_wpu = 0; } +/** + * @brief Get RTC GPIO pad pullup status. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @return Whether the pullup of the pad is enabled or not. + */ +static inline bool rtcio_ll_is_pullup_enabled(int rtcio_num) +{ + return LP_IO_MUX.gpion[rtcio_num].gpion_fun_wpu; +} + /** * RTC GPIO pulldown enable. * @@ -251,6 +262,17 @@ static inline void rtcio_ll_pulldown_disable(int rtcio_num) LP_IO_MUX.gpion[rtcio_num].gpion_fun_wpd = 0; } +/** + * @brief Get RTC GPIO pad pulldown status. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @return Whether the pulldown of the pad is enabled or not. + */ +static inline bool rtcio_ll_is_pulldown_enabled(int rtcio_num) +{ + return LP_IO_MUX.gpion[rtcio_num].gpion_fun_wpd; +} + /** * Enable force hold function for an RTC IO pad. * diff --git a/components/hal/esp32c6/include/hal/gpio_ll.h b/components/hal/esp32c6/include/hal/gpio_ll.h index cccc167247..e116441fc8 100644 --- a/components/hal/esp32c6/include/hal/gpio_ll.h +++ b/components/hal/esp32c6/include/hal/gpio_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/components/hal/esp32c6/include/hal/rtc_io_ll.h b/components/hal/esp32c6/include/hal/rtc_io_ll.h index 6fcac4cd40..5a9fcbe5a5 100644 --- a/components/hal/esp32c6/include/hal/rtc_io_ll.h +++ b/components/hal/esp32c6/include/hal/rtc_io_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -228,6 +228,17 @@ static inline void rtcio_ll_pullup_disable(int rtcio_num) LP_IO.gpio[rtcio_num].fun_wpu = 0; } +/** + * @brief Get RTC GPIO pad pullup status. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @return Whether the pullup of the pad is enabled or not. + */ +static inline bool rtcio_ll_is_pullup_enabled(int rtcio_num) +{ + return LP_IO.gpio[rtcio_num].fun_wpu; +} + /** * RTC GPIO pulldown enable. * @@ -250,6 +261,17 @@ static inline void rtcio_ll_pulldown_disable(int rtcio_num) LP_IO.gpio[rtcio_num].fun_wpd = 0; } +/** + * @brief Get RTC GPIO pad pulldown status. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @return Whether the pulldown of the pad is enabled or not. + */ +static inline bool rtcio_ll_is_pulldown_enabled(int rtcio_num) +{ + return LP_IO.gpio[rtcio_num].fun_wpd; +} + /** * Enable force hold function for an RTC IO pad. * diff --git a/components/hal/esp32c61/include/hal/gpio_ll.h b/components/hal/esp32c61/include/hal/gpio_ll.h index 79a9b07306..eddc93672f 100644 --- a/components/hal/esp32c61/include/hal/gpio_ll.h +++ b/components/hal/esp32c61/include/hal/gpio_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/components/hal/esp32c61/include/hal/rtc_io_ll.h b/components/hal/esp32c61/include/hal/rtc_io_ll.h index 60bd5fd7d0..4d5c85cb07 100644 --- a/components/hal/esp32c61/include/hal/rtc_io_ll.h +++ b/components/hal/esp32c61/include/hal/rtc_io_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -229,6 +229,17 @@ static inline void rtcio_ll_pullup_disable(int rtcio_num) LP_IO_MUX.gpion[rtcio_num].gpion_fun_wpu = 0; } +/** + * @brief Get RTC GPIO pad pullup status. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @return Whether the pullup of the pad is enabled or not. + */ +static inline bool rtcio_ll_is_pullup_enabled(int rtcio_num) +{ + return LP_IO_MUX.gpion[rtcio_num].gpion_fun_wpu; +} + /** * RTC GPIO pulldown enable. * @@ -251,6 +262,17 @@ static inline void rtcio_ll_pulldown_disable(int rtcio_num) LP_IO_MUX.gpion[rtcio_num].gpion_fun_wpd = 0; } +/** + * @brief Get RTC GPIO pad pulldown status. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @return Whether the pulldown of the pad is enabled or not. + */ +static inline bool rtcio_ll_is_pulldown_enabled(int rtcio_num) +{ + return LP_IO_MUX.gpion[rtcio_num].gpion_fun_wpd; +} + /** * Enable force hold function for an RTC IO pad. * diff --git a/components/hal/esp32h2/include/hal/gpio_ll.h b/components/hal/esp32h2/include/hal/gpio_ll.h index 21826ae4ec..cc6878c830 100644 --- a/components/hal/esp32h2/include/hal/gpio_ll.h +++ b/components/hal/esp32h2/include/hal/gpio_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/components/hal/esp32p4/include/hal/gpio_ll.h b/components/hal/esp32p4/include/hal/gpio_ll.h index c1211b11f6..5f83f2b6f4 100644 --- a/components/hal/esp32p4/include/hal/gpio_ll.h +++ b/components/hal/esp32p4/include/hal/gpio_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/components/hal/esp32p4/include/hal/rtc_io_ll.h b/components/hal/esp32p4/include/hal/rtc_io_ll.h index 1bfe4659ff..3ff8eaa3ba 100644 --- a/components/hal/esp32p4/include/hal/rtc_io_ll.h +++ b/components/hal/esp32p4/include/hal/rtc_io_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -267,6 +267,17 @@ static inline void rtcio_ll_pullup_disable(int rtcio_num) LP_IOMUX.pad[rtcio_num].rue = 0; } +/** + * @brief Get RTC GPIO pad pullup status. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @return Whether the pullup of the pad is enabled or not. + */ +static inline bool rtcio_ll_is_pullup_enabled(int rtcio_num) +{ + return LP_IOMUX.pad[rtcio_num].rue; +} + /** * @brief RTC GPIO pulldown enable. * @@ -289,6 +300,17 @@ static inline void rtcio_ll_pulldown_disable(int rtcio_num) LP_IOMUX.pad[rtcio_num].rde = 0; } +/** + * @brief Get RTC GPIO pad pulldown status. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @return Whether the pulldown of the pad is enabled or not. + */ +static inline bool rtcio_ll_is_pulldown_enabled(int rtcio_num) +{ + return LP_IOMUX.pad[rtcio_num].rde; +} + /** * @brief Enable force hold function for an RTC IO pad. * diff --git a/components/hal/esp32s2/include/hal/gpio_ll.h b/components/hal/esp32s2/include/hal/gpio_ll.h index d90ea5a3da..2241ca3cf2 100644 --- a/components/hal/esp32s2/include/hal/gpio_ll.h +++ b/components/hal/esp32s2/include/hal/gpio_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/components/hal/esp32s2/include/hal/rtc_io_ll.h b/components/hal/esp32s2/include/hal/rtc_io_ll.h index 5e695ba145..647a69da79 100644 --- a/components/hal/esp32s2/include/hal/rtc_io_ll.h +++ b/components/hal/esp32s2/include/hal/rtc_io_ll.h @@ -12,6 +12,7 @@ #pragma once +#include #include #include #include "soc/rtc_io_struct.h" @@ -206,6 +207,21 @@ static inline void rtcio_ll_pullup_disable(int rtcio_num) } } +/** + * @brief Get RTC GPIO pad pullup status. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @return Whether the pullup of the pad is enabled or not. + */ +static inline bool rtcio_ll_is_pullup_enabled(int rtcio_num) +{ + if (rtc_io_desc[rtcio_num].pullup) { + return GET_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].pullup); + } else { + return false; + } +} + /** * RTC GPIO pulldown enable. * @@ -230,6 +246,21 @@ static inline void rtcio_ll_pulldown_disable(int rtcio_num) } } +/** + * @brief Get RTC GPIO pad pulldown status. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @return Whether the pulldown of the pad is enabled or not. + */ +static inline bool rtcio_ll_is_pulldown_enabled(int rtcio_num) +{ + if (rtc_io_desc[rtcio_num].pulldown) { + return GET_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].pulldown); + } else { + return false; + } +} + /** * Enable force hold function on an RTC IO pad. * diff --git a/components/hal/esp32s3/include/hal/gpio_ll.h b/components/hal/esp32s3/include/hal/gpio_ll.h index 703fe65ce8..ab18f549b1 100644 --- a/components/hal/esp32s3/include/hal/gpio_ll.h +++ b/components/hal/esp32s3/include/hal/gpio_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -34,39 +34,6 @@ extern "C" { #define GPIO_LL_INTR_ENA (BIT(0)) #define GPIO_LL_NMI_INTR_ENA (BIT(1)) -/** - * @brief Get the configuration for an IO - * - * @param hw Peripheral GPIO hardware instance address. - * @param gpio_num GPIO number - * @param pu Pull-up enabled or not - * @param pd Pull-down enabled or not - * @param ie Input enabled or not - * @param oe Output enabled or not - * @param od Open-drain enabled or not - * @param drv Drive strength value - * @param fun_sel IOMUX function selection value - * @param sig_out Outputting peripheral signal index - * @param slp_sel Pin sleep mode enabled or not - */ -static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, - bool *pu, bool *pd, bool *ie, bool *oe, bool *od, uint32_t *drv, - uint32_t *fun_sel, uint32_t *sig_out, bool *slp_sel) -{ - uint32_t bit_shift = (gpio_num < 32) ? gpio_num : (gpio_num - 32); - uint32_t bit_mask = 1 << bit_shift; - uint32_t iomux_reg_val = REG_READ(GPIO_PIN_MUX_REG[gpio_num]); - *pu = (iomux_reg_val & FUN_PU_M) >> FUN_PU_S; - *pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S; - *ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S; - *oe = (((gpio_num < 32) ? hw->enable : hw->enable1.val) & bit_mask) >> bit_shift; - *od = hw->pin[gpio_num].pad_driver; - *drv = (iomux_reg_val & FUN_DRV_M) >> FUN_DRV_S; - *fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S; - *sig_out = hw->func_out_sel_cfg[gpio_num].func_sel; - *slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S; -} - /** * @brief Enable pull-up on GPIO. * @@ -737,6 +704,39 @@ static inline void gpio_ll_sleep_output_enable(gpio_dev_t *hw, uint32_t gpio_num PIN_SLP_OUTPUT_ENABLE(GPIO_PIN_MUX_REG[gpio_num]); } +/** + * @brief Get the configuration for an IO + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + * @param pu Pull-up enabled or not + * @param pd Pull-down enabled or not + * @param ie Input enabled or not + * @param oe Output enabled or not + * @param od Open-drain enabled or not + * @param drv Drive strength value + * @param fun_sel IOMUX function selection value + * @param sig_out Outputting peripheral signal index + * @param slp_sel Pin sleep mode enabled or not + */ +static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, + bool *pu, bool *pd, bool *ie, bool *oe, bool *od, uint32_t *drv, + uint32_t *fun_sel, uint32_t *sig_out, bool *slp_sel) +{ + uint32_t bit_shift = (gpio_num < 32) ? gpio_num : (gpio_num - 32); + uint32_t bit_mask = 1 << bit_shift; + uint32_t iomux_reg_val = REG_READ(GPIO_PIN_MUX_REG[gpio_num]); + *pu = (iomux_reg_val & FUN_PU_M) >> FUN_PU_S; + *pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S; + *ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S; + *oe = (((gpio_num < 32) ? hw->enable : hw->enable1.val) & bit_mask) >> bit_shift; + *od = hw->pin[gpio_num].pad_driver; + gpio_ll_get_drive_capability(hw, gpio_num, (gpio_drive_cap_t *)drv); // specific workaround in the LL + *fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S; + *sig_out = hw->func_out_sel_cfg[gpio_num].func_sel; + *slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S; +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32s3/include/hal/rtc_io_ll.h b/components/hal/esp32s3/include/hal/rtc_io_ll.h index 6cd31a3a00..a5cd10b502 100644 --- a/components/hal/esp32s3/include/hal/rtc_io_ll.h +++ b/components/hal/esp32s3/include/hal/rtc_io_ll.h @@ -12,6 +12,7 @@ #pragma once +#include #include #include #include "soc/rtc_io_struct.h" @@ -233,6 +234,21 @@ static inline void rtcio_ll_pullup_disable(int rtcio_num) } } +/** + * @brief Get RTC GPIO pad pullup status. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @return Whether the pullup of the pad is enabled or not. + */ +static inline bool rtcio_ll_is_pullup_enabled(int rtcio_num) +{ + if (rtc_io_desc[rtcio_num].pullup) { + return GET_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].pullup); + } else { + return false; + } +} + /** * RTC GPIO pulldown enable. * @@ -257,6 +273,21 @@ static inline void rtcio_ll_pulldown_disable(int rtcio_num) } } +/** + * @brief Get RTC GPIO pad pulldown status. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @return Whether the pulldown of the pad is enabled or not. + */ +static inline bool rtcio_ll_is_pulldown_enabled(int rtcio_num) +{ + if (rtc_io_desc[rtcio_num].pulldown) { + return GET_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].pulldown); + } else { + return false; + } +} + /** * Enable force hold function on an RTC IO pad. * diff --git a/components/hal/include/hal/rtc_io_hal.h b/components/hal/include/hal/rtc_io_hal.h index 471a09e006..a613c2c83f 100644 --- a/components/hal/include/hal/rtc_io_hal.h +++ b/components/hal/include/hal/rtc_io_hal.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -161,6 +161,14 @@ void rtcio_hal_set_direction_in_sleep(int rtcio_num, rtc_gpio_mode_t mode); */ #define rtcio_hal_pullup_disable(rtcio_num) rtcio_ll_pullup_disable(rtcio_num) +/** + * @brief Get RTC GPIO pad pullup status. + * + * @param rtcio_num The index of rtcio. 0 ~ SOC_RTCIO_PIN_COUNT. + * @return Whether the pullup of the pad is enabled or not. + */ +#define rtcio_hal_is_pullup_enabled(rtcio_num) rtcio_ll_is_pullup_enabled(rtcio_num) + /** * RTC GPIO pulldown enable. * @@ -175,6 +183,14 @@ void rtcio_hal_set_direction_in_sleep(int rtcio_num, rtc_gpio_mode_t mode); */ #define rtcio_hal_pulldown_disable(rtcio_num) rtcio_ll_pulldown_disable(rtcio_num) +/** + * @brief Get RTC GPIO pad pulldown status. + * + * @param rtcio_num The index of rtcio. 0 ~ SOC_RTCIO_PIN_COUNT. + * @return Whether the pulldown of the pad is enabled or not. + */ +#define rtcio_hal_is_pulldown_enabled(rtcio_num) rtcio_ll_is_pulldown_enabled(rtcio_num) + /** * Select a RTC IOMUX function for the RTC IO * From f61b453a25bd54462eb13b4cbae77023e1ae52d4 Mon Sep 17 00:00:00 2001 From: Song Ruo Jing Date: Fri, 20 Dec 2024 21:14:34 +0800 Subject: [PATCH 2/5] fix(gpio): fix 8/16-bit gpio, rtc/lp_io register access --- .../test_apps/gpio/CMakeLists.txt | 10 ++++++++ .../gpio_extensions/main/CMakeLists.txt | 5 ++++ .../test_apps/sigma_delta/CMakeLists.txt | 5 ++++ components/hal/esp32c2/include/hal/gpio_ll.h | 10 ++++---- components/hal/esp32c3/include/hal/gpio_ll.h | 5 ++-- components/hal/esp32c5/include/hal/gpio_ll.h | 1 - .../hal/esp32c5/include/hal/rtc_io_ll.h | 12 +++++----- components/hal/esp32c6/include/hal/gpio_ll.h | 9 +++---- .../hal/esp32c6/include/hal/rtc_io_ll.h | 8 +++---- components/hal/esp32h2/include/hal/gpio_ll.h | 7 ++---- components/hal/esp32p4/include/hal/gpio_ll.h | 8 +++++-- components/hal/esp32s2/include/hal/gpio_ll.h | 1 - components/hal/esp32s3/include/hal/gpio_ll.h | 1 - .../soc/esp32c2/register/soc/gpio_struct.h | 4 ++-- .../soc/esp32c3/register/soc/gpio_struct.h | 4 ++-- .../soc/esp32c5/register/soc/lp_gpio_struct.h | 24 +++++++++---------- .../soc/esp32c6/register/soc/lp_io_struct.h | 18 +++++++------- 17 files changed, 73 insertions(+), 59 deletions(-) diff --git a/components/esp_driver_gpio/test_apps/gpio/CMakeLists.txt b/components/esp_driver_gpio/test_apps/gpio/CMakeLists.txt index 886e85131a..705e3c5154 100644 --- a/components/esp_driver_gpio/test_apps/gpio/CMakeLists.txt +++ b/components/esp_driver_gpio/test_apps/gpio/CMakeLists.txt @@ -19,3 +19,13 @@ if(CONFIG_COMPILER_DUMP_RTL_FILES) DEPENDS ${elf} ) endif() + +include($ENV{IDF_PATH}/tools/ci/check_register_rw_half_word.cmake) +message(STATUS "Checking gpio registers are not read-write by half-word") +check_register_rw_half_word(SOC_MODULES "gpio" "io_mux" "rtc_cntl" "rtc_io" "pcr" "hp_sys_clkrst" "hp_system" + "lp_aon" "lp_iomux" "pmu" + HAL_MODULES "gpio") + +message(STATUS "Checking rtcio registers are not read-write by half-word") +check_register_rw_half_word(SOC_MODULES "rtc_io" "sens" "pcr" "lp_aon" "lp_io" "lp_gpio" "lp_iomux" "lpperi" "pmu" + HAL_MODULES "rtc_io") diff --git a/components/esp_driver_gpio/test_apps/gpio_extensions/main/CMakeLists.txt b/components/esp_driver_gpio/test_apps/gpio_extensions/main/CMakeLists.txt index c61fee0bb5..ac737d0ac3 100644 --- a/components/esp_driver_gpio/test_apps/gpio_extensions/main/CMakeLists.txt +++ b/components/esp_driver_gpio/test_apps/gpio_extensions/main/CMakeLists.txt @@ -21,3 +21,8 @@ endif() idf_component_register(SRCS ${srcs} PRIV_REQUIRES unity esp_driver_gpio WHOLE_ARCHIVE) + +message(STATUS "Checking gpio_ext registers are not read-write by half-word") +include($ENV{IDF_PATH}/tools/ci/check_register_rw_half_word.cmake) +check_register_rw_half_word(SOC_MODULES "gpio_ext" + HAL_MODULES "gpio_etm" "gpio_glitch_filter") diff --git a/components/esp_driver_sdm/test_apps/sigma_delta/CMakeLists.txt b/components/esp_driver_sdm/test_apps/sigma_delta/CMakeLists.txt index 7ad2bd49ba..ca89d987bb 100644 --- a/components/esp_driver_sdm/test_apps/sigma_delta/CMakeLists.txt +++ b/components/esp_driver_sdm/test_apps/sigma_delta/CMakeLists.txt @@ -19,3 +19,8 @@ if(CONFIG_COMPILER_DUMP_RTL_FILES) DEPENDS ${elf} ) endif() + +message(STATUS "Checking sdm registers are not read-write by half-word") +include($ENV{IDF_PATH}/tools/ci/check_register_rw_half_word.cmake) +check_register_rw_half_word(SOC_MODULES "gpio_ext" "gpio_sd" + HAL_MODULES "sdm") diff --git a/components/hal/esp32c2/include/hal/gpio_ll.h b/components/hal/esp32c2/include/hal/gpio_ll.h index b4a1a199fc..182d9e71ec 100644 --- a/components/hal/esp32c2/include/hal/gpio_ll.h +++ b/components/hal/esp32c2/include/hal/gpio_ll.h @@ -21,6 +21,7 @@ #include "soc/rtc_cntl_reg.h" #include "hal/gpio_types.h" #include "hal/assert.h" +#include "hal/misc.h" #ifdef __cplusplus extern "C" { @@ -60,7 +61,7 @@ static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, *od = hw->pin[gpio_num].pad_driver; *drv = (iomux_reg_val & FUN_DRV_M) >> FUN_DRV_S; *fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S; - *sig_out = hw->func_out_sel_cfg[gpio_num].func_sel; + *sig_out = HAL_FORCE_READ_U32_REG_FIELD(hw->func_out_sel_cfg[gpio_num], out_sel); *slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S; } @@ -300,10 +301,7 @@ static inline void gpio_ll_od_enable(gpio_dev_t *hw, uint32_t gpio_num) __attribute__((always_inline)) static inline void gpio_ll_matrix_out_default(gpio_dev_t *hw, uint32_t gpio_num) { - gpio_func_out_sel_cfg_reg_t reg = { - .func_sel = SIG_GPIO_OUT_IDX, - }; - hw->func_out_sel_cfg[gpio_num].val = reg.val; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->func_out_sel_cfg[gpio_num], out_sel, SIG_GPIO_OUT_IDX); } /** @@ -553,7 +551,7 @@ static inline int gpio_ll_get_in_signal_connected_io(gpio_dev_t *hw, uint32_t in { gpio_func_in_sel_cfg_reg_t reg; reg.val = hw->func_in_sel_cfg[in_sig_idx].val; - return (reg.sig_in_sel ? reg.func_sel : -1); + return (reg.sig_in_sel ? reg.in_sel : -1); } /** diff --git a/components/hal/esp32c3/include/hal/gpio_ll.h b/components/hal/esp32c3/include/hal/gpio_ll.h index e0096a0edc..690830a7e3 100644 --- a/components/hal/esp32c3/include/hal/gpio_ll.h +++ b/components/hal/esp32c3/include/hal/gpio_ll.h @@ -23,6 +23,7 @@ #include "soc/usb_serial_jtag_reg.h" #include "hal/gpio_types.h" #include "hal/assert.h" +#include "hal/misc.h" #ifdef __cplusplus extern "C" { @@ -544,7 +545,7 @@ static inline int gpio_ll_get_in_signal_connected_io(gpio_dev_t *hw, uint32_t in { typeof(hw->func_in_sel_cfg[in_sig_idx]) reg; reg.val = hw->func_in_sel_cfg[in_sig_idx].val; - return (reg.sig_in_sel ? reg.func_sel : -1); + return (reg.sig_in_sel ? reg.in_sel : -1); } /** @@ -766,7 +767,7 @@ static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, *od = hw->pin[gpio_num].pad_driver; gpio_ll_get_drive_capability(hw, gpio_num, (gpio_drive_cap_t *)drv); // specific workaround in the LL *fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S; - *sig_out = hw->func_out_sel_cfg[gpio_num].func_sel; + *sig_out = HAL_FORCE_READ_U32_REG_FIELD(hw->func_out_sel_cfg[gpio_num], out_sel); *slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S; } diff --git a/components/hal/esp32c5/include/hal/gpio_ll.h b/components/hal/esp32c5/include/hal/gpio_ll.h index c9de0b5dc7..99060c83c2 100644 --- a/components/hal/esp32c5/include/hal/gpio_ll.h +++ b/components/hal/esp32c5/include/hal/gpio_ll.h @@ -27,7 +27,6 @@ #include "soc/usb_serial_jtag_struct.h" #include "hal/gpio_types.h" #include "hal/assert.h" -#include "soc/lp_gpio_struct.h" #ifdef __cplusplus extern "C" { diff --git a/components/hal/esp32c5/include/hal/rtc_io_ll.h b/components/hal/esp32c5/include/hal/rtc_io_ll.h index ce6e7c511e..5e31fc7f12 100644 --- a/components/hal/esp32c5/include/hal/rtc_io_ll.h +++ b/components/hal/esp32c5/include/hal/rtc_io_ll.h @@ -115,7 +115,7 @@ static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func) */ static inline void rtcio_ll_output_enable(int rtcio_num) { - HAL_FORCE_MODIFY_U32_REG_FIELD(LP_GPIO.enable_w1ts, enable_w1ts, BIT(rtcio_num)); + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_GPIO.enable_w1ts, out_enable_w1ts, BIT(rtcio_num)); } /** @@ -125,7 +125,7 @@ static inline void rtcio_ll_output_enable(int rtcio_num) */ static inline void rtcio_ll_output_disable(int rtcio_num) { - HAL_FORCE_MODIFY_U32_REG_FIELD(LP_GPIO.enable_w1tc, enable_w1tc, BIT(rtcio_num)); + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_GPIO.enable_w1tc, out_enable_w1tc, BIT(rtcio_num)); } /** @@ -137,9 +137,9 @@ static inline void rtcio_ll_output_disable(int rtcio_num) static inline void rtcio_ll_set_level(int rtcio_num, uint32_t level) { if (level) { - HAL_FORCE_MODIFY_U32_REG_FIELD(LP_GPIO.out_w1ts, out_w1ts, BIT(rtcio_num)); + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_GPIO.out_w1ts, out_data_w1ts, BIT(rtcio_num)); } else { - HAL_FORCE_MODIFY_U32_REG_FIELD(LP_GPIO.out_w1tc, out_w1tc, BIT(rtcio_num)); + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_GPIO.out_w1tc, out_data_w1tc, BIT(rtcio_num)); } } @@ -357,7 +357,7 @@ static inline void rtcio_ll_intr_enable(int rtcio_num, rtcio_ll_intr_type_t type LP_GPIO.pinn[rtcio_num].pinn_int_type = type; /* Work around for HW issue, - need to also enable this clk, so that LP_GPIO.status.status_interrupt can get updated, + need to also enable this clk, so that (LP_GPIO.status, status_interrupt) can get updated, and trigger the interrupt on the LP Core */ LP_GPIO.clock_gate.clk_en = 1; @@ -450,7 +450,7 @@ static inline uint32_t rtcio_ll_get_interrupt_status(void) */ static inline void rtcio_ll_clear_interrupt_status(void) { - HAL_FORCE_MODIFY_U32_REG_FIELD(LP_GPIO.status_w1tc, status_w1tc, 0xff); + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_GPIO.status_w1tc, status_intr_w1tc, 0xff); } #ifdef __cplusplus diff --git a/components/hal/esp32c6/include/hal/gpio_ll.h b/components/hal/esp32c6/include/hal/gpio_ll.h index e116441fc8..3355909d69 100644 --- a/components/hal/esp32c6/include/hal/gpio_ll.h +++ b/components/hal/esp32c6/include/hal/gpio_ll.h @@ -20,13 +20,13 @@ #include "soc/gpio_periph.h" #include "soc/gpio_struct.h" #include "soc/lp_aon_struct.h" -#include "soc/lp_io_struct.h" #include "soc/pmu_struct.h" #include "soc/usb_serial_jtag_reg.h" #include "soc/pcr_struct.h" #include "soc/clk_tree_defs.h" #include "hal/gpio_types.h" #include "hal/assert.h" +#include "hal/misc.h" #ifdef __cplusplus extern "C" { @@ -66,7 +66,7 @@ static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, *od = hw->pin[gpio_num].pad_driver; *drv = (iomux_reg_val & FUN_DRV_M) >> FUN_DRV_S; *fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S; - *sig_out = hw->func_out_sel_cfg[gpio_num].out_sel; + *sig_out = HAL_FORCE_READ_U32_REG_FIELD(hw->func_out_sel_cfg[gpio_num], out_sel); *slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S; } @@ -315,10 +315,7 @@ static inline void gpio_ll_od_enable(gpio_dev_t *hw, uint32_t gpio_num) __attribute__((always_inline)) static inline void gpio_ll_matrix_out_default(gpio_dev_t *hw, uint32_t gpio_num) { - gpio_func_out_sel_cfg_reg_t reg = { - .out_sel = SIG_GPIO_OUT_IDX, - }; - hw->func_out_sel_cfg[gpio_num].val = reg.val; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->func_out_sel_cfg[gpio_num], out_sel, SIG_GPIO_OUT_IDX); } /** diff --git a/components/hal/esp32c6/include/hal/rtc_io_ll.h b/components/hal/esp32c6/include/hal/rtc_io_ll.h index 5a9fcbe5a5..d17fbb1250 100644 --- a/components/hal/esp32c6/include/hal/rtc_io_ll.h +++ b/components/hal/esp32c6/include/hal/rtc_io_ll.h @@ -136,9 +136,9 @@ static inline void rtcio_ll_output_disable(int rtcio_num) static inline void rtcio_ll_set_level(int rtcio_num, uint32_t level) { if (level) { - HAL_FORCE_MODIFY_U32_REG_FIELD(LP_IO.out_data_w1ts, out_data_w1ts, BIT(rtcio_num)); + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_IO.out_data_w1ts, out_w1ts, BIT(rtcio_num)); } else { - HAL_FORCE_MODIFY_U32_REG_FIELD(LP_IO.out_data_w1tc, out_data_w1tc, BIT(rtcio_num)); + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_IO.out_data_w1tc, out_w1tc, BIT(rtcio_num)); } } @@ -364,7 +364,7 @@ static inline void rtcio_ll_intr_enable(int rtcio_num, rtcio_ll_intr_type_t type LP_IO.pin[rtcio_num].int_type = type; /* Work around for HW issue, - need to also enable this clk, so that LP_IO.status.status_interrupt can get updated, + need to also enable this clk, so that (LP_IO.status, status_interrupt) can get updated, and trigger the interrupt on the LP Core */ LP_IO.date.clk_en = 1; @@ -457,7 +457,7 @@ static inline uint32_t rtcio_ll_get_interrupt_status(void) */ static inline void rtcio_ll_clear_interrupt_status(void) { - HAL_FORCE_MODIFY_U32_REG_FIELD(LP_IO.status_w1tc, status_w1tc, 0xff); + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_IO.status_w1tc, status_intr_w1tc, 0xff); } #ifdef __cplusplus diff --git a/components/hal/esp32h2/include/hal/gpio_ll.h b/components/hal/esp32h2/include/hal/gpio_ll.h index cc6878c830..7d1bc5daad 100644 --- a/components/hal/esp32h2/include/hal/gpio_ll.h +++ b/components/hal/esp32h2/include/hal/gpio_ll.h @@ -66,7 +66,7 @@ static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, *od = hw->pin[gpio_num].pad_driver; *drv = (iomux_reg_val & FUN_DRV_M) >> FUN_DRV_S; *fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S; - *sig_out = hw->func_out_sel_cfg[gpio_num].out_sel; + *sig_out = HAL_FORCE_READ_U32_REG_FIELD(hw->func_out_sel_cfg[gpio_num], out_sel); *slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S; } @@ -360,10 +360,7 @@ static inline void gpio_ll_od_enable(gpio_dev_t *hw, gpio_num_t gpio_num) __attribute__((always_inline)) static inline void gpio_ll_matrix_out_default(gpio_dev_t *hw, uint32_t gpio_num) { - gpio_func_out_sel_cfg_reg_t reg = { - .out_sel = SIG_GPIO_OUT_IDX, - }; - hw->func_out_sel_cfg[gpio_num].val = reg.val; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->func_out_sel_cfg[gpio_num], out_sel, SIG_GPIO_OUT_IDX); } /** diff --git a/components/hal/esp32p4/include/hal/gpio_ll.h b/components/hal/esp32p4/include/hal/gpio_ll.h index 5f83f2b6f4..be812c27b3 100644 --- a/components/hal/esp32p4/include/hal/gpio_ll.h +++ b/components/hal/esp32p4/include/hal/gpio_ll.h @@ -285,7 +285,9 @@ static inline void gpio_ll_pin_input_hysteresis_enable(gpio_dev_t *hw, uint32_t uint64_t bit_mask = 1ULL << gpio_num; if (!(bit_mask & SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK)) { // GPIO0-15 - LP_IOMUX.lp_pad_hys.reg_lp_gpio_hys |= bit_mask; + uint32_t hys_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_IOMUX.lp_pad_hys, reg_lp_gpio_hys); + hys_mask |= bit_mask; + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_IOMUX.lp_pad_hys, reg_lp_gpio_hys, hys_mask); } else { if (gpio_num < 32 + SOC_RTCIO_PIN_COUNT) { // GPIO 16-47 @@ -308,7 +310,9 @@ static inline void gpio_ll_pin_input_hysteresis_disable(gpio_dev_t *hw, uint32_t uint64_t bit_mask = 1ULL << gpio_num; if (!(bit_mask & SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK)) { // GPIO0-15 - LP_IOMUX.lp_pad_hys.reg_lp_gpio_hys &= ~bit_mask; + uint32_t hys_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_IOMUX.lp_pad_hys, reg_lp_gpio_hys); + hys_mask &= ~bit_mask; + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_IOMUX.lp_pad_hys, reg_lp_gpio_hys, hys_mask); } else { if (gpio_num < 32 + SOC_RTCIO_PIN_COUNT) { // GPIO 16-47 diff --git a/components/hal/esp32s2/include/hal/gpio_ll.h b/components/hal/esp32s2/include/hal/gpio_ll.h index 2241ca3cf2..65c451e499 100644 --- a/components/hal/esp32s2/include/hal/gpio_ll.h +++ b/components/hal/esp32s2/include/hal/gpio_ll.h @@ -18,7 +18,6 @@ #include "soc/soc.h" #include "soc/gpio_periph.h" #include "soc/rtc_cntl_reg.h" -#include "soc/rtc_io_reg.h" #include "soc/gpio_struct.h" #include "hal/gpio_types.h" #include "hal/assert.h" diff --git a/components/hal/esp32s3/include/hal/gpio_ll.h b/components/hal/esp32s3/include/hal/gpio_ll.h index ab18f549b1..a0365773bb 100644 --- a/components/hal/esp32s3/include/hal/gpio_ll.h +++ b/components/hal/esp32s3/include/hal/gpio_ll.h @@ -18,7 +18,6 @@ #include "soc/soc.h" #include "soc/gpio_periph.h" #include "soc/rtc_cntl_reg.h" -#include "soc/rtc_io_reg.h" #include "soc/usb_serial_jtag_reg.h" #include "hal/gpio_types.h" #include "soc/gpio_struct.h" diff --git a/components/soc/esp32c2/register/soc/gpio_struct.h b/components/soc/esp32c2/register/soc/gpio_struct.h index 83f7f41402..97ab45e928 100644 --- a/components/soc/esp32c2/register/soc/gpio_struct.h +++ b/components/soc/esp32c2/register/soc/gpio_struct.h @@ -301,7 +301,7 @@ typedef union { * set this value: s=0-53: connect GPIO[s] to this port. s=0x38: set this port always * high level. s=0x3C: set this port always low level. */ - uint32_t func_sel:5; + uint32_t in_sel:5; /** in_inv_sel : R/W; bitpos: [5]; default: 0; * set this bit to invert input signal. 1:invert. 0:not invert. */ @@ -325,7 +325,7 @@ typedef union { * output of GPIO[n] equals input of peripheral[s]. s=256: output of GPIO[n] equals * GPIO_OUT_REG[n]. */ - uint32_t func_sel:8; + uint32_t out_sel:8; /** out_inv_sel : R/W; bitpos: [8]; default: 0; * set this bit to invert output signal.1:invert.0:not invert. */ diff --git a/components/soc/esp32c3/register/soc/gpio_struct.h b/components/soc/esp32c3/register/soc/gpio_struct.h index 1fbb0779b4..25acf43cac 100644 --- a/components/soc/esp32c3/register/soc/gpio_struct.h +++ b/components/soc/esp32c3/register/soc/gpio_struct.h @@ -182,7 +182,7 @@ typedef volatile struct gpio_dev_s { uint32_t reserved_150; union { struct { - uint32_t func_sel: 5; + uint32_t in_sel: 5; uint32_t sig_in_inv: 1; uint32_t sig_in_sel: 1; uint32_t reserved7: 25; @@ -319,7 +319,7 @@ typedef volatile struct gpio_dev_s { uint32_t reserved_550; union { struct { - uint32_t func_sel: 8; + uint32_t out_sel: 8; uint32_t inv_sel: 1; uint32_t oen_sel: 1; uint32_t oen_inv_sel: 1; diff --git a/components/soc/esp32c5/register/soc/lp_gpio_struct.h b/components/soc/esp32c5/register/soc/lp_gpio_struct.h index deb66bb732..826a29ef18 100644 --- a/components/soc/esp32c5/register/soc/lp_gpio_struct.h +++ b/components/soc/esp32c5/register/soc/lp_gpio_struct.h @@ -33,7 +33,7 @@ typedef union { */ typedef union { struct { - /** out_w1ts : WT; bitpos: [7:0]; default: 0; + /** out_data_w1ts : WT; bitpos: [7:0]; default: 0; * Configures whether or not to enable the output register LP_IO_OUT_REG of GPIO0 ~ * GPIO7.\\ * @@ -42,7 +42,7 @@ typedef union { * will be set to 1. * - Recommended operation: use this register to set LP_IO_OUT_REG. */ - uint32_t out_w1ts:8; + uint32_t out_data_w1ts:8; uint32_t reserved_8:24; }; uint32_t val; @@ -53,7 +53,7 @@ typedef union { */ typedef union { struct { - /** out_w1tc : WT; bitpos: [7:0]; default: 0; + /** out_data_w1tc : WT; bitpos: [7:0]; default: 0; * Configures whether or not to clear the output register LP_IO_OUT_REG of GPIO0 ~ * GPIO7.\\ * @@ -62,7 +62,7 @@ typedef union { * will be cleared. * - Recommended operation: use this register to clear LP_IO_OUT_REG. */ - uint32_t out_w1tc:8; + uint32_t out_data_w1tc:8; uint32_t reserved_8:24; }; uint32_t val; @@ -90,7 +90,7 @@ typedef union { */ typedef union { struct { - /** enable_w1ts : WT; bitpos: [7:0]; default: 0; + /** out_enable_w1ts : WT; bitpos: [7:0]; default: 0; * Configures whether or not to set the output enable register LP_IO_ENABLE_REG of * GPIO0 ~ GPIO7.\\ * @@ -99,7 +99,7 @@ typedef union { * LP_IO_ENABLE_REG will be set to 1. * - Recommended operation: use this register to set LP_IO_ENABLE_REG. */ - uint32_t enable_w1ts:8; + uint32_t out_enable_w1ts:8; uint32_t reserved_8:24; }; uint32_t val; @@ -110,7 +110,7 @@ typedef union { */ typedef union { struct { - /** enable_w1tc : WT; bitpos: [7:0]; default: 0; + /** out_enable_w1tc : WT; bitpos: [7:0]; default: 0; * Configures whether or not to clear the output enable register LP_IO_ENABLE_REG of * GPIO0 ~ GPIO7.\\ * @@ -119,7 +119,7 @@ typedef union { * LP_IO_ENABLE_REG will be cleared. * - Recommended operation: use this register to clear LP_IO_ENABLE_REG. */ - uint32_t enable_w1tc:8; + uint32_t out_enable_w1tc:8; uint32_t reserved_8:24; }; uint32_t val; @@ -165,7 +165,7 @@ typedef union { */ typedef union { struct { - /** status_w1ts : WT; bitpos: [7:0]; default: 0; + /** status_intr_w1ts : WT; bitpos: [7:0]; default: 0; * Configures whether or not to set the interrupt status register LP_IO_STATUS_INT of * GPIO0 ~ GPIO7.\\ * @@ -174,7 +174,7 @@ typedef union { * LP_IO_STATUS_INT will be set to 1. * - Recommended operation: use this register to set LP_IO_STATUS_INT. */ - uint32_t status_w1ts:8; + uint32_t status_intr_w1ts:8; uint32_t reserved_8:24; }; uint32_t val; @@ -185,7 +185,7 @@ typedef union { */ typedef union { struct { - /** status_w1tc : WT; bitpos: [7:0]; default: 0; + /** status_intr_w1tc : WT; bitpos: [7:0]; default: 0; * Configures whether or not to clear the interrupt status register LP_IO_STATUS_INT * of GPIO0 ~ GPIO7. \\ * @@ -194,7 +194,7 @@ typedef union { * LP_IO_STATUS_INT will be cleared * - ecommended operation: use this register to clear LP_IO_STATUS_INT. */ - uint32_t status_w1tc:8; + uint32_t status_intr_w1tc:8; uint32_t reserved_8:24; }; uint32_t val; diff --git a/components/soc/esp32c6/register/soc/lp_io_struct.h b/components/soc/esp32c6/register/soc/lp_io_struct.h index cfaa3127cf..2305ebf6ad 100644 --- a/components/soc/esp32c6/register/soc/lp_io_struct.h +++ b/components/soc/esp32c6/register/soc/lp_io_struct.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -30,10 +30,10 @@ typedef union { */ typedef union { struct { - /** out_data_w1ts : WT; bitpos: [7:0]; default: 0; + /** out_w1ts : WT; bitpos: [7:0]; default: 0; * set one time output data */ - uint32_t out_data_w1ts:8; + uint32_t out_w1ts:8; uint32_t reserved_8:24; }; uint32_t val; @@ -44,10 +44,10 @@ typedef union { */ typedef union { struct { - /** out_data_w1tc : WT; bitpos: [7:0]; default: 0; + /** out_w1tc : WT; bitpos: [7:0]; default: 0; * clear one time output data */ - uint32_t out_data_w1tc:8; + uint32_t out_w1tc:8; uint32_t reserved_8:24; }; uint32_t val; @@ -114,10 +114,10 @@ typedef union { */ typedef union { struct { - /** status_w1ts : WT; bitpos: [7:0]; default: 0; + /** status_intr_w1ts : WT; bitpos: [7:0]; default: 0; * set one time output data */ - uint32_t status_w1ts:8; + uint32_t status_intr_w1ts:8; uint32_t reserved_8:24; }; uint32_t val; @@ -128,10 +128,10 @@ typedef union { */ typedef union { struct { - /** status_w1tc : WT; bitpos: [7:0]; default: 0; + /** status_intr_w1tc : WT; bitpos: [7:0]; default: 0; * clear one time output data */ - uint32_t status_w1tc:8; + uint32_t status_intr_w1tc:8; uint32_t reserved_8:24; }; uint32_t val; From 9ed617fb179b9b0a16a2a3af6c792dc7feabc808 Mon Sep 17 00:00:00 2001 From: Song Ruo Jing Date: Fri, 14 Feb 2025 15:43:45 +0800 Subject: [PATCH 3/5] fix(gpio): removed unnecessary step when routing input signal to a pin --- components/esp_driver_gpio/README.md | 2 +- components/esp_driver_parlio/src/parlio_rx.c | 3 --- components/esp_driver_parlio/src/parlio_tx.c | 1 - components/esp_driver_uart/src/uart.c | 2 -- components/esp_driver_uart/test_apps/uart/main/test_uart.c | 2 ++ 5 files changed, 3 insertions(+), 7 deletions(-) diff --git a/components/esp_driver_gpio/README.md b/components/esp_driver_gpio/README.md index 26fd08afb3..10dc64e16a 100644 --- a/components/esp_driver_gpio/README.md +++ b/components/esp_driver_gpio/README.md @@ -20,6 +20,6 @@ When a peripheral driver does de-initialization, to de-configure the pin as the If the signal is routed through IO MUX to the pin, then call `gpio_iomux_out` to select the IO MUX function index, and also call `gpio_iomux_in` to direct the signal to IO MUX. Input will be enabled for the IO internally. -If the signal is routed through GPIO Matrix to the pin, then first call `gpio_func_sel` to let the pin use `PIN_FUNC_GPIO` function, follow by calling `gpio_input_enable` and `esp_rom_gpio_connect_in_signal` to enable the input and connect the signal to the pin. +If the signal is routed through GPIO Matrix to the pin, then call `gpio_input_enable` and `esp_rom_gpio_connect_in_signal` to enable the input and connect the signal to the pin. When a peripheral driver does de-initialization, to de-configure the pin as the peripheral signal input, use `esp_rom_gpio_connect_in_signal` to connect the signal to CONST_ONE or CONST_ZERO, so that it is disconnected from the pin. It is not desired to call `gpio_input_disable`, because there might be other drivers still using this pin as an input. diff --git a/components/esp_driver_parlio/src/parlio_rx.c b/components/esp_driver_parlio/src/parlio_rx.c index caef2ad7a3..da67ddfca0 100644 --- a/components/esp_driver_parlio/src/parlio_rx.c +++ b/components/esp_driver_parlio/src/parlio_rx.c @@ -256,7 +256,6 @@ static esp_err_t s_parlio_rx_unit_set_gpio(parlio_rx_unit_handle_t rx_unit, cons if (config->clk_src == PARLIO_CLK_SRC_EXTERNAL) { ESP_RETURN_ON_FALSE(config->clk_in_gpio_num >= 0, ESP_ERR_INVALID_ARG, TAG, "clk_in_gpio_num must be set while the clock input from external"); /* Connect the clock in signal to the GPIO matrix if it is set */ - gpio_func_sel(config->clk_in_gpio_num, PIN_FUNC_GPIO); gpio_input_enable(config->clk_in_gpio_num); // deprecated, to be removed in in esp-idf v6.0 @@ -288,7 +287,6 @@ static esp_err_t s_parlio_rx_unit_set_gpio(parlio_rx_unit_handle_t rx_unit, cons /* Initialize the valid GPIO as input */ if (config->valid_gpio_num >= 0) { - gpio_func_sel(config->valid_gpio_num, PIN_FUNC_GPIO); gpio_input_enable(config->valid_gpio_num); // deprecated, to be removed in in esp-idf v6.0 @@ -303,7 +301,6 @@ static esp_err_t s_parlio_rx_unit_set_gpio(parlio_rx_unit_handle_t rx_unit, cons for (int i = 0; i < config->data_width; i++) { /* Loop the data_gpio_nums to connect data and valid signals via GPIO matrix */ if (config->data_gpio_nums[i] >= 0) { - gpio_func_sel(config->data_gpio_nums[i], PIN_FUNC_GPIO); gpio_input_enable(config->data_gpio_nums[i]); // deprecated, to be removed in in esp-idf v6.0 diff --git a/components/esp_driver_parlio/src/parlio_tx.c b/components/esp_driver_parlio/src/parlio_tx.c index ec463631dd..f16c4f0edc 100644 --- a/components/esp_driver_parlio/src/parlio_tx.c +++ b/components/esp_driver_parlio/src/parlio_tx.c @@ -182,7 +182,6 @@ static esp_err_t parlio_tx_unit_configure_gpio(parlio_tx_unit_t *tx_unit, const parlio_periph_signals.groups[group_id].tx_units[unit_id].clk_out_sig, false, false); } if (config->clk_in_gpio_num >= 0) { - gpio_func_sel(config->clk_in_gpio_num, PIN_FUNC_GPIO); gpio_input_enable(config->clk_in_gpio_num); // deprecated, to be removed in in esp-idf v6.0 diff --git a/components/esp_driver_uart/src/uart.c b/components/esp_driver_uart/src/uart.c index 5cd2060598..166fb502a5 100644 --- a/components/esp_driver_uart/src/uart.c +++ b/components/esp_driver_uart/src/uart.c @@ -771,7 +771,6 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r if (rx_io_num >= 0 && (tx_rx_same_io || !uart_try_set_iomux_pin(uart_num, rx_io_num, SOC_UART_RX_PIN_IDX))) { io_reserve_mask &= ~BIT64(rx_io_num); // input IO via GPIO matrix does not need to be reserved if (uart_num < SOC_UART_HP_NUM) { - gpio_func_sel(rx_io_num, PIN_FUNC_GPIO); gpio_input_enable(rx_io_num); esp_rom_gpio_connect_in_signal(rx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RX_PIN_IDX), 0); } @@ -806,7 +805,6 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r if (cts_io_num >= 0 && !uart_try_set_iomux_pin(uart_num, cts_io_num, SOC_UART_CTS_PIN_IDX)) { io_reserve_mask &= ~BIT64(cts_io_num); // input IO via GPIO matrix does not need to be reserved if (uart_num < SOC_UART_HP_NUM) { - gpio_func_sel(cts_io_num, PIN_FUNC_GPIO); gpio_pullup_en(cts_io_num); gpio_input_enable(cts_io_num); esp_rom_gpio_connect_in_signal(cts_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_CTS_PIN_IDX), 0); diff --git a/components/esp_driver_uart/test_apps/uart/main/test_uart.c b/components/esp_driver_uart/test_apps/uart/main/test_uart.c index 2add03dbf2..78671ae7dd 100644 --- a/components/esp_driver_uart/test_apps/uart/main/test_uart.c +++ b/components/esp_driver_uart/test_apps/uart/main/test_uart.c @@ -10,6 +10,7 @@ #include "driver/uart.h" #include "esp_log.h" #include "esp_rom_gpio.h" +#include "esp_private/gpio.h" #if SOC_LP_GPIO_MATRIX_SUPPORTED #include "driver/lp_io.h" #include "driver/rtc_io.h" @@ -463,6 +464,7 @@ TEST_CASE("uart int state restored after flush", "[uart]") /* Make sure UART's TX signal is connected to RX pin * This creates a loop that lets us receive anything we send on the UART */ if (uart_num < SOC_UART_HP_NUM) { + gpio_func_sel(uart_rx, PIN_FUNC_GPIO); esp_rom_gpio_connect_out_signal(uart_rx, uart_tx_signal, false, false); #if SOC_UART_LP_NUM > 0 } else { From 8f231272f6d45f5ecba15af761b16516602e9077 Mon Sep 17 00:00:00 2001 From: Song Ruo Jing Date: Fri, 14 Mar 2025 20:38:05 +0800 Subject: [PATCH 4/5] fix(gpio): fix IO output enable control oen_sel and oen_inv_sel fields from func_out_sel_cfg register --- components/esp_driver_gpio/src/gpio.c | 20 ++++++++++---- components/hal/esp32/include/hal/gpio_ll.h | 26 +++++++++++++++---- components/hal/esp32c2/include/hal/gpio_ll.h | 26 +++++++++++++++---- components/hal/esp32c3/include/hal/gpio_ll.h | 26 +++++++++++++++---- components/hal/esp32c5/include/hal/gpio_ll.h | 26 +++++++++++++++---- components/hal/esp32c6/include/hal/gpio_ll.h | 26 +++++++++++++++---- components/hal/esp32c61/include/hal/gpio_ll.h | 26 +++++++++++++++---- components/hal/esp32h2/include/hal/gpio_ll.h | 26 +++++++++++++++---- components/hal/esp32p4/include/hal/gpio_ll.h | 26 +++++++++++++++---- components/hal/esp32s2/include/hal/gpio_ll.h | 26 +++++++++++++++---- components/hal/esp32s3/include/hal/gpio_ll.h | 26 +++++++++++++++---- components/hal/include/hal/gpio_hal.h | 21 +++++++++++---- 12 files changed, 241 insertions(+), 60 deletions(-) diff --git a/components/esp_driver_gpio/src/gpio.c b/components/esp_driver_gpio/src/gpio.c index be6a1ecc35..5b17568bce 100644 --- a/components/esp_driver_gpio/src/gpio.c +++ b/components/esp_driver_gpio/src/gpio.c @@ -207,7 +207,7 @@ esp_err_t gpio_output_disable(gpio_num_t gpio_num) { GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); gpio_hal_output_disable(gpio_context.gpio_hal, gpio_num); - gpio_hal_matrix_out_default(gpio_context.gpio_hal, gpio_num); // Ensure no other output signal is routed via GPIO matrix to this pin + gpio_hal_set_output_enable_ctrl(gpio_context.gpio_hal, gpio_num, false, false); // so that output disable could take effect return ESP_OK; } @@ -800,7 +800,8 @@ void gpio_iomux_in(uint32_t gpio, uint32_t signal_idx) void gpio_iomux_out(uint8_t gpio_num, int func, bool out_en_inv) { - gpio_hal_iomux_out(gpio_context.gpio_hal, gpio_num, func, (uint32_t)out_en_inv); + (void)out_en_inv; // out_en_inv only takes effect when signal goes through gpio matrix to the IO + gpio_hal_iomux_out(gpio_context.gpio_hal, gpio_num, func); } static esp_err_t gpio_sleep_pullup_en(gpio_num_t gpio_num) @@ -1031,12 +1032,14 @@ esp_err_t gpio_dump_io_configuration(FILE *out_stream, uint64_t io_bit_mask) bool pd = 0; bool ie = 0; bool oe = 0; + bool oe_ctrl_by_periph = 0; + bool oe_inv = 0; bool od = 0; bool slp_sel = 0; uint32_t drv = 0; uint32_t fun_sel = 0; uint32_t sig_out = 0; - gpio_hal_get_io_config(gpio_context.gpio_hal, gpio_num, &pu, &pd, &ie, &oe, &od, &drv, &fun_sel, &sig_out, &slp_sel); + gpio_hal_get_io_config(gpio_context.gpio_hal, gpio_num, &pu, &pd, &ie, &oe, &oe_ctrl_by_periph, &oe_inv, &od, &drv, &fun_sel, &sig_out, &slp_sel); #if !SOC_GPIO_SUPPORT_RTC_INDEPENDENT && SOC_RTCIO_PIN_COUNT > 0 if (rtc_gpio_is_valid_gpio(gpio_num)) { int rtcio_num = rtc_io_number_get(gpio_num); @@ -1046,11 +1049,18 @@ esp_err_t gpio_dump_io_configuration(FILE *out_stream, uint64_t io_bit_mask) } #endif + // When the IO is used as a simple GPIO output, oe signal can only be controlled by the oe register + // When the IO is not used as a simple GPIO output, oe signal could be controlled by the peripheral + const char *oe_str = oe ? "1" : "0"; + if (sig_out != SIG_GPIO_OUT_IDX && oe_ctrl_by_periph) { + oe_str = "[periph_sig_ctrl]"; + } + fprintf(out_stream, "IO[%"PRIu32"]%s -\n", gpio_num, esp_gpio_is_reserved(BIT64(gpio_num)) ? " **RESERVED**" : ""); fprintf(out_stream, " Pullup: %d, Pulldown: %d, DriveCap: %"PRIu32"\n", pu, pd, drv); - fprintf(out_stream, " InputEn: %d, OutputEn: %d, OpenDrain: %d\n", ie, oe, od); + fprintf(out_stream, " InputEn: %d, OutputEn: %s%s, OpenDrain: %d\n", ie, oe_str, ((fun_sel == PIN_FUNC_GPIO) && (oe_inv)) ? " (inversed)" : "", od); fprintf(out_stream, " FuncSel: %"PRIu32" (%s)\n", fun_sel, (fun_sel == PIN_FUNC_GPIO) ? "GPIO" : "IOMUX"); - if (oe && fun_sel == PIN_FUNC_GPIO) { + if (fun_sel == PIN_FUNC_GPIO) { fprintf(out_stream, " GPIO Matrix SigOut ID: %"PRIu32"%s\n", sig_out, (sig_out == SIG_GPIO_OUT_IDX) ? " (simple GPIO output)" : ""); } if (ie && fun_sel == PIN_FUNC_GPIO) { diff --git a/components/hal/esp32/include/hal/gpio_ll.h b/components/hal/esp32/include/hal/gpio_ll.h index 128334c51e..d86949819d 100644 --- a/components/hal/esp32/include/hal/gpio_ll.h +++ b/components/hal/esp32/include/hal/gpio_ll.h @@ -51,6 +51,8 @@ extern const uint8_t GPIO_PIN_MUX_REG_OFFSET[SOC_GPIO_PIN_COUNT]; * @param pd Pull-down enabled or not * @param ie Input enabled or not * @param oe Output enabled or not + * @param oe_ctrl_by_periph Output enable signal from peripheral or not + * @param oe_inv Output enable signal is inversed or not * @param od Open-drain enabled or not * @param drv Drive strength value * @param fun_sel IOMUX function selection value @@ -58,7 +60,7 @@ extern const uint8_t GPIO_PIN_MUX_REG_OFFSET[SOC_GPIO_PIN_COUNT]; * @param slp_sel Pin sleep mode enabled or not */ static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, - bool *pu, bool *pd, bool *ie, bool *oe, bool *od, uint32_t *drv, + bool *pu, bool *pd, bool *ie, bool *oe, bool *oe_ctrl_by_periph, bool *oe_inv, bool *od, uint32_t *drv, uint32_t *fun_sel, uint32_t *sig_out, bool *slp_sel) { uint32_t bit_shift = (gpio_num < 32) ? gpio_num : (gpio_num - 32); @@ -68,6 +70,8 @@ static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, *pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S; *ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S; *oe = (((gpio_num < 32) ? hw->enable : hw->enable1.val) & bit_mask) >> bit_shift; + *oe_ctrl_by_periph = !(hw->func_out_sel_cfg[gpio_num].oen_sel); + *oe_inv = hw->func_out_sel_cfg[gpio_num].oen_inv_sel; *od = hw->pin[gpio_num].pad_driver; *drv = (iomux_reg_val & FUN_DRV_M) >> FUN_DRV_S; *fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S; @@ -706,6 +710,20 @@ static inline void gpio_ll_iomux_func_sel(uint32_t pin_name, uint32_t func) PIN_FUNC_SELECT(pin_name, func); } +/** + * @brief Configure the source of output enable signal for the GPIO pin. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number of the pad. + * @param ctrl_by_periph True if use output enable signal from peripheral, false if force the output enable signal to be sourced from bit n of GPIO_ENABLE_REG + * @param oen_inv True if the output enable needs to be inverted, otherwise False. + */ +static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_num, bool ctrl_by_periph, bool oen_inv) +{ + hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; // control valid only when using gpio matrix to route signal to the IO + hw->func_out_sel_cfg[gpio_num].oen_sel = !ctrl_by_periph; +} + /** * @brief Control the pin in the IOMUX * @@ -726,12 +744,10 @@ static inline void gpio_ll_set_pin_ctrl(uint32_t val, uint32_t bmap, uint32_t sh * @param gpio_num gpio_num GPIO number of the pad. * @param func The function number of the peripheral pin to output pin. * One of the ``FUNC_X_*`` of specified pin (X) in ``soc/io_mux_reg.h``. - * @param oen_inv True if the output enable needs to be inverted, otherwise False. */ -static inline void gpio_ll_iomux_out(gpio_dev_t *hw, uint8_t gpio_num, int func, uint32_t oen_inv) +static inline void gpio_ll_iomux_out(gpio_dev_t *hw, uint8_t gpio_num, int func) { - hw->func_out_sel_cfg[gpio_num].oen_sel = 0; - hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; + gpio_ll_set_output_enable_ctrl(hw, gpio_num, true, false); gpio_ll_func_sel(hw, gpio_num, func); } diff --git a/components/hal/esp32c2/include/hal/gpio_ll.h b/components/hal/esp32c2/include/hal/gpio_ll.h index 182d9e71ec..2412a39c00 100644 --- a/components/hal/esp32c2/include/hal/gpio_ll.h +++ b/components/hal/esp32c2/include/hal/gpio_ll.h @@ -42,6 +42,8 @@ extern "C" { * @param pd Pull-down enabled or not * @param ie Input enabled or not * @param oe Output enabled or not + * @param oe_ctrl_by_periph Output enable signal from peripheral or not + * @param oe_inv Output enable signal is inversed or not * @param od Open-drain enabled or not * @param drv Drive strength value * @param fun_sel IOMUX function selection value @@ -49,7 +51,7 @@ extern "C" { * @param slp_sel Pin sleep mode enabled or not */ static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, - bool *pu, bool *pd, bool *ie, bool *oe, bool *od, uint32_t *drv, + bool *pu, bool *pd, bool *ie, bool *oe, bool *oe_ctrl_by_periph, bool *oe_inv, bool *od, uint32_t *drv, uint32_t *fun_sel, uint32_t *sig_out, bool *slp_sel) { uint32_t bit_mask = 1 << gpio_num; @@ -58,6 +60,8 @@ static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, *pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S; *ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S; *oe = (hw->enable.val & bit_mask) >> gpio_num; + *oe_ctrl_by_periph = !(hw->func_out_sel_cfg[gpio_num].oen_sel); + *oe_inv = hw->func_out_sel_cfg[gpio_num].oen_inv_sel; *od = hw->pin[gpio_num].pad_driver; *drv = (iomux_reg_val & FUN_DRV_M) >> FUN_DRV_S; *fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S; @@ -508,6 +512,20 @@ static inline void gpio_ll_iomux_func_sel(uint32_t pin_name, uint32_t func) PIN_FUNC_SELECT(pin_name, func); } +/** + * @brief Configure the source of output enable signal for the GPIO pin. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number of the pad. + * @param ctrl_by_periph True if use output enable signal from peripheral, false if force the output enable signal to be sourced from bit n of GPIO_ENABLE_REG + * @param oen_inv True if the output enable needs to be inverted, otherwise False. + */ +static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_num, bool ctrl_by_periph, bool oen_inv) +{ + hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; // control valid only when using gpio matrix to route signal to the IO + hw->func_out_sel_cfg[gpio_num].oen_sel = !ctrl_by_periph; +} + /** * @brief Control the pin in the IOMUX * @@ -528,12 +546,10 @@ static inline void gpio_ll_set_pin_ctrl(uint32_t val, uint32_t bmap, uint32_t sh * @param gpio_num gpio_num GPIO number of the pad. * @param func The function number of the peripheral pin to output pin. * One of the ``FUNC_X_*`` of specified pin (X) in ``soc/io_mux_reg.h``. - * @param oen_inv True if the output enable needs to be inverted, otherwise False. */ -static inline void gpio_ll_iomux_out(gpio_dev_t *hw, uint8_t gpio_num, int func, uint32_t oen_inv) +static inline void gpio_ll_iomux_out(gpio_dev_t *hw, uint8_t gpio_num, int func) { - hw->func_out_sel_cfg[gpio_num].oen_sel = 0; - hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; + gpio_ll_set_output_enable_ctrl(hw, gpio_num, true, false); gpio_ll_func_sel(hw, gpio_num, func); } diff --git a/components/hal/esp32c3/include/hal/gpio_ll.h b/components/hal/esp32c3/include/hal/gpio_ll.h index 690830a7e3..dde10281de 100644 --- a/components/hal/esp32c3/include/hal/gpio_ll.h +++ b/components/hal/esp32c3/include/hal/gpio_ll.h @@ -502,6 +502,20 @@ static inline void gpio_ll_iomux_func_sel(uint32_t pin_name, uint32_t func) PIN_FUNC_SELECT(pin_name, func); } +/** + * @brief Configure the source of output enable signal for the GPIO pin. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number of the pad. + * @param ctrl_by_periph True if use output enable signal from peripheral, false if force the output enable signal to be sourced from bit n of GPIO_ENABLE_REG + * @param oen_inv True if the output enable needs to be inverted, otherwise False. + */ +static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_num, bool ctrl_by_periph, bool oen_inv) +{ + hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; // control valid only when using gpio matrix to route signal to the IO + hw->func_out_sel_cfg[gpio_num].oen_sel = !ctrl_by_periph; +} + /** * @brief Control the pin in the IOMUX * @@ -522,12 +536,10 @@ static inline void gpio_ll_set_pin_ctrl(uint32_t val, uint32_t bmap, uint32_t sh * @param gpio_num gpio_num GPIO number of the pad. * @param func The function number of the peripheral pin to output pin. * One of the ``FUNC_X_*`` of specified pin (X) in ``soc/io_mux_reg.h``. - * @param oen_inv True if the output enable needs to be inverted, otherwise False. */ -static inline void gpio_ll_iomux_out(gpio_dev_t *hw, uint8_t gpio_num, int func, uint32_t oen_inv) +static inline void gpio_ll_iomux_out(gpio_dev_t *hw, uint8_t gpio_num, int func) { - hw->func_out_sel_cfg[gpio_num].oen_sel = 0; - hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; + gpio_ll_set_output_enable_ctrl(hw, gpio_num, true, false); gpio_ll_func_sel(hw, gpio_num, func); } @@ -748,6 +760,8 @@ static inline bool gpio_ll_deepsleep_wakeup_is_enabled(gpio_dev_t *hw, uint32_t * @param pd Pull-down enabled or not * @param ie Input enabled or not * @param oe Output enabled or not + * @param oe_ctrl_by_periph Output enable signal from peripheral or not + * @param oe_inv Output enable signal is inversed or not * @param od Open-drain enabled or not * @param drv Drive strength value * @param fun_sel IOMUX function selection value @@ -755,7 +769,7 @@ static inline bool gpio_ll_deepsleep_wakeup_is_enabled(gpio_dev_t *hw, uint32_t * @param slp_sel Pin sleep mode enabled or not */ static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, - bool *pu, bool *pd, bool *ie, bool *oe, bool *od, uint32_t *drv, + bool *pu, bool *pd, bool *ie, bool *oe, bool *oe_ctrl_by_periph, bool *oe_inv, bool *od, uint32_t *drv, uint32_t *fun_sel, uint32_t *sig_out, bool *slp_sel) { uint32_t bit_mask = 1 << gpio_num; @@ -764,6 +778,8 @@ static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, *pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S; *ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S; *oe = (hw->enable.val & bit_mask) >> gpio_num; + *oe_ctrl_by_periph = !(hw->func_out_sel_cfg[gpio_num].oen_sel); + *oe_inv = hw->func_out_sel_cfg[gpio_num].oen_inv_sel; *od = hw->pin[gpio_num].pad_driver; gpio_ll_get_drive_capability(hw, gpio_num, (gpio_drive_cap_t *)drv); // specific workaround in the LL *fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S; diff --git a/components/hal/esp32c5/include/hal/gpio_ll.h b/components/hal/esp32c5/include/hal/gpio_ll.h index 99060c83c2..80f92f4d97 100644 --- a/components/hal/esp32c5/include/hal/gpio_ll.h +++ b/components/hal/esp32c5/include/hal/gpio_ll.h @@ -46,6 +46,8 @@ extern "C" { * @param pd Pull-down enabled or not * @param ie Input enabled or not * @param oe Output enabled or not + * @param oe_ctrl_by_periph Output enable signal from peripheral or not + * @param oe_inv Output enable signal is inversed or not * @param od Open-drain enabled or not * @param drv Drive strength value * @param fun_sel IOMUX function selection value @@ -53,13 +55,15 @@ extern "C" { * @param slp_sel Pin sleep mode enabled or not */ static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, - bool *pu, bool *pd, bool *ie, bool *oe, bool *od, uint32_t *drv, + bool *pu, bool *pd, bool *ie, bool *oe, bool *oe_ctrl_by_periph, bool *oe_inv, bool *od, uint32_t *drv, uint32_t *fun_sel, uint32_t *sig_out, bool *slp_sel) { *pu = IO_MUX.gpio[gpio_num].fun_wpu; *pd = IO_MUX.gpio[gpio_num].fun_wpd; *ie = IO_MUX.gpio[gpio_num].fun_ie; *oe = (hw->enable.val & (1 << gpio_num)) >> gpio_num; + *oe_ctrl_by_periph = !(hw->func_out_sel_cfg[gpio_num].oen_sel); + *oe_inv = hw->func_out_sel_cfg[gpio_num].oen_inv_sel; *od = hw->pin[gpio_num].pad_driver; *drv = IO_MUX.gpio[gpio_num].fun_drv; *fun_sel = IO_MUX.gpio[gpio_num].mcu_sel; @@ -484,6 +488,20 @@ static inline void gpio_ll_iomux_in(gpio_dev_t *hw, uint32_t gpio, uint32_t sign IO_MUX.gpio[gpio].fun_ie = 1; } +/** + * @brief Configure the source of output enable signal for the GPIO pin. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number of the pad. + * @param ctrl_by_periph True if use output enable signal from peripheral, false if force the output enable signal to be sourced from bit n of GPIO_ENABLE_REG + * @param oen_inv True if the output enable needs to be inverted, otherwise False. + */ +static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_num, bool ctrl_by_periph, bool oen_inv) +{ + hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; // control valid only when using gpio matrix to route signal to the IO + hw->func_out_sel_cfg[gpio_num].oen_sel = !ctrl_by_periph; +} + /** * @brief Select a function for the pin in the IOMUX * @@ -523,12 +541,10 @@ static inline void gpio_ll_func_sel(gpio_dev_t *hw, uint8_t gpio_num, uint32_t f * @param gpio_num gpio_num GPIO number of the pad. * @param func The function number of the peripheral pin to output pin. * One of the ``FUNC_X_*`` of specified pin (X) in ``soc/io_mux_reg.h``. - * @param oen_inv True if the output enable needs to be inverted, otherwise False. */ -static inline void gpio_ll_iomux_out(gpio_dev_t *hw, uint8_t gpio_num, int func, uint32_t oen_inv) +static inline void gpio_ll_iomux_out(gpio_dev_t *hw, uint8_t gpio_num, int func) { - hw->func_out_sel_cfg[gpio_num].oen_sel = 0; - hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; + gpio_ll_set_output_enable_ctrl(hw, gpio_num, true, false); gpio_ll_func_sel(hw, gpio_num, func); } diff --git a/components/hal/esp32c6/include/hal/gpio_ll.h b/components/hal/esp32c6/include/hal/gpio_ll.h index 3355909d69..d19bbd566b 100644 --- a/components/hal/esp32c6/include/hal/gpio_ll.h +++ b/components/hal/esp32c6/include/hal/gpio_ll.h @@ -47,6 +47,8 @@ extern "C" { * @param pd Pull-down enabled or not * @param ie Input enabled or not * @param oe Output enabled or not + * @param oe_ctrl_by_periph Output enable signal from peripheral or not + * @param oe_inv Output enable signal is inversed or not * @param od Open-drain enabled or not * @param drv Drive strength value * @param fun_sel IOMUX function selection value @@ -54,7 +56,7 @@ extern "C" { * @param slp_sel Pin sleep mode enabled or not */ static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, - bool *pu, bool *pd, bool *ie, bool *oe, bool *od, uint32_t *drv, + bool *pu, bool *pd, bool *ie, bool *oe, bool *oe_ctrl_by_periph, bool *oe_inv, bool *od, uint32_t *drv, uint32_t *fun_sel, uint32_t *sig_out, bool *slp_sel) { uint32_t bit_mask = 1 << gpio_num; @@ -63,6 +65,8 @@ static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, *pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S; *ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S; *oe = (hw->enable.val & bit_mask) >> gpio_num; + *oe_ctrl_by_periph = !(hw->func_out_sel_cfg[gpio_num].oen_sel); + *oe_inv = hw->func_out_sel_cfg[gpio_num].oen_inv_sel; *od = hw->pin[gpio_num].pad_driver; *drv = (iomux_reg_val & FUN_DRV_M) >> FUN_DRV_S; *fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S; @@ -470,6 +474,20 @@ static inline void gpio_ll_iomux_func_sel(uint32_t pin_name, uint32_t func) PIN_FUNC_SELECT(pin_name, func); } +/** + * @brief Configure the source of output enable signal for the GPIO pin. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number of the pad. + * @param ctrl_by_periph True if use output enable signal from peripheral, false if force the output enable signal to be sourced from bit n of GPIO_ENABLE_REG + * @param oen_inv True if the output enable needs to be inverted, otherwise False. + */ +static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_num, bool ctrl_by_periph, bool oen_inv) +{ + hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; // control valid only when using gpio matrix to route signal to the IO + hw->func_out_sel_cfg[gpio_num].oen_sel = !ctrl_by_periph; +} + /** * @brief Control the pin in the IOMUX * @@ -507,12 +525,10 @@ static inline void gpio_ll_func_sel(gpio_dev_t *hw, uint8_t gpio_num, uint32_t f * @param gpio_num gpio_num GPIO number of the pad. * @param func The function number of the peripheral pin to output pin. * One of the ``FUNC_X_*`` of specified pin (X) in ``soc/io_mux_reg.h``. - * @param oen_inv True if the output enable needs to be inverted, otherwise False. */ -static inline void gpio_ll_iomux_out(gpio_dev_t *hw, uint8_t gpio_num, int func, uint32_t oen_inv) +static inline void gpio_ll_iomux_out(gpio_dev_t *hw, uint8_t gpio_num, int func) { - hw->func_out_sel_cfg[gpio_num].oen_sel = 0; - hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; + gpio_ll_set_output_enable_ctrl(hw, gpio_num, true, false); gpio_ll_func_sel(hw, gpio_num, func); } diff --git a/components/hal/esp32c61/include/hal/gpio_ll.h b/components/hal/esp32c61/include/hal/gpio_ll.h index eddc93672f..ab73eebd96 100644 --- a/components/hal/esp32c61/include/hal/gpio_ll.h +++ b/components/hal/esp32c61/include/hal/gpio_ll.h @@ -47,6 +47,8 @@ extern "C" { * @param pd Pull-down enabled or not * @param ie Input enabled or not * @param oe Output enabled or not + * @param oe_ctrl_by_periph Output enable signal from peripheral or not + * @param oe_inv Output enable signal is inversed or not * @param od Open-drain enabled or not * @param drv Drive strength value * @param fun_sel IOMUX function selection value @@ -54,13 +56,15 @@ extern "C" { * @param slp_sel Pin sleep mode enabled or not */ static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, - bool *pu, bool *pd, bool *ie, bool *oe, bool *od, uint32_t *drv, + bool *pu, bool *pd, bool *ie, bool *oe, bool *oe_ctrl_by_periph, bool *oe_inv, bool *od, uint32_t *drv, uint32_t *fun_sel, uint32_t *sig_out, bool *slp_sel) { *pu = IO_MUX.gpion[gpio_num].gpion_fun_wpu; *pd = IO_MUX.gpion[gpio_num].gpion_fun_wpd; *ie = IO_MUX.gpion[gpio_num].gpion_fun_ie; *oe = (hw->enable.val & (1 << gpio_num)) >> gpio_num; + *oe_ctrl_by_periph = !(hw->funcn_out_sel_cfg[gpio_num].funcn_oe_sel); + *oe_inv = hw->funcn_out_sel_cfg[gpio_num].funcn_oe_inv_sel; *od = hw->pinn[gpio_num].pinn_pad_driver; *drv = IO_MUX.gpion[gpio_num].gpion_fun_drv; *fun_sel = IO_MUX.gpion[gpio_num].gpion_mcu_sel; @@ -516,6 +520,20 @@ static inline void gpio_ll_func_sel(gpio_dev_t *hw, uint8_t gpio_num, uint32_t f IO_MUX.gpion[gpio_num].gpion_mcu_sel = func; } +/** + * @brief Configure the source of output enable signal for the GPIO pin. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number of the pad. + * @param ctrl_by_periph True if use output enable signal from peripheral, false if force the output enable signal to be sourced from bit n of GPIO_ENABLE_REG + * @param oen_inv True if the output enable needs to be inverted, otherwise False. + */ +static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_num, bool ctrl_by_periph, bool oen_inv) +{ + hw->funcn_out_sel_cfg[gpio_num].funcn_oe_inv_sel = oen_inv; // control valid only when using gpio matrix to route signal to the IO + hw->funcn_out_sel_cfg[gpio_num].funcn_oe_sel = !ctrl_by_periph; +} + /** * @brief Set peripheral output to an GPIO pad through the IO_MUX. * @@ -523,12 +541,10 @@ static inline void gpio_ll_func_sel(gpio_dev_t *hw, uint8_t gpio_num, uint32_t f * @param gpio_num gpio_num GPIO number of the pad. * @param func The function number of the peripheral pin to output pin. * One of the ``FUNC_X_*`` of specified pin (X) in ``soc/io_mux_reg.h``. - * @param oen_inv True if the output enable needs to be inverted, otherwise False. */ -static inline void gpio_ll_iomux_out(gpio_dev_t *hw, uint8_t gpio_num, int func, uint32_t oen_inv) +static inline void gpio_ll_iomux_out(gpio_dev_t *hw, uint8_t gpio_num, int func) { - hw->funcn_out_sel_cfg[gpio_num].funcn_oe_sel = 0; - hw->funcn_out_sel_cfg[gpio_num].funcn_oe_inv_sel = oen_inv; + gpio_ll_set_output_enable_ctrl(hw, gpio_num, true, false); gpio_ll_func_sel(hw, gpio_num, func); } diff --git a/components/hal/esp32h2/include/hal/gpio_ll.h b/components/hal/esp32h2/include/hal/gpio_ll.h index 7d1bc5daad..5ac5faa53e 100644 --- a/components/hal/esp32h2/include/hal/gpio_ll.h +++ b/components/hal/esp32h2/include/hal/gpio_ll.h @@ -47,6 +47,8 @@ extern "C" { * @param pd Pull-down enabled or not * @param ie Input enabled or not * @param oe Output enabled or not + * @param oe_ctrl_by_periph Output enable signal from peripheral or not + * @param oe_inv Output enable signal is inversed or not * @param od Open-drain enabled or not * @param drv Drive strength value * @param fun_sel IOMUX function selection value @@ -54,7 +56,7 @@ extern "C" { * @param slp_sel Pin sleep mode enabled or not */ static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, - bool *pu, bool *pd, bool *ie, bool *oe, bool *od, uint32_t *drv, + bool *pu, bool *pd, bool *ie, bool *oe, bool *oe_ctrl_by_periph, bool *oe_inv, bool *od, uint32_t *drv, uint32_t *fun_sel, uint32_t *sig_out, bool *slp_sel) { uint32_t bit_mask = 1 << gpio_num; @@ -63,6 +65,8 @@ static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, *pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S; *ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S; *oe = (hw->enable.val & bit_mask) >> gpio_num; + *oe_ctrl_by_periph = !(hw->func_out_sel_cfg[gpio_num].oen_sel); + *oe_inv = hw->func_out_sel_cfg[gpio_num].oen_inv_sel; *od = hw->pin[gpio_num].pad_driver; *drv = (iomux_reg_val & FUN_DRV_M) >> FUN_DRV_S; *fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S; @@ -533,6 +537,20 @@ static inline void gpio_ll_func_sel(gpio_dev_t *hw, uint8_t gpio_num, uint32_t f PIN_FUNC_SELECT(IO_MUX_GPIO0_REG + (gpio_num * 4), func); } +/** + * @brief Configure the source of output enable signal for the GPIO pin. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number of the pad. + * @param ctrl_by_periph True if use output enable signal from peripheral, false if force the output enable signal to be sourced from bit n of GPIO_ENABLE_REG + * @param oen_inv True if the output enable needs to be inverted, otherwise False. + */ +static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_num, bool ctrl_by_periph, bool oen_inv) +{ + hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; // control valid only when using gpio matrix to route signal to the IO + hw->func_out_sel_cfg[gpio_num].oen_sel = !ctrl_by_periph; +} + /** * @brief Set peripheral output to an GPIO pad through the IOMUX. * @@ -540,12 +558,10 @@ static inline void gpio_ll_func_sel(gpio_dev_t *hw, uint8_t gpio_num, uint32_t f * @param gpio_num gpio_num GPIO number of the pad. * @param func The function number of the peripheral pin to output pin. * One of the ``FUNC_X_*`` of specified pin (X) in ``soc/io_mux_reg.h``. - * @param oen_inv True if the output enable needs to be inverted, otherwise False. */ -static inline void gpio_ll_iomux_out(gpio_dev_t *hw, uint8_t gpio_num, int func, uint32_t oen_inv) +static inline void gpio_ll_iomux_out(gpio_dev_t *hw, uint8_t gpio_num, int func) { - hw->func_out_sel_cfg[gpio_num].oen_sel = 0; - hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; + gpio_ll_set_output_enable_ctrl(hw, gpio_num, true, false); gpio_ll_func_sel(hw, gpio_num, func); } diff --git a/components/hal/esp32p4/include/hal/gpio_ll.h b/components/hal/esp32p4/include/hal/gpio_ll.h index be812c27b3..cc3a44cf35 100644 --- a/components/hal/esp32p4/include/hal/gpio_ll.h +++ b/components/hal/esp32p4/include/hal/gpio_ll.h @@ -53,6 +53,8 @@ extern "C" { * @param pd Pull-down enabled or not * @param ie Input enabled or not * @param oe Output enabled or not + * @param oe_ctrl_by_periph Output enable signal from peripheral or not + * @param oe_inv Output enable signal is inversed or not * @param od Open-drain enabled or not * @param drv Drive strength value * @param fun_sel IOMUX function selection value @@ -60,7 +62,7 @@ extern "C" { * @param slp_sel Pin sleep mode enabled or not */ static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, - bool *pu, bool *pd, bool *ie, bool *oe, bool *od, uint32_t *drv, + bool *pu, bool *pd, bool *ie, bool *oe, bool *oe_ctrl_by_periph, bool *oe_inv, bool *od, uint32_t *drv, uint32_t *fun_sel, uint32_t *sig_out, bool *slp_sel) { uint32_t bit_shift = (gpio_num < 32) ? gpio_num : (gpio_num - 32); @@ -69,6 +71,8 @@ static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, *pd = IO_MUX.gpio[gpio_num].fun_wpd; *ie = IO_MUX.gpio[gpio_num].fun_ie; *oe = (((gpio_num < 32) ? hw->enable.val : hw->enable1.val) & bit_mask) >> bit_shift; + *oe_ctrl_by_periph = !(hw->func_out_sel_cfg[gpio_num].oen_sel); + *oe_inv = hw->func_out_sel_cfg[gpio_num].oen_inv_sel; *od = hw->pin[gpio_num].pad_driver; *drv = IO_MUX.gpio[gpio_num].fun_drv; *fun_sel = IO_MUX.gpio[gpio_num].mcu_sel; @@ -627,6 +631,20 @@ static inline void gpio_ll_func_sel(gpio_dev_t *hw, uint8_t gpio_num, uint32_t f IO_MUX.gpio[gpio_num].mcu_sel = func; } +/** + * @brief Configure the source of output enable signal for the GPIO pin. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number of the pad. + * @param ctrl_by_periph True if use output enable signal from peripheral, false if force the output enable signal to be sourced from bit n of GPIO_ENABLE_REG + * @param oen_inv True if the output enable needs to be inverted, otherwise False. + */ +static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_num, bool ctrl_by_periph, bool oen_inv) +{ + hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; // control valid only when using gpio matrix to route signal to the IO + hw->func_out_sel_cfg[gpio_num].oen_sel = !ctrl_by_periph; +} + /** * @brief Set peripheral output to an GPIO pad through the IO_MUX. * @@ -634,12 +652,10 @@ static inline void gpio_ll_func_sel(gpio_dev_t *hw, uint8_t gpio_num, uint32_t f * @param gpio_num gpio_num GPIO number of the pad. * @param func The function number of the peripheral pin to output pin. * One of the ``FUNC_X_*`` of specified pin (X) in ``soc/io_mux_reg.h``. - * @param oen_inv True if the output enable needs to be inverted, otherwise False. */ -static inline void gpio_ll_iomux_out(gpio_dev_t *hw, uint8_t gpio_num, int func, uint32_t oen_inv) +static inline void gpio_ll_iomux_out(gpio_dev_t *hw, uint8_t gpio_num, int func) { - hw->func_out_sel_cfg[gpio_num].oen_sel = 0; - hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; + gpio_ll_set_output_enable_ctrl(hw, gpio_num, true, false); gpio_ll_func_sel(hw, gpio_num, func); } diff --git a/components/hal/esp32s2/include/hal/gpio_ll.h b/components/hal/esp32s2/include/hal/gpio_ll.h index 65c451e499..e2251f9c48 100644 --- a/components/hal/esp32s2/include/hal/gpio_ll.h +++ b/components/hal/esp32s2/include/hal/gpio_ll.h @@ -41,6 +41,8 @@ extern "C" { * @param pd Pull-down enabled or not * @param ie Input enabled or not * @param oe Output enabled or not + * @param oe_ctrl_by_periph Output enable signal from peripheral or not + * @param oe_inv Output enable signal is inversed or not * @param od Open-drain enabled or not * @param drv Drive strength value * @param fun_sel IOMUX function selection value @@ -48,7 +50,7 @@ extern "C" { * @param slp_sel Pin sleep mode enabled or not */ static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, - bool *pu, bool *pd, bool *ie, bool *oe, bool *od, uint32_t *drv, + bool *pu, bool *pd, bool *ie, bool *oe, bool *oe_ctrl_by_periph, bool *oe_inv, bool *od, uint32_t *drv, uint32_t *fun_sel, uint32_t *sig_out, bool *slp_sel) { uint32_t bit_shift = (gpio_num < 32) ? gpio_num : (gpio_num - 32); @@ -58,6 +60,8 @@ static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, *pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S; *ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S; *oe = (((gpio_num < 32) ? hw->enable : hw->enable1.val) & bit_mask) >> bit_shift; + *oe_ctrl_by_periph = !(hw->func_out_sel_cfg[gpio_num].oen_sel); + *oe_inv = hw->func_out_sel_cfg[gpio_num].oen_inv_sel; *od = hw->pin[gpio_num].pad_driver; *drv = (iomux_reg_val & FUN_DRV_M) >> FUN_DRV_S; *fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S; @@ -520,6 +524,20 @@ static inline void gpio_ll_iomux_func_sel(uint32_t pin_name, uint32_t func) PIN_FUNC_SELECT(pin_name, func); } +/** + * @brief Configure the source of output enable signal for the GPIO pin. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number of the pad. + * @param ctrl_by_periph True if use output enable signal from peripheral, false if force the output enable signal to be sourced from bit n of GPIO_ENABLE_REG + * @param oen_inv True if the output enable needs to be inverted, otherwise False. + */ +static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_num, bool ctrl_by_periph, bool oen_inv) +{ + hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; // control valid only when using gpio matrix to route signal to the IO + hw->func_out_sel_cfg[gpio_num].oen_sel = !ctrl_by_periph; +} + /** * @brief Control the pin in the IOMUX * @@ -539,12 +557,10 @@ static inline void gpio_ll_set_pin_ctrl(uint32_t val, uint32_t bmap, uint32_t sh * @param gpio_num gpio_num GPIO number of the pad. * @param func The function number of the peripheral pin to output pin. * One of the ``FUNC_X_*`` of specified pin (X) in ``soc/io_mux_reg.h``. - * @param oen_inv True if the output enable needs to be inverted, otherwise False. */ -static inline void gpio_ll_iomux_out(gpio_dev_t *hw, uint8_t gpio_num, int func, uint32_t oen_inv) +static inline void gpio_ll_iomux_out(gpio_dev_t *hw, uint8_t gpio_num, int func) { - hw->func_out_sel_cfg[gpio_num].oen_sel = 0; - hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; + gpio_ll_set_output_enable_ctrl(hw, gpio_num, true, false); gpio_ll_func_sel(hw, gpio_num, func); } diff --git a/components/hal/esp32s3/include/hal/gpio_ll.h b/components/hal/esp32s3/include/hal/gpio_ll.h index a0365773bb..e53df0e3f8 100644 --- a/components/hal/esp32s3/include/hal/gpio_ll.h +++ b/components/hal/esp32s3/include/hal/gpio_ll.h @@ -516,6 +516,20 @@ static inline void gpio_ll_iomux_func_sel(uint32_t pin_name, uint32_t func) PIN_FUNC_SELECT(pin_name, func); } +/** + * @brief Configure the source of output enable signal for the GPIO pin. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number of the pad. + * @param ctrl_by_periph True if use output enable signal from peripheral, false if force the output enable signal to be sourced from bit n of GPIO_ENABLE_REG + * @param oen_inv True if the output enable needs to be inverted, otherwise False. + */ +static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_num, bool ctrl_by_periph, bool oen_inv) +{ + hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; // control valid only when using gpio matrix to route signal to the IO + hw->func_out_sel_cfg[gpio_num].oen_sel = !ctrl_by_periph; +} + /** * @brief Control the pin in the IOMUX * @@ -536,12 +550,10 @@ static inline void gpio_ll_set_pin_ctrl(uint32_t val, uint32_t bmap, uint32_t sh * @param gpio_num gpio_num GPIO number of the pad. * @param func The function number of the peripheral pin to output pin. * One of the ``FUNC_X_*`` of specified pin (X) in ``soc/io_mux_reg.h``. - * @param oen_inv True if the output enable needs to be inverted, otherwise False. */ -static inline void gpio_ll_iomux_out(gpio_dev_t *hw, uint8_t gpio_num, int func, uint32_t oen_inv) +static inline void gpio_ll_iomux_out(gpio_dev_t *hw, uint8_t gpio_num, int func) { - hw->func_out_sel_cfg[gpio_num].oen_sel = 0; - hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; + gpio_ll_set_output_enable_ctrl(hw, gpio_num, true, false); gpio_ll_func_sel(hw, gpio_num, func); } @@ -712,6 +724,8 @@ static inline void gpio_ll_sleep_output_enable(gpio_dev_t *hw, uint32_t gpio_num * @param pd Pull-down enabled or not * @param ie Input enabled or not * @param oe Output enabled or not + * @param oe_ctrl_by_periph Output enable signal from peripheral or not + * @param oe_inv Output enable signal is inversed or not * @param od Open-drain enabled or not * @param drv Drive strength value * @param fun_sel IOMUX function selection value @@ -719,7 +733,7 @@ static inline void gpio_ll_sleep_output_enable(gpio_dev_t *hw, uint32_t gpio_num * @param slp_sel Pin sleep mode enabled or not */ static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, - bool *pu, bool *pd, bool *ie, bool *oe, bool *od, uint32_t *drv, + bool *pu, bool *pd, bool *ie, bool *oe, bool *oe_ctrl_by_periph, bool *oe_inv, bool *od, uint32_t *drv, uint32_t *fun_sel, uint32_t *sig_out, bool *slp_sel) { uint32_t bit_shift = (gpio_num < 32) ? gpio_num : (gpio_num - 32); @@ -729,6 +743,8 @@ static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, *pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S; *ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S; *oe = (((gpio_num < 32) ? hw->enable : hw->enable1.val) & bit_mask) >> bit_shift; + *oe_ctrl_by_periph = !(hw->func_out_sel_cfg[gpio_num].oen_sel); + *oe_inv = hw->func_out_sel_cfg[gpio_num].oen_inv_sel; *od = hw->pin[gpio_num].pad_driver; gpio_ll_get_drive_capability(hw, gpio_num, (gpio_drive_cap_t *)drv); // specific workaround in the LL *fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S; diff --git a/components/hal/include/hal/gpio_hal.h b/components/hal/include/hal/gpio_hal.h index 269456b217..aaaac253c4 100644 --- a/components/hal/include/hal/gpio_hal.h +++ b/components/hal/include/hal/gpio_hal.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -43,14 +43,16 @@ typedef struct { * @param pd Pointer to accept the status of pull-down enabled or not * @param ie Pointer to accept the status of input enabled or not * @param oe Pointer to accept the status of output enabled or not + * @param oe_ctrl_by_periph Pointer to accept the status of output enable signal control + * @param oe_inv Pointer to accept the status of output enable signal inversed or not * @param od Pointer to accept the status of open-drain enabled or not * @param drv Pointer to accept the value of drive strength * @param fun_sel Pointer to accept the value of IOMUX function selection * @param sig_out Pointer to accept the index of outputting peripheral signal * @param slp_sel Pointer to accept the status of pin sleep mode enabled or not */ -#define gpio_hal_get_io_config(hal, gpio_num, pu, pd, ie, oe, od, drv, fun_sel, sig_out, slp_sel) \ - gpio_ll_get_io_config((hal)->dev, gpio_num, pu, pd, ie, oe, od, drv, fun_sel, sig_out, slp_sel) +#define gpio_hal_get_io_config(hal, gpio_num, pu, pd, ie, oe, oe_ctrl_by_periph, oe_inv, od, drv, fun_sel, sig_out, slp_sel) \ + gpio_ll_get_io_config((hal)->dev, gpio_num, pu, pd, ie, oe, oe_ctrl_by_periph, oe_inv, od, drv, fun_sel, sig_out, slp_sel) /** * @brief Enable pull-up on GPIO. @@ -169,6 +171,16 @@ void gpio_hal_intr_disable(gpio_hal_context_t *hal, uint32_t gpio_num); */ #define gpio_hal_output_enable(hal, gpio_num) gpio_ll_output_enable((hal)->dev, gpio_num) +/** + * @brief Configure the source of output enable signal for the GPIO pin. + * + * @param hal Context of the HAL layer + * @param gpio_num GPIO number + * @param ctrl_by_periph True if use output enable signal from peripheral, false if force the output enable signal to be sourced from bit n of GPIO_ENABLE_REG + * @param oen_inv True if the output enable needs to be inverted, otherwise False + */ + #define gpio_hal_set_output_enable_ctrl(hal, gpio_num, ctrl_by_periph, oen_inv) gpio_ll_set_output_enable_ctrl((hal)->dev, gpio_num, ctrl_by_periph, oen_inv) + /** * @brief Disable open-drain mode on GPIO. * @@ -371,9 +383,8 @@ void gpio_hal_intr_disable(gpio_hal_context_t *hal, uint32_t gpio_num); * @param gpio_num gpio_num GPIO number of the pad. * @param func The function number of the peripheral pin to output pin. * One of the ``FUNC_X_*`` of specified pin (X) in ``soc/io_mux_reg.h``. - * @param oen_inv True if the output enable needs to be inverted, otherwise False. */ -#define gpio_hal_iomux_out(hal, gpio_num, func, oen_inv) gpio_ll_iomux_out((hal)->dev, gpio_num, func, oen_inv) +#define gpio_hal_iomux_out(hal, gpio_num, func) gpio_ll_iomux_out((hal)->dev, gpio_num, func) #if SOC_GPIO_SUPPORT_FORCE_HOLD /** From c3e4134b0ca80cb995795d1abae6ddb5fa88c25d Mon Sep 17 00:00:00 2001 From: Song Ruo Jing Date: Thu, 20 Mar 2025 14:50:44 +0800 Subject: [PATCH 5/5] feat(gpio): gpio_reset_pin should do IO reservation revoke Closes https://github.com/espressif/esp-idf/issues/15598 --- components/esp_driver_gpio/include/esp_private/gpio.h | 4 ++-- components/esp_driver_gpio/src/gpio.c | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/components/esp_driver_gpio/include/esp_private/gpio.h b/components/esp_driver_gpio/include/esp_private/gpio.h index 2e06192f63..1f6c185b1b 100644 --- a/components/esp_driver_gpio/include/esp_private/gpio.h +++ b/components/esp_driver_gpio/include/esp_private/gpio.h @@ -83,7 +83,7 @@ esp_err_t gpio_output_disable(gpio_num_t gpio_num); * - ESP_OK Success * - ESP_ERR_INVALID_ARG GPIO number error */ -esp_err_t gpio_od_disable(gpio_num_t gpio_num); +esp_err_t gpio_od_enable(gpio_num_t gpio_num); /** * @brief Disable open-drain for an IO @@ -94,7 +94,7 @@ esp_err_t gpio_od_disable(gpio_num_t gpio_num); * - ESP_OK Success * - ESP_ERR_INVALID_ARG GPIO number error */ -esp_err_t gpio_od_enable(gpio_num_t gpio_num); +esp_err_t gpio_od_disable(gpio_num_t gpio_num); #ifdef __cplusplus } diff --git a/components/esp_driver_gpio/src/gpio.c b/components/esp_driver_gpio/src/gpio.c index 5b17568bce..6e95f08654 100644 --- a/components/esp_driver_gpio/src/gpio.c +++ b/components/esp_driver_gpio/src/gpio.c @@ -445,6 +445,7 @@ esp_err_t gpio_reset_pin(gpio_num_t gpio_num) .intr_type = GPIO_INTR_DISABLE, }; gpio_config(&cfg); + esp_gpio_revoke(BIT64(gpio_num)); return ESP_OK; }