From 3a8d065908683166336cead7c82624f2ecc3acf4 Mon Sep 17 00:00:00 2001 From: Song Ruo Jing Date: Tue, 14 Jan 2025 16:51:58 +0800 Subject: [PATCH 1/2] refactor(gpio): improve gpio_iomux_in/out API --- components/esp_driver_gpio/README.md | 4 +- .../esp_driver_gpio/include/driver/gpio.h | 6 +-- .../include/esp_private/gpio.h | 30 ++++++++++++- components/esp_driver_gpio/src/gpio.c | 31 +++++++++++-- .../esp_driver_spi/src/gpspi/spi_common.c | 30 ++++++------- .../esp_driver_spi/src/gpspi/spi_slave.c | 2 +- components/esp_driver_uart/src/uart.c | 11 ++--- .../esp_eth/src/mac/esp_eth_mac_esp_gpio.c | 14 ++---- components/hal/esp32/include/hal/gpio_ll.h | 43 +++++++++---------- components/hal/esp32c2/include/hal/gpio_ll.h | 43 +++++++++---------- components/hal/esp32c3/include/hal/gpio_ll.h | 43 +++++++++---------- components/hal/esp32c5/include/hal/gpio_ll.h | 43 +++++++++---------- components/hal/esp32c6/include/hal/gpio_ll.h | 43 +++++++++---------- components/hal/esp32c61/include/hal/gpio_ll.h | 43 +++++++++---------- components/hal/esp32h2/include/hal/gpio_ll.h | 43 +++++++++---------- components/hal/esp32h21/include/hal/gpio_ll.h | 43 +++++++++---------- components/hal/esp32p4/include/hal/gpio_ll.h | 43 +++++++++---------- components/hal/esp32s2/include/hal/gpio_ll.h | 42 +++++++++--------- components/hal/esp32s3/include/hal/gpio_ll.h | 43 +++++++++---------- components/hal/gpio_hal.c | 15 ++++++- components/hal/include/hal/gpio_hal.h | 12 +++--- .../esp_flash/main/test_esp_flash_drv.c | 11 ++--- 22 files changed, 332 insertions(+), 306 deletions(-) diff --git a/components/esp_driver_gpio/README.md b/components/esp_driver_gpio/README.md index 40ecb1cb5d..98ec691cfd 100644 --- a/components/esp_driver_gpio/README.md +++ b/components/esp_driver_gpio/README.md @@ -10,7 +10,7 @@ Use `gpio_od_enable` to configure an output IO as open-drain mode if necessary. There is no need to enable the output for the IO explicitly, it is done internally in the following function calls. -If the signal is routed through IO MUX to the pin, then only needs to call `gpio_iomux_out` to select the IO MUX function index. +If the signal is routed through IO MUX to the pin, then only needs to call `gpio_iomux_output` to select the IO MUX function index. Output enable is controlled by the signal itself. 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 `esp_rom_gpio_connect_out_signal` to connect the signal. @@ -18,7 +18,7 @@ When a peripheral driver does de-initialization, to de-configure the pin as the ## Configure an IO as a peripheral signal input -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 IO MUX to the pin, then only needs to call `gpio_iomux_input` to select the IO MUX function index and 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. diff --git a/components/esp_driver_gpio/include/driver/gpio.h b/components/esp_driver_gpio/include/driver/gpio.h index b5822a55a0..49bd4b07d4 100644 --- a/components/esp_driver_gpio/include/driver/gpio.h +++ b/components/esp_driver_gpio/include/driver/gpio.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 */ @@ -460,7 +460,7 @@ void gpio_deep_sleep_hold_dis(void); * @param gpio_num GPIO number of the pad. * @param signal_idx Peripheral signal id to input. One of the ``*_IN_IDX`` signals in ``soc/gpio_sig_map.h``. */ -void gpio_iomux_in(uint32_t gpio_num, uint32_t signal_idx); +void gpio_iomux_in(uint32_t gpio_num, uint32_t signal_idx) __attribute__((deprecated("Please use `gpio_iomux_input` instead"))); /** * @brief Set peripheral output to an GPIO pad through the IOMUX. @@ -469,7 +469,7 @@ void gpio_iomux_in(uint32_t gpio_num, uint32_t signal_idx); * One of the ``FUNC_X_*`` of specified pin (X) in ``soc/io_mux_reg.h``. * @param out_en_inv True if the output enable needs to be inverted, otherwise False. */ -void gpio_iomux_out(uint8_t gpio_num, int func, bool out_en_inv); +void gpio_iomux_out(uint8_t gpio_num, int func, bool out_en_inv) __attribute__((deprecated("Please use `gpio_iomux_output` instead"))); #if SOC_GPIO_SUPPORT_FORCE_HOLD /** diff --git a/components/esp_driver_gpio/include/esp_private/gpio.h b/components/esp_driver_gpio/include/esp_private/gpio.h index ce4d84a7bd..5357fe07b6 100644 --- a/components/esp_driver_gpio/include/esp_private/gpio.h +++ b/components/esp_driver_gpio/include/esp_private/gpio.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 */ @@ -106,6 +106,34 @@ esp_err_t gpio_od_enable(gpio_num_t gpio_num); */ esp_err_t gpio_config_as_analog(gpio_num_t gpio_num); +/** + * @brief Set pad input to a peripheral signal through the IOMUX. + * + * @param gpio_num GPIO number of the pad. + * @param func The index number of the IOMUX function to be selected for the pin. + * One of the ``FUNC_X_*`` of specified pin (X) in ``soc/io_mux_reg.h``. + * @param signal_idx Peripheral signal id to input. One of the ``*_IN_IDX`` signals in ``soc/gpio_sig_map.h``. + * + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG GPIO number error + */ +esp_err_t gpio_iomux_input(gpio_num_t gpio_num, int func, uint32_t signal_idx); + +/** + * @brief Set peripheral output to an GPIO pad through the IOMUX. + * + * @param gpio_num GPIO number of the pad. + * @param func The index number of the IOMUX function to be selected for the pin. + * One of the ``FUNC_X_*`` of specified pin (X) in ``soc/io_mux_reg.h``. + * @param out_en_inv Whether the output enable control is inverted or not. + * + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG GPIO number error + */ +esp_err_t gpio_iomux_output(gpio_num_t gpio_num, int func, bool out_en_inv); + #ifdef __cplusplus } #endif diff --git a/components/esp_driver_gpio/src/gpio.c b/components/esp_driver_gpio/src/gpio.c index 9d088a1ed0..5863871681 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 */ @@ -815,14 +815,39 @@ esp_err_t IRAM_ATTR gpio_force_unhold_all() } #endif //SOC_GPIO_SUPPORT_FORCE_HOLD +// Deprecated function void gpio_iomux_in(uint32_t gpio, uint32_t signal_idx) { - gpio_hal_iomux_in(gpio_context.gpio_hal, gpio, signal_idx); + gpio_ll_set_input_signal_from(gpio_context.gpio_hal->dev, signal_idx, false); + gpio_hal_input_enable(gpio_context.gpio_hal, gpio); } +esp_err_t gpio_iomux_input(gpio_num_t gpio_num, int func, uint32_t signal_idx) +{ + GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); + + portENTER_CRITICAL(&gpio_context.gpio_spinlock); + gpio_hal_iomux_in(gpio_context.gpio_hal, gpio_num, func, signal_idx); + portEXIT_CRITICAL(&gpio_context.gpio_spinlock); + + return ESP_OK; +} + +// Deprecated function 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); + gpio_hal_iomux_out(gpio_context.gpio_hal, gpio_num, func, out_en_inv); +} + +esp_err_t gpio_iomux_output(gpio_num_t gpio_num, int func, bool out_en_inv) +{ + GPIO_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); + + portENTER_CRITICAL(&gpio_context.gpio_spinlock); + gpio_hal_iomux_out(gpio_context.gpio_hal, gpio_num, func, out_en_inv); + portEXIT_CRITICAL(&gpio_context.gpio_spinlock); + + return ESP_OK; } static esp_err_t gpio_sleep_pullup_en(gpio_num_t gpio_num) diff --git a/components/esp_driver_spi/src/gpspi/spi_common.c b/components/esp_driver_spi/src/gpspi/spi_common.c index 65764f38bd..562f62f60d 100644 --- a/components/esp_driver_spi/src/gpspi/spi_common.c +++ b/components/esp_driver_spi/src/gpspi/spi_common.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 */ @@ -443,9 +443,9 @@ static void bus_iomux_pins_set_oct(spi_host_device_t host, const spi_bus_config_ }; for (size_t i = 0; i < sizeof(io_nums) / sizeof(io_nums[0]); i++) { if (io_nums[i] > 0) { - gpio_iomux_in(io_nums[i], io_signals[i]); // In Octal mode use function channel 2 - gpio_iomux_out(io_nums[i], SPI2_FUNC_NUM_OCT, false); + gpio_iomux_input(io_nums[i], SPI2_FUNC_NUM_OCT, io_signals[i]); + gpio_iomux_output(io_nums[i], SPI2_FUNC_NUM_OCT, false); } } } @@ -454,24 +454,24 @@ static void bus_iomux_pins_set_oct(spi_host_device_t host, const spi_bus_config_ static void bus_iomux_pins_set_quad(spi_host_device_t host, const spi_bus_config_t* bus_config) { if (bus_config->mosi_io_num >= 0) { - gpio_iomux_in(bus_config->mosi_io_num, spi_periph_signal[host].spid_in); - gpio_iomux_out(bus_config->mosi_io_num, spi_periph_signal[host].func, false); + gpio_iomux_input(bus_config->mosi_io_num, spi_periph_signal[host].func, spi_periph_signal[host].spid_in); + gpio_iomux_output(bus_config->mosi_io_num, spi_periph_signal[host].func, false); } if (bus_config->miso_io_num >= 0) { - gpio_iomux_in(bus_config->miso_io_num, spi_periph_signal[host].spiq_in); - gpio_iomux_out(bus_config->miso_io_num, spi_periph_signal[host].func, false); + gpio_iomux_input(bus_config->miso_io_num, spi_periph_signal[host].func, spi_periph_signal[host].spiq_in); + gpio_iomux_output(bus_config->miso_io_num, spi_periph_signal[host].func, false); } if (bus_config->quadwp_io_num >= 0) { - gpio_iomux_in(bus_config->quadwp_io_num, spi_periph_signal[host].spiwp_in); - gpio_iomux_out(bus_config->quadwp_io_num, spi_periph_signal[host].func, false); + gpio_iomux_input(bus_config->quadwp_io_num, spi_periph_signal[host].func, spi_periph_signal[host].spiwp_in); + gpio_iomux_output(bus_config->quadwp_io_num, spi_periph_signal[host].func, false); } if (bus_config->quadhd_io_num >= 0) { - gpio_iomux_in(bus_config->quadhd_io_num, spi_periph_signal[host].spihd_in); - gpio_iomux_out(bus_config->quadhd_io_num, spi_periph_signal[host].func, false); + gpio_iomux_input(bus_config->quadhd_io_num, spi_periph_signal[host].func, spi_periph_signal[host].spihd_in); + gpio_iomux_output(bus_config->quadhd_io_num, spi_periph_signal[host].func, false); } if (bus_config->sclk_io_num >= 0) { - gpio_iomux_in(bus_config->sclk_io_num, spi_periph_signal[host].spiclk_in); - gpio_iomux_out(bus_config->sclk_io_num, spi_periph_signal[host].func, false); + gpio_iomux_input(bus_config->sclk_io_num, spi_periph_signal[host].func, spi_periph_signal[host].spiclk_in); + gpio_iomux_output(bus_config->sclk_io_num, spi_periph_signal[host].func, false); } } @@ -732,8 +732,8 @@ void spicommon_cs_initialize(spi_host_device_t host, int cs_io_num, int cs_num, { if (!force_gpio_matrix && cs_io_num == spi_periph_signal[host].spics0_iomux_pin && cs_num == 0) { //The cs0s for all SPI peripherals map to pin mux source 1, so we use that instead of a define. - gpio_iomux_in(cs_io_num, spi_periph_signal[host].spics_in); - gpio_iomux_out(cs_io_num, spi_periph_signal[host].func, false); + gpio_iomux_input(cs_io_num, spi_periph_signal[host].func, spi_periph_signal[host].spics_in); + gpio_iomux_output(cs_io_num, spi_periph_signal[host].func, false); } else { //Use GPIO matrix if (GPIO_IS_VALID_OUTPUT_GPIO(cs_io_num)) { diff --git a/components/esp_driver_spi/src/gpspi/spi_slave.c b/components/esp_driver_spi/src/gpspi/spi_slave.c index 4d41aa60e0..188742e4e1 100644 --- a/components/esp_driver_spi/src/gpspi/spi_slave.c +++ b/components/esp_driver_spi/src/gpspi/spi_slave.c @@ -111,7 +111,7 @@ static void SPI_SLAVE_ISR_ATTR freeze_cs(spi_slave_t *host) static inline void SPI_SLAVE_ISR_ATTR restore_cs(spi_slave_t *host) { if (host->cs_iomux) { - gpio_ll_iomux_in(GPIO_HAL_GET_HW(GPIO_PORT_0), host->cfg.spics_io_num, host->cs_in_signal); + gpio_ll_set_input_signal_from(GPIO_HAL_GET_HW(GPIO_PORT_0), host->cs_in_signal, false); } else { esp_rom_gpio_connect_in_signal(host->cfg.spics_io_num, host->cs_in_signal, false); } diff --git a/components/esp_driver_uart/src/uart.c b/components/esp_driver_uart/src/uart.c index fec9052da1..fac88f324e 100644 --- a/components/esp_driver_uart/src/uart.c +++ b/components/esp_driver_uart/src/uart.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 */ @@ -19,7 +19,6 @@ #include "freertos/idf_additions.h" #include "esp_private/critical_section.h" #include "hal/uart_hal.h" -#include "hal/gpio_hal.h" #include "soc/uart_periph.h" #include "soc/soc_caps.h" #include "driver/uart.h" @@ -684,12 +683,10 @@ static bool uart_try_set_iomux_pin(uart_port_t uart_num, int io_num, uint32_t id /* Assign the correct funct to the GPIO. */ assert(upin->iomux_func != -1); if (uart_num < SOC_UART_HP_NUM) { - gpio_iomux_out(io_num, upin->iomux_func, false); - - /* If the pin is input, we also have to redirect the signal, - * in order to bypasse the GPIO matrix. */ if (upin->input) { - gpio_iomux_in(io_num, upin->signal); + gpio_iomux_input(io_num, upin->iomux_func, upin->signal); + } else { + gpio_iomux_output(io_num, upin->iomux_func, false); } } #if (SOC_UART_LP_NUM >= 1) && (SOC_RTCIO_PIN_COUNT >= 1) diff --git a/components/esp_eth/src/mac/esp_eth_mac_esp_gpio.c b/components/esp_eth/src/mac/esp_eth_mac_esp_gpio.c index 949f583094..af2a6fbea2 100644 --- a/components/esp_eth/src/mac/esp_eth_mac_esp_gpio.c +++ b/components/esp_eth/src/mac/esp_eth_mac_esp_gpio.c @@ -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 */ @@ -88,17 +88,9 @@ static esp_err_t emac_esp_iomux_init(gpio_num_t gpio_num, const emac_iomux_info_ TAG, "GPIO %i is already reserved", iomux_info->gpio_num); s_emac_esp_used_gpio_mask |= BIT64(iomux_info->gpio_num); if (is_input) { - ESP_RETURN_ON_ERROR(gpio_func_sel(iomux_info->gpio_num, iomux_info->func), TAG, "failed to set GPIO function at GPIO %i", iomux_info->gpio_num); - // if the signal can be also connected via IO matrix, disconnect it (SIG_GPIO_OUT_IDX indicates no IO matrix) - if (signal_idx != SIG_GPIO_OUT_IDX) { - // enable input and disconnect from IO Matrix - gpio_iomux_in(iomux_info->gpio_num, signal_idx); - } else { - // just enable input - gpio_input_enable(iomux_info->gpio_num); - } + ESP_RETURN_ON_ERROR(gpio_iomux_input(iomux_info->gpio_num, iomux_info->func, signal_idx), TAG, "failed to set perip. input via IOMUX"); } else { - gpio_iomux_out(iomux_info->gpio_num, iomux_info->func, false); + ESP_RETURN_ON_ERROR(gpio_iomux_output(iomux_info->gpio_num, iomux_info->func, false), TAG, "failed to set perip. output via IOMUX"); } ESP_RETURN_ON_ERROR(gpio_set_pull_mode(iomux_info->gpio_num, GPIO_FLOATING), TAG, "failed to set pull mode at GPIO %i", iomux_info->gpio_num); diff --git a/components/hal/esp32/include/hal/gpio_ll.h b/components/hal/esp32/include/hal/gpio_ll.h index 0f70f48873..2b2e2ba2ac 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 */ @@ -699,17 +699,30 @@ static inline bool gpio_ll_is_digital_io_hold(gpio_dev_t *hw, uint32_t gpio_num) } /** - * @brief Set pad input to a peripheral signal through the IOMUX. + * @brief Configure peripheral signal input whether to bypass GPIO matrix. + * + * @param hw Peripheral GPIO hardware instance address. + * @param signal_idx Peripheral signal id to input. One of the ``*_IN_IDX`` signals in ``soc/gpio_sig_map.h``. + * @param from_gpio_matrix True if not to bypass GPIO matrix, otherwise False. + */ +__attribute__((always_inline)) +static inline void gpio_ll_set_input_signal_from(gpio_dev_t *hw, uint32_t signal_idx, bool from_gpio_matrix) +{ + hw->func_in_sel_cfg[signal_idx].sig_in_sel = from_gpio_matrix; +} + +/** + * @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 signal_idx Peripheral signal id to input. One of the ``*_IN_IDX`` signals in ``soc/gpio_sig_map.h``. + * @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. */ -__attribute__((always_inline)) -static inline void gpio_ll_iomux_in(gpio_dev_t *hw, uint32_t gpio, uint32_t signal_idx) +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_in_sel_cfg[signal_idx].sig_in_sel = 0; - PIN_INPUT_ENABLE(DR_REG_IO_MUX_BASE + GPIO_PIN_MUX_REG_OFFSET[gpio]); + hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; + hw->func_out_sel_cfg[gpio_num].oen_sel = !ctrl_by_periph; } /** @@ -737,22 +750,6 @@ static inline void gpio_ll_set_pin_ctrl(uint32_t val, uint32_t bmap, uint32_t sh SET_PERI_REG_BITS(PIN_CTRL, bmap, val, shift); } -/** - * @brief Set peripheral output to an GPIO pad through the IOMUX. - * - * @param hw Peripheral GPIO hardware instance address. - * @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) -{ - hw->func_out_sel_cfg[gpio_num].oen_sel = 0; - hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; - gpio_ll_func_sel(hw, gpio_num, func); -} - /** * @brief Get the GPIO number that is routed to the input peripheral signal through GPIO matrix. * diff --git a/components/hal/esp32c2/include/hal/gpio_ll.h b/components/hal/esp32c2/include/hal/gpio_ll.h index 516fb46b43..534ff1164e 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 */ @@ -501,17 +501,30 @@ static inline bool gpio_ll_is_digital_io_hold(gpio_dev_t *hw, uint32_t gpio_num) } /** - * @brief Set pad input to a peripheral signal through the IOMUX. + * @brief Configure peripheral signal input whether to bypass GPIO matrix. + * + * @param hw Peripheral GPIO hardware instance address. + * @param signal_idx Peripheral signal id to input. One of the ``*_IN_IDX`` signals in ``soc/gpio_sig_map.h``. + * @param from_gpio_matrix True if not to bypass GPIO matrix, otherwise False. + */ +__attribute__((always_inline)) +static inline void gpio_ll_set_input_signal_from(gpio_dev_t *hw, uint32_t signal_idx, bool from_gpio_matrix) +{ + hw->func_in_sel_cfg[signal_idx].sig_in_sel = from_gpio_matrix; +} + +/** + * @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 signal_idx Peripheral signal id to input. One of the ``*_IN_IDX`` signals in ``soc/gpio_sig_map.h``. + * @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. */ -__attribute__((always_inline)) -static inline void gpio_ll_iomux_in(gpio_dev_t *hw, uint32_t gpio, uint32_t signal_idx) +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_in_sel_cfg[signal_idx].sig_in_sel = 0; - PIN_INPUT_ENABLE(IO_MUX_GPIO0_REG + (gpio * 4)); + hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; + hw->func_out_sel_cfg[gpio_num].oen_sel = !ctrl_by_periph; } /** @@ -539,22 +552,6 @@ static inline void gpio_ll_set_pin_ctrl(uint32_t val, uint32_t bmap, uint32_t sh SET_PERI_REG_BITS(PIN_CTRL, bmap, val, shift); } -/** - * @brief Set peripheral output to an GPIO pad through the IOMUX. - * - * @param hw Peripheral GPIO hardware instance address. - * @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) -{ - hw->func_out_sel_cfg[gpio_num].oen_sel = 0; - hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; - gpio_ll_func_sel(hw, gpio_num, func); -} - /** * @brief Get the GPIO number that is routed to the input peripheral signal through GPIO matrix. * diff --git a/components/hal/esp32c3/include/hal/gpio_ll.h b/components/hal/esp32c3/include/hal/gpio_ll.h index f93d03ab79..7ce22c2d63 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 */ @@ -473,17 +473,30 @@ static inline bool gpio_ll_is_digital_io_hold(gpio_dev_t *hw, uint32_t gpio_num) } /** - * @brief Set pad input to a peripheral signal through the IOMUX. + * @brief Configure peripheral signal input whether to bypass GPIO matrix. + * + * @param hw Peripheral GPIO hardware instance address. + * @param signal_idx Peripheral signal id to input. One of the ``*_IN_IDX`` signals in ``soc/gpio_sig_map.h``. + * @param from_gpio_matrix True if not to bypass GPIO matrix, otherwise False. + */ +__attribute__((always_inline)) +static inline void gpio_ll_set_input_signal_from(gpio_dev_t *hw, uint32_t signal_idx, bool from_gpio_matrix) +{ + hw->func_in_sel_cfg[signal_idx].sig_in_sel = from_gpio_matrix; +} + +/** + * @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 signal_idx Peripheral signal id to input. One of the ``*_IN_IDX`` signals in ``soc/gpio_sig_map.h``. + * @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. */ -__attribute__((always_inline)) -static inline void gpio_ll_iomux_in(gpio_dev_t *hw, uint32_t gpio, uint32_t signal_idx) +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_in_sel_cfg[signal_idx].sig_in_sel = 0; - PIN_INPUT_ENABLE(IO_MUX_GPIO0_REG + (gpio * 4)); + hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; + hw->func_out_sel_cfg[gpio_num].oen_sel = !ctrl_by_periph; } /** @@ -515,22 +528,6 @@ static inline void gpio_ll_set_pin_ctrl(uint32_t val, uint32_t bmap, uint32_t sh SET_PERI_REG_BITS(PIN_CTRL, bmap, val, shift); } -/** - * @brief Set peripheral output to an GPIO pad through the IOMUX. - * - * @param hw Peripheral GPIO hardware instance address. - * @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) -{ - hw->func_out_sel_cfg[gpio_num].oen_sel = 0; - hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; - gpio_ll_func_sel(hw, gpio_num, func); -} - /** * @brief Get the GPIO number that is routed to the input peripheral signal through GPIO matrix. * diff --git a/components/hal/esp32c5/include/hal/gpio_ll.h b/components/hal/esp32c5/include/hal/gpio_ll.h index 78134e4afa..ee87ac5f21 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 */ @@ -489,17 +489,30 @@ static inline bool gpio_ll_is_digital_io_hold(gpio_dev_t *hw, uint32_t gpio_num) } /** - * @brief Set pad input to a peripheral signal through the IO_MUX. + * @brief Configure peripheral signal input whether to bypass GPIO matrix. + * + * @param hw Peripheral GPIO hardware instance address. + * @param signal_idx Peripheral signal id to input. One of the ``*_IN_IDX`` signals in ``soc/gpio_sig_map.h``. + * @param from_gpio_matrix True if not to bypass GPIO matrix, otherwise False. + */ +__attribute__((always_inline)) +static inline void gpio_ll_set_input_signal_from(gpio_dev_t *hw, uint32_t signal_idx, bool from_gpio_matrix) +{ + hw->func_in_sel_cfg[signal_idx].sig_in_sel = from_gpio_matrix; +} + +/** + * @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 signal_idx Peripheral signal id to input. One of the ``*_IN_IDX`` signals in ``soc/gpio_sig_map.h``. + * @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. */ -__attribute__((always_inline)) -static inline void gpio_ll_iomux_in(gpio_dev_t *hw, uint32_t gpio, uint32_t signal_idx) +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_in_sel_cfg[signal_idx].sig_in_sel = 0; - IO_MUX.gpio[gpio].fun_ie = 1; + hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; + hw->func_out_sel_cfg[gpio_num].oen_sel = !ctrl_by_periph; } /** @@ -534,22 +547,6 @@ 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 Set peripheral output to an GPIO pad through the IO_MUX. - * - * @param hw Peripheral GPIO hardware instance address. - * @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) -{ - hw->func_out_sel_cfg[gpio_num].oen_sel = 0; - hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; - gpio_ll_func_sel(hw, gpio_num, func); -} - /** * @brief Set clock source of IO MUX module * diff --git a/components/hal/esp32c6/include/hal/gpio_ll.h b/components/hal/esp32c6/include/hal/gpio_ll.h index e87fd20813..733a6ca999 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 */ @@ -460,17 +460,30 @@ static inline bool gpio_ll_is_digital_io_hold(gpio_dev_t *hw, uint32_t gpio_num) } /** - * @brief Set pad input to a peripheral signal through the IOMUX. + * @brief Configure peripheral signal input whether to bypass GPIO matrix. + * + * @param hw Peripheral GPIO hardware instance address. + * @param signal_idx Peripheral signal id to input. One of the ``*_IN_IDX`` signals in ``soc/gpio_sig_map.h``. + * @param from_gpio_matrix True if not to bypass GPIO matrix, otherwise False. + */ +__attribute__((always_inline)) +static inline void gpio_ll_set_input_signal_from(gpio_dev_t *hw, uint32_t signal_idx, bool from_gpio_matrix) +{ + hw->func_in_sel_cfg[signal_idx].sig_in_sel = from_gpio_matrix; +} + +/** + * @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 signal_idx Peripheral signal id to input. One of the ``*_IN_IDX`` signals in ``soc/gpio_sig_map.h``. + * @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. */ -__attribute__((always_inline)) -static inline void gpio_ll_iomux_in(gpio_dev_t *hw, uint32_t gpio, uint32_t signal_idx) +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_in_sel_cfg[signal_idx].sig_in_sel = 0; - PIN_INPUT_ENABLE(IO_MUX_GPIO0_REG + (gpio * 4)); + hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; + hw->func_out_sel_cfg[gpio_num].oen_sel = !ctrl_by_periph; } /** @@ -518,22 +531,6 @@ 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 Set peripheral output to an GPIO pad through the IOMUX. - * - * @param hw Peripheral GPIO hardware instance address. - * @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) -{ - hw->func_out_sel_cfg[gpio_num].oen_sel = 0; - hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; - gpio_ll_func_sel(hw, gpio_num, func); -} - /** * @brief Set clock source of IO MUX module * diff --git a/components/hal/esp32c61/include/hal/gpio_ll.h b/components/hal/esp32c61/include/hal/gpio_ll.h index 461dae1720..f8c44f1b40 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 */ @@ -489,17 +489,30 @@ static inline bool gpio_ll_is_digital_io_hold(gpio_dev_t *hw, uint32_t gpio_num) } /** - * @brief Set pad input to a peripheral signal through the IO_MUX. + * @brief Configure peripheral signal input whether to bypass GPIO matrix. + * + * @param hw Peripheral GPIO hardware instance address. + * @param signal_idx Peripheral signal id to input. One of the ``*_IN_IDX`` signals in ``soc/gpio_sig_map.h``. + * @param from_gpio_matrix True if not to bypass GPIO matrix, otherwise False. + */ +__attribute__((always_inline)) +static inline void gpio_ll_set_input_signal_from(gpio_dev_t *hw, uint32_t signal_idx, bool from_gpio_matrix) +{ + hw->func_in_sel_cfg[signal_idx].sig_in_sel = from_gpio_matrix; +} + +/** + * @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 signal_idx Peripheral signal id to input. One of the ``*_IN_IDX`` signals in ``soc/gpio_sig_map.h``. + * @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. */ -__attribute__((always_inline)) -static inline void gpio_ll_iomux_in(gpio_dev_t *hw, uint32_t gpio, uint32_t signal_idx) +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_in_sel_cfg[signal_idx].sig_in_sel = 0; - IO_MUX.gpion[gpio].gpion_fun_ie = 1; + hw->funcn_out_sel_cfg[gpio_num].funcn_oe_inv_sel = oen_inv; + hw->funcn_out_sel_cfg[gpio_num].funcn_oe_sel = !ctrl_by_periph; } /** @@ -534,22 +547,6 @@ 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 Set peripheral output to an GPIO pad through the IO_MUX. - * - * @param hw Peripheral GPIO hardware instance address. - * @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) -{ - 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_func_sel(hw, gpio_num, func); -} - /** * @brief Set clock source of IO MUX module * diff --git a/components/hal/esp32h2/include/hal/gpio_ll.h b/components/hal/esp32h2/include/hal/gpio_ll.h index f7e24c2ce0..f274a31a81 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 */ @@ -506,17 +506,30 @@ static inline bool gpio_ll_is_digital_io_hold(gpio_dev_t *hw, uint32_t gpio_num) } /** - * @brief Set pad input to a peripheral signal through the IOMUX. + * @brief Configure peripheral signal input whether to bypass GPIO matrix. + * + * @param hw Peripheral GPIO hardware instance address. + * @param signal_idx Peripheral signal id to input. One of the ``*_IN_IDX`` signals in ``soc/gpio_sig_map.h``. + * @param from_gpio_matrix True if not to bypass GPIO matrix, otherwise False. + */ +__attribute__((always_inline)) +static inline void gpio_ll_set_input_signal_from(gpio_dev_t *hw, uint32_t signal_idx, bool from_gpio_matrix) +{ + hw->func_in_sel_cfg[signal_idx].sig_in_sel = from_gpio_matrix; +} + +/** + * @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 signal_idx Peripheral signal id to input. One of the ``*_IN_IDX`` signals in ``soc/gpio_sig_map.h``. + * @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. */ -__attribute__((always_inline)) -static inline void gpio_ll_iomux_in(gpio_dev_t *hw, uint32_t gpio, uint32_t signal_idx) +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_in_sel_cfg[signal_idx].sig_in_sel = 0; - PIN_INPUT_ENABLE(IO_MUX_GPIO0_REG + (gpio * 4)); + hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; + hw->func_out_sel_cfg[gpio_num].oen_sel = !ctrl_by_periph; } /** @@ -551,22 +564,6 @@ 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 Set peripheral output to an GPIO pad through the IOMUX. - * - * @param hw Peripheral GPIO hardware instance address. - * @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) -{ - hw->func_out_sel_cfg[gpio_num].oen_sel = 0; - hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; - gpio_ll_func_sel(hw, gpio_num, func); -} - /** * @brief Control the pin in the IOMUX * diff --git a/components/hal/esp32h21/include/hal/gpio_ll.h b/components/hal/esp32h21/include/hal/gpio_ll.h index 15902b3efc..1213e6a02c 100644 --- a/components/hal/esp32h21/include/hal/gpio_ll.h +++ b/components/hal/esp32h21/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 */ @@ -495,17 +495,30 @@ static inline bool gpio_ll_is_digital_io_hold(gpio_dev_t *hw, uint32_t gpio_num) } /** - * @brief Set pad input to a peripheral signal through the IOMUX. + * @brief Configure peripheral signal input whether to bypass GPIO matrix. + * + * @param hw Peripheral GPIO hardware instance address. + * @param signal_idx Peripheral signal id to input. One of the ``*_IN_IDX`` signals in ``soc/gpio_sig_map.h``. + * @param from_gpio_matrix True if not to bypass GPIO matrix, otherwise False. + */ +__attribute__((always_inline)) +static inline void gpio_ll_set_input_signal_from(gpio_dev_t *hw, uint32_t signal_idx, bool from_gpio_matrix) +{ + hw->func_in_sel_cfg[signal_idx].sig_in_sel = from_gpio_matrix; +} + +/** + * @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 signal_idx Peripheral signal id to input. One of the ``*_IN_IDX`` signals in ``soc/gpio_sig_map.h``. + * @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. */ -__attribute__((always_inline)) -static inline void gpio_ll_iomux_in(gpio_dev_t *hw, uint32_t gpio, uint32_t signal_idx) +static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_num, bool ctrl_by_periph, bool oen_inv) { - REG_CLR_BIT(GPIO_FUNC0_IN_SEL_CFG_REG + signal_idx * 4, GPIO_SIG0_IN_SEL); - PIN_INPUT_ENABLE(IO_MUX_GPIO0_REG + (gpio * 4)); + hw->funcn_out_sel_cfg[gpio_num].funcn_oe_inv_sel = oen_inv; + hw->funcn_out_sel_cfg[gpio_num].funcn_oe_sel = !ctrl_by_periph; } /** @@ -540,22 +553,6 @@ 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 Set peripheral output to an GPIO pad through the IOMUX. - * - * @param hw Peripheral GPIO hardware instance address. - * @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) -{ - 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_func_sel(hw, gpio_num, func); -} - /** * @brief Control the pin in the IOMUX * diff --git a/components/hal/esp32p4/include/hal/gpio_ll.h b/components/hal/esp32p4/include/hal/gpio_ll.h index dd249a27f6..6dbe4a3b1a 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 */ @@ -592,17 +592,30 @@ static inline bool gpio_ll_is_digital_io_hold(gpio_dev_t *hw, uint32_t gpio_num) } /** - * @brief Set pad input to a peripheral signal through the IO_MUX. + * @brief Configure peripheral signal input whether to bypass GPIO matrix. + * + * @param hw Peripheral GPIO hardware instance address. + * @param signal_idx Peripheral signal id to input. One of the ``*_IN_IDX`` signals in ``soc/gpio_sig_map.h``. + * @param from_gpio_matrix True if not to bypass GPIO matrix, otherwise False. + */ +__attribute__((always_inline)) +static inline void gpio_ll_set_input_signal_from(gpio_dev_t *hw, uint32_t signal_idx, bool from_gpio_matrix) +{ + hw->func_in_sel_cfg[signal_idx].sig_in_sel = from_gpio_matrix; +} + +/** + * @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 signal_idx Peripheral signal id to input. One of the ``*_IN_IDX`` signals in ``soc/gpio_sig_map.h``. + * @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. */ -__attribute__((always_inline)) -static inline void gpio_ll_iomux_in(gpio_dev_t *hw, uint32_t gpio, uint32_t signal_idx) +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_in_sel_cfg[signal_idx].sig_in_sel = 0; - IO_MUX.gpio[gpio].fun_ie = 1; + hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; + hw->func_out_sel_cfg[gpio_num].oen_sel = !ctrl_by_periph; } /** @@ -645,22 +658,6 @@ 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 Set peripheral output to an GPIO pad through the IO_MUX. - * - * @param hw Peripheral GPIO hardware instance address. - * @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) -{ - hw->func_out_sel_cfg[gpio_num].oen_sel = 0; - hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; - gpio_ll_func_sel(hw, gpio_num, func); -} - /** * @brief Set clock source of IO MUX module * diff --git a/components/hal/esp32s2/include/hal/gpio_ll.h b/components/hal/esp32s2/include/hal/gpio_ll.h index a4c073a7f0..16ac0edb3b 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 */ @@ -513,17 +513,30 @@ static inline bool gpio_ll_is_digital_io_hold(gpio_dev_t *hw, uint32_t gpio_num) } /** - * @brief Set pad input to a peripheral signal through the IOMUX. + * @brief Configure peripheral signal input whether to bypass GPIO matrix. + * + * @param hw Peripheral GPIO hardware instance address. + * @param signal_idx Peripheral signal id to input. One of the ``*_IN_IDX`` signals in ``soc/gpio_sig_map.h``. + * @param from_gpio_matrix True if not to bypass GPIO matrix, otherwise False. + */ +__attribute__((always_inline)) +static inline void gpio_ll_set_input_signal_from(gpio_dev_t *hw, uint32_t signal_idx, bool from_gpio_matrix) +{ + hw->func_in_sel_cfg[signal_idx].sig_in_sel = from_gpio_matrix; +} + +/** + * @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 signal_idx Peripheral signal id to input. One of the ``*_IN_IDX`` signals in ``soc/gpio_sig_map.h``. + * @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. */ -__attribute__((always_inline)) -static inline void gpio_ll_iomux_in(gpio_dev_t *hw, uint32_t gpio, uint32_t signal_idx) +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_in_sel_cfg[signal_idx].sig_in_sel = 0; - PIN_INPUT_ENABLE(IO_MUX_GPIO0_REG + (gpio * 4)); + hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; + hw->func_out_sel_cfg[gpio_num].oen_sel = !ctrl_by_periph; } /** @@ -550,21 +563,6 @@ static inline void gpio_ll_set_pin_ctrl(uint32_t val, uint32_t bmap, uint32_t sh { SET_PERI_REG_BITS(PIN_CTRL, bmap, val, shift); } -/** - * @brief Set peripheral output to an GPIO pad through the IOMUX. - * - * @param hw Peripheral GPIO hardware instance address. - * @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) -{ - hw->func_out_sel_cfg[gpio_num].oen_sel = 0; - hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; - gpio_ll_func_sel(hw, gpio_num, func); -} /** * @brief Get the GPIO number that is routed to the input peripheral signal through GPIO matrix. diff --git a/components/hal/esp32s3/include/hal/gpio_ll.h b/components/hal/esp32s3/include/hal/gpio_ll.h index 17c7f625ff..33440ee77f 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 */ @@ -488,17 +488,30 @@ static inline bool gpio_ll_is_digital_io_hold(gpio_dev_t *hw, uint32_t gpio_num) } /** - * @brief Set pad input to a peripheral signal through the IOMUX. + * @brief Configure peripheral signal input whether to bypass GPIO matrix. + * + * @param hw Peripheral GPIO hardware instance address. + * @param signal_idx Peripheral signal id to input. One of the ``*_IN_IDX`` signals in ``soc/gpio_sig_map.h``. + * @param from_gpio_matrix True if not to bypass GPIO matrix, otherwise False. + */ +__attribute__((always_inline)) +static inline void gpio_ll_set_input_signal_from(gpio_dev_t *hw, uint32_t signal_idx, bool from_gpio_matrix) +{ + hw->func_in_sel_cfg[signal_idx].sig_in_sel = from_gpio_matrix; +} + +/** + * @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 signal_idx Peripheral signal id to input. One of the ``*_IN_IDX`` signals in ``soc/gpio_sig_map.h``. + * @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. */ -__attribute__((always_inline)) -static inline void gpio_ll_iomux_in(gpio_dev_t *hw, uint32_t gpio, uint32_t signal_idx) +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_in_sel_cfg[signal_idx].sig_in_sel = 0; - PIN_INPUT_ENABLE(IO_MUX_GPIO0_REG + (gpio * 4)); + hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; + hw->func_out_sel_cfg[gpio_num].oen_sel = !ctrl_by_periph; } /** @@ -529,22 +542,6 @@ static inline void gpio_ll_set_pin_ctrl(uint32_t val, uint32_t bmap, uint32_t sh SET_PERI_REG_BITS(PIN_CTRL, bmap, val, shift); } -/** - * @brief Set peripheral output to an GPIO pad through the IOMUX. - * - * @param hw Peripheral GPIO hardware instance address. - * @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) -{ - hw->func_out_sel_cfg[gpio_num].oen_sel = 0; - hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; - gpio_ll_func_sel(hw, gpio_num, func); -} - /** * @brief Get the GPIO number that is routed to the input peripheral signal through GPIO matrix. * diff --git a/components/hal/gpio_hal.c b/components/hal/gpio_hal.c index 67a51bef85..7cc00407d2 100644 --- a/components/hal/gpio_hal.c +++ b/components/hal/gpio_hal.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 */ @@ -31,6 +31,19 @@ void gpio_hal_intr_disable(gpio_hal_context_t *hal, uint32_t gpio_num) } } +void gpio_hal_iomux_in(gpio_hal_context_t *hal, uint32_t gpio_num, int func, uint32_t signal_idx) +{ + gpio_ll_set_input_signal_from(hal->dev, signal_idx, false); + gpio_ll_input_enable(hal->dev, gpio_num); + gpio_ll_func_sel(hal->dev, gpio_num, func); +} + +void gpio_hal_iomux_out(gpio_hal_context_t *hal, uint32_t gpio_num, int func, bool oen_inv) +{ + gpio_ll_set_output_enable_ctrl(hal->dev, gpio_num, true, oen_inv); + gpio_ll_func_sel(hal->dev, gpio_num, func); +} + #if SOC_GPIO_SUPPORT_PIN_HYS_FILTER void gpio_hal_hysteresis_soft_enable(gpio_hal_context_t *hal, uint32_t gpio_num, bool enable) { diff --git a/components/hal/include/hal/gpio_hal.h b/components/hal/include/hal/gpio_hal.h index 269456b217..546e434b1b 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 */ @@ -360,20 +360,22 @@ void gpio_hal_intr_disable(gpio_hal_context_t *hal, uint32_t gpio_num); * * @param hal Context of the HAL layer * @param gpio_num GPIO number of the pad. + * @param func The index number of the IOMUX function to be selected for the pin. + * One of the ``FUNC_X_*`` of specified pin (X) in ``soc/io_mux_reg.h``. * @param signal_idx Peripheral signal id to input. One of the ``*_IN_IDX`` signals in ``soc/gpio_sig_map.h``. */ -#define gpio_hal_iomux_in(hal, gpio_num, signal_idx) gpio_ll_iomux_in((hal)->dev, gpio_num, signal_idx) +void gpio_hal_iomux_in(gpio_hal_context_t *hal, uint32_t gpio_num, int func, uint32_t signal_idx); /** * @brief Set peripheral output to an GPIO pad through the IOMUX. * * @param hal Context of the HAL layer - * @param gpio_num gpio_num GPIO number of the pad. - * @param func The function number of the peripheral pin to output pin. + * @param gpio_num GPIO number of the pad. + * @param func The index number of the IOMUX function to be selected for the 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) + void gpio_hal_iomux_out(gpio_hal_context_t *hal, uint32_t gpio_num, int func, bool oen_inv); #if SOC_GPIO_SUPPORT_FORCE_HOLD /** diff --git a/components/spi_flash/test_apps/esp_flash/main/test_esp_flash_drv.c b/components/spi_flash/test_apps/esp_flash/main/test_esp_flash_drv.c index b75e3b7eaf..be079fcf01 100644 --- a/components/spi_flash/test_apps/esp_flash/main/test_esp_flash_drv.c +++ b/components/spi_flash/test_apps/esp_flash/main/test_esp_flash_drv.c @@ -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: Unlicense OR CC0-1.0 */ @@ -20,6 +20,7 @@ #include "test_utils.h" #include "unity.h" #include "driver/gpio.h" +#include "esp_private/gpio.h" #include "soc/io_mux_reg.h" #include "sdkconfig.h" @@ -99,10 +100,10 @@ static void setup_bus(spi_host_device_t host_id) //Initialize the WP and HD pins, which are not automatically initialized on ESP32-S2. int wp_pin = spi_periph_signal[host_id].spiwp_iomux_pin; int hd_pin = spi_periph_signal[host_id].spihd_iomux_pin; - gpio_iomux_in(wp_pin, spi_periph_signal[host_id].spiwp_in); - gpio_iomux_out(wp_pin, spi_periph_signal[host_id].func, false); - gpio_iomux_in(hd_pin, spi_periph_signal[host_id].spihd_in); - gpio_iomux_out(hd_pin, spi_periph_signal[host_id].func, false); + gpio_iomux_input(wp_pin, spi_periph_signal[host_id].func, spi_periph_signal[host_id].spiwp_in); + gpio_iomux_output(wp_pin, spi_periph_signal[host_id].func, false); + gpio_iomux_input(hd_pin, spi_periph_signal[host_id].func, spi_periph_signal[host_id].spihd_in); + gpio_iomux_output(hd_pin, spi_periph_signal[host_id].func, false); #endif //CONFIG_ESPTOOLPY_FLASHMODE_QIO || CONFIG_ESPTOOLPY_FLASHMODE_QOUT //currently the SPI bus for main flash chip is initialized through GPIO matrix } else if (host_id == SPI2_HOST) { From a6ac2bb3220fc911a30b6165f2df09164c7f746e Mon Sep 17 00:00:00 2001 From: Song Ruo Jing Date: Tue, 14 Jan 2025 19:47:18 +0800 Subject: [PATCH 2/2] refactor(gpio): improve gpio_get_io_config API --- .../esp_driver_gpio/include/driver/gpio.h | 14 +----- components/esp_driver_gpio/src/gpio.c | 46 ++++++----------- components/hal/esp32/include/hal/gpio_ll.h | 50 ++++--------------- components/hal/esp32c2/include/hal/gpio_ll.h | 50 ++++--------------- components/hal/esp32c3/include/hal/gpio_ll.h | 50 ++++--------------- components/hal/esp32c5/include/hal/gpio_ll.h | 50 ++++--------------- components/hal/esp32c6/include/hal/gpio_ll.h | 50 ++++--------------- components/hal/esp32c61/include/hal/gpio_ll.h | 50 ++++--------------- components/hal/esp32h2/include/hal/gpio_ll.h | 50 ++++--------------- components/hal/esp32h21/include/hal/gpio_ll.h | 32 ++++-------- components/hal/esp32p4/include/hal/gpio_ll.h | 50 ++++--------------- components/hal/esp32s2/include/hal/gpio_ll.h | 50 ++++--------------- components/hal/esp32s3/include/hal/gpio_ll.h | 50 ++++--------------- components/hal/include/hal/gpio_hal.h | 13 +---- components/hal/include/hal/gpio_types.h | 19 ++++++- 15 files changed, 159 insertions(+), 465 deletions(-) diff --git a/components/esp_driver_gpio/include/driver/gpio.h b/components/esp_driver_gpio/include/driver/gpio.h index 49bd4b07d4..af7e801bfb 100644 --- a/components/esp_driver_gpio/include/driver/gpio.h +++ b/components/esp_driver_gpio/include/driver/gpio.h @@ -594,23 +594,13 @@ esp_err_t gpio_dump_io_configuration(FILE *out_stream, uint64_t io_bit_mask); * @brief Get the configuration for an IO * * @param gpio_num GPIO number - * @param pu Pointer to accept the status of pull-up enabled or not, passing in NULL if this info is unwanted - * @param pd Pointer to accept the status of pull-down enabled or not, passing in NULL if this info is unwanted - * @param ie Pointer to accept the status of input enabled or not, passing in NULL if this info is unwanted - * @param oe Pointer to accept the status of output enabled or not, passing in NULL if this info is unwanted - * @param od Pointer to accept the status of open-drain enabled or not, passing in NULL if this info is unwanted - * @param drv Pointer to accept the value of drive strength, passing in NULL if this info is unwanted - * @param fun_sel Pointer to accept the value of IOMUX function selection, passing in NULL if this info is unwanted - * @param sig_out Pointer to accept the index of outputting peripheral signal, passing in NULL if this info is unwanted - * @param slp_sel Pointer to accept the status of pin sleep mode enabled or not, passing in NULL if this info is unwanted + * @param[out] out_io_config Pointer to the structure that saves the specific IO configuration * * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error */ -esp_err_t gpio_get_io_config(gpio_num_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); +esp_err_t gpio_get_io_config(gpio_num_t gpio_num, gpio_io_config_t *out_io_config); #ifdef __cplusplus } diff --git a/components/esp_driver_gpio/src/gpio.c b/components/esp_driver_gpio/src/gpio.c index 5863871681..7742ff10a2 100644 --- a/components/esp_driver_gpio/src/gpio.c +++ b/components/esp_driver_gpio/src/gpio.c @@ -1064,24 +1064,18 @@ esp_err_t gpio_deep_sleep_wakeup_disable(gpio_num_t gpio_num) } #endif // SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP && SOC_DEEP_SLEEP_SUPPORTED -esp_err_t gpio_get_io_config(gpio_num_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) +esp_err_t gpio_get_io_config(gpio_num_t gpio_num, gpio_io_config_t *out_io_config) { GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); - gpio_hal_get_io_config(gpio_context.gpio_hal, gpio_num, pu, pd, ie, oe, od, drv, fun_sel, sig_out, slp_sel); + ESP_RETURN_ON_FALSE(out_io_config, ESP_ERR_INVALID_ARG, GPIO_TAG, "out_io_config is a null pointer"); + + gpio_hal_get_io_config(gpio_context.gpio_hal, gpio_num, out_io_config); #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); - if (pu) { - *pu = rtcio_hal_is_pullup_enabled(rtcio_num); - } - if (pd) { - *pd = rtcio_hal_is_pulldown_enabled(rtcio_num); - } - if (drv) { - *drv = rtcio_hal_get_drive_capability(rtcio_num); - } + out_io_config->pu = rtcio_hal_is_pullup_enabled(rtcio_num); + out_io_config->pd = rtcio_hal_is_pulldown_enabled(rtcio_num); + out_io_config->drv = rtcio_hal_get_drive_capability(rtcio_num); } #endif return ESP_OK; @@ -1097,25 +1091,17 @@ 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 = 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_get_io_config(gpio_num, &pu, &pd, &ie, &oe, &od, &drv, &fun_sel, &sig_out, &slp_sel); + gpio_io_config_t io_config = {}; + gpio_get_io_config(gpio_num, &io_config); 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, " FuncSel: %"PRIu32" (%s)\n", fun_sel, (fun_sel == PIN_FUNC_GPIO) ? "GPIO" : "IOMUX"); - if (oe && 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)" : ""); + fprintf(out_stream, " Pullup: %d, Pulldown: %d, DriveCap: %"PRIu32"\n", io_config.pu, io_config.pd, (uint32_t)io_config.drv); + fprintf(out_stream, " InputEn: %d, OutputEn: %d, OpenDrain: %d\n", io_config.ie, io_config.oe, io_config.od); + fprintf(out_stream, " FuncSel: %"PRIu32" (%s)\n", io_config.fun_sel, (io_config.fun_sel == PIN_FUNC_GPIO) ? "GPIO" : "IOMUX"); + if (io_config.oe && io_config.fun_sel == PIN_FUNC_GPIO) { + fprintf(out_stream, " GPIO Matrix SigOut ID: %"PRIu32"%s\n", io_config.sig_out, (io_config.sig_out == SIG_GPIO_OUT_IDX) ? " (simple GPIO output)" : ""); } - if (ie && fun_sel == PIN_FUNC_GPIO) { + if (io_config.ie && io_config.fun_sel == PIN_FUNC_GPIO) { uint32_t cnt = 0; fprintf(out_stream, " GPIO Matrix SigIn ID:"); for (int i = 0; i < SIG_GPIO_OUT_IDX; i++) { @@ -1129,7 +1115,7 @@ esp_err_t gpio_dump_io_configuration(FILE *out_stream, uint64_t io_bit_mask) } fprintf(out_stream, "\n"); } - fprintf(out_stream, " SleepSelEn: %d\n", slp_sel); + fprintf(out_stream, " SleepSelEn: %d\n", io_config.slp_sel); fprintf(out_stream, "\n"); } fprintf(out_stream, "=================IO DUMP End=================\n"); diff --git a/components/hal/esp32/include/hal/gpio_ll.h b/components/hal/esp32/include/hal/gpio_ll.h index 2b2e2ba2ac..44e3f5fb5a 100644 --- a/components/hal/esp32/include/hal/gpio_ll.h +++ b/components/hal/esp32/include/hal/gpio_ll.h @@ -47,50 +47,22 @@ extern const uint8_t GPIO_PIN_MUX_REG_OFFSET[SOC_GPIO_PIN_COUNT]; * * @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 + * @param[out] io_config Pointer to the structure that saves the specific IO configuration */ -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) +static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, gpio_io_config_t *io_config) { 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]); - if (pu) { - *pu = (iomux_reg_val & FUN_PU_M) >> FUN_PU_S; - } - if (pd) { - *pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S; - } - if (ie) { - *ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S; - } - if (oe) { - *oe = (((gpio_num < 32) ? hw->enable : hw->enable1.val) & bit_mask) >> bit_shift; - } - if (od) { - *od = hw->pin[gpio_num].pad_driver; - } - if (drv) { - *drv = (iomux_reg_val & FUN_DRV_M) >> FUN_DRV_S; - } - if (fun_sel) { - *fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S; - } - if (sig_out) { - *sig_out = hw->func_out_sel_cfg[gpio_num].func_sel; - } - if (slp_sel) { - *slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S; - } + io_config->pu = (iomux_reg_val & FUN_PU_M) >> FUN_PU_S; + io_config->pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S; + io_config->ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S; + io_config->oe = (((gpio_num < 32) ? hw->enable : hw->enable1.val) & bit_mask) >> bit_shift; + io_config->od = hw->pin[gpio_num].pad_driver; + io_config->drv = (gpio_drive_cap_t)((iomux_reg_val & FUN_DRV_M) >> FUN_DRV_S); + io_config->fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S; + io_config->sig_out = hw->func_out_sel_cfg[gpio_num].func_sel; + io_config->slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S; } /** diff --git a/components/hal/esp32c2/include/hal/gpio_ll.h b/components/hal/esp32c2/include/hal/gpio_ll.h index 534ff1164e..30866fa130 100644 --- a/components/hal/esp32c2/include/hal/gpio_ll.h +++ b/components/hal/esp32c2/include/hal/gpio_ll.h @@ -38,49 +38,21 @@ extern "C" { * * @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 + * @param[out] io_config Pointer to the structure that saves the specific IO configuration */ -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) +static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, gpio_io_config_t *io_config) { uint32_t bit_mask = 1 << gpio_num; uint32_t iomux_reg_val = REG_READ(GPIO_PIN_MUX_REG[gpio_num]); - if (pu) { - *pu = (iomux_reg_val & FUN_PU_M) >> FUN_PU_S; - } - if (pd) { - *pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S; - } - if (ie) { - *ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S; - } - if (oe) { - *oe = (hw->enable.val & bit_mask) >> gpio_num; - } - if (od) { - *od = hw->pin[gpio_num].pad_driver; - } - if (drv) { - *drv = (iomux_reg_val & FUN_DRV_M) >> FUN_DRV_S; - } - if (fun_sel) { - *fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S; - } - if (sig_out) { - *sig_out = HAL_FORCE_READ_U32_REG_FIELD(hw->func_out_sel_cfg[gpio_num], out_sel); - } - if (slp_sel) { - *slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S; - } + io_config->pu = (iomux_reg_val & FUN_PU_M) >> FUN_PU_S; + io_config->pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S; + io_config->ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S; + io_config->oe = (hw->enable.val & bit_mask) >> gpio_num; + io_config->od = hw->pin[gpio_num].pad_driver; + io_config->drv = (gpio_drive_cap_t)((iomux_reg_val & FUN_DRV_M) >> FUN_DRV_S); + io_config->fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S; + io_config->sig_out = HAL_FORCE_READ_U32_REG_FIELD(hw->func_out_sel_cfg[gpio_num], out_sel); + io_config->slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S; } /** diff --git a/components/hal/esp32c3/include/hal/gpio_ll.h b/components/hal/esp32c3/include/hal/gpio_ll.h index 7ce22c2d63..40eadb5f3c 100644 --- a/components/hal/esp32c3/include/hal/gpio_ll.h +++ b/components/hal/esp32c3/include/hal/gpio_ll.h @@ -741,49 +741,21 @@ static inline bool gpio_ll_deepsleep_wakeup_is_enabled(gpio_dev_t *hw, uint32_t * * @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 + * @param[out] io_config Pointer to the structure that saves the specific IO configuration */ -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) +static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, gpio_io_config_t *io_config) { uint32_t bit_mask = 1 << gpio_num; uint32_t iomux_reg_val = REG_READ(GPIO_PIN_MUX_REG[gpio_num]); - if (pu) { - *pu = (iomux_reg_val & FUN_PU_M) >> FUN_PU_S; - } - if (pd) { - *pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S; - } - if (ie) { - *ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S; - } - if (oe) { - *oe = (hw->enable.val & bit_mask) >> gpio_num; - } - if (od) { - *od = hw->pin[gpio_num].pad_driver; - } - if (drv) { - gpio_ll_get_drive_capability(hw, gpio_num, (gpio_drive_cap_t *)drv); // specific workaround in the LL - } - if (fun_sel) { - *fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S; - } - if (sig_out) { - *sig_out = HAL_FORCE_READ_U32_REG_FIELD(hw->func_out_sel_cfg[gpio_num], out_sel); - } - if (slp_sel) { - *slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S; - } + io_config->pu = (iomux_reg_val & FUN_PU_M) >> FUN_PU_S; + io_config->pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S; + io_config->ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S; + io_config->oe = (hw->enable.val & bit_mask) >> gpio_num; + io_config->od = hw->pin[gpio_num].pad_driver; + gpio_ll_get_drive_capability(hw, gpio_num, &(io_config->drv)); // specific workaround in the LL + io_config->fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S; + io_config->sig_out = HAL_FORCE_READ_U32_REG_FIELD(hw->func_out_sel_cfg[gpio_num], out_sel); + io_config->slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S; } #ifdef __cplusplus diff --git a/components/hal/esp32c5/include/hal/gpio_ll.h b/components/hal/esp32c5/include/hal/gpio_ll.h index ee87ac5f21..af0429fd89 100644 --- a/components/hal/esp32c5/include/hal/gpio_ll.h +++ b/components/hal/esp32c5/include/hal/gpio_ll.h @@ -42,47 +42,19 @@ extern "C" { * * @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 + * @param[out] io_config Pointer to the structure that saves the specific IO configuration */ -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) +static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, gpio_io_config_t *io_config) { - if (pu) { - *pu = IO_MUX.gpio[gpio_num].fun_wpu; - } - if (pd) { - *pd = IO_MUX.gpio[gpio_num].fun_wpd; - } - if (ie) { - *ie = IO_MUX.gpio[gpio_num].fun_ie; - } - if (oe) { - *oe = (hw->enable.val & (1 << gpio_num)) >> gpio_num; - } - if (od) { - *od = hw->pin[gpio_num].pad_driver; - } - if (drv) { - *drv = IO_MUX.gpio[gpio_num].fun_drv; - } - if (fun_sel) { - *fun_sel = IO_MUX.gpio[gpio_num].mcu_sel; - } - if (sig_out) { - *sig_out = hw->func_out_sel_cfg[gpio_num].out_sel; - } - if (slp_sel) { - *slp_sel = IO_MUX.gpio[gpio_num].slp_sel; - } + io_config->pu = IO_MUX.gpio[gpio_num].fun_wpu; + io_config->pd = IO_MUX.gpio[gpio_num].fun_wpd; + io_config->ie = IO_MUX.gpio[gpio_num].fun_ie; + io_config->oe = (hw->enable.val & (1 << gpio_num)) >> gpio_num; + io_config->od = hw->pin[gpio_num].pad_driver; + io_config->drv = (gpio_drive_cap_t)IO_MUX.gpio[gpio_num].fun_drv; + io_config->fun_sel = IO_MUX.gpio[gpio_num].mcu_sel; + io_config->sig_out = hw->func_out_sel_cfg[gpio_num].out_sel; + io_config->slp_sel = IO_MUX.gpio[gpio_num].slp_sel; } /** diff --git a/components/hal/esp32c6/include/hal/gpio_ll.h b/components/hal/esp32c6/include/hal/gpio_ll.h index 733a6ca999..1e23bdcb36 100644 --- a/components/hal/esp32c6/include/hal/gpio_ll.h +++ b/components/hal/esp32c6/include/hal/gpio_ll.h @@ -43,49 +43,21 @@ extern "C" { * * @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 + * @param[out] io_config Pointer to the structure that saves the specific IO configuration */ -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) +static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, gpio_io_config_t *io_config) { uint32_t bit_mask = 1 << gpio_num; uint32_t iomux_reg_val = REG_READ(IO_MUX_GPIO0_REG + (gpio_num * 4)); - if (pu) { - *pu = (iomux_reg_val & FUN_PU_M) >> FUN_PU_S; - } - if (pd) { - *pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S; - } - if (ie) { - *ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S; - } - if (oe) { - *oe = (hw->enable.val & bit_mask) >> gpio_num; - } - if (od) { - *od = hw->pin[gpio_num].pad_driver; - } - if (drv) { - *drv = (iomux_reg_val & FUN_DRV_M) >> FUN_DRV_S; - } - if (fun_sel) { - *fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S; - } - if (sig_out) { - *sig_out = HAL_FORCE_READ_U32_REG_FIELD(hw->func_out_sel_cfg[gpio_num], out_sel); - } - if (slp_sel) { - *slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S; - } + io_config->pu = (iomux_reg_val & FUN_PU_M) >> FUN_PU_S; + io_config->pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S; + io_config->ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S; + io_config->oe = (hw->enable.val & bit_mask) >> gpio_num; + io_config->od = hw->pin[gpio_num].pad_driver; + io_config->drv = (gpio_drive_cap_t)((iomux_reg_val & FUN_DRV_M) >> FUN_DRV_S); + io_config->fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S; + io_config->sig_out = HAL_FORCE_READ_U32_REG_FIELD(hw->func_out_sel_cfg[gpio_num], out_sel); + io_config->slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S; } /** diff --git a/components/hal/esp32c61/include/hal/gpio_ll.h b/components/hal/esp32c61/include/hal/gpio_ll.h index f8c44f1b40..cd2b594310 100644 --- a/components/hal/esp32c61/include/hal/gpio_ll.h +++ b/components/hal/esp32c61/include/hal/gpio_ll.h @@ -43,47 +43,19 @@ extern "C" { * * @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 + * @param[out] io_config Pointer to the structure that saves the specific IO configuration */ -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) +static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, gpio_io_config_t *io_config) { - if (pu) { - *pu = IO_MUX.gpion[gpio_num].gpion_fun_wpu; - } - if (pd) { - *pd = IO_MUX.gpion[gpio_num].gpion_fun_wpd; - } - if (ie) { - *ie = IO_MUX.gpion[gpio_num].gpion_fun_ie; - } - if (oe) { - *oe = (hw->enable.val & (1 << gpio_num)) >> gpio_num; - } - if (od) { - *od = hw->pinn[gpio_num].pinn_pad_driver; - } - if (drv) { - *drv = IO_MUX.gpion[gpio_num].gpion_fun_drv; - } - if (fun_sel) { - *fun_sel = IO_MUX.gpion[gpio_num].gpion_mcu_sel; - } - if (sig_out) { - *sig_out = hw->funcn_out_sel_cfg[gpio_num].funcn_out_sel; - } - if (slp_sel) { - *slp_sel = IO_MUX.gpion[gpio_num].gpion_slp_sel; - } + io_config->pu = IO_MUX.gpion[gpio_num].gpion_fun_wpu; + io_config->pd = IO_MUX.gpion[gpio_num].gpion_fun_wpd; + io_config->ie = IO_MUX.gpion[gpio_num].gpion_fun_ie; + io_config->oe = (hw->enable.val & (1 << gpio_num)) >> gpio_num; + io_config->od = hw->pinn[gpio_num].pinn_pad_driver; + io_config->drv = (gpio_drive_cap_t)IO_MUX.gpion[gpio_num].gpion_fun_drv; + io_config->fun_sel = IO_MUX.gpion[gpio_num].gpion_mcu_sel; + io_config->sig_out = hw->funcn_out_sel_cfg[gpio_num].funcn_out_sel; + io_config->slp_sel = IO_MUX.gpion[gpio_num].gpion_slp_sel; } /** diff --git a/components/hal/esp32h2/include/hal/gpio_ll.h b/components/hal/esp32h2/include/hal/gpio_ll.h index f274a31a81..59f9199791 100644 --- a/components/hal/esp32h2/include/hal/gpio_ll.h +++ b/components/hal/esp32h2/include/hal/gpio_ll.h @@ -43,49 +43,21 @@ extern "C" { * * @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 + * @param[out] io_config Pointer to the structure that saves the specific IO configuration */ -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) +static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, gpio_io_config_t *io_config) { uint32_t bit_mask = 1 << gpio_num; uint32_t iomux_reg_val = REG_READ(IO_MUX_GPIO0_REG + (gpio_num * 4)); - if (pu) { - *pu = (iomux_reg_val & FUN_PU_M) >> FUN_PU_S; - } - if (pd) { - *pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S; - } - if (ie) { - *ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S; - } - if (oe) { - *oe = (hw->enable.val & bit_mask) >> gpio_num; - } - if (od) { - *od = hw->pin[gpio_num].pad_driver; - } - if (drv) { - *drv = (iomux_reg_val & FUN_DRV_M) >> FUN_DRV_S; - } - if (fun_sel) { - *fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S; - } - if (sig_out) { - *sig_out = HAL_FORCE_READ_U32_REG_FIELD(hw->func_out_sel_cfg[gpio_num], out_sel); - } - if (slp_sel) { - *slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S; - } + io_config->pu = (iomux_reg_val & FUN_PU_M) >> FUN_PU_S; + io_config->pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S; + io_config->ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S; + io_config->oe = (hw->enable.val & bit_mask) >> gpio_num; + io_config->od = hw->pin[gpio_num].pad_driver; + io_config->drv = (gpio_drive_cap_t)((iomux_reg_val & FUN_DRV_M) >> FUN_DRV_S); + io_config->fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S; + io_config->sig_out = HAL_FORCE_READ_U32_REG_FIELD(hw->func_out_sel_cfg[gpio_num], out_sel); + io_config->slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S; } /** diff --git a/components/hal/esp32h21/include/hal/gpio_ll.h b/components/hal/esp32h21/include/hal/gpio_ll.h index 1213e6a02c..a20018b100 100644 --- a/components/hal/esp32h21/include/hal/gpio_ll.h +++ b/components/hal/esp32h21/include/hal/gpio_ll.h @@ -45,31 +45,21 @@ extern "C" { * * @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 + * @param[out] io_config Pointer to the structure that saves the specific IO configuration */ -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) +static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, gpio_io_config_t *io_config) { uint32_t bit_mask = 1 << gpio_num; uint32_t iomux_reg_val = REG_READ(IO_MUX_GPIO0_REG + (gpio_num * 4)); - *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->pinn[gpio_num].pinn_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->funcn_out_sel_cfg[gpio_num].funcn_out_sel; - *slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S; + io_config->pu = (iomux_reg_val & FUN_PU_M) >> FUN_PU_S; + io_config->pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S; + io_config->ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S; + io_config->oe = (hw->enable.val & bit_mask) >> gpio_num; + io_config->od = hw->pinn[gpio_num].pinn_pad_driver; + io_config->drv = (gpio_drive_cap_t)((iomux_reg_val & FUN_DRV_M) >> FUN_DRV_S); + io_config->fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S; + io_config->sig_out = hw->funcn_out_sel_cfg[gpio_num].funcn_out_sel; + io_config->slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S; } /** diff --git a/components/hal/esp32p4/include/hal/gpio_ll.h b/components/hal/esp32p4/include/hal/gpio_ll.h index 6dbe4a3b1a..bb65323af6 100644 --- a/components/hal/esp32p4/include/hal/gpio_ll.h +++ b/components/hal/esp32p4/include/hal/gpio_ll.h @@ -49,49 +49,21 @@ extern "C" { * * @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 + * @param[out] io_config Pointer to the structure that saves the specific IO configuration */ -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) +static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, gpio_io_config_t *io_config) { uint32_t bit_shift = (gpio_num < 32) ? gpio_num : (gpio_num - 32); uint32_t bit_mask = 1 << bit_shift; - if (pu) { - *pu = IO_MUX.gpio[gpio_num].fun_wpu; - } - if (pd) { - *pd = IO_MUX.gpio[gpio_num].fun_wpd; - } - if (ie) { - *ie = IO_MUX.gpio[gpio_num].fun_ie; - } - if (oe) { - *oe = (((gpio_num < 32) ? hw->enable.val : hw->enable1.val) & bit_mask) >> bit_shift; - } - if (od) { - *od = hw->pin[gpio_num].pad_driver; - } - if (drv) { - *drv = IO_MUX.gpio[gpio_num].fun_drv; - } - if (fun_sel) { - *fun_sel = IO_MUX.gpio[gpio_num].mcu_sel; - } - if (sig_out) { - *sig_out = hw->func_out_sel_cfg[gpio_num].out_sel; - } - if (slp_sel) { - *slp_sel = IO_MUX.gpio[gpio_num].slp_sel; - } + io_config->pu = IO_MUX.gpio[gpio_num].fun_wpu; + io_config->pd = IO_MUX.gpio[gpio_num].fun_wpd; + io_config->ie = IO_MUX.gpio[gpio_num].fun_ie; + io_config->oe = (((gpio_num < 32) ? hw->enable.val : hw->enable1.val) & bit_mask) >> bit_shift; + io_config->od = hw->pin[gpio_num].pad_driver; + io_config->drv = (gpio_drive_cap_t)IO_MUX.gpio[gpio_num].fun_drv; + io_config->fun_sel = IO_MUX.gpio[gpio_num].mcu_sel; + io_config->sig_out = hw->func_out_sel_cfg[gpio_num].out_sel; + io_config->slp_sel = IO_MUX.gpio[gpio_num].slp_sel; } /** diff --git a/components/hal/esp32s2/include/hal/gpio_ll.h b/components/hal/esp32s2/include/hal/gpio_ll.h index 16ac0edb3b..7d450a25e4 100644 --- a/components/hal/esp32s2/include/hal/gpio_ll.h +++ b/components/hal/esp32s2/include/hal/gpio_ll.h @@ -37,50 +37,22 @@ extern "C" { * * @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 + * @param[out] io_config Pointer to the structure that saves the specific IO configuration */ -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) +static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, gpio_io_config_t *io_config) { 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]); - if (pu) { - *pu = (iomux_reg_val & FUN_PU_M) >> FUN_PU_S; - } - if (pd) { - *pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S; - } - if (ie) { - *ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S; - } - if (oe) { - *oe = (((gpio_num < 32) ? hw->enable : hw->enable1.val) & bit_mask) >> bit_shift; - } - if (od) { - *od = hw->pin[gpio_num].pad_driver; - } - if (drv) { - *drv = (iomux_reg_val & FUN_DRV_M) >> FUN_DRV_S; - } - if (fun_sel) { - *fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S; - } - if (sig_out) { - *sig_out = hw->func_out_sel_cfg[gpio_num].func_sel; - } - if (slp_sel) { - *slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S; - } + io_config->pu = (iomux_reg_val & FUN_PU_M) >> FUN_PU_S; + io_config->pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S; + io_config->ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S; + io_config->oe = (((gpio_num < 32) ? hw->enable : hw->enable1.val) & bit_mask) >> bit_shift; + io_config->od = hw->pin[gpio_num].pad_driver; + io_config->drv = (gpio_drive_cap_t)((iomux_reg_val & FUN_DRV_M) >> FUN_DRV_S); + io_config->fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S; + io_config->sig_out = hw->func_out_sel_cfg[gpio_num].func_sel; + io_config->slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S; } /** diff --git a/components/hal/esp32s3/include/hal/gpio_ll.h b/components/hal/esp32s3/include/hal/gpio_ll.h index 33440ee77f..9f547b4b09 100644 --- a/components/hal/esp32s3/include/hal/gpio_ll.h +++ b/components/hal/esp32s3/include/hal/gpio_ll.h @@ -705,50 +705,22 @@ static inline void gpio_ll_sleep_output_enable(gpio_dev_t *hw, uint32_t gpio_num * * @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 + * @param[out] io_config Pointer to the structure that saves the specific IO configuration */ -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) +static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, gpio_io_config_t *io_config) { 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]); - if (pu) { - *pu = (iomux_reg_val & FUN_PU_M) >> FUN_PU_S; - } - if (pd) { - *pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S; - } - if (ie) { - *ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S; - } - if (oe) { - *oe = (((gpio_num < 32) ? hw->enable : hw->enable1.val) & bit_mask) >> bit_shift; - } - if (od) { - *od = hw->pin[gpio_num].pad_driver; - } - if (drv) { - gpio_ll_get_drive_capability(hw, gpio_num, (gpio_drive_cap_t *)drv); // specific workaround in the LL - } - if (fun_sel) { - *fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S; - } - if (sig_out) { - *sig_out = hw->func_out_sel_cfg[gpio_num].func_sel; - } - if (slp_sel) { - *slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S; - } + io_config->pu = (iomux_reg_val & FUN_PU_M) >> FUN_PU_S; + io_config->pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S; + io_config->ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S; + io_config->oe = (((gpio_num < 32) ? hw->enable : hw->enable1.val) & bit_mask) >> bit_shift; + io_config->od = hw->pin[gpio_num].pad_driver; + gpio_ll_get_drive_capability(hw, gpio_num, &(io_config->drv)); // specific workaround in the LL + io_config->fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S; + io_config->sig_out = hw->func_out_sel_cfg[gpio_num].func_sel; + io_config->slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S; } #ifdef __cplusplus diff --git a/components/hal/include/hal/gpio_hal.h b/components/hal/include/hal/gpio_hal.h index 546e434b1b..68f803b4c2 100644 --- a/components/hal/include/hal/gpio_hal.h +++ b/components/hal/include/hal/gpio_hal.h @@ -39,18 +39,9 @@ typedef struct { * * @param hal Context of the HAL layer * @param gpio_num GPIO number - * @param pu Pointer to accept the status of pull-up enabled or not - * @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 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 + * @param[out] out_io_config Pointer to the structure that saves the specific IO configuration */ -#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, out_io_config) gpio_ll_get_io_config((hal)->dev, gpio_num, out_io_config) /** * @brief Enable pull-up on GPIO. diff --git a/components/hal/include/hal/gpio_types.h b/components/hal/include/hal/gpio_types.h index d785ec491a..093da239bd 100644 --- a/components/hal/include/hal/gpio_types.h +++ b/components/hal/include/hal/gpio_types.h @@ -1,11 +1,13 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once +#include +#include #include "soc/soc_caps.h" #include "soc/gpio_num.h" #include "esp_bit_defs.h" @@ -140,6 +142,21 @@ typedef enum { } gpio_hys_ctrl_mode_t; #endif +/** + * @brief Structure that contains the configuration of an IO + */ +typedef struct { + uint32_t fun_sel; /*!< Value of IOMUX function selection */ + uint32_t sig_out; /*!< Index of the outputting peripheral signal */ + gpio_drive_cap_t drv; /*!< Value of drive strength */ + bool pu; /*!< Status of pull-up enabled or not */ + bool pd; /*!< Status of pull-down enabled or not */ + bool ie; /*!< Status of input enabled or not */ + bool oe; /*!< Status of output enabled or not */ + bool od; /*!< Status of open-drain enabled or not */ + bool slp_sel; /*!< Status of pin sleep mode enabled or not */ +} gpio_io_config_t; + #ifdef __cplusplus } #endif