diff --git a/components/esp_driver_gpio/README.md b/components/esp_driver_gpio/README.md index 273aadcf6d..9af30390f4 100644 --- a/components/esp_driver_gpio/README.md +++ b/components/esp_driver_gpio/README.md @@ -12,7 +12,7 @@ There is no need to enable the output for the IO explicitly, it is done internal 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. +If the signal is routed through GPIO Matrix to the pin, then call `gpio_matrix_output` to select the `PIN_FUNC_GPIO` function and connect the signal to the pin. When a peripheral driver does de-initialization, to de-configure the pin as the peripheral signal output, a call to `gpio_output_disable` is enough. It will disconnect the signal internally. @@ -20,7 +20,7 @@ When a peripheral driver does de-initialization, to de-configure the pin as the If the signal is routed through IO MUX to the pin, then 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 call `gpio_input_enable` and `esp_rom_gpio_connect_in_signal` to enable the input and connect the signal to the pin. +If the signal is routed through GPIO Matrix to the pin, then call `gpio_matrix_input` to enable the input and connect the signal to the pin. When a peripheral driver does de-initialization, to de-configure the pin as the peripheral signal input, use `esp_rom_gpio_connect_in_signal` to connect the signal to CONST_ONE or CONST_ZERO, so that it is disconnected from the pin. It is not desired to call `gpio_input_disable`, because there might be other drivers still using this pin as an input. diff --git a/components/esp_driver_gpio/include/driver/gpio.h b/components/esp_driver_gpio/include/driver/gpio.h index 681f88eaa1..a15bf533f0 100644 --- a/components/esp_driver_gpio/include/driver/gpio.h +++ b/components/esp_driver_gpio/include/driver/gpio.h @@ -497,22 +497,6 @@ void gpio_deep_sleep_hold_en(void); void gpio_deep_sleep_hold_dis(void); #endif //SOC_GPIO_SUPPORT_HOLD_IO_IN_DSLP && !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP -/** - * @brief Set pad input to a peripheral signal through the IOMUX. - * @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) __attribute__((deprecated("Please use `gpio_iomux_input` instead"))); - -/** - * @brief Set peripheral output to an GPIO pad through the IOMUX. - * @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 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) __attribute__((deprecated("Please use `gpio_iomux_output` instead"))); - #if SOC_GPIO_SUPPORT_FORCE_HOLD /** * @brief Force hold all digital and rtc gpio pads. diff --git a/components/esp_driver_gpio/include/esp_private/gpio.h b/components/esp_driver_gpio/include/esp_private/gpio.h index 66dd4092aa..473991c753 100644 --- a/components/esp_driver_gpio/include/esp_private/gpio.h +++ b/components/esp_driver_gpio/include/esp_private/gpio.h @@ -68,7 +68,7 @@ esp_err_t gpio_config_as_analog(gpio_num_t gpio_num); * @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``. + * @param signal_idx Peripheral signal index to input. One of the ``*_IN_IDX`` signals in ``soc/gpio_sig_map.h``. * * @return * - ESP_OK Success @@ -89,6 +89,41 @@ esp_err_t gpio_iomux_input(gpio_num_t gpio_num, int func, uint32_t signal_idx); */ esp_err_t gpio_iomux_output(gpio_num_t gpio_num, int func); +/** + * @brief Set pad input to a peripheral signal through the GPIO matrix. + * + * @note A GPIO can combine with multiple input signals. + * + * @param gpio_num GPIO number, especially, `GPIO_MATRIX_CONST_ZERO_INPUT` means connect logic 0 to signal; + * `GPIO_MATRIX_CONST_ONE_INPUT` means connect logic 1 to signal. + * @param signal_idx Peripheral signal index (tagged as input attribute). + * One of the ``*_IN_IDX`` signals in ``soc/gpio_sig_map.h``. + * @param in_inv Whether the GPIO input to be inverted or not. + * + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG GPIO number error + */ +esp_err_t gpio_matrix_input(gpio_num_t gpio_num, uint32_t signal_idx, bool in_inv); + +/** + * @brief Set peripheral output to an GPIO pad through the GPIO matrix. + * + * @note An output signal can be combined with multiple GPIOs. + * + * @param gpio_num GPIO number + * @param signal_idx Peripheral signal index (tagged as output attribute). + * One of the ``*_OUT_IDX`` signals in ``soc/gpio_sig_map.h``. + * Particularly, `SIG_GPIO_OUT_IDX` means disconnect GPIO with any peripheral. + * @param out_inv Whether to signal to be inverted or not. + * @param oen_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_matrix_output(gpio_num_t gpio_num, uint32_t signal_idx, bool out_inv, bool oen_inv); + #ifdef __cplusplus } #endif diff --git a/components/esp_driver_gpio/src/gpio.c b/components/esp_driver_gpio/src/gpio.c index 56a09aad33..fcf422824e 100644 --- a/components/esp_driver_gpio/src/gpio.c +++ b/components/esp_driver_gpio/src/gpio.c @@ -813,13 +813,6 @@ 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_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); @@ -831,13 +824,6 @@ esp_err_t gpio_iomux_input(gpio_num_t gpio_num, int func, uint32_t signal_idx) return ESP_OK; } -// Deprecated function -void gpio_iomux_out(uint8_t gpio_num, int func, bool out_en_inv) -{ - (void)out_en_inv; // out_en_inv only takes effect when signal goes through gpio matrix to the IO - gpio_hal_iomux_out(gpio_context.gpio_hal, gpio_num, func); -} - esp_err_t gpio_iomux_output(gpio_num_t gpio_num, int func) { GPIO_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); @@ -849,6 +835,24 @@ esp_err_t gpio_iomux_output(gpio_num_t gpio_num, int func) return ESP_OK; } +esp_err_t gpio_matrix_input(gpio_num_t gpio_num, uint32_t signal_idx, bool in_inv) +{ + GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); + + gpio_hal_matrix_in(gpio_context.gpio_hal, gpio_num, signal_idx, in_inv); + + return ESP_OK; +} + +esp_err_t gpio_matrix_output(gpio_num_t gpio_num, uint32_t signal_idx, bool out_inv, bool oen_inv) +{ + GPIO_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); + + gpio_hal_matrix_out(gpio_context.gpio_hal, gpio_num, signal_idx, out_inv, oen_inv); + + return ESP_OK; +} + static esp_err_t gpio_sleep_pullup_en(gpio_num_t gpio_num) { GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); diff --git a/components/esp_driver_ledc/src/ledc.c b/components/esp_driver_ledc/src/ledc.c index 9737e06cbf..1db84af62c 100644 --- a/components/esp_driver_ledc/src/ledc.c +++ b/components/esp_driver_ledc/src/ledc.c @@ -17,7 +17,6 @@ #include "soc/soc_caps.h" #include "hal/ledc_hal.h" #include "driver/ledc.h" -#include "esp_rom_gpio.h" #include "clk_ctrl_os.h" #include "esp_private/esp_sleep_internal.h" #include "esp_private/periph_ctrl.h" @@ -807,14 +806,13 @@ esp_err_t ledc_timer_config(const ledc_timer_config_t *timer_conf) esp_err_t _ledc_set_pin(int gpio_num, bool out_inv, ledc_mode_t speed_mode, ledc_channel_t channel) { - gpio_func_sel(gpio_num, PIN_FUNC_GPIO); // reserve the GPIO output path, because we don't expect another peripheral to signal to the same GPIO uint64_t old_gpio_rsv_mask = esp_gpio_reserve(BIT64(gpio_num)); // check if the GPIO is already used by others, LEDC signal only uses the output path of the GPIO if (old_gpio_rsv_mask & BIT64(gpio_num)) { ESP_LOGW(LEDC_TAG, "GPIO %d is not usable, maybe conflict with others", gpio_num); } - esp_rom_gpio_connect_out_signal(gpio_num, ledc_periph_signal[speed_mode].sig_out0_idx + channel, out_inv, 0); + gpio_matrix_output(gpio_num, ledc_periph_signal[speed_mode].sig_out0_idx + channel, out_inv, false); return ESP_OK; } diff --git a/components/esp_driver_ledc/test_apps/ledc/sdkconfig.ci.iram_safe b/components/esp_driver_ledc/test_apps/ledc/sdkconfig.ci.iram_safe index c20ccf5cf6..90e54a6377 100644 --- a/components/esp_driver_ledc/test_apps/ledc/sdkconfig.ci.iram_safe +++ b/components/esp_driver_ledc/test_apps/ledc/sdkconfig.ci.iram_safe @@ -7,3 +7,5 @@ CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y # ledc driver uses assert in the ISR code path CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE=y CONFIG_LEDC_CTRL_FUNC_IN_IRAM=y +# test gpio signal connection with non-default option +CONFIG_HAL_GPIO_USE_ROM_IMPL=n diff --git a/components/esp_driver_uart/src/uart.c b/components/esp_driver_uart/src/uart.c index 8eb9caa1eb..77b6e3f28a 100644 --- a/components/esp_driver_uart/src/uart.c +++ b/components/esp_driver_uart/src/uart.c @@ -844,10 +844,7 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r #endif if (tx_rx_same_io || !uart_try_set_iomux_pin(uart_num, tx_io_num, SOC_UART_TX_PIN_IDX)) { if (uart_num < SOC_UART_HP_NUM) { - gpio_func_sel(tx_io_num, PIN_FUNC_GPIO); - esp_rom_gpio_connect_out_signal(tx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_TX_PIN_IDX), 0, 0); - // output enable is set inside esp_rom_gpio_connect_out_signal func after the signal is connected - // (output enabled too early may cause unnecessary level change at the pad) + gpio_matrix_output(tx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_TX_PIN_IDX), false, false); } #if SOC_LP_GPIO_MATRIX_SUPPORTED else { @@ -870,8 +867,7 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r if (tx_rx_same_io || !uart_try_set_iomux_pin(uart_num, rx_io_num, SOC_UART_RX_PIN_IDX)) { io_reserve_mask &= ~BIT64(rx_io_num); // input IO via GPIO matrix does not need to be reserved if (uart_num < SOC_UART_HP_NUM) { - gpio_input_enable(rx_io_num); - esp_rom_gpio_connect_in_signal(rx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RX_PIN_IDX), 0); + gpio_matrix_input(rx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RX_PIN_IDX), false); } #if SOC_LP_GPIO_MATRIX_SUPPORTED else { @@ -889,9 +885,7 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r if (rts_io_num >= 0 && (uart_context[uart_num].rts_io_num = rts_io_num, !uart_try_set_iomux_pin(uart_num, rts_io_num, SOC_UART_RTS_PIN_IDX))) { if (uart_num < SOC_UART_HP_NUM) { - gpio_func_sel(rts_io_num, PIN_FUNC_GPIO); - esp_rom_gpio_connect_out_signal(rts_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RTS_PIN_IDX), 0, 0); - // output enable is set inside esp_rom_gpio_connect_out_signal func after the signal is connected + gpio_matrix_output(rts_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RTS_PIN_IDX), false, false); } #if SOC_LP_GPIO_MATRIX_SUPPORTED else { @@ -905,9 +899,7 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r if (cts_io_num >= 0 && (uart_context[uart_num].cts_io_num = cts_io_num, !uart_try_set_iomux_pin(uart_num, cts_io_num, SOC_UART_CTS_PIN_IDX))) { io_reserve_mask &= ~BIT64(cts_io_num); // input IO via GPIO matrix does not need to be reserved if (uart_num < SOC_UART_HP_NUM) { - gpio_pullup_en(cts_io_num); - gpio_input_enable(cts_io_num); - esp_rom_gpio_connect_in_signal(cts_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_CTS_PIN_IDX), 0); + gpio_matrix_input(cts_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_CTS_PIN_IDX), false); } #if SOC_LP_GPIO_MATRIX_SUPPORTED else { diff --git a/components/esp_driver_uart/test_apps/uart/sdkconfig.ci.iram_safe b/components/esp_driver_uart/test_apps/uart/sdkconfig.ci.iram_safe index cbb32fa7fd..a686b3564b 100644 --- a/components/esp_driver_uart/test_apps/uart/sdkconfig.ci.iram_safe +++ b/components/esp_driver_uart/test_apps/uart/sdkconfig.ci.iram_safe @@ -6,3 +6,5 @@ CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y # silent the error check, as the error string are stored in rodata, causing RTL check failure CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y +# test gpio signal connection with non-default option +CONFIG_HAL_GPIO_USE_ROM_IMPL=n diff --git a/components/hal/Kconfig b/components/hal/Kconfig index 74fb4bc022..671e27fbd4 100644 --- a/components/hal/Kconfig +++ b/components/hal/Kconfig @@ -91,6 +91,16 @@ menu "Hardware Abstraction Layer (HAL) and Low Level (LL)" features will be added and bugs will be fixed in the IDF source but cannot be synced to ROM. + config HAL_GPIO_USE_ROM_IMPL + bool "Use ROM implementation of GPIO HAL driver" + default y + help + Enable this flag to use HAL functions from ROM when applicable instead of ESP-IDF. + + If keeping this as "n" in your project, you will have less free IRAM. + When compiling an application for a CPU that cannot access to the ROM memory, + this option should be disabled. + config HAL_ECDSA_GEN_SIG_CM bool "Enable countermeasure for ECDSA signature generation" depends on IDF_TARGET_ESP32H2 diff --git a/components/hal/esp32/include/hal/gpio_ll.h b/components/hal/esp32/include/hal/gpio_ll.h index 930006ad49..0e3da444d9 100644 --- a/components/hal/esp32/include/hal/gpio_ll.h +++ b/components/hal/esp32/include/hal/gpio_ll.h @@ -468,18 +468,6 @@ static inline void gpio_ll_od_enable(gpio_dev_t *hw, uint32_t gpio_num) hw->pin[gpio_num].pad_driver = 1; } -/** - * @brief Disconnect any peripheral output signal routed via GPIO matrix to the pin - * - * @param hw Peripheral GPIO hardware instance address. - * @param gpio_num GPIO number - */ -__attribute__((always_inline)) -static inline void gpio_ll_matrix_out_default(gpio_dev_t *hw, uint32_t gpio_num) -{ - REG_WRITE(GPIO_FUNC0_OUT_SEL_CFG_REG + (gpio_num * 4), SIG_GPIO_OUT_IDX); -} - /** * @brief Select a function for the pin in the IOMUX * @@ -688,30 +676,20 @@ static inline void gpio_ll_set_input_signal_from(gpio_dev_t *hw, uint32_t signal } /** - * @brief Configure the source of output enable signal for the GPIO pin. - * - * @param hw Peripheral GPIO hardware instance address. - * @param gpio_num GPIO number of the pad. - * @param ctrl_by_periph True if use output enable signal from peripheral, false if force the output enable signal to be sourced from bit n of GPIO_ENABLE_REG - * @param oen_inv True if the output enable needs to be inverted, otherwise False. - */ -static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_num, bool ctrl_by_periph, bool oen_inv) -{ - hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; // control valid only when using gpio matrix to route signal to the IO - hw->func_out_sel_cfg[gpio_num].oen_sel = !ctrl_by_periph; -} - -/** - * @brief Control the pin in the IOMUX + * @brief Connect a GPIO input with a peripheral signal, which tagged as input attribute. * - * @param bmap write mask of control value - * @param val Control value - * @param shift write mask shift of control value + * @note There's no limitation on the number of signals that a GPIO can combine with. + * + * @param signal_idx Peripheral signal index (tagged as input attribute) + * @param gpio_num GPIO number, especially, `GPIO_MATRIX_CONST_ZERO_INPUT` means connect logic 0 to signal + * `GPIO_MATRIX_CONST_ONE_INPUT` means connect logic 1 to signal + * @param in_inv True if the GPIO input needs to be inverted, otherwise False. */ -__attribute__((always_inline)) -static inline void gpio_ll_set_pin_ctrl(uint32_t val, uint32_t bmap, uint32_t shift) +static inline void gpio_ll_set_input_signal_matrix_source(gpio_dev_t *hw, uint32_t signal_idx, uint32_t gpio_num, bool in_inv) { - SET_PERI_REG_BITS(PIN_CTRL, bmap, val, shift); + hw->func_in_sel_cfg[signal_idx].func_sel = gpio_num; + hw->func_in_sel_cfg[signal_idx].sig_in_inv = in_inv; + gpio_ll_set_input_signal_from(hw, signal_idx, true); } /** @@ -731,6 +709,48 @@ static inline int gpio_ll_get_in_signal_connected_io(gpio_dev_t *hw, uint32_t in return (reg.sig_in_sel ? reg.func_sel : -1); } +/** + * @brief Configure the source of output enable signal for the GPIO pin. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number of the pad. + * @param ctrl_by_periph True if use output enable signal from peripheral, false if force the output enable signal to be sourced from bit n of GPIO_ENABLE_REG + * @param oen_inv True if the output enable needs to be inverted, otherwise False. + */ +static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_num, bool ctrl_by_periph, bool oen_inv) +{ + hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; // control valid only when using gpio matrix to route signal to the IO + hw->func_out_sel_cfg[gpio_num].oen_sel = !ctrl_by_periph; +} + +/** + * @brief Connect a peripheral signal which tagged as output attribute with a GPIO. + * + * @note There's no limitation on the number of signals that a GPIO can combine with. + * + * @param gpio_num GPIO number + * @param signal_idx Peripheral signal index (tagged as output attribute). Particularly, `SIG_GPIO_OUT_IDX` means disconnect GPIO and other peripherals. Only the GPIO driver can control the output level. + * @param out_inv True if the signal output needs to be inverted, otherwise False. + */ +static inline void gpio_ll_set_output_signal_matrix_source(gpio_dev_t *hw, uint32_t gpio_num, uint32_t signal_idx, bool out_inv) +{ + hw->func_out_sel_cfg[gpio_num].func_sel = signal_idx; + hw->func_out_sel_cfg[gpio_num].inv_sel = out_inv; +} + +/** + * @brief Control the pin in the IOMUX + * + * @param bmap write mask of control value + * @param val Control value + * @param shift write mask shift of control value + */ +__attribute__((always_inline)) +static inline void gpio_ll_set_pin_ctrl(uint32_t val, uint32_t bmap, uint32_t shift) +{ + SET_PERI_REG_BITS(PIN_CTRL, bmap, val, shift); +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32c2/include/hal/gpio_ll.h b/components/hal/esp32c2/include/hal/gpio_ll.h index b5b915f505..4820a12f00 100644 --- a/components/hal/esp32c2/include/hal/gpio_ll.h +++ b/components/hal/esp32c2/include/hal/gpio_ll.h @@ -286,18 +286,6 @@ static inline void gpio_ll_od_enable(gpio_dev_t *hw, uint32_t gpio_num) hw->pin[gpio_num].pad_driver = 1; } -/** - * @brief Disconnect any peripheral output signal routed via GPIO matrix to the pin - * - * @param hw Peripheral GPIO hardware instance address. - * @param gpio_num GPIO number - */ -__attribute__((always_inline)) -static inline void gpio_ll_matrix_out_default(gpio_dev_t *hw, uint32_t gpio_num) -{ - HAL_FORCE_MODIFY_U32_REG_FIELD(hw->func_out_sel_cfg[gpio_num], out_sel, SIG_GPIO_OUT_IDX); -} - /** * @brief Select a function for the pin in the IOMUX * @@ -490,30 +478,20 @@ static inline void gpio_ll_set_input_signal_from(gpio_dev_t *hw, uint32_t signal } /** - * @brief Configure the source of output enable signal for the GPIO pin. - * - * @param hw Peripheral GPIO hardware instance address. - * @param gpio_num GPIO number of the pad. - * @param ctrl_by_periph True if use output enable signal from peripheral, false if force the output enable signal to be sourced from bit n of GPIO_ENABLE_REG - * @param oen_inv True if the output enable needs to be inverted, otherwise False. - */ -static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_num, bool ctrl_by_periph, bool oen_inv) -{ - hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; // control valid only when using gpio matrix to route signal to the IO - hw->func_out_sel_cfg[gpio_num].oen_sel = !ctrl_by_periph; -} - -/** - * @brief Control the pin in the IOMUX + * @brief Connect a GPIO input with a peripheral signal, which tagged as input attribute. * - * @param bmap write mask of control value - * @param val Control value - * @param shift write mask shift of control value + * @note There's no limitation on the number of signals that a GPIO can combine with. + * + * @param signal_idx Peripheral signal index (tagged as input attribute) + * @param gpio_num GPIO number, especially, `GPIO_MATRIX_CONST_ZERO_INPUT` means connect logic 0 to signal + * `GPIO_MATRIX_CONST_ONE_INPUT` means connect logic 1 to signal + * @param in_inv True if the GPIO input needs to be inverted, otherwise False. */ -__attribute__((always_inline)) -static inline void gpio_ll_set_pin_ctrl(uint32_t val, uint32_t bmap, uint32_t shift) +static inline void gpio_ll_set_input_signal_matrix_source(gpio_dev_t *hw, uint32_t signal_idx, uint32_t gpio_num, bool in_inv) { - SET_PERI_REG_BITS(PIN_CTRL, bmap, val, shift); + hw->func_in_sel_cfg[signal_idx].in_sel = gpio_num; + hw->func_in_sel_cfg[signal_idx].sig_in_inv = in_inv; + gpio_ll_set_input_signal_from(hw, signal_idx, true); } /** @@ -533,6 +511,48 @@ static inline int gpio_ll_get_in_signal_connected_io(gpio_dev_t *hw, uint32_t in return (reg.sig_in_sel ? reg.in_sel : -1); } +/** + * @brief Configure the source of output enable signal for the GPIO pin. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number of the pad. + * @param ctrl_by_periph True if use output enable signal from peripheral, false if force the output enable signal to be sourced from bit n of GPIO_ENABLE_REG + * @param oen_inv True if the output enable needs to be inverted, otherwise False. + */ +static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_num, bool ctrl_by_periph, bool oen_inv) +{ + hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; // control valid only when using gpio matrix to route signal to the IO + hw->func_out_sel_cfg[gpio_num].oen_sel = !ctrl_by_periph; +} + +/** + * @brief Connect a peripheral signal which tagged as output attribute with a GPIO. + * + * @note There's no limitation on the number of signals that a GPIO can combine with. + * + * @param gpio_num GPIO number + * @param signal_idx Peripheral signal index (tagged as output attribute). Particularly, `SIG_GPIO_OUT_IDX` means disconnect GPIO and other peripherals. Only the GPIO driver can control the output level. + * @param out_inv True if the signal output needs to be inverted, otherwise False. + */ +static inline void gpio_ll_set_output_signal_matrix_source(gpio_dev_t *hw, uint32_t gpio_num, uint32_t signal_idx, bool out_inv) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->func_out_sel_cfg[gpio_num], out_sel, signal_idx); + hw->func_out_sel_cfg[gpio_num].inv_sel = out_inv; +} + +/** + * @brief Control the pin in the IOMUX + * + * @param bmap write mask of control value + * @param val Control value + * @param shift write mask shift of control value + */ +__attribute__((always_inline)) +static inline void gpio_ll_set_pin_ctrl(uint32_t val, uint32_t bmap, uint32_t shift) +{ + SET_PERI_REG_BITS(PIN_CTRL, bmap, val, shift); +} + /** * @brief Force hold all digital(VDD3P3_CPU) and rtc(VDD3P3_RTC) gpio pads. * @note GPIO force hold, whether the chip in sleep mode or wakeup mode. diff --git a/components/hal/esp32c3/include/hal/gpio_ll.h b/components/hal/esp32c3/include/hal/gpio_ll.h index 834f994fb3..5628d0f247 100644 --- a/components/hal/esp32c3/include/hal/gpio_ll.h +++ b/components/hal/esp32c3/include/hal/gpio_ll.h @@ -270,18 +270,6 @@ static inline void gpio_ll_od_enable(gpio_dev_t *hw, uint32_t gpio_num) hw->pin[gpio_num].pad_driver = 1; } -/** - * @brief Disconnect any peripheral output signal routed via GPIO matrix to the pin - * - * @param hw Peripheral GPIO hardware instance address. - * @param gpio_num GPIO number - */ -__attribute__((always_inline)) -static inline void gpio_ll_matrix_out_default(gpio_dev_t *hw, uint32_t gpio_num) -{ - REG_WRITE(GPIO_FUNC0_OUT_SEL_CFG_REG + (gpio_num * 4), SIG_GPIO_OUT_IDX); -} - /** * @brief Select a function for the pin in the IOMUX * @@ -488,30 +476,20 @@ static inline void gpio_ll_set_input_signal_from(gpio_dev_t *hw, uint32_t signal } /** - * @brief Configure the source of output enable signal for the GPIO pin. - * - * @param hw Peripheral GPIO hardware instance address. - * @param gpio_num GPIO number of the pad. - * @param ctrl_by_periph True if use output enable signal from peripheral, false if force the output enable signal to be sourced from bit n of GPIO_ENABLE_REG - * @param oen_inv True if the output enable needs to be inverted, otherwise False. - */ -static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_num, bool ctrl_by_periph, bool oen_inv) -{ - hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; // control valid only when using gpio matrix to route signal to the IO - hw->func_out_sel_cfg[gpio_num].oen_sel = !ctrl_by_periph; -} - -/** - * @brief Control the pin in the IOMUX + * @brief Connect a GPIO input with a peripheral signal, which tagged as input attribute. * - * @param bmap write mask of control value - * @param val Control value - * @param shift write mask shift of control value + * @note There's no limitation on the number of signals that a GPIO can combine with. + * + * @param signal_idx Peripheral signal index (tagged as input attribute) + * @param gpio_num GPIO number, especially, `GPIO_MATRIX_CONST_ZERO_INPUT` means connect logic 0 to signal + * `GPIO_MATRIX_CONST_ONE_INPUT` means connect logic 1 to signal + * @param in_inv True if the GPIO input needs to be inverted, otherwise False. */ -__attribute__((always_inline)) -static inline void gpio_ll_set_pin_ctrl(uint32_t val, uint32_t bmap, uint32_t shift) +static inline void gpio_ll_set_input_signal_matrix_source(gpio_dev_t *hw, uint32_t signal_idx, uint32_t gpio_num, bool in_inv) { - SET_PERI_REG_BITS(PIN_CTRL, bmap, val, shift); + hw->func_in_sel_cfg[signal_idx].in_sel = gpio_num; + hw->func_in_sel_cfg[signal_idx].sig_in_inv = in_inv; + gpio_ll_set_input_signal_from(hw, signal_idx, true); } /** @@ -531,6 +509,48 @@ static inline int gpio_ll_get_in_signal_connected_io(gpio_dev_t *hw, uint32_t in return (reg.sig_in_sel ? reg.in_sel : -1); } +/** + * @brief Configure the source of output enable signal for the GPIO pin. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number of the pad. + * @param ctrl_by_periph True if use output enable signal from peripheral, false if force the output enable signal to be sourced from bit n of GPIO_ENABLE_REG + * @param oen_inv True if the output enable needs to be inverted, otherwise False. + */ +static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_num, bool ctrl_by_periph, bool oen_inv) +{ + hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; // control valid only when using gpio matrix to route signal to the IO + hw->func_out_sel_cfg[gpio_num].oen_sel = !ctrl_by_periph; +} + +/** + * @brief Connect a peripheral signal which tagged as output attribute with a GPIO. + * + * @note There's no limitation on the number of signals that a GPIO can combine with. + * + * @param gpio_num GPIO number + * @param signal_idx Peripheral signal index (tagged as output attribute). Particularly, `SIG_GPIO_OUT_IDX` means disconnect GPIO and other peripherals. Only the GPIO driver can control the output level. + * @param out_inv True if the signal output needs to be inverted, otherwise False. + */ +static inline void gpio_ll_set_output_signal_matrix_source(gpio_dev_t *hw, uint32_t gpio_num, uint32_t signal_idx, bool out_inv) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->func_out_sel_cfg[gpio_num], out_sel, signal_idx); + hw->func_out_sel_cfg[gpio_num].inv_sel = out_inv; +} + +/** + * @brief Control the pin in the IOMUX + * + * @param bmap write mask of control value + * @param val Control value + * @param shift write mask shift of control value + */ +__attribute__((always_inline)) +static inline void gpio_ll_set_pin_ctrl(uint32_t val, uint32_t bmap, uint32_t shift) +{ + SET_PERI_REG_BITS(PIN_CTRL, bmap, val, shift); +} + /** * @brief Force hold all digital(VDD3P3_CPU) and rtc(VDD3P3_RTC) gpio pads. * @note GPIO force hold, whether the chip in sleep mode or wakeup mode. diff --git a/components/hal/esp32c5/include/hal/gpio_ll.h b/components/hal/esp32c5/include/hal/gpio_ll.h index fd9f444aa4..ec30974adf 100644 --- a/components/hal/esp32c5/include/hal/gpio_ll.h +++ b/components/hal/esp32c5/include/hal/gpio_ll.h @@ -326,21 +326,6 @@ static inline void gpio_ll_od_enable(gpio_dev_t *hw, uint32_t gpio_num) hw->pin[gpio_num].pad_driver = 1; } -/** - * @brief Disconnect any peripheral output signal routed via GPIO matrix to the pin - * - * @param hw Peripheral GPIO hardware instance address. - * @param gpio_num GPIO number - */ -__attribute__((always_inline)) -static inline void gpio_ll_matrix_out_default(gpio_dev_t *hw, uint32_t gpio_num) -{ - gpio_func_out_sel_cfg_reg_t reg = { - .out_sel = SIG_GPIO_OUT_IDX, - }; - hw->func_out_sel_cfg[gpio_num].val = reg.val; -} - /** * @brief GPIO set output level * @@ -477,6 +462,40 @@ static inline void gpio_ll_set_input_signal_from(gpio_dev_t *hw, uint32_t signal hw->func_in_sel_cfg[signal_idx].sig_in_sel = from_gpio_matrix; } +/** + * @brief Connect a GPIO input with a peripheral signal, which tagged as input attribute. + * + * @note There's no limitation on the number of signals that a GPIO can combine with. + * + * @param signal_idx Peripheral signal index (tagged as input attribute) + * @param gpio_num GPIO number, especially, `GPIO_MATRIX_CONST_ZERO_INPUT` means connect logic 0 to signal + * `GPIO_MATRIX_CONST_ONE_INPUT` means connect logic 1 to signal + * @param in_inv True if the GPIO input needs to be inverted, otherwise False. + */ +static inline void gpio_ll_set_input_signal_matrix_source(gpio_dev_t *hw, uint32_t signal_idx, uint32_t gpio_num, bool in_inv) +{ + hw->func_in_sel_cfg[signal_idx].in_sel = gpio_num; + hw->func_in_sel_cfg[signal_idx].in_inv_sel = in_inv; + gpio_ll_set_input_signal_from(hw, signal_idx, true); +} + +/** + * @brief Get the GPIO number that is routed to the input peripheral signal through GPIO matrix. + * + * @param hw Peripheral GPIO hardware instance address. + * @param in_sig_idx Peripheral signal index (tagged as input attribute). + * + * @return + * - -1 Signal bypassed GPIO matrix + * - Others GPIO number + */ +static inline int gpio_ll_get_in_signal_connected_io(gpio_dev_t *hw, uint32_t in_sig_idx) +{ + gpio_func_in_sel_cfg_reg_t reg; + reg.val = hw->func_in_sel_cfg[in_sig_idx].val; + return (reg.sig_in_sel ? reg.in_sel : -1); +} + /** * @brief Configure the source of output enable signal for the GPIO pin. * @@ -491,6 +510,21 @@ static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_n hw->func_out_sel_cfg[gpio_num].oen_sel = !ctrl_by_periph; } +/** + * @brief Connect a peripheral signal which tagged as output attribute with a GPIO. + * + * @note There's no limitation on the number of signals that a GPIO can combine with. + * + * @param gpio_num GPIO number + * @param signal_idx Peripheral signal index (tagged as output attribute). Particularly, `SIG_GPIO_OUT_IDX` means disconnect GPIO and other peripherals. Only the GPIO driver can control the output level. + * @param out_inv True if the signal output needs to be inverted, otherwise False. + */ +static inline void gpio_ll_set_output_signal_matrix_source(gpio_dev_t *hw, uint32_t gpio_num, uint32_t signal_idx, bool out_inv) +{ + hw->func_out_sel_cfg[gpio_num].out_sel = signal_idx; + hw->func_out_sel_cfg[gpio_num].out_inv_sel = out_inv; +} + /** * @brief Select a function for the pin in the IOMUX * @@ -531,23 +565,6 @@ static inline void gpio_ll_iomux_set_clk_src(soc_module_clk_t src) } } -/** - * @brief Get the GPIO number that is routed to the input peripheral signal through GPIO matrix. - * - * @param hw Peripheral GPIO hardware instance address. - * @param in_sig_idx Peripheral signal index (tagged as input attribute). - * - * @return - * - -1 Signal bypassed GPIO matrix - * - Others GPIO number - */ -static inline int gpio_ll_get_in_signal_connected_io(gpio_dev_t *hw, uint32_t in_sig_idx) -{ - gpio_func_in_sel_cfg_reg_t reg; - reg.val = hw->func_in_sel_cfg[in_sig_idx].val; - return (reg.sig_in_sel ? reg.in_sel : -1); -} - /** * @brief Force hold digital io pad. * @note GPIO force hold, whether the chip in sleep mode or wakeup mode. diff --git a/components/hal/esp32c6/include/hal/gpio_ll.h b/components/hal/esp32c6/include/hal/gpio_ll.h index 54d39baa3b..22f4064af7 100644 --- a/components/hal/esp32c6/include/hal/gpio_ll.h +++ b/components/hal/esp32c6/include/hal/gpio_ll.h @@ -300,18 +300,6 @@ static inline void gpio_ll_od_enable(gpio_dev_t *hw, uint32_t gpio_num) hw->pin[gpio_num].pad_driver = 1; } -/** - * @brief Disconnect any peripheral output signal routed via GPIO matrix to the pin - * - * @param hw Peripheral GPIO hardware instance address. - * @param gpio_num GPIO number - */ -__attribute__((always_inline)) -static inline void gpio_ll_matrix_out_default(gpio_dev_t *hw, uint32_t gpio_num) -{ - HAL_FORCE_MODIFY_U32_REG_FIELD(hw->func_out_sel_cfg[gpio_num], out_sel, SIG_GPIO_OUT_IDX); -} - /** * @brief GPIO set output level * @@ -448,6 +436,40 @@ static inline void gpio_ll_set_input_signal_from(gpio_dev_t *hw, uint32_t signal hw->func_in_sel_cfg[signal_idx].sig_in_sel = from_gpio_matrix; } +/** + * @brief Connect a GPIO input with a peripheral signal, which tagged as input attribute. + * + * @note There's no limitation on the number of signals that a GPIO can combine with. + * + * @param signal_idx Peripheral signal index (tagged as input attribute) + * @param gpio_num GPIO number, especially, `GPIO_MATRIX_CONST_ZERO_INPUT` means connect logic 0 to signal + * `GPIO_MATRIX_CONST_ONE_INPUT` means connect logic 1 to signal + * @param in_inv True if the GPIO input needs to be inverted, otherwise False. + */ +static inline void gpio_ll_set_input_signal_matrix_source(gpio_dev_t *hw, uint32_t signal_idx, uint32_t gpio_num, bool in_inv) +{ + hw->func_in_sel_cfg[signal_idx].in_sel = gpio_num; + hw->func_in_sel_cfg[signal_idx].in_inv_sel = in_inv; + gpio_ll_set_input_signal_from(hw, signal_idx, true); +} + +/** + * @brief Get the GPIO number that is routed to the input peripheral signal through GPIO matrix. + * + * @param hw Peripheral GPIO hardware instance address. + * @param in_sig_idx Peripheral signal index (tagged as input attribute). + * + * @return + * - -1 Signal bypassed GPIO matrix + * - Others GPIO number + */ +static inline int gpio_ll_get_in_signal_connected_io(gpio_dev_t *hw, uint32_t in_sig_idx) +{ + gpio_func_in_sel_cfg_reg_t reg; + reg.val = hw->func_in_sel_cfg[in_sig_idx].val; + return (reg.sig_in_sel ? reg.in_sel : -1); +} + /** * @brief Configure the source of output enable signal for the GPIO pin. * @@ -462,6 +484,21 @@ static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_n hw->func_out_sel_cfg[gpio_num].oen_sel = !ctrl_by_periph; } +/** + * @brief Connect a peripheral signal which tagged as output attribute with a GPIO. + * + * @note There's no limitation on the number of signals that a GPIO can combine with. + * + * @param gpio_num GPIO number + * @param signal_idx Peripheral signal index (tagged as output attribute). Particularly, `SIG_GPIO_OUT_IDX` means disconnect GPIO and other peripherals. Only the GPIO driver can control the output level. + * @param out_inv True if the signal output needs to be inverted, otherwise False. + */ +static inline void gpio_ll_set_output_signal_matrix_source(gpio_dev_t *hw, uint32_t gpio_num, uint32_t signal_idx, bool out_inv) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->func_out_sel_cfg[gpio_num], out_sel, signal_idx); + hw->func_out_sel_cfg[gpio_num].out_inv_sel = out_inv; +} + /** * @brief Control the pin in the IOMUX * @@ -512,23 +549,6 @@ static inline void gpio_ll_iomux_set_clk_src(soc_module_clk_t src) } } -/** - * @brief Get the GPIO number that is routed to the input peripheral signal through GPIO matrix. - * - * @param hw Peripheral GPIO hardware instance address. - * @param in_sig_idx Peripheral signal index (tagged as input attribute). - * - * @return - * - -1 Signal bypassed GPIO matrix - * - Others GPIO number - */ -static inline int gpio_ll_get_in_signal_connected_io(gpio_dev_t *hw, uint32_t in_sig_idx) -{ - gpio_func_in_sel_cfg_reg_t reg; - reg.val = hw->func_in_sel_cfg[in_sig_idx].val; - return (reg.sig_in_sel ? reg.in_sel : -1); -} - /** * @brief Force hold digital io pad. * @note GPIO force hold, whether the chip in sleep mode or wakeup mode. diff --git a/components/hal/esp32c61/include/hal/gpio_ll.h b/components/hal/esp32c61/include/hal/gpio_ll.h index 11048e7d56..bee5182bd9 100644 --- a/components/hal/esp32c61/include/hal/gpio_ll.h +++ b/components/hal/esp32c61/include/hal/gpio_ll.h @@ -324,21 +324,6 @@ static inline void gpio_ll_od_enable(gpio_dev_t *hw, uint32_t gpio_num) hw->pinn[gpio_num].pinn_pad_driver = 1; } -/** - * @brief Disconnect any peripheral output signal routed via GPIO matrix to the pin - * - * @param hw Peripheral GPIO hardware instance address. - * @param gpio_num GPIO number - */ -__attribute__((always_inline)) -static inline void gpio_ll_matrix_out_default(gpio_dev_t *hw, uint32_t gpio_num) -{ - gpio_funcn_out_sel_cfg_reg_t reg = { - .funcn_out_sel = SIG_GPIO_OUT_IDX, - }; - hw->funcn_out_sel_cfg[gpio_num].val = reg.val; -} - /** * @brief GPIO set output level * @@ -477,6 +462,40 @@ static inline void gpio_ll_set_input_signal_from(gpio_dev_t *hw, uint32_t signal hw->func_in_sel_cfg[signal_idx].sig_in_sel = from_gpio_matrix; } +/** + * @brief Connect a GPIO input with a peripheral signal, which tagged as input attribute. + * + * @note There's no limitation on the number of signals that a GPIO can combine with. + * + * @param signal_idx Peripheral signal index (tagged as input attribute) + * @param gpio_num GPIO number, especially, `GPIO_MATRIX_CONST_ZERO_INPUT` means connect logic 0 to signal + * `GPIO_MATRIX_CONST_ONE_INPUT` means connect logic 1 to signal + * @param in_inv True if the GPIO input needs to be inverted, otherwise False. + */ +static inline void gpio_ll_set_input_signal_matrix_source(gpio_dev_t *hw, uint32_t signal_idx, uint32_t gpio_num, bool in_inv) +{ + hw->func_in_sel_cfg[signal_idx].func_in_sel = gpio_num; + hw->func_in_sel_cfg[signal_idx].func_in_inv_sel = in_inv; + gpio_ll_set_input_signal_from(hw, signal_idx, true); +} + +/** + * @brief Get the GPIO number that is routed to the input peripheral signal through GPIO matrix. + * + * @param hw Peripheral GPIO hardware instance address. + * @param in_sig_idx Peripheral signal index (tagged as input attribute). + * + * @return + * - -1 Signal bypassed GPIO matrix + * - Others GPIO number + */ +static inline int gpio_ll_get_in_signal_connected_io(gpio_dev_t *hw, uint32_t in_sig_idx) +{ + gpio_func_in_sel_cfg_reg_t reg; + reg.val = hw->func_in_sel_cfg[in_sig_idx].val; + return (reg.sig_in_sel ? reg.func_in_sel : -1); +} + /** * @brief Configure the source of output enable signal for the GPIO pin. * @@ -491,6 +510,21 @@ static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_n hw->funcn_out_sel_cfg[gpio_num].funcn_oe_sel = !ctrl_by_periph; } +/** + * @brief Connect a peripheral signal which tagged as output attribute with a GPIO. + * + * @note There's no limitation on the number of signals that a GPIO can combine with. + * + * @param gpio_num GPIO number + * @param signal_idx Peripheral signal index (tagged as output attribute). Particularly, `SIG_GPIO_OUT_IDX` means disconnect GPIO and other peripherals. Only the GPIO driver can control the output level. + * @param out_inv True if the signal output needs to be inverted, otherwise False. + */ +static inline void gpio_ll_set_output_signal_matrix_source(gpio_dev_t *hw, uint32_t gpio_num, uint32_t signal_idx, bool out_inv) +{ + hw->funcn_out_sel_cfg[gpio_num].funcn_out_sel = signal_idx; + hw->funcn_out_sel_cfg[gpio_num].funcn_out_inv_sel = out_inv; +} + /** * @brief Select a function for the pin in the IOMUX * @@ -531,23 +565,6 @@ static inline void gpio_ll_iomux_set_clk_src(soc_module_clk_t src) } } -/** - * @brief Get the GPIO number that is routed to the input peripheral signal through GPIO matrix. - * - * @param hw Peripheral GPIO hardware instance address. - * @param in_sig_idx Peripheral signal index (tagged as input attribute). - * - * @return - * - -1 Signal bypassed GPIO matrix - * - Others GPIO number - */ -static inline int gpio_ll_get_in_signal_connected_io(gpio_dev_t *hw, uint32_t in_sig_idx) -{ - gpio_func_in_sel_cfg_reg_t reg; - reg.val = hw->func_in_sel_cfg[in_sig_idx].val; - return (reg.sig_in_sel ? reg.func_in_sel : -1); -} - /** * @brief Force hold digital io pad. * @note GPIO force hold, whether the chip in sleep mode or wakeup mode. diff --git a/components/hal/esp32h2/include/hal/gpio_ll.h b/components/hal/esp32h2/include/hal/gpio_ll.h index ed12ec6299..71b0ccbfe4 100644 --- a/components/hal/esp32h2/include/hal/gpio_ll.h +++ b/components/hal/esp32h2/include/hal/gpio_ll.h @@ -345,18 +345,6 @@ static inline void gpio_ll_od_enable(gpio_dev_t *hw, uint32_t gpio_num) hw->pin[gpio_num].pad_driver = 1; } -/** - * @brief Disconnect any peripheral output signal routed via GPIO matrix to the pin - * - * @param hw Peripheral GPIO hardware instance address. - * @param gpio_num GPIO number - */ -__attribute__((always_inline)) -static inline void gpio_ll_matrix_out_default(gpio_dev_t *hw, uint32_t gpio_num) -{ - HAL_FORCE_MODIFY_U32_REG_FIELD(hw->func_out_sel_cfg[gpio_num], out_sel, SIG_GPIO_OUT_IDX); -} - /** * @brief GPIO set output level * @@ -494,6 +482,40 @@ static inline void gpio_ll_set_input_signal_from(gpio_dev_t *hw, uint32_t signal hw->func_in_sel_cfg[signal_idx].sig_in_sel = from_gpio_matrix; } +/** + * @brief Connect a GPIO input with a peripheral signal, which tagged as input attribute. + * + * @note There's no limitation on the number of signals that a GPIO can combine with. + * + * @param signal_idx Peripheral signal index (tagged as input attribute) + * @param gpio_num GPIO number, especially, `GPIO_MATRIX_CONST_ZERO_INPUT` means connect logic 0 to signal + * `GPIO_MATRIX_CONST_ONE_INPUT` means connect logic 1 to signal + * @param in_inv True if the GPIO input needs to be inverted, otherwise False. + */ +static inline void gpio_ll_set_input_signal_matrix_source(gpio_dev_t *hw, uint32_t signal_idx, uint32_t gpio_num, bool in_inv) +{ + hw->func_in_sel_cfg[signal_idx].in_sel = gpio_num; + hw->func_in_sel_cfg[signal_idx].in_inv_sel = in_inv; + gpio_ll_set_input_signal_from(hw, signal_idx, true); +} + +/** + * @brief Get the GPIO number that is routed to the input peripheral signal through GPIO matrix. + * + * @param hw Peripheral GPIO hardware instance address. + * @param in_sig_idx Peripheral signal index (tagged as input attribute). + * + * @return + * - -1 Signal bypassed GPIO matrix + * - Others GPIO number + */ +static inline int gpio_ll_get_in_signal_connected_io(gpio_dev_t *hw, uint32_t in_sig_idx) +{ + gpio_func_in_sel_cfg_reg_t reg; + reg.val = hw->func_in_sel_cfg[in_sig_idx].val; + return (reg.sig_in_sel ? reg.in_sel : -1); +} + /** * @brief Configure the source of output enable signal for the GPIO pin. * @@ -508,6 +530,21 @@ static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_n hw->func_out_sel_cfg[gpio_num].oen_sel = !ctrl_by_periph; } +/** + * @brief Connect a peripheral signal which tagged as output attribute with a GPIO. + * + * @note There's no limitation on the number of signals that a GPIO can combine with. + * + * @param gpio_num GPIO number + * @param signal_idx Peripheral signal index (tagged as output attribute). Particularly, `SIG_GPIO_OUT_IDX` means disconnect GPIO and other peripherals. Only the GPIO driver can control the output level. + * @param out_inv True if the signal output needs to be inverted, otherwise False. + */ +static inline void gpio_ll_set_output_signal_matrix_source(gpio_dev_t *hw, uint32_t gpio_num, uint32_t signal_idx, bool out_inv) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->func_out_sel_cfg[gpio_num], out_sel, signal_idx); + hw->func_out_sel_cfg[gpio_num].out_inv_sel = out_inv; +} + /** * @brief Select a function for the pin in the IOMUX * @@ -558,23 +595,6 @@ static inline void gpio_ll_iomux_set_clk_src(soc_module_clk_t src) } } -/** - * @brief Get the GPIO number that is routed to the input peripheral signal through GPIO matrix. - * - * @param hw Peripheral GPIO hardware instance address. - * @param in_sig_idx Peripheral signal index (tagged as input attribute). - * - * @return - * - -1 Signal bypassed GPIO matrix - * - Others GPIO number - */ -static inline int gpio_ll_get_in_signal_connected_io(gpio_dev_t *hw, uint32_t in_sig_idx) -{ - gpio_func_in_sel_cfg_reg_t reg; - reg.val = hw->func_in_sel_cfg[in_sig_idx].val; - return (reg.sig_in_sel ? reg.in_sel : -1); -} - /** * @brief Force hold all digital(VDDPST2) and lp(VDDPST1) io pads. * @note GPIO force hold, whether the chip in sleep mode or wakeup mode. diff --git a/components/hal/esp32h21/include/hal/gpio_ll.h b/components/hal/esp32h21/include/hal/gpio_ll.h index e988be8099..9bc442dece 100644 --- a/components/hal/esp32h21/include/hal/gpio_ll.h +++ b/components/hal/esp32h21/include/hal/gpio_ll.h @@ -327,21 +327,6 @@ static inline void gpio_ll_od_enable(gpio_dev_t *hw, uint32_t gpio_num) hw->pinn[gpio_num].pinn_pad_driver = 1; } -/** - * @brief Disconnect any peripheral output signal routed via GPIO matrix to the pin - * - * @param hw Peripheral GPIO hardware instance address. - * @param gpio_num GPIO number - */ -__attribute__((always_inline)) -static inline void gpio_ll_matrix_out_default(gpio_dev_t *hw, uint32_t gpio_num) -{ - gpio_funcn_out_sel_cfg_reg_t reg = { - .funcn_out_sel = SIG_GPIO_OUT_IDX, - }; - hw->funcn_out_sel_cfg[gpio_num].val = reg.val; -} - /** * @brief GPIO set output level * @@ -478,6 +463,40 @@ static inline void gpio_ll_set_input_signal_from(gpio_dev_t *hw, uint32_t signal hw->func_in_sel_cfg[signal_idx].sig_in_sel = from_gpio_matrix; } +/** + * @brief Connect a GPIO input with a peripheral signal, which tagged as input attribute. + * + * @note There's no limitation on the number of signals that a GPIO can combine with. + * + * @param signal_idx Peripheral signal index (tagged as input attribute) + * @param gpio_num GPIO number, especially, `GPIO_MATRIX_CONST_ZERO_INPUT` means connect logic 0 to signal + * `GPIO_MATRIX_CONST_ONE_INPUT` means connect logic 1 to signal + * @param in_inv True if the GPIO input needs to be inverted, otherwise False. + */ +static inline void gpio_ll_set_input_signal_matrix_source(gpio_dev_t *hw, uint32_t signal_idx, uint32_t gpio_num, bool in_inv) +{ + hw->func_in_sel_cfg[signal_idx].func_in_sel = gpio_num; + hw->func_in_sel_cfg[signal_idx].func_in_inv_sel = in_inv; + gpio_ll_set_input_signal_from(hw, signal_idx, true); +} + +/** + * @brief Get the GPIO number that is routed to the input peripheral signal through GPIO matrix. + * + * @param hw Peripheral GPIO hardware instance address. + * @param in_sig_idx Peripheral signal index (tagged as input attribute). + * + * @return + * - -1 Signal bypassed GPIO matrix + * - Others GPIO number + */ +static inline int gpio_ll_get_in_signal_connected_io(gpio_dev_t *hw, uint32_t in_sig_idx) +{ + gpio_func_in_sel_cfg_reg_t reg; + reg.val = hw->func_in_sel_cfg[in_sig_idx].val; + return (reg.sig_in_sel ? reg.func_in_sel : -1); +} + /** * @brief Configure the source of output enable signal for the GPIO pin. * @@ -492,6 +511,21 @@ static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_n hw->funcn_out_sel_cfg[gpio_num].funcn_oe_sel = !ctrl_by_periph; } +/** + * @brief Connect a peripheral signal which tagged as output attribute with a GPIO. + * + * @note There's no limitation on the number of signals that a GPIO can combine with. + * + * @param gpio_num GPIO number + * @param signal_idx Peripheral signal index (tagged as output attribute). Particularly, `SIG_GPIO_OUT_IDX` means disconnect GPIO and other peripherals. Only the GPIO driver can control the output level. + * @param out_inv True if the signal output needs to be inverted, otherwise False. + */ +static inline void gpio_ll_set_output_signal_matrix_source(gpio_dev_t *hw, uint32_t gpio_num, uint32_t signal_idx, bool out_inv) +{ + hw->funcn_out_sel_cfg[gpio_num].funcn_out_sel = signal_idx; + hw->funcn_out_sel_cfg[gpio_num].funcn_out_inv_sel = out_inv; +} + /** * @brief Select a function for the pin in the IOMUX * @@ -532,23 +566,6 @@ static inline void gpio_ll_iomux_set_clk_src(soc_module_clk_t src) } } -/** - * @brief Get the GPIO number that is routed to the input peripheral signal through GPIO matrix. - * - * @param hw Peripheral GPIO hardware instance address. - * @param in_sig_idx Peripheral signal index (tagged as input attribute). - * - * @return - * - -1 Signal bypassed GPIO matrix - * - Others GPIO number - */ -static inline int gpio_ll_get_in_signal_connected_io(gpio_dev_t *hw, uint32_t in_sig_idx) -{ - gpio_func_in_sel_cfg_reg_t reg; - reg.val = hw->func_in_sel_cfg[in_sig_idx].val; - return (reg.sig_in_sel ? reg.func_in_sel : -1); -} - /** * @brief Force hold all digital(VDDPST2) and lp(VDDPST1) io pads. * @note GPIO force hold, whether the chip in sleep mode or wakeup mode. diff --git a/components/hal/esp32h4/include/hal/gpio_ll.h b/components/hal/esp32h4/include/hal/gpio_ll.h index 01a8346f8d..85f703ea3b 100644 --- a/components/hal/esp32h4/include/hal/gpio_ll.h +++ b/components/hal/esp32h4/include/hal/gpio_ll.h @@ -304,21 +304,6 @@ static inline void gpio_ll_od_enable(gpio_dev_t *hw, uint32_t gpio_num) hw->pinn[gpio_num].pinn_pad_driver = 1; } -/** - * @brief Disconnect any peripheral output signal routed via GPIO matrix to the pin - * - * @param hw Peripheral GPIO hardware instance address. - * @param gpio_num GPIO number - */ -__attribute__((always_inline)) -static inline void gpio_ll_matrix_out_default(gpio_dev_t *hw, uint32_t gpio_num) -{ - gpio_funcn_out_sel_cfg_reg_t reg = { - .out_sel = SIG_GPIO_OUT_IDX, - }; - hw->funcn_out_sel_cfg[gpio_num].val = reg.val; -} - /** * @brief GPIO set output level * @@ -478,20 +463,38 @@ static inline void gpio_ll_set_input_signal_from(gpio_dev_t *hw, uint32_t signal } /** - * @brief Select a function for the pin in the IOMUX + * @brief Connect a GPIO input with a peripheral signal, which tagged as input attribute. * - * @param hw Peripheral GPIO hardware instance address. - * @param gpio_num GPIO number - * @param func Function to assign to the pin + * @note There's no limitation on the number of signals that a GPIO can combine with. + * + * @param signal_idx Peripheral signal index (tagged as input attribute) + * @param gpio_num GPIO number, especially, `GPIO_MATRIX_CONST_ZERO_INPUT` means connect logic 0 to signal + * `GPIO_MATRIX_CONST_ONE_INPUT` means connect logic 1 to signal + * @param in_inv True if the GPIO input needs to be inverted, otherwise False. */ -__attribute__((always_inline)) -static inline void gpio_ll_func_sel(gpio_dev_t *hw, uint8_t gpio_num, uint32_t func) +static inline void gpio_ll_set_input_signal_matrix_source(gpio_dev_t *hw, uint32_t signal_idx, uint32_t gpio_num, bool in_inv) { - // Disable USB Serial JTAG if USB pins needs to select an IOMUX function - if (gpio_num == USB_INT_PHY0_DM_GPIO_NUM || gpio_num == USB_INT_PHY0_DP_GPIO_NUM) { - USB_SERIAL_JTAG.serial_jtag_conf0.serial_jtag_usb_pad_enable = 0; - } - IO_MUX.gpio[gpio_num].mcu_sel = func; + hw->func_in_sel_cfg[signal_idx].func_in_sel = gpio_num; + hw->func_in_sel_cfg[signal_idx].func_in_inv_sel = in_inv; + gpio_ll_set_input_signal_from(hw, signal_idx, true); +} + +/** + * @brief Get the GPIO number that is routed to the input peripheral signal through GPIO matrix. + * + * @param hw Peripheral GPIO hardware instance address. + * @param in_sig_idx Peripheral signal index (tagged as input attribute). + * + * @return + * - -1 Signal bypassed GPIO matrix + * - Others GPIO number + */ +static inline int gpio_ll_get_in_signal_connected_io(gpio_dev_t *hw, uint32_t in_sig_idx) +{ + gpio_func_in_sel_cfg_reg_t reg = { + .val = hw->func_in_sel_cfg[in_sig_idx].val, + }; + return (reg.sig_in_sel ? reg.func_in_sel : -1); } /** @@ -508,6 +511,38 @@ static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_n hw->funcn_out_sel_cfg[gpio_num].oe_sel = !ctrl_by_periph; } +/** + * @brief Connect a peripheral signal which tagged as output attribute with a GPIO. + * + * @note There's no limitation on the number of signals that a GPIO can combine with. + * + * @param gpio_num GPIO number + * @param signal_idx Peripheral signal index (tagged as output attribute). Particularly, `SIG_GPIO_OUT_IDX` means disconnect GPIO and other peripherals. Only the GPIO driver can control the output level. + * @param out_inv True if the signal output needs to be inverted, otherwise False. + */ +static inline void gpio_ll_set_output_signal_matrix_source(gpio_dev_t *hw, uint32_t gpio_num, uint32_t signal_idx, bool out_inv) +{ + hw->funcn_out_sel_cfg[gpio_num].out_sel = signal_idx; + hw->funcn_out_sel_cfg[gpio_num].out_inv_sel = out_inv; +} + +/** + * @brief Select a function for the pin in the IOMUX + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + * @param func Function to assign to the pin + */ +__attribute__((always_inline)) +static inline void gpio_ll_func_sel(gpio_dev_t *hw, uint8_t gpio_num, uint32_t func) +{ + // Disable USB Serial JTAG if USB pins needs to select an IOMUX function + if (gpio_num == USB_INT_PHY0_DM_GPIO_NUM || gpio_num == USB_INT_PHY0_DP_GPIO_NUM) { + USB_SERIAL_JTAG.serial_jtag_conf0.serial_jtag_usb_pad_enable = 0; + } + IO_MUX.gpio[gpio_num].mcu_sel = func; +} + /** * @brief Set clock source of IO MUX module * @@ -531,24 +566,6 @@ static inline void gpio_ll_iomux_set_clk_src(soc_module_clk_t src) } } -/** - * @brief Get the GPIO number that is routed to the input peripheral signal through GPIO matrix. - * - * @param hw Peripheral GPIO hardware instance address. - * @param in_sig_idx Peripheral signal index (tagged as input attribute). - * - * @return - * - -1 Signal bypassed GPIO matrix - * - Others GPIO number - */ -static inline int gpio_ll_get_in_signal_connected_io(gpio_dev_t *hw, uint32_t in_sig_idx) -{ - gpio_func_in_sel_cfg_reg_t reg = { - .val = hw->func_in_sel_cfg[in_sig_idx].val, - }; - return (reg.sig_in_sel ? reg.func_in_sel : -1); -} - /** * @brief Force hold all digital(VDDPST2) and lp(VDDPST1) io pads. * @note GPIO force hold, whether the chip in sleep mode or wakeup mode. diff --git a/components/hal/esp32p4/include/hal/gpio_ll.h b/components/hal/esp32p4/include/hal/gpio_ll.h index 402fc8801b..431213e653 100644 --- a/components/hal/esp32p4/include/hal/gpio_ll.h +++ b/components/hal/esp32p4/include/hal/gpio_ll.h @@ -372,21 +372,6 @@ static inline void gpio_ll_od_enable(gpio_dev_t *hw, uint32_t gpio_num) hw->pin[gpio_num].pad_driver = 1; } -/** - * @brief Disconnect any peripheral output signal routed via GPIO matrix to the pin - * - * @param hw Peripheral GPIO hardware instance address. - * @param gpio_num GPIO number - */ -__attribute__((always_inline)) -static inline void gpio_ll_matrix_out_default(gpio_dev_t *hw, uint32_t gpio_num) -{ - gpio_func_out_sel_cfg_reg_t reg = { - .out_sel = SIG_GPIO_OUT_IDX, - }; - hw->func_out_sel_cfg[gpio_num].val = reg.val; -} - /** * @brief GPIO set output level * @@ -580,6 +565,40 @@ static inline void gpio_ll_set_input_signal_from(gpio_dev_t *hw, uint32_t signal hw->func_in_sel_cfg[signal_idx].sig_in_sel = from_gpio_matrix; } +/** + * @brief Connect a GPIO input with a peripheral signal, which tagged as input attribute. + * + * @note There's no limitation on the number of signals that a GPIO can combine with. + * + * @param signal_idx Peripheral signal index (tagged as input attribute) + * @param gpio_num GPIO number, especially, `GPIO_MATRIX_CONST_ZERO_INPUT` means connect logic 0 to signal + * `GPIO_MATRIX_CONST_ONE_INPUT` means connect logic 1 to signal + * @param in_inv True if the GPIO input needs to be inverted, otherwise False. + */ +static inline void gpio_ll_set_input_signal_matrix_source(gpio_dev_t *hw, uint32_t signal_idx, uint32_t gpio_num, bool in_inv) +{ + hw->func_in_sel_cfg[signal_idx].in_sel = gpio_num; + hw->func_in_sel_cfg[signal_idx].in_inv_sel = in_inv; + gpio_ll_set_input_signal_from(hw, signal_idx, true); +} + +/** + * @brief Get the GPIO number that is routed to the input peripheral signal through GPIO matrix. + * + * @param hw Peripheral GPIO hardware instance address. + * @param in_sig_idx Peripheral signal index (tagged as input attribute). + * + * @return + * - -1 Signal bypassed GPIO matrix + * - Others GPIO number + */ +static inline int gpio_ll_get_in_signal_connected_io(gpio_dev_t *hw, uint32_t in_sig_idx) +{ + gpio_func_in_sel_cfg_reg_t reg; + reg.val = hw->func_in_sel_cfg[in_sig_idx].val; + return (reg.sig_in_sel ? reg.in_sel : -1); +} + /** * @brief Configure the source of output enable signal for the GPIO pin. * @@ -594,6 +613,21 @@ static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_n hw->func_out_sel_cfg[gpio_num].oen_sel = !ctrl_by_periph; } +/** + * @brief Connect a peripheral signal which tagged as output attribute with a GPIO. + * + * @note There's no limitation on the number of signals that a GPIO can combine with. + * + * @param gpio_num GPIO number + * @param signal_idx Peripheral signal index (tagged as output attribute). Particularly, `SIG_GPIO_OUT_IDX` means disconnect GPIO and other peripherals. Only the GPIO driver can control the output level. + * @param out_inv True if the signal output needs to be inverted, otherwise False. + */ +static inline void gpio_ll_set_output_signal_matrix_source(gpio_dev_t *hw, uint32_t gpio_num, uint32_t signal_idx, bool out_inv) +{ + hw->func_out_sel_cfg[gpio_num].out_sel = signal_idx; + hw->func_out_sel_cfg[gpio_num].out_inv_sel = out_inv; +} + /** * @brief Select a function for the pin in the IOMUX * @@ -642,23 +676,6 @@ static inline void gpio_ll_iomux_set_clk_src(soc_module_clk_t src) gpio_ll_iomux_set_clk_src(__VA_ARGS__); \ } while(0) -/** - * @brief Get the GPIO number that is routed to the input peripheral signal through GPIO matrix. - * - * @param hw Peripheral GPIO hardware instance address. - * @param in_sig_idx Peripheral signal index (tagged as input attribute). - * - * @return - * - -1 Signal bypassed GPIO matrix - * - Others GPIO number - */ -static inline int gpio_ll_get_in_signal_connected_io(gpio_dev_t *hw, uint32_t in_sig_idx) -{ - gpio_func_in_sel_cfg_reg_t reg; - reg.val = hw->func_in_sel_cfg[in_sig_idx].val; - return (reg.sig_in_sel ? reg.in_sel : -1); -} - /** * @brief Force hold digital io pad. * @note GPIO force hold, whether the chip in sleep mode or wakeup mode. diff --git a/components/hal/esp32s2/include/hal/gpio_ll.h b/components/hal/esp32s2/include/hal/gpio_ll.h index 872fc55c82..16fa760d07 100644 --- a/components/hal/esp32s2/include/hal/gpio_ll.h +++ b/components/hal/esp32s2/include/hal/gpio_ll.h @@ -294,18 +294,6 @@ static inline void gpio_ll_od_enable(gpio_dev_t *hw, uint32_t gpio_num) hw->pin[gpio_num].pad_driver = 1; } -/** - * @brief Disconnect any peripheral output signal routed via GPIO matrix to the pin - * - * @param hw Peripheral GPIO hardware instance address. - * @param gpio_num GPIO number - */ -__attribute__((always_inline)) -static inline void gpio_ll_matrix_out_default(gpio_dev_t *hw, uint32_t gpio_num) -{ - REG_WRITE(GPIO_FUNC0_OUT_SEL_CFG_REG + (gpio_num * 4), SIG_GPIO_OUT_IDX); -} - /** * @brief Select a function for the pin in the IOMUX * @@ -502,30 +490,20 @@ static inline void gpio_ll_set_input_signal_from(gpio_dev_t *hw, uint32_t signal } /** - * @brief Configure the source of output enable signal for the GPIO pin. - * - * @param hw Peripheral GPIO hardware instance address. - * @param gpio_num GPIO number of the pad. - * @param ctrl_by_periph True if use output enable signal from peripheral, false if force the output enable signal to be sourced from bit n of GPIO_ENABLE_REG - * @param oen_inv True if the output enable needs to be inverted, otherwise False. - */ -static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_num, bool ctrl_by_periph, bool oen_inv) -{ - hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; // control valid only when using gpio matrix to route signal to the IO - hw->func_out_sel_cfg[gpio_num].oen_sel = !ctrl_by_periph; -} - -/** - * @brief Control the pin in the IOMUX + * @brief Connect a GPIO input with a peripheral signal, which tagged as input attribute. * - * @param bmap write mask of control value - * @param val Control value - * @param shift write mask shift of control value + * @note There's no limitation on the number of signals that a GPIO can combine with. + * + * @param signal_idx Peripheral signal index (tagged as input attribute) + * @param gpio_num GPIO number, especially, `GPIO_MATRIX_CONST_ZERO_INPUT` means connect logic 0 to signal + * `GPIO_MATRIX_CONST_ONE_INPUT` means connect logic 1 to signal + * @param in_inv True if the GPIO input needs to be inverted, otherwise False. */ -__attribute__((always_inline)) -static inline void gpio_ll_set_pin_ctrl(uint32_t val, uint32_t bmap, uint32_t shift) +static inline void gpio_ll_set_input_signal_matrix_source(gpio_dev_t *hw, uint32_t signal_idx, uint32_t gpio_num, bool in_inv) { - SET_PERI_REG_BITS(PIN_CTRL, bmap, val, shift); + hw->func_in_sel_cfg[signal_idx].func_sel = gpio_num; + hw->func_in_sel_cfg[signal_idx].sig_in_inv = in_inv; + gpio_ll_set_input_signal_from(hw, signal_idx, true); } /** @@ -545,6 +523,48 @@ static inline int gpio_ll_get_in_signal_connected_io(gpio_dev_t *hw, uint32_t in return (reg.sig_in_sel ? reg.func_sel : -1); } +/** + * @brief Configure the source of output enable signal for the GPIO pin. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number of the pad. + * @param ctrl_by_periph True if use output enable signal from peripheral, false if force the output enable signal to be sourced from bit n of GPIO_ENABLE_REG + * @param oen_inv True if the output enable needs to be inverted, otherwise False. + */ +static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_num, bool ctrl_by_periph, bool oen_inv) +{ + hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; // control valid only when using gpio matrix to route signal to the IO + hw->func_out_sel_cfg[gpio_num].oen_sel = !ctrl_by_periph; +} + +/** + * @brief Connect a peripheral signal which tagged as output attribute with a GPIO. + * + * @note There's no limitation on the number of signals that a GPIO can combine with. + * + * @param gpio_num GPIO number + * @param signal_idx Peripheral signal index (tagged as output attribute). Particularly, `SIG_GPIO_OUT_IDX` means disconnect GPIO and other peripherals. Only the GPIO driver can control the output level. + * @param out_inv True if the signal output needs to be inverted, otherwise False. + */ +static inline void gpio_ll_set_output_signal_matrix_source(gpio_dev_t *hw, uint32_t gpio_num, uint32_t signal_idx, bool out_inv) +{ + hw->func_out_sel_cfg[gpio_num].func_sel = signal_idx; + hw->func_out_sel_cfg[gpio_num].inv_sel = out_inv; +} + +/** + * @brief Control the pin in the IOMUX + * + * @param bmap write mask of control value + * @param val Control value + * @param shift write mask shift of control value + */ +__attribute__((always_inline)) +static inline void gpio_ll_set_pin_ctrl(uint32_t val, uint32_t bmap, uint32_t shift) +{ + SET_PERI_REG_BITS(PIN_CTRL, bmap, val, shift); +} + /** * @brief Force hold digital gpio pad. * @note GPIO force hold, whether the chip in sleep mode or wakeup mode. diff --git a/components/hal/esp32s3/include/hal/gpio_ll.h b/components/hal/esp32s3/include/hal/gpio_ll.h index ddebea0479..dc4a467868 100644 --- a/components/hal/esp32s3/include/hal/gpio_ll.h +++ b/components/hal/esp32s3/include/hal/gpio_ll.h @@ -282,18 +282,6 @@ static inline void gpio_ll_od_enable(gpio_dev_t *hw, uint32_t gpio_num) hw->pin[gpio_num].pad_driver = 1; } -/** - * @brief Disconnect any peripheral output signal routed via GPIO matrix to the pin - * - * @param hw Peripheral GPIO hardware instance address. - * @param gpio_num GPIO number - */ -__attribute__((always_inline)) -static inline void gpio_ll_matrix_out_default(gpio_dev_t *hw, uint32_t gpio_num) -{ - REG_WRITE(GPIO_FUNC0_OUT_SEL_CFG_REG + (gpio_num * 4), SIG_GPIO_OUT_IDX); -} - /** * @brief Select a function for the pin in the IOMUX * @@ -503,30 +491,20 @@ static inline void gpio_ll_set_input_signal_from(gpio_dev_t *hw, uint32_t signal } /** - * @brief Configure the source of output enable signal for the GPIO pin. - * - * @param hw Peripheral GPIO hardware instance address. - * @param gpio_num GPIO number of the pad. - * @param ctrl_by_periph True if use output enable signal from peripheral, false if force the output enable signal to be sourced from bit n of GPIO_ENABLE_REG - * @param oen_inv True if the output enable needs to be inverted, otherwise False. - */ -static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_num, bool ctrl_by_periph, bool oen_inv) -{ - hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; // control valid only when using gpio matrix to route signal to the IO - hw->func_out_sel_cfg[gpio_num].oen_sel = !ctrl_by_periph; -} - -/** - * @brief Control the pin in the IOMUX + * @brief Connect a GPIO input with a peripheral signal, which tagged as input attribute. * - * @param bmap write mask of control value - * @param val Control value - * @param shift write mask shift of control value + * @note There's no limitation on the number of signals that a GPIO can combine with. + * + * @param signal_idx Peripheral signal index (tagged as input attribute) + * @param gpio_num GPIO number, especially, `GPIO_MATRIX_CONST_ZERO_INPUT` means connect logic 0 to signal + * `GPIO_MATRIX_CONST_ONE_INPUT` means connect logic 1 to signal + * @param in_inv True if the GPIO input needs to be inverted, otherwise False. */ -__attribute__((always_inline)) -static inline void gpio_ll_set_pin_ctrl(uint32_t val, uint32_t bmap, uint32_t shift) +static inline void gpio_ll_set_input_signal_matrix_source(gpio_dev_t *hw, uint32_t signal_idx, uint32_t gpio_num, bool in_inv) { - SET_PERI_REG_BITS(PIN_CTRL, bmap, val, shift); + hw->func_in_sel_cfg[signal_idx].func_sel = gpio_num; + hw->func_in_sel_cfg[signal_idx].sig_in_inv = in_inv; + gpio_ll_set_input_signal_from(hw, signal_idx, true); } /** @@ -546,6 +524,48 @@ static inline int gpio_ll_get_in_signal_connected_io(gpio_dev_t *hw, uint32_t in return (reg.sig_in_sel ? reg.func_sel : -1); } +/** + * @brief Configure the source of output enable signal for the GPIO pin. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number of the pad. + * @param ctrl_by_periph True if use output enable signal from peripheral, false if force the output enable signal to be sourced from bit n of GPIO_ENABLE_REG + * @param oen_inv True if the output enable needs to be inverted, otherwise False. + */ +static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_num, bool ctrl_by_periph, bool oen_inv) +{ + hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; // control valid only when using gpio matrix to route signal to the IO + hw->func_out_sel_cfg[gpio_num].oen_sel = !ctrl_by_periph; +} + +/** + * @brief Connect a peripheral signal which tagged as output attribute with a GPIO. + * + * @note There's no limitation on the number of signals that a GPIO can combine with. + * + * @param gpio_num GPIO number + * @param signal_idx Peripheral signal index (tagged as output attribute). Particularly, `SIG_GPIO_OUT_IDX` means disconnect GPIO and other peripherals. Only the GPIO driver can control the output level. + * @param out_inv True if the signal output needs to be inverted, otherwise False. + */ +static inline void gpio_ll_set_output_signal_matrix_source(gpio_dev_t *hw, uint32_t gpio_num, uint32_t signal_idx, bool out_inv) +{ + hw->func_out_sel_cfg[gpio_num].func_sel = signal_idx; + hw->func_out_sel_cfg[gpio_num].inv_sel = out_inv; +} + +/** + * @brief Control the pin in the IOMUX + * + * @param bmap write mask of control value + * @param val Control value + * @param shift write mask shift of control value + */ +__attribute__((always_inline)) +static inline void gpio_ll_set_pin_ctrl(uint32_t val, uint32_t bmap, uint32_t shift) +{ + SET_PERI_REG_BITS(PIN_CTRL, bmap, val, shift); +} + /** * @brief Force hold digital gpio pad. * @note GPIO force hold, whether the chip in sleep mode or wakeup mode. diff --git a/components/hal/gpio_hal.c b/components/hal/gpio_hal.c index 7bba273a2e..7b1646fefc 100644 --- a/components/hal/gpio_hal.c +++ b/components/hal/gpio_hal.c @@ -10,6 +10,8 @@ #include "esp_attr.h" #include "soc/gpio_periph.h" #include "hal/gpio_hal.h" +#include "esp_rom_gpio.h" +#include "hal/config.h" void gpio_hal_intr_enable_on_core(gpio_hal_context_t *hal, uint32_t gpio_num, uint32_t core_id) { @@ -44,6 +46,27 @@ void gpio_hal_iomux_out(gpio_hal_context_t *hal, uint32_t gpio_num, int func) gpio_ll_func_sel(hal->dev, gpio_num, func); } +void gpio_hal_matrix_in(gpio_hal_context_t *hal, uint32_t gpio_num, uint32_t signal_idx, bool in_inv) +{ + gpio_ll_input_enable(hal->dev, gpio_num); +#if HAL_CONFIG_GPIO_USE_ROM_API + esp_rom_gpio_connect_in_signal(gpio_num, signal_idx, in_inv); +#else + gpio_ll_set_input_signal_matrix_source(hal->dev, signal_idx, gpio_num, in_inv); +#endif +} + +void gpio_hal_matrix_out(gpio_hal_context_t *hal, uint32_t gpio_num, uint32_t signal_idx, bool out_inv, bool oen_inv) +{ + gpio_ll_func_sel(hal->dev, gpio_num, PIN_FUNC_GPIO); +#if HAL_CONFIG_GPIO_USE_ROM_API + esp_rom_gpio_connect_out_signal(gpio_num, signal_idx, out_inv, oen_inv); +#else + gpio_ll_set_output_signal_matrix_source(hal->dev, gpio_num, signal_idx, out_inv); + gpio_ll_set_output_enable_ctrl(hal->dev, gpio_num, true, oen_inv); // output is enabled at the end to avoid undesired level change +#endif +} + #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 ee99019350..2d6eb171b7 100644 --- a/components/hal/include/hal/gpio_hal.h +++ b/components/hal/include/hal/gpio_hal.h @@ -192,7 +192,7 @@ 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 */ -#define gpio_hal_matrix_out_default(hal, gpio_num) gpio_ll_matrix_out_default((hal)->dev, gpio_num) +#define gpio_hal_matrix_out_default(hal, gpio_num) gpio_ll_set_output_signal_matrix_source((hal)->dev, gpio_num, SIG_GPIO_OUT_IDX, false) /** * @brief Select a function for the pin in the IOMUX @@ -363,7 +363,7 @@ void gpio_hal_intr_disable(gpio_hal_context_t *hal, uint32_t gpio_num); * @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``. + * @param signal_idx Peripheral signal index to input. One of the ``*_IN_IDX`` signals in ``soc/gpio_sig_map.h``. */ void gpio_hal_iomux_in(gpio_hal_context_t *hal, uint32_t gpio_num, int func, uint32_t signal_idx); @@ -377,6 +377,32 @@ void gpio_hal_iomux_in(gpio_hal_context_t *hal, uint32_t gpio_num, int func, uin */ void gpio_hal_iomux_out(gpio_hal_context_t *hal, uint32_t gpio_num, int func); +/** + * @brief Set pad input to a peripheral signal through the GPIO matrix. + * + * @note There's no limitation on the number of signals that a GPIO can combine with. + * + * @param hal Context of the HAL layer + * @param gpio_num GPIO number, especially, `GPIO_MATRIX_CONST_ZERO_INPUT` means connect logic 0 to signal; + * `GPIO_MATRIX_CONST_ONE_INPUT` means connect logic 1 to signal. + * @param signal_idx Peripheral signal index (tagged as input attribute). One of the ``*_IN_IDX`` signals in ``soc/gpio_sig_map.h``. + * @param in_inv Whether the GPIO input to be inverted or not. + */ +void gpio_hal_matrix_in(gpio_hal_context_t *hal, uint32_t gpio_num, uint32_t signal_idx, bool in_inv); + +/** + * @brief Set peripheral output to an GPIO pad through the GPIO matrix. + * + * @note There's no limitation on the number of signals that a GPIO can combine with. + * + * @param hal Context of the HAL layer + * @param gpio_num GPIO number + * @param signal_idx Peripheral signal index (tagged as output attribute). One of the ``*_OUT_IDX`` signals in ``soc/gpio_sig_map.h``. Particularly, `SIG_GPIO_OUT_IDX` means disconnect GPIO and other peripherals. Only the GPIO driver can control the output level. + * @param out_inv Whether to signal to be inverted or not. + * @param oen_inv Whether the output enable control is inverted or not. + */ +void gpio_hal_matrix_out(gpio_hal_context_t *hal, uint32_t gpio_num, uint32_t signal_idx, bool out_inv, bool oen_inv); + #if SOC_GPIO_SUPPORT_FORCE_HOLD /** * @brief Force hold all digital gpio pads (including those powered by VDD3P3_RTC power domain). diff --git a/components/hal/platform_port/include/hal/config.h b/components/hal/platform_port/include/hal/config.h new file mode 100644 index 0000000000..99ddd712f5 --- /dev/null +++ b/components/hal/platform_port/include/hal/config.h @@ -0,0 +1,18 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include "sdkconfig.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define HAL_CONFIG_GPIO_USE_ROM_API CONFIG_HAL_GPIO_USE_ROM_IMPL + +#ifdef __cplusplus +} +#endif diff --git a/docs/en/migration-guides/release-6.x/6.0/peripherals.rst b/docs/en/migration-guides/release-6.x/6.0/peripherals.rst index 1cd5f7261a..d5c2b6b922 100644 --- a/docs/en/migration-guides/release-6.x/6.0/peripherals.rst +++ b/docs/en/migration-guides/release-6.x/6.0/peripherals.rst @@ -30,6 +30,11 @@ The ``pull_up`` and ``pull_down`` members have been removed from the following c - :cpp:type:`mcpwm_gpio_sync_src_config_t` - :cpp:type:`mcpwm_capture_channel_config_t` +GPIO +---- + +:func:`gpio_iomux_in` and :func:`gpio_iomux_out` have been replaced by :func:`gpio_iomux_input` and :func:`gpio_iomux_output`, and have been moved to ``esp_private/gpio.h`` header file as private APIs for internal use only. + I2C --- diff --git a/docs/zh_CN/migration-guides/release-6.x/6.0/peripherals.rst b/docs/zh_CN/migration-guides/release-6.x/6.0/peripherals.rst index 7bf288cd14..5f0f88c28c 100644 --- a/docs/zh_CN/migration-guides/release-6.x/6.0/peripherals.rst +++ b/docs/zh_CN/migration-guides/release-6.x/6.0/peripherals.rst @@ -30,6 +30,11 @@ MCPWM - :cpp:type:`mcpwm_gpio_sync_src_config_t` - :cpp:type:`mcpwm_capture_channel_config_t` +GPIO +---- + +:func:`gpio_iomux_in` 和 :func:`gpio_iomux_out` 已被 :func:`gpio_iomux_input` 和 :func:`gpio_iomux_output` 函数取代, 并移至 ``esp_private/gpio.h`` 头文件中作为仅供内部使用的私有 API。 + I2C ---