Skip to content

Commit 60bef64

Browse files
committed
feat(gpio): esp_rom_gpio_connect_in/out_signal now has their hal implementation
1 parent 42682b1 commit 60bef64

File tree

26 files changed

+754
-425
lines changed

26 files changed

+754
-425
lines changed

components/esp_driver_gpio/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@ There is no need to enable the output for the IO explicitly, it is done internal
1212

1313
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.
1414

15-
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.
15+
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.
1616

1717
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.
1818

1919
## Configure an IO as a peripheral signal input
2020

2121
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.
2222

23-
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.
23+
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.
2424

2525
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.
2626

components/esp_driver_gpio/include/driver/gpio.h

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -497,22 +497,6 @@ void gpio_deep_sleep_hold_en(void);
497497
void gpio_deep_sleep_hold_dis(void);
498498
#endif //SOC_GPIO_SUPPORT_HOLD_IO_IN_DSLP && !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
499499

500-
/**
501-
* @brief Set pad input to a peripheral signal through the IOMUX.
502-
* @param gpio_num GPIO number of the pad.
503-
* @param signal_idx Peripheral signal id to input. One of the ``*_IN_IDX`` signals in ``soc/gpio_sig_map.h``.
504-
*/
505-
void gpio_iomux_in(uint32_t gpio_num, uint32_t signal_idx) __attribute__((deprecated("Please use `gpio_iomux_input` instead")));
506-
507-
/**
508-
* @brief Set peripheral output to an GPIO pad through the IOMUX.
509-
* @param gpio_num gpio_num GPIO number of the pad.
510-
* @param func The function number of the peripheral pin to output pin.
511-
* One of the ``FUNC_X_*`` of specified pin (X) in ``soc/io_mux_reg.h``.
512-
* @param out_en_inv True if the output enable needs to be inverted, otherwise False.
513-
*/
514-
void gpio_iomux_out(uint8_t gpio_num, int func, bool out_en_inv) __attribute__((deprecated("Please use `gpio_iomux_output` instead")));
515-
516500
#if SOC_GPIO_SUPPORT_FORCE_HOLD
517501
/**
518502
* @brief Force hold all digital and rtc gpio pads.

components/esp_driver_gpio/include/esp_private/gpio.h

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ esp_err_t gpio_config_as_analog(gpio_num_t gpio_num);
6868
* @param gpio_num GPIO number of the pad.
6969
* @param func The index number of the IOMUX function to be selected for the pin.
7070
* One of the ``FUNC_X_*`` of specified pin (X) in ``soc/io_mux_reg.h``.
71-
* @param signal_idx Peripheral signal id to input. One of the ``*_IN_IDX`` signals in ``soc/gpio_sig_map.h``.
71+
* @param signal_idx Peripheral signal index to input. One of the ``*_IN_IDX`` signals in ``soc/gpio_sig_map.h``.
7272
*
7373
* @return
7474
* - ESP_OK Success
@@ -89,6 +89,41 @@ esp_err_t gpio_iomux_input(gpio_num_t gpio_num, int func, uint32_t signal_idx);
8989
*/
9090
esp_err_t gpio_iomux_output(gpio_num_t gpio_num, int func);
9191

92+
/**
93+
* @brief Set pad input to a peripheral signal through the GPIO matrix.
94+
*
95+
* @note A GPIO can combine with multiple input signals.
96+
*
97+
* @param gpio_num GPIO number, especially, `GPIO_MATRIX_CONST_ZERO_INPUT` means connect logic 0 to signal;
98+
* `GPIO_MATRIX_CONST_ONE_INPUT` means connect logic 1 to signal.
99+
* @param signal_idx Peripheral signal index (tagged as input attribute).
100+
* One of the ``*_IN_IDX`` signals in ``soc/gpio_sig_map.h``.
101+
* @param in_inv Whether the GPIO input to be inverted or not.
102+
*
103+
* @return
104+
* - ESP_OK Success
105+
* - ESP_ERR_INVALID_ARG GPIO number error
106+
*/
107+
esp_err_t gpio_matrix_input(gpio_num_t gpio_num, uint32_t signal_idx, bool in_inv);
108+
109+
/**
110+
* @brief Set peripheral output to an GPIO pad through the GPIO matrix.
111+
*
112+
* @note An output signal can be combined with multiple GPIOs.
113+
*
114+
* @param gpio_num GPIO number
115+
* @param signal_idx Peripheral signal index (tagged as output attribute).
116+
* One of the ``*_OUT_IDX`` signals in ``soc/gpio_sig_map.h``.
117+
* Particularly, `SIG_GPIO_OUT_IDX` means disconnect GPIO with any peripheral.
118+
* @param out_inv Whether to signal to be inverted or not.
119+
* @param oen_inv Whether the output enable control is inverted or not.
120+
*
121+
* @return
122+
* - ESP_OK Success
123+
* - ESP_ERR_INVALID_ARG GPIO number error
124+
*/
125+
esp_err_t gpio_matrix_output(gpio_num_t gpio_num, uint32_t signal_idx, bool out_inv, bool oen_inv);
126+
92127
#ifdef __cplusplus
93128
}
94129
#endif

