From 3a8d065908683166336cead7c82624f2ecc3acf4 Mon Sep 17 00:00:00 2001 From: Song Ruo Jing Date: Tue, 14 Jan 2025 16:51:58 +0800 Subject: [PATCH] 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) {