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_gpio/test_apps/gpio/sdkconfig.ci.iram_safe b/components/esp_driver_gpio/test_apps/gpio/sdkconfig.ci.iram_safe index 8d43b77909..653c5c641a 100644 --- a/components/esp_driver_gpio/test_apps/gpio/sdkconfig.ci.iram_safe +++ b/components/esp_driver_gpio/test_apps/gpio/sdkconfig.ci.iram_safe @@ -8,3 +8,5 @@ CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y # GPIO test uses IPC call, the default stack size of IPC task can satisfy the -O0 optimization CONFIG_ESP_IPC_TASK_STACK_SIZE=2048 +# test gpio functionality with non-default option +CONFIG_HAL_GPIO_USE_ROM_IMPL=n 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/esp_rom/esp32/include/esp32/rom/gpio.h b/components/esp_rom/esp32/include/esp32/rom/gpio.h index 6a6b458718..24570f19ef 100644 --- a/components/esp_rom/esp32/include/esp32/rom/gpio.h +++ b/components/esp_rom/esp32/include/esp32/rom/gpio.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -36,15 +36,6 @@ extern "C" { #define GPIO_REGID_TO_PINIDX(reg_id) ((reg_id) - GPIO_ID_PIN0) -typedef enum { - GPIO_PIN_INTR_DISABLE = 0, - GPIO_PIN_INTR_POSEDGE = 1, - GPIO_PIN_INTR_NEGEDGE = 2, - GPIO_PIN_INTR_ANYEDGE = 3, - GPIO_PIN_INTR_LOLEVEL = 4, - GPIO_PIN_INTR_HILEVEL = 5 -} GPIO_INT_TYPE; - #define GPIO_OUTPUT_SET(gpio_no, bit_value) \ ((gpio_no < 32) ? gpio_output_set(bit_value<BIT(0). - * There is no particular ordering guaranteed; so if the order of writes is significant, - * calling code should divide a single call into multiple calls. + * @brief Set GPIO output level * - * @param uint32_t set_mask : the gpios that need high level. - * - * @param uint32_t clear_mask : the gpios that need low level. - * - * @param uint32_t enable_mask : the gpios that need be changed. - * - * @param uint32_t disable_mask : the gpios that need disable output. - * - * @return None + * @param gpio_num GPIO number + * @param level Output level, 0:low; 1:high */ -void gpio_output_set(uint32_t set_mask, uint32_t clear_mask, uint32_t enable_mask, uint32_t disable_mask); +void gpio_set_output_level(uint32_t gpio_num, uint32_t level); /** - * @brief Sample the value of GPIO input pins(0-28) and returns a bitmask. - * @param None + * @brief Get GPIO input level * - * @return uint32_t : bitmask for GPIO input pins, BIT(0) for GPIO0. + * @param gpio_num GPIO number + * + * @return 0:the GPIO_input level is low; 1:the GPIO input level is high */ -uint32_t gpio_input_get(void); - -/** - * @brief Set GPIO to wakeup. - * Please do not call this function in SDK. - * - * @param uint32_t i: gpio number. - * - * @param GPIO_INT_TYPE intr_state : only GPIO_PIN_INTR_LOLEVEL\GPIO_PIN_INTR_HILEVEL can be used - * - * @return None - */ -void gpio_pin_wakeup_enable(uint32_t i, GPIO_INT_TYPE intr_state); - -/** - * @brief disable GPIOs to wakeup. - * Please do not call this function in SDK. - * - * @param None - * - * @return None - */ -void gpio_pin_wakeup_disable(void); +uint32_t gpio_get_input_level(uint32_t gpio_num); /** * @brief set gpio input to a signal, one gpio can input to several signals. diff --git a/components/esp_rom/esp32c6/include/esp32c6/rom/gpio.h b/components/esp_rom/esp32c6/include/esp32c6/rom/gpio.h index 6ac6dc21da..935cbd1e97 100644 --- a/components/esp_rom/esp32c6/include/esp32c6/rom/gpio.h +++ b/components/esp_rom/esp32c6/include/esp32c6/rom/gpio.h @@ -72,7 +72,7 @@ void gpio_output_set(uint32_t set_mask, uint32_t clear_mask, uint32_t enable_mas uint32_t gpio_input_get(void); /** - * @brief Set GPIO to wakeup the ESP32. + * @brief Set GPIO to wakeup the chip. * Please do not call this function in SDK. * * @param uint32_t i: gpio number. @@ -84,7 +84,7 @@ uint32_t gpio_input_get(void); void gpio_pin_wakeup_enable(uint32_t i, GPIO_INT_TYPE intr_state); /** - * @brief disable GPIOs to wakeup the ESP32. + * @brief disable GPIOs to wakeup the chip. * Please do not call this function in SDK. * * @param None diff --git a/components/esp_rom/esp32c61/include/esp32c61/rom/gpio.h b/components/esp_rom/esp32c61/include/esp32c61/rom/gpio.h index abaa4a8ab0..9ba44accc7 100644 --- a/components/esp_rom/esp32c61/include/esp32c61/rom/gpio.h +++ b/components/esp_rom/esp32c61/include/esp32c61/rom/gpio.h @@ -33,62 +33,23 @@ extern "C" { #define GPIO_REGID_TO_PINIDX(reg_id) ((reg_id) - GPIO_ID_PIN0) -typedef enum { - GPIO_PIN_INTR_DISABLE = 0, - GPIO_PIN_INTR_POSEDGE = 1, - GPIO_PIN_INTR_NEGEDGE = 2, - GPIO_PIN_INTR_ANYEDGE = 3, - GPIO_PIN_INTR_LOLEVEL = 4, - GPIO_PIN_INTR_HILEVEL = 5 -} GPIO_INT_TYPE; - /** - * @brief Change GPIO(0-29) pin output by setting, clearing, or disabling pins, GPIO0<->BIT(0). - * There is no particular ordering guaranteed; so if the order of writes is significant, - * calling code should divide a single call into multiple calls. + * @brief Set GPIO output level * - * @param uint32_t set_mask : the gpios that need high level. - * - * @param uint32_t clear_mask : the gpios that need low level. - * - * @param uint32_t enable_mask : the gpios that need be changed. - * - * @param uint32_t disable_mask : the gpios that need disable output. - * - * @return None + * @param gpio_num GPIO number + * @param level Output level, 0:low; 1:high */ -void gpio_output_set(uint32_t set_mask, uint32_t clear_mask, uint32_t enable_mask, uint32_t disable_mask); +void gpio_set_output_level(uint32_t gpio_num, uint32_t level); /** - * @brief Sample the value of GPIO input pins(0-29) and returns a bitmask. - * @param None + * @brief Get GPIO input level * - * @return uint32_t : bitmask for GPIO input pins, BIT(0) for GPIO0. + * @param gpio_num GPIO number + * + * @return 0:the GPIO_input level is low; 1:the GPIO input level is high */ -uint32_t gpio_input_get(void); - -/** - * @brief Set GPIO to wakeup. - * Please do not call this function in SDK. - * - * @param uint32_t i: gpio number. - * - * @param GPIO_INT_TYPE intr_state : only GPIO_PIN_INTR_LOLEVEL\GPIO_PIN_INTR_HILEVEL can be used - * - * @return None - */ -void gpio_pin_wakeup_enable(uint32_t i, GPIO_INT_TYPE intr_state); - -/** - * @brief disable GPIOs to wakeup. - * Please do not call this function in SDK. - * - * @param None - * - * @return None - */ -void gpio_pin_wakeup_disable(void); +uint32_t gpio_get_input_level(uint32_t gpio_num); /** * @brief set gpio input to a signal, one gpio can input to several signals. diff --git a/components/esp_rom/esp32h2/include/esp32h2/rom/gpio.h b/components/esp_rom/esp32h2/include/esp32h2/rom/gpio.h index 5829765c60..74551dd693 100644 --- a/components/esp_rom/esp32h2/include/esp32h2/rom/gpio.h +++ b/components/esp_rom/esp32h2/include/esp32h2/rom/gpio.h @@ -73,7 +73,7 @@ void gpio_output_set(uint32_t set_mask, uint32_t clear_mask, uint32_t enable_mas uint32_t gpio_input_get(void); /** - * @brief Set GPIO to wakeup the ESP32. + * @brief Set GPIO to wakeup the chip. * Please do not call this function in SDK. * * @param uint32_t i: gpio number. @@ -85,7 +85,7 @@ uint32_t gpio_input_get(void); void gpio_pin_wakeup_enable(uint32_t i, GPIO_INT_TYPE intr_state); /** - * @brief disable GPIOs to wakeup the ESP32. + * @brief disable GPIOs to wakeup the chip. * Please do not call this function in SDK. * * @param None diff --git a/components/esp_rom/esp32h21/include/esp32h21/rom/gpio.h b/components/esp_rom/esp32h21/include/esp32h21/rom/gpio.h index 4fa2cd0e98..987cd887a8 100644 --- a/components/esp_rom/esp32h21/include/esp32h21/rom/gpio.h +++ b/components/esp_rom/esp32h21/include/esp32h21/rom/gpio.h @@ -73,7 +73,7 @@ void gpio_output_set(uint32_t set_mask, uint32_t clear_mask, uint32_t enable_mas uint32_t gpio_input_get(void); /** - * @brief Set GPIO to wakeup the ESP32H21. + * @brief Set GPIO to wakeup the chip. * Please do not call this function in SDK. * * @param uint32_t i: gpio number. @@ -85,7 +85,7 @@ uint32_t gpio_input_get(void); void gpio_pin_wakeup_enable(uint32_t i, GPIO_INT_TYPE intr_state); /** - * @brief disable GPIOs to wakeup the ESP32H21. + * @brief disable GPIOs to wakeup the chip. * Please do not call this function in SDK. * * @param None diff --git a/components/esp_rom/esp32h4/include/esp32h4/rom/gpio.h b/components/esp_rom/esp32h4/include/esp32h4/rom/gpio.h index a4e36af30a..da4cec9da0 100644 --- a/components/esp_rom/esp32h4/include/esp32h4/rom/gpio.h +++ b/components/esp_rom/esp32h4/include/esp32h4/rom/gpio.h @@ -25,10 +25,6 @@ extern "C" { #define GPIO_REG_READ(reg) READ_PERI_REG(reg) #define GPIO_REG_WRITE(reg, val) WRITE_PERI_REG(reg, val) -#define GPIO_OUTPUT_SET(gpio_no, bit_value) gpio_set_output_level(gpio_no, bit_value) -#define GPIO_DIS_OUTPUT(gpio_no) gpio_output_disable(gpio_no) -#define GPIO_INPUT_GET(gpio_no) gpio_get_input_level(gpio_no) - /** * @brief Set GPIO output level * @@ -83,23 +79,23 @@ void gpio_bypass_matrix_in(uint32_t signal_idx); */ void gpio_matrix_out(uint32_t gpio_num, uint32_t signal_idx, bool out_inv, bool oen_inv); -/** - * @brief enable gpio output. - * - * @param uint32_t gpio_num : gpio number - * - * @return None - */ -void gpio_output_enable(uint32_t gpio_num); +// /** +// * @brief enable gpio output. +// * +// * @param uint32_t gpio_num : gpio number +// * +// * @return None +// */ +// void gpio_output_enable(uint32_t gpio_num); -/** - * @brief disable gpio output. - * - * @param uint32_t gpio_num : gpio number - * - * @return None - */ -void gpio_output_disable(uint32_t gpio_num); +// /** +// * @brief disable gpio output. +// * +// * @param uint32_t gpio_num : gpio number +// * +// * @return None +// */ +// void gpio_output_disable(uint32_t gpio_num); /** * @brief Select pad as a gpio function from IOMUX. @@ -110,15 +106,6 @@ void gpio_output_disable(uint32_t gpio_num); */ void gpio_pad_select_gpio(uint32_t gpio_num); -/** - * @brief Select a mux for the pad(LP pad) in the IOMUX. - * @note This function is only for LP pad and not all chips have LP pad. - * - * @param gpio_num GPIO number should be LP GPIO - * @param mux_sel Select pad as LP GPIO or HP GPIO, 1:LP GPIO,0:HP GPIO - */ -void gpio_lppad_select_mux(uint32_t gpio_num, uint32_t mux_sel); - /** * @brief Set pad driver capability. * @@ -130,17 +117,6 @@ void gpio_lppad_select_mux(uint32_t gpio_num, uint32_t mux_sel); */ void gpio_pad_set_drv(uint32_t gpio_num, uint32_t drv); -/** - * @brief Set MSPI dedicated pad driver capability. - * - * @param uint32_t gpio_num : MSPI dedicated gpio number - * - * @param uint32_t drv : 0-3 - * - * @return None - */ -void gpio_ded_pad_set_drv(uint32_t ded_gpio_num, uint32_t drv); - /** * @brief Pull up the pad from gpio number. * @@ -150,15 +126,6 @@ void gpio_ded_pad_set_drv(uint32_t ded_gpio_num, uint32_t drv); */ void gpio_pad_pullup(uint32_t gpio_num); -/** - * @brief Pull up the MSPI dedicated pad from gpio number. - * - * @param uint32_t gpio_num : MSPI dedicated gpio number - * - * @return None - */ -void gpio_ded_pad_pullup(uint32_t ded_gpio_num); - /** * @brief Pull down the pad from gpio number. * @@ -168,15 +135,6 @@ void gpio_ded_pad_pullup(uint32_t ded_gpio_num); */ void gpio_pad_pulldown(uint32_t gpio_num); -/** - * @brief Pull down the MSPI dedicated pad from gpio number. - * - * @param uint32_t gpio_num : MSPI dedicated gpio number - * - * @return None - */ -void gpio_ded_pad_pulldown(uint32_t ded_gpio_num); - /** * @brief enable gpio pad input. * @@ -204,15 +162,6 @@ void gpio_pad_input_disable(uint32_t gpio_num); */ void gpio_pad_unhold(uint32_t gpio_num); -/** - * @brief Unhold the mspi dedicated pad from gpio number. - * - * @param uint32_t gpio_num : mspi dedicated gpio number - * - * @return None - */ -void gpio_ded_pad_unhold(uint32_t ded_gpio_num); - /** * @brief Hold the pad from gpio number. * @@ -222,15 +171,6 @@ void gpio_ded_pad_unhold(uint32_t ded_gpio_num); */ void gpio_pad_hold(uint32_t gpio_num); -/** - * @brief Hold the mspi dedicated pad from gpio number. - * - * @param uint32_t gpio_num : mspi dedicated gpio number - * - * @return None - */ -void gpio_ded_pad_hold(uint32_t gpio_num); - /** * @} */ diff --git a/components/esp_rom/esp32p4/include/esp32p4/rom/gpio.h b/components/esp_rom/esp32p4/include/esp32p4/rom/gpio.h index e59383319b..c07d11114f 100644 --- a/components/esp_rom/esp32p4/include/esp32p4/rom/gpio.h +++ b/components/esp_rom/esp32p4/include/esp32p4/rom/gpio.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -38,161 +38,22 @@ extern "C" { #define GPIO_REGID_TO_PINIDX(reg_id) ((reg_id) - GPIO_ID_PIN0) -typedef enum { - GPIO_PIN_INTR_DISABLE = 0, - GPIO_PIN_INTR_POSEDGE = 1, - GPIO_PIN_INTR_NEGEDGE = 2, - GPIO_PIN_INTR_ANYEDGE = 3, - GPIO_PIN_INTR_LOLEVEL = 4, - GPIO_PIN_INTR_HILEVEL = 5 -} GPIO_INT_TYPE; - -#define GPIO_OUTPUT_SET(gpio_no, bit_value) \ - ((gpio_no < 32) ? gpio_output_set(bit_value<>gpio_no)&BIT0) : ((gpio_input_get_high()>>(gpio_no - 32))&BIT0)) - -/* GPIO interrupt handler, registered through gpio_intr_handler_register */ -typedef void (* gpio_intr_handler_fn_t)(uint32_t intr_mask, bool high, void *arg); +/** + * @brief Set GPIO output level + * + * @param gpio_num GPIO number + * @param level Output level, 0:low; 1:high + */ +void gpio_set_output_level(uint32_t gpio_num, uint32_t level); /** - * @brief Initialize GPIO. This includes reading the GPIO Configuration DataSet - * to initialize "output enables" and pin configurations for each gpio pin. - * Please do not call this function in SDK. + * @brief Get GPIO input level * - * @param None + * @param gpio_num GPIO number * - * @return None + * @return 0:the GPIO_input level is low; 1:the GPIO input level is high */ -void gpio_init(void); - -/** - * @brief Change GPIO(0-31) pin output by setting, clearing, or disabling pins, GPIO0<->BIT(0). - * There is no particular ordering guaranteed; so if the order of writes is significant, - * calling code should divide a single call into multiple calls. - * - * @param uint32_t set_mask : the gpios that need high level. - * - * @param uint32_t clear_mask : the gpios that need low level. - * - * @param uint32_t enable_mask : the gpios that need be changed. - * - * @param uint32_t disable_mask : the gpios that need disable output. - * - * @return None - */ -void gpio_output_set(uint32_t set_mask, uint32_t clear_mask, uint32_t enable_mask, uint32_t disable_mask); - -/** - * @brief Change GPIO(32-54) pin output by setting, clearing, or disabling pins, GPIO32<->BIT(0). - * There is no particular ordering guaranteed; so if the order of writes is significant, - * calling code should divide a single call into multiple calls. - * - * @param uint32_t set_mask : the gpios that need high level. - * - * @param uint32_t clear_mask : the gpios that need low level. - * - * @param uint32_t enable_mask : the gpios that need be changed. - * - * @param uint32_t disable_mask : the gpios that need disable output. - * - * @return None - */ -void gpio_output_set_high(uint32_t set_mask, uint32_t clear_mask, uint32_t enable_mask, uint32_t disable_mask); - -/** - * @brief Sample the value of GPIO input pins(0-31) and returns a bitmask. - * - * @param None - * - * @return uint32_t : bitmask for GPIO input pins, BIT(0) for GPIO0. - */ -uint32_t gpio_input_get(void); - -/** - * @brief Sample the value of GPIO input pins(32-54) and returns a bitmask. - * - * @param None - * - * @return uint32_t : bitmask for GPIO input pins, BIT(0) for GPIO32. - */ -uint32_t gpio_input_get_high(void); - -/** - * @brief Register an application-specific interrupt handler for GPIO pin interrupts. - * Once the interrupt handler is called, it will not be called again until after a call to gpio_intr_ack. - * Please do not call this function in SDK. - * - * @param gpio_intr_handler_fn_t fn : gpio application-specific interrupt handler - * - * @param void *arg : gpio application-specific interrupt handler argument. - * - * @return None - */ -void gpio_intr_handler_register(gpio_intr_handler_fn_t fn, void *arg); - -/** - * @brief Get gpio interrupts which happens but not processed. - * Please do not call this function in SDK. - * - * @param None - * - * @return uint32_t : bitmask for GPIO pending interrupts, BIT(0) for GPIO0. - */ -uint32_t gpio_intr_pending(void); - -/** - * @brief Get gpio interrupts which happens but not processed. - * Please do not call this function in SDK. - * - * @param None - * - * @return uint32_t : bitmask for GPIO pending interrupts, BIT(0) for GPIO32. - */ -uint32_t gpio_intr_pending_high(void); - -/** - * @brief Ack gpio interrupts to process pending interrupts. - * Please do not call this function in SDK. - * - * @param uint32_t ack_mask: bitmask for GPIO ack interrupts, BIT(0) for GPIO0. - * - * @return None - */ -void gpio_intr_ack(uint32_t ack_mask); - -/** - * @brief Ack gpio interrupts to process pending interrupts. - * Please do not call this function in SDK. - * - * @param uint32_t ack_mask: bitmask for GPIO ack interrupts, BIT(0) for GPIO32. - * - * @return None - */ -void gpio_intr_ack_high(uint32_t ack_mask); - -/** - * @brief Set GPIO to wakeup the ESP32P4. - * Please do not call this function in SDK. - * - * @param uint32_t i: gpio number. - * - * @param GPIO_INT_TYPE intr_state : only GPIO_PIN_INTR_LOLEVEL\GPIO_PIN_INTR_HILEVEL can be used - * - * @return None - */ -void gpio_pin_wakeup_enable(uint32_t i, GPIO_INT_TYPE intr_state); - -/** - * @brief disable GPIOs to wakeup the ESP32P4. - * Please do not call this function in SDK. - * - * @param None - * - * @return None - */ -void gpio_pin_wakeup_disable(void); +uint32_t gpio_get_input_level(uint32_t gpio_num); /** * @brief set gpio input to a signal, one gpio can input to several signals. diff --git a/components/esp_rom/esp32s2/include/esp32s2/rom/gpio.h b/components/esp_rom/esp32s2/include/esp32s2/rom/gpio.h index 84e0af1adb..c350a1200c 100644 --- a/components/esp_rom/esp32s2/include/esp32s2/rom/gpio.h +++ b/components/esp_rom/esp32s2/include/esp32s2/rom/gpio.h @@ -104,7 +104,7 @@ uint32_t gpio_input_get(void); uint32_t gpio_input_get_high(void); /** - * @brief Set GPIO to wakeup the ESP32. + * @brief Set GPIO to wakeup the chip. * Please do not call this function in SDK. * * @param uint32_t i: gpio number. @@ -116,7 +116,7 @@ uint32_t gpio_input_get_high(void); void gpio_pin_wakeup_enable(uint32_t i, GPIO_INT_TYPE intr_state); /** - * @brief disable GPIOs to wakeup the ESP32. + * @brief disable GPIOs to wakeup the chip. * Please do not call this function in SDK. * * @param None diff --git a/components/esp_rom/esp32s3/include/esp32s3/rom/gpio.h b/components/esp_rom/esp32s3/include/esp32s3/rom/gpio.h index 8958b03578..414bbc91d6 100644 --- a/components/esp_rom/esp32s3/include/esp32s3/rom/gpio.h +++ b/components/esp_rom/esp32s3/include/esp32s3/rom/gpio.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -63,6 +63,7 @@ typedef enum { */ void gpio_output_set(uint32_t set_mask, uint32_t clear_mask, uint32_t enable_mask, uint32_t disable_mask); +// gpio_output_set_high does not show in ESP32S3 ROM /** * @brief Sample the value of GPIO input pins(0-31) and returns a bitmask. @@ -73,8 +74,10 @@ void gpio_output_set(uint32_t set_mask, uint32_t clear_mask, uint32_t enable_mas */ uint32_t gpio_input_get(void); +// gpio_input_get_high does not show in ESP32S3 ROM + /** - * @brief Set GPIO to wakeup the ESP32. + * @brief Set GPIO to wakeup the chip. * Please do not call this function in SDK. * * @param uint32_t i: gpio number. @@ -86,7 +89,7 @@ uint32_t gpio_input_get(void); void gpio_pin_wakeup_enable(uint32_t i, GPIO_INT_TYPE intr_state); /** - * @brief disable GPIOs to wakeup the ESP32. + * @brief disable GPIOs to wakeup the chip. * Please do not call this function in SDK. * * @param None 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..f4d65bb499 100644 --- a/components/hal/esp32c5/include/hal/gpio_ll.h +++ b/components/hal/esp32c5/include/hal/gpio_ll.h @@ -27,6 +27,8 @@ #include "soc/usb_serial_jtag_struct.h" #include "hal/gpio_types.h" #include "hal/assert.h" +#include "hal/config.h" +#include "rom/gpio.h" #ifdef __cplusplus extern "C" { @@ -326,21 +328,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 * @@ -351,11 +338,15 @@ static inline void gpio_ll_matrix_out_default(gpio_dev_t *hw, uint32_t gpio_num) __attribute__((always_inline)) static inline void gpio_ll_set_level(gpio_dev_t *hw, uint32_t gpio_num, uint32_t level) { +#if HAL_CONFIG_GPIO_USE_ROM_API + gpio_set_output_level(gpio_num, level); +#else if (level) { hw->out_w1ts.val = 1 << gpio_num; } else { hw->out_w1tc.val = 1 << gpio_num; } +#endif } /** @@ -373,7 +364,11 @@ static inline void gpio_ll_set_level(gpio_dev_t *hw, uint32_t gpio_num, uint32_t __attribute__((always_inline)) static inline int gpio_ll_get_level(gpio_dev_t *hw, uint32_t gpio_num) { +#if HAL_CONFIG_GPIO_USE_ROM_API + return gpio_get_input_level(gpio_num); +#else return (hw->in.in_data_next >> gpio_num) & 0x1; +#endif } /** @@ -477,6 +472,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 +520,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 +575,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..3e8ff27654 100644 --- a/components/hal/esp32c61/include/hal/gpio_ll.h +++ b/components/hal/esp32c61/include/hal/gpio_ll.h @@ -27,6 +27,8 @@ #include "soc/io_mux_struct.h" #include "hal/gpio_types.h" #include "hal/assert.h" +#include "hal/config.h" +#include "rom/gpio.h" #ifdef __cplusplus extern "C" { @@ -324,21 +326,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 * @@ -349,11 +336,15 @@ static inline void gpio_ll_matrix_out_default(gpio_dev_t *hw, uint32_t gpio_num) __attribute__((always_inline)) static inline void gpio_ll_set_level(gpio_dev_t *hw, uint32_t gpio_num, uint32_t level) { +#if HAL_CONFIG_GPIO_USE_ROM_API + gpio_set_output_level(gpio_num, level); +#else if (level) { hw->out_w1ts.val = 1 << gpio_num; } else { hw->out_w1tc.val = 1 << gpio_num; } +#endif } /** @@ -371,7 +362,11 @@ static inline void gpio_ll_set_level(gpio_dev_t *hw, uint32_t gpio_num, uint32_t __attribute__((always_inline)) static inline int gpio_ll_get_level(gpio_dev_t *hw, uint32_t gpio_num) { +#if HAL_CONFIG_GPIO_USE_ROM_API + return gpio_get_input_level(gpio_num); +#else return (hw->in.in_data_next >> gpio_num) & 0x1; +#endif } /** @@ -477,6 +472,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 +520,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 +575,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..3bb8747402 100644 --- a/components/hal/esp32h4/include/hal/gpio_ll.h +++ b/components/hal/esp32h4/include/hal/gpio_ll.h @@ -26,6 +26,8 @@ #include "hal/gpio_types.h" #include "hal/misc.h" #include "hal/assert.h" +#include "hal/config.h" +#include "rom/gpio.h" #ifdef __cplusplus extern "C" { @@ -304,21 +306,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 * @@ -329,6 +316,9 @@ static inline void gpio_ll_matrix_out_default(gpio_dev_t *hw, uint32_t gpio_num) __attribute__((always_inline)) static inline void gpio_ll_set_level(gpio_dev_t *hw, uint32_t gpio_num, uint32_t level) { +#if HAL_CONFIG_GPIO_USE_ROM_API + gpio_set_output_level(gpio_num, level); +#else if (level) { if (gpio_num < 32) { hw->out_w1ts.val = (1 << gpio_num); @@ -342,6 +332,7 @@ static inline void gpio_ll_set_level(gpio_dev_t *hw, uint32_t gpio_num, uint32_t hw->out1_w1tc.val = (1 << (gpio_num - 32)); } } +#endif } /** @@ -359,11 +350,15 @@ static inline void gpio_ll_set_level(gpio_dev_t *hw, uint32_t gpio_num, uint32_t __attribute__((always_inline)) static inline int gpio_ll_get_level(gpio_dev_t *hw, uint32_t gpio_num) { +#if HAL_CONFIG_GPIO_USE_ROM_API + return gpio_get_input_level(gpio_num); +#else if (gpio_num < 32) { return (hw->in.in_data_next >> gpio_num) & 0x1; } else { return (hw->in1.in1_data_next >> (gpio_num - 32)) & 0x1; } +#endif } /** @@ -478,20 +473,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 +521,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 +576,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..ae72435ac5 100644 --- a/components/hal/esp32p4/include/hal/gpio_ll.h +++ b/components/hal/esp32p4/include/hal/gpio_ll.h @@ -31,6 +31,8 @@ #include "hal/gpio_types.h" #include "hal/misc.h" #include "hal/assert.h" +#include "hal/config.h" +#include "rom/gpio.h" #ifdef __cplusplus extern "C" { @@ -372,21 +374,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 * @@ -397,6 +384,9 @@ static inline void gpio_ll_matrix_out_default(gpio_dev_t *hw, uint32_t gpio_num) __attribute__((always_inline)) static inline void gpio_ll_set_level(gpio_dev_t *hw, uint32_t gpio_num, uint32_t level) { +#if HAL_CONFIG_GPIO_USE_ROM_API + gpio_set_output_level(gpio_num, level); +#else if (level) { if (gpio_num < 32) { hw->out_w1ts.val = 1 << gpio_num; @@ -410,6 +400,7 @@ static inline void gpio_ll_set_level(gpio_dev_t *hw, uint32_t gpio_num, uint32_t hw->out1_w1tc.val = 1 << (gpio_num - 32); } } +#endif } /** @@ -427,11 +418,15 @@ static inline void gpio_ll_set_level(gpio_dev_t *hw, uint32_t gpio_num, uint32_t __attribute__((always_inline)) static inline int gpio_ll_get_level(gpio_dev_t *hw, uint32_t gpio_num) { +#if HAL_CONFIG_GPIO_USE_ROM_API + return gpio_get_input_level(gpio_num); +#else if (gpio_num < 32) { return (hw->in.in_data_next >> gpio_num) & 0x1; } else { return (hw->in1.in1_data_next >> (gpio_num - 32)) & 0x1; } +#endif } /** @@ -580,6 +575,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 +623,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 +686,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 01755deac1..e72fa9aa7a 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 ce9f518f4b..0540dd04ba 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 ---