components/esp_driver_gpio/src/gpio.c

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -813,13 +813,6 @@ esp_err_t IRAM_ATTR gpio_force_unhold_all()
813813
}
814814
#endif //SOC_GPIO_SUPPORT_FORCE_HOLD
815815

816-
// Deprecated function
817-
void gpio_iomux_in(uint32_t gpio, uint32_t signal_idx)
818-
{
819-
gpio_ll_set_input_signal_from(gpio_context.gpio_hal->dev, signal_idx, false);
820-
gpio_hal_input_enable(gpio_context.gpio_hal, gpio);
821-
}
822-
823816
esp_err_t gpio_iomux_input(gpio_num_t gpio_num, int func, uint32_t signal_idx)
824817
{
825818
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)
831824
return ESP_OK;
832825
}
833826

834-
// Deprecated function
835-
void gpio_iomux_out(uint8_t gpio_num, int func, bool out_en_inv)
836-
{
837-
(void)out_en_inv; // out_en_inv only takes effect when signal goes through gpio matrix to the IO
838-
gpio_hal_iomux_out(gpio_context.gpio_hal, gpio_num, func);
839-
}
840-
841827
esp_err_t gpio_iomux_output(gpio_num_t gpio_num, int func)
842828
{
843829
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)
849835
return ESP_OK;
850836
}
851837

838+
esp_err_t gpio_matrix_input(gpio_num_t gpio_num, uint32_t signal_idx, bool in_inv)
839+
{
840+
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
841+
842+
gpio_hal_matrix_in(gpio_context.gpio_hal, gpio_num, signal_idx, in_inv);
843+
844+
return ESP_OK;
845+
}
846+
847+
esp_err_t gpio_matrix_output(gpio_num_t gpio_num, uint32_t signal_idx, bool out_inv, bool oen_inv)
848+
{
849+
GPIO_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
850+
851+
gpio_hal_matrix_out(gpio_context.gpio_hal, gpio_num, signal_idx, out_inv, oen_inv);
852+
853+
return ESP_OK;
854+
}
855+
852856
static esp_err_t gpio_sleep_pullup_en(gpio_num_t gpio_num)
853857
{
854858
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);

components/esp_driver_ledc/src/ledc.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
#include "soc/soc_caps.h"
1818
#include "hal/ledc_hal.h"
1919
#include "driver/ledc.h"
20-
#include "esp_rom_gpio.h"
2120
#include "clk_ctrl_os.h"
2221
#include "esp_private/esp_sleep_internal.h"
2322
#include "esp_private/periph_ctrl.h"
@@ -807,14 +806,13 @@ esp_err_t ledc_timer_config(const ledc_timer_config_t *timer_conf)
807806

808807
esp_err_t _ledc_set_pin(int gpio_num, bool out_inv, ledc_mode_t speed_mode, ledc_channel_t channel)
809808
{
810-
gpio_func_sel(gpio_num, PIN_FUNC_GPIO);
811809
// reserve the GPIO output path, because we don't expect another peripheral to signal to the same GPIO
812810
uint64_t old_gpio_rsv_mask = esp_gpio_reserve(BIT64(gpio_num));
813811
// check if the GPIO is already used by others, LEDC signal only uses the output path of the GPIO
814812
if (old_gpio_rsv_mask & BIT64(gpio_num)) {
815813
ESP_LOGW(LEDC_TAG, "GPIO %d is not usable, maybe conflict with others", gpio_num);
816814
}
817-
esp_rom_gpio_connect_out_signal(gpio_num, ledc_periph_signal[speed_mode].sig_out0_idx + channel, out_inv, 0);
815+
gpio_matrix_output(gpio_num, ledc_periph_signal[speed_mode].sig_out0_idx + channel, out_inv, false);
818816
return ESP_OK;
819817
}
820818

components/esp_driver_ledc/test_apps/ledc/sdkconfig.ci.iram_safe

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@ CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y
77
# ledc driver uses assert in the ISR code path
88
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE=y
99
CONFIG_LEDC_CTRL_FUNC_IN_IRAM=y
10+
# test gpio signal connection with non-default option
11+
CONFIG_HAL_GPIO_USE_ROM_IMPL=n

components/esp_driver_uart/src/uart.c

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -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
844844
#endif
845845
if (tx_rx_same_io || !uart_try_set_iomux_pin(uart_num, tx_io_num, SOC_UART_TX_PIN_IDX)) {
846846
if (uart_num < SOC_UART_HP_NUM) {
847-
gpio_func_sel(tx_io_num, PIN_FUNC_GPIO);
848-
esp_rom_gpio_connect_out_signal(tx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_TX_PIN_IDX), 0, 0);
849-
// output enable is set inside esp_rom_gpio_connect_out_signal func after the signal is connected
850-
// (output enabled too early may cause unnecessary level change at the pad)
847+
gpio_matrix_output(tx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_TX_PIN_IDX), false, false);
851848
}
852849
#if SOC_LP_GPIO_MATRIX_SUPPORTED
853850
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
870867
if (tx_rx_same_io || !uart_try_set_iomux_pin(uart_num, rx_io_num, SOC_UART_RX_PIN_IDX)) {
871868
io_reserve_mask &= ~BIT64(rx_io_num); // input IO via GPIO matrix does not need to be reserved
872869
if (uart_num < SOC_UART_HP_NUM) {
873-
gpio_input_enable(rx_io_num);
874-
esp_rom_gpio_connect_in_signal(rx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RX_PIN_IDX), 0);
870+
gpio_matrix_input(rx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RX_PIN_IDX), false);
875871
}
876872
#if SOC_LP_GPIO_MATRIX_SUPPORTED
877873
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
889885

890886
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))) {
891887
if (uart_num < SOC_UART_HP_NUM) {
892-
gpio_func_sel(rts_io_num, PIN_FUNC_GPIO);
893-
esp_rom_gpio_connect_out_signal(rts_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RTS_PIN_IDX), 0, 0);
894-
// output enable is set inside esp_rom_gpio_connect_out_signal func after the signal is connected
888+
gpio_matrix_output(rts_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RTS_PIN_IDX), false, false);
895889
}
896890
#if SOC_LP_GPIO_MATRIX_SUPPORTED
897891
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
905899
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))) {
906900
io_reserve_mask &= ~BIT64(cts_io_num); // input IO via GPIO matrix does not need to be reserved
907901
if (uart_num < SOC_UART_HP_NUM) {
908-
gpio_pullup_en(cts_io_num);
909-
gpio_input_enable(cts_io_num);
910-
esp_rom_gpio_connect_in_signal(cts_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_CTS_PIN_IDX), 0);
902+
gpio_matrix_input(cts_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_CTS_PIN_IDX), false);
911903
}
912904
#if SOC_LP_GPIO_MATRIX_SUPPORTED
913905
else {

components/esp_driver_uart/test_apps/uart/sdkconfig.ci.iram_safe

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,5 @@ CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y
66
# silent the error check, as the error string are stored in rodata, causing RTL check failure
77
CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y
88
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y
9+
# test gpio signal connection with non-default option
10+
CONFIG_HAL_GPIO_USE_ROM_IMPL=n

components/hal/Kconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,16 @@ menu "Hardware Abstraction Layer (HAL) and Low Level (LL)"
9191
features will be added and bugs will be fixed in the IDF source
9292
but cannot be synced to ROM.
9393

94+
config HAL_GPIO_USE_ROM_IMPL
95+
bool "Use ROM implementation of GPIO HAL driver"
96+
default y
97+
help
98+
Enable this flag to use HAL functions from ROM when applicable instead of ESP-IDF.
99+
100+
If keeping this as "n" in your project, you will have less free IRAM.
101+
When compiling an application for a CPU that cannot access to the ROM memory,
102+
this option should be disabled.
103+
94104
config HAL_ECDSA_GEN_SIG_CM
95105
bool "Enable countermeasure for ECDSA signature generation"
96106
depends on IDF_TARGET_ESP32H2

components/hal/esp32/include/hal/gpio_ll.h

Lines changed: 49 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -468,18 +468,6 @@ static inline void gpio_ll_od_enable(gpio_dev_t *hw, uint32_t gpio_num)
468468
hw->pin[gpio_num].pad_driver = 1;
469469
}
470470

471-
/**
472-
* @brief Disconnect any peripheral output signal routed via GPIO matrix to the pin
473-
*
474-
* @param hw Peripheral GPIO hardware instance address.
475-
* @param gpio_num GPIO number
476-
*/
477-
__attribute__((always_inline))
478-
static inline void gpio_ll_matrix_out_default(gpio_dev_t *hw, uint32_t gpio_num)
479-
{
480-
REG_WRITE(GPIO_FUNC0_OUT_SEL_CFG_REG + (gpio_num * 4), SIG_GPIO_OUT_IDX);
481-
}
482-
483471
/**
484472
* @brief Select a function for the pin in the IOMUX
485473
*
@@ -687,6 +675,40 @@ static inline void gpio_ll_set_input_signal_from(gpio_dev_t *hw, uint32_t signal
687675
hw->func_in_sel_cfg[signal_idx].sig_in_sel = from_gpio_matrix;
688676
}
689677

678+
/**
679+
* @brief Connect a GPIO input with a peripheral signal, which tagged as input attribute.
680+
*
681+
* @note There's no limitation on the number of signals that a GPIO can combine with.
682+
*
683+
* @param signal_idx Peripheral signal index (tagged as input attribute)
684+
* @param gpio_num GPIO number, especially, `GPIO_MATRIX_CONST_ZERO_INPUT` means connect logic 0 to signal
685+
* `GPIO_MATRIX_CONST_ONE_INPUT` means connect logic 1 to signal
686+
* @param in_inv True if the GPIO input needs to be inverted, otherwise False.
687+
*/
688+
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)
689+
{
690+
hw->func_in_sel_cfg[signal_idx].func_sel = gpio_num;
691+
hw->func_in_sel_cfg[signal_idx].sig_in_inv = in_inv;
692+
gpio_ll_set_input_signal_from(hw, signal_idx, true);
693+
}
694+
695+
/**
696+
* @brief Get the GPIO number that is routed to the input peripheral signal through GPIO matrix.
697+
*
698+
* @param hw Peripheral GPIO hardware instance address.
699+
* @param in_sig_idx Peripheral signal index (tagged as input attribute).
700+
*
701+
* @return
702+
* - -1 Signal bypassed GPIO matrix
703+
* - Others GPIO number
704+
*/
705+
static inline int gpio_ll_get_in_signal_connected_io(gpio_dev_t *hw, uint32_t in_sig_idx)
706+
{
707+
typeof(hw->func_in_sel_cfg[in_sig_idx]) reg;
708+
reg.val = hw->func_in_sel_cfg[in_sig_idx].val;
709+
return (reg.sig_in_sel ? reg.func_sel : -1);
710+
}
711+
690712
/**
691713
* @brief Configure the source of output enable signal for the GPIO pin.
692714
*
@@ -701,6 +723,21 @@ static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_n
701723
hw->func_out_sel_cfg[gpio_num].oen_sel = !ctrl_by_periph;
702724
}
703725

726+
/**
727+
* @brief Connect a peripheral signal which tagged as output attribute with a GPIO.
728+
*
729+
* @note There's no limitation on the number of signals that a GPIO can combine with.
730+
*
731+
* @param gpio_num GPIO number
732+
* @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.
733+
* @param out_inv True if the signal output needs to be inverted, otherwise False.
734+
*/
735+
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)
736+
{
737+
hw->func_out_sel_cfg[gpio_num].func_sel = signal_idx;
738+
hw->func_out_sel_cfg[gpio_num].inv_sel = out_inv;
739+
}
740+
704741
/**
705742
* @brief Control the pin in the IOMUX
706743
*
@@ -714,23 +751,6 @@ static inline void gpio_ll_set_pin_ctrl(uint32_t val, uint32_t bmap, uint32_t sh
714751
SET_PERI_REG_BITS(PIN_CTRL, bmap, val, shift);
715752
}
716753

717-
/**
718-
* @brief Get the GPIO number that is routed to the input peripheral signal through GPIO matrix.
719-
*
720-
* @param hw Peripheral GPIO hardware instance address.
721-
* @param in_sig_idx Peripheral signal index (tagged as input attribute).
722-
*
723-
* @return
724-
* - -1 Signal bypassed GPIO matrix
725-
* - Others GPIO number
726-
*/
727-
static inline int gpio_ll_get_in_signal_connected_io(gpio_dev_t *hw, uint32_t in_sig_idx)
728-
{
729-
typeof(hw->func_in_sel_cfg[in_sig_idx]) reg;
730-
reg.val = hw->func_in_sel_cfg[in_sig_idx].val;
731-
return (reg.sig_in_sel ? reg.func_sel : -1);
732-
}
733-
734754
#ifdef __cplusplus
735755
}
736756
#endif

0 commit comments

Comments
 (0)