refactor(rtcio): align LP GPIO matrix related APIs with GPIO matrix APIs

This commit is contained in:
Song Ruo Jing
2026-04-13 21:43:40 +08:00
parent 1d50587ab2
commit e689feee9d
21 changed files with 198 additions and 123 deletions

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -44,6 +44,40 @@ esp_err_t lp_gpio_connect_in_signal(gpio_num_t gpio_num, uint32_t signal_idx, bo
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t lp_gpio_connect_out_signal(gpio_num_t gpio_num, uint32_t signal_idx, bool out_inv, bool out_en_inv);
/**
* @brief Set LP IO pad input to a LP peripheral signal through the LP GPIO matrix
*
* @note There's no limitation on the number of signals that a RTC(LP) GPIO can connect with
*
* @param gpio_num GPIO number, especially, `LP_GPIO_MATRIX_CONST_ZERO_INPUT` means connect logic 0 to signal;
* `LP_GPIO_MATRIX_CONST_ONE_INPUT` means connect logic 1 to signal.
* @param signal_idx LP peripheral signal index (tagged as input attribute).
* One of the ``*_IN_IDX`` signals in ``soc/gpio_sig_map.h``.
* @param in_inv Whether the RTC(LP) IO input to be inverted or not.
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG GPIO number error
*/
esp_err_t lp_gpio_matrix_input(gpio_num_t gpio_num, uint32_t signal_idx, bool in_inv);
/**
* @brief Set LP peripheral output to an LP GPIO pad through the LP GPIO matrix
*
* @note There's no limitation on the number of LP IOs that a signal can connect with
*
* @param gpio_num GPIO number
* @param signal_idx LP peripheral signal index (tagged as input attribute), especially, `LP_SIG_GPIO_OUT_IDX` means disconnect RTC(LP) GPIO and other peripherals. Only the RTC GPIO driver can control the output level
* @param out_inv Whether to signal to be inverted or not.
* @param out_en_inv Whether the output enable control is inverted or not.
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG GPIO number error
*/
esp_err_t lp_gpio_matrix_output(gpio_num_t gpio_num, uint32_t signal_idx, bool out_inv, bool out_en_inv);
#endif // SOC_LP_GPIO_MATRIX_SUPPORTED
#ifdef __cplusplus

View File

@@ -216,7 +216,7 @@ esp_err_t rtc_gpio_iomux_output(gpio_num_t gpio_num, int func)
}
#if SOC_LP_GPIO_MATRIX_SUPPORTED
esp_err_t lp_gpio_connect_in_signal(gpio_num_t gpio_num, uint32_t signal_idx, bool inv)
esp_err_t lp_gpio_matrix_input(gpio_num_t gpio_num, uint32_t signal_idx, bool inv)
{
uint32_t io_num;
if (gpio_num == LP_GPIO_MATRIX_CONST_ZERO_INPUT || gpio_num == LP_GPIO_MATRIX_CONST_ONE_INPUT) {
@@ -229,12 +229,35 @@ esp_err_t lp_gpio_connect_in_signal(gpio_num_t gpio_num, uint32_t signal_idx, bo
return ESP_OK;
}
esp_err_t lp_gpio_connect_out_signal(gpio_num_t gpio_num, uint32_t signal_idx, bool out_inv, bool out_en_inv)
esp_err_t lp_gpio_matrix_output(gpio_num_t gpio_num, uint32_t signal_idx, bool out_inv, bool out_en_inv)
{
ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "LP_IO number error");
rtcio_hal_matrix_out(rtc_io_number_get(gpio_num), signal_idx, out_inv, out_en_inv);
return ESP_OK;
}
esp_err_t lp_gpio_connect_in_signal(gpio_num_t gpio_num, uint32_t signal_idx, bool inv)
{
uint32_t io_num;
if (gpio_num == LP_GPIO_MATRIX_CONST_ZERO_INPUT || gpio_num == LP_GPIO_MATRIX_CONST_ONE_INPUT) {
io_num = gpio_num;
} else {
ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "LP_IO number error");
io_num = rtc_io_number_get(gpio_num);
}
rtcio_ll_set_input_signal_matrix_source(io_num, signal_idx, inv);
return ESP_OK;
}
esp_err_t lp_gpio_connect_out_signal(gpio_num_t gpio_num, uint32_t signal_idx, bool out_inv, bool out_en_inv)
{
ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "LP_IO number error");
uint32_t rtcio_num = rtc_io_number_get(gpio_num);
rtcio_ll_set_output_signal_matrix_source(rtcio_num, signal_idx, out_inv);
rtcio_ll_set_output_enable_ctrl(rtcio_num, true, out_en_inv);
return ESP_OK;
}
#endif // SOC_LP_GPIO_MATRIX_SUPPORTED
#endif // SOC_RTCIO_INPUT_OUTPUT_SUPPORTED

View File

@@ -264,7 +264,7 @@ static bool uart_module_enable(uart_port_t uart_num)
// Workaround: Set RX signal to high to avoid false RX BRK_DET interrupt raised after register reset
if (uart_context[uart_num].rx_io_num == -1) { // if RX pin is already configured, then workaround not needed, skip
#if SOC_LP_GPIO_MATRIX_SUPPORTED
lp_gpio_connect_in_signal(LP_GPIO_MATRIX_CONST_ONE_INPUT, UART_PERIPH_SIGNAL(uart_num, SOC_UART_PERIPH_SIGNAL_RX), false);
rtcio_ll_set_input_signal_matrix_source(LP_GPIO_MATRIX_CONST_ONE_INPUT, UART_PERIPH_SIGNAL(uart_num, SOC_UART_PERIPH_SIGNAL_RX), false);
#else
// the signal is directly connected to its LP IO pin, the only way is to enable its pullup
uint32_t io_num = uart_periph_signal[uart_num].pins[SOC_UART_PERIPH_SIGNAL_RX].default_gpio;
@@ -782,7 +782,7 @@ static void uart_release_pin(uart_port_t uart_num, bool release_tx, bool release
#if (SOC_UART_LP_NUM >= 1)
else {
#if SOC_LP_GPIO_MATRIX_SUPPORTED
lp_gpio_connect_in_signal(LP_GPIO_MATRIX_CONST_ONE_INPUT, UART_PERIPH_SIGNAL(uart_num, SOC_UART_PERIPH_SIGNAL_RX), false);
lp_gpio_matrix_input(LP_GPIO_MATRIX_CONST_ONE_INPUT, UART_PERIPH_SIGNAL(uart_num, SOC_UART_PERIPH_SIGNAL_RX), false);
#endif
rtc_gpio_deinit(uart_context[uart_num].rx_io_num);
}
@@ -814,7 +814,7 @@ static void uart_release_pin(uart_port_t uart_num, bool release_tx, bool release
#if (SOC_UART_LP_NUM >= 1)
else {
#if SOC_LP_GPIO_MATRIX_SUPPORTED
lp_gpio_connect_in_signal(LP_GPIO_MATRIX_CONST_ZERO_INPUT, UART_PERIPH_SIGNAL(uart_num, SOC_UART_PERIPH_SIGNAL_CTS), false);
lp_gpio_matrix_input(LP_GPIO_MATRIX_CONST_ZERO_INPUT, UART_PERIPH_SIGNAL(uart_num, SOC_UART_PERIPH_SIGNAL_CTS), false);
#endif
rtc_gpio_deinit(uart_context[uart_num].cts_io_num);
}
@@ -843,7 +843,7 @@ static void uart_release_pin(uart_port_t uart_num, bool release_tx, bool release
#if (SOC_UART_LP_NUM >= 1)
else {
#if SOC_LP_GPIO_MATRIX_SUPPORTED
lp_gpio_connect_in_signal(LP_GPIO_MATRIX_CONST_ZERO_INPUT, UART_PERIPH_SIGNAL(uart_num, SOC_UART_PERIPH_SIGNAL_DSR), false);
lp_gpio_matrix_input(LP_GPIO_MATRIX_CONST_ZERO_INPUT, UART_PERIPH_SIGNAL(uart_num, SOC_UART_PERIPH_SIGNAL_DSR), false);
#endif
rtc_gpio_deinit(uart_context[uart_num].dsr_io_num);
}
@@ -928,8 +928,8 @@ esp_err_t _uart_set_pin6(uart_port_t uart_num, int tx_io_num, int rx_io_num, int
#if SOC_LP_GPIO_MATRIX_SUPPORTED && (SOC_UART_LP_NUM >= 1)
else {
rtc_gpio_init(tx_io_num); // set as a LP_GPIO pin
lp_gpio_connect_out_signal(tx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_PERIPH_SIGNAL_TX), 0, 0);
// output enable is set inside lp_gpio_connect_out_signal func after the signal is connected
lp_gpio_matrix_output(tx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_PERIPH_SIGNAL_TX), 0, 0);
// output enable is set inside lp_gpio_matrix_output func after the signal is connected
}
#endif
}
@@ -950,13 +950,10 @@ esp_err_t _uart_set_pin6(uart_port_t uart_num, int tx_io_num, int rx_io_num, int
}
#if SOC_LP_GPIO_MATRIX_SUPPORTED && (SOC_UART_LP_NUM >= 1)
else {
rtc_gpio_mode_t mode = (tx_rx_same_io ? RTC_GPIO_MODE_INPUT_OUTPUT : RTC_GPIO_MODE_INPUT_ONLY);
rtc_gpio_set_direction(rx_io_num, mode);
if (!tx_rx_same_io) { // set the same pin again as a LP_GPIO will overwrite connected out_signal, not desired, so skip
rtc_gpio_init(rx_io_num); // set as a LP_GPIO pin
}
lp_gpio_connect_in_signal(rx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_PERIPH_SIGNAL_RX), 0);
lp_gpio_matrix_input(rx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_PERIPH_SIGNAL_RX), 0);
}
#endif
}
@@ -969,8 +966,8 @@ esp_err_t _uart_set_pin6(uart_port_t uart_num, int tx_io_num, int rx_io_num, int
#if SOC_LP_GPIO_MATRIX_SUPPORTED && (SOC_UART_LP_NUM >= 1)
else {
rtc_gpio_init(rts_io_num); // set as a LP_GPIO pin
lp_gpio_connect_out_signal(rts_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_PERIPH_SIGNAL_RTS), 0, 0);
// output enable is set inside lp_gpio_connect_out_signal func after the signal is connected
lp_gpio_matrix_output(rts_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_PERIPH_SIGNAL_RTS), 0, 0);
// output enable is set inside lp_gpio_matrix_output func after the signal is connected
}
#endif
}
@@ -982,9 +979,8 @@ esp_err_t _uart_set_pin6(uart_port_t uart_num, int tx_io_num, int rx_io_num, int
}
#if SOC_LP_GPIO_MATRIX_SUPPORTED && (SOC_UART_LP_NUM >= 1)
else {
rtc_gpio_set_direction(cts_io_num, RTC_GPIO_MODE_INPUT_ONLY);
rtc_gpio_init(cts_io_num); // set as a LP_GPIO pin
lp_gpio_connect_in_signal(cts_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_PERIPH_SIGNAL_CTS), 0);
lp_gpio_matrix_input(cts_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_PERIPH_SIGNAL_CTS), 0);
}
#endif
}
@@ -996,8 +992,8 @@ esp_err_t _uart_set_pin6(uart_port_t uart_num, int tx_io_num, int rx_io_num, int
#if SOC_LP_GPIO_MATRIX_SUPPORTED && (SOC_UART_LP_NUM >= 1)
else {
rtc_gpio_init(dtr_io_num); // set as a LP_GPIO pin
lp_gpio_connect_out_signal(dtr_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_PERIPH_SIGNAL_DTR), 0, 0);
// output enable is set inside lp_gpio_connect_out_signal func after the signal is connected
lp_gpio_matrix_output(dtr_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_PERIPH_SIGNAL_DTR), 0, 0);
// output enable is set inside lp_gpio_matrix_output func after the signal is connected
}
#endif
}
@@ -1009,9 +1005,8 @@ esp_err_t _uart_set_pin6(uart_port_t uart_num, int tx_io_num, int rx_io_num, int
}
#if SOC_LP_GPIO_MATRIX_SUPPORTED && (SOC_UART_LP_NUM >= 1)
else {
rtc_gpio_set_direction(dsr_io_num, RTC_GPIO_MODE_INPUT_ONLY);
rtc_gpio_init(dsr_io_num); // set as a LP_GPIO pin
lp_gpio_connect_in_signal(dsr_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_PERIPH_SIGNAL_DSR), 0);
lp_gpio_matrix_input(dsr_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_PERIPH_SIGNAL_DSR), 0);
}
#endif
}

View File

@@ -533,10 +533,9 @@ TEST_CASE("uart int state restored after flush", "[uart]")
// This means RX IO should also only use LP_GPIO matrix to connect the RX signal
// In case the selected RX IO is the LP UART IOMUX IO, and the IO has been configured to IOMUX function in the driver
// Do the following:
TEST_ESP_OK(rtc_gpio_iomux_func_sel(uart_rx, RTCIO_LL_PIN_FUNC));
const int uart_rx_signal = uart_periph_signal[uart_num].pins[SOC_UART_PERIPH_SIGNAL_RX].signal;
TEST_ESP_OK(lp_gpio_connect_in_signal(uart_rx, uart_rx_signal, false));
TEST_ESP_OK(lp_gpio_connect_out_signal(uart_rx, uart_tx_signal, false, false));
TEST_ESP_OK(lp_gpio_matrix_input(uart_rx, uart_rx_signal, false));
TEST_ESP_OK(lp_gpio_matrix_output(uart_rx, uart_tx_signal, false, false));
#else
// The only way is to use loop back feature
TEST_ESP_OK(uart_set_loop_back(uart_num, true));
@@ -710,25 +709,27 @@ IRAM_ATTR static void uart_signal_inject_glitch_task(void *param)
uart_port_param_t *port_param = (uart_port_param_t *)param;
uart_port_t uart_num = port_param->port_num;
uint32_t tx_pin = port_param->tx_pin_num;
uint32_t tx_signal = UART_PERIPH_SIGNAL(uart_num, SOC_UART_PERIPH_SIGNAL_TX);
// while sending, frequently disconnect from UART TX signal and set level to high to create glitches
gpio_ll_set_level(&GPIO, tx_pin, 1);
gpio_ll_output_enable(&GPIO, tx_pin);
#if SOC_UART_LP_NUM > 0 && SOC_LP_GPIO_MATRIX_SUPPORTED
uint32_t rtc_gpio_num = rtc_io_number_get(tx_pin);
rtcio_ll_set_level(rtc_gpio_num, 1);
rtcio_ll_output_enable(rtc_gpio_num);
#endif
while (1) {
// make sure the glitch is always less than 6us
portDISABLE_INTERRUPTS();
if (uart_num < SOC_UART_HP_NUM) {
esp_rom_gpio_connect_out_signal(tx_pin, SIG_GPIO_OUT_IDX, false, false);
gpio_ll_set_output_enable_ctrl(&GPIO, tx_pin, false, false);
esp_rom_gpio_connect_out_signal(tx_pin, UART_PERIPH_SIGNAL(uart_num, SOC_UART_PERIPH_SIGNAL_TX), false, false);
gpio_ll_set_output_signal_matrix_source(&GPIO, tx_pin, SIG_GPIO_OUT_IDX, false);
// // When IO is set to GPIO use, its output control is only controlled by the GPIO_ENABLE_REG only
gpio_ll_set_output_signal_matrix_source(&GPIO, tx_pin, tx_signal, false);
#if SOC_UART_LP_NUM > 0 && SOC_LP_GPIO_MATRIX_SUPPORTED
} else {
rtcio_ll_matrix_out(rtc_gpio_num, LP_SIG_GPIO_OUT_IDX, false, false);
rtcio_ll_set_output_enable_ctrl(rtc_gpio_num, false, false);
rtcio_ll_matrix_out(rtc_gpio_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_PERIPH_SIGNAL_TX), false, false);
rtcio_ll_set_output_signal_matrix_source(rtc_gpio_num, LP_SIG_GPIO_OUT_IDX, false);
rtcio_ll_set_output_signal_matrix_source(rtc_gpio_num, tx_signal, false);
#endif
}
portENABLE_INTERRUPTS();

View File

@@ -755,6 +755,7 @@ static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_n
* @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.
*/
__attribute__((always_inline))
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;

View File

@@ -561,6 +561,7 @@ static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_n
* @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.
*/
__attribute__((always_inline))
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);

View File

@@ -558,6 +558,7 @@ static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_n
* @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.
*/
__attribute__((always_inline))
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);

View File

@@ -545,6 +545,7 @@ static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_n
* @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.
*/
__attribute__((always_inline))
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;

View File

@@ -509,6 +509,7 @@ static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_n
* @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.
*/
__attribute__((always_inline))
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);

View File

@@ -545,6 +545,7 @@ static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_n
* @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.
*/
__attribute__((always_inline))
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;

View File

@@ -555,6 +555,7 @@ static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_n
* @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.
*/
__attribute__((always_inline))
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);

View File

@@ -536,6 +536,7 @@ static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_n
* @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.
*/
__attribute__((always_inline))
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;

View File

@@ -554,6 +554,7 @@ static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_n
* @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.
*/
__attribute__((always_inline))
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;

View File

@@ -671,6 +671,7 @@ static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_n
* @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.
*/
__attribute__((always_inline))
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;

View File

@@ -58,59 +58,39 @@ static inline void _rtcio_ll_enable_io_clock(bool enable)
#define rtcio_ll_enable_io_clock(...) _rtcio_ll_enable_io_clock(__VA_ARGS__)
/**
* @brief Select RTC GPIO input to a signal.
* @brief Configure peripheral signal input whether to bypass LP_GPIO matrix.
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
* @param signal_idx LP peripheral signal index.
* @param inv True to invert input signal; False then no invert.
* @param from_gpio_matrix True if not to bypass LP_GPIO matrix, otherwise False.
*/
static inline void rtcio_ll_matrix_in(int rtcio_num, uint32_t signal_idx, bool inv)
{
lp_gpio_func_in_sel_cfg_reg_t reg;
reg.func_in_sel = rtcio_num;
reg.in_inv_sel = inv;
reg.sig_in_sel = 1; // Signal should not bypass LP_GPIO matrix
LP_GPIO.func_in_sel_cfg[signal_idx].val = reg.val;
}
/**
* @brief Select signal output to a RTC GPIO.
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
* @param signal_idx LP peripheral signal index.
* @param out_inv True to invert output signal; False then no invert.
* @param oen_inv True to invert output enable signal; False then no invert.
*/
static inline void rtcio_ll_matrix_out(int rtcio_num, uint32_t signal_idx, bool out_inv, bool oen_inv)
{
lp_gpio_func_out_sel_cfg_reg_t reg;
reg.func_out_sel = signal_idx;
reg.out_inv_sel = out_inv;
reg.oe_inv_sel = oen_inv;
reg.oe_sel = 0; // output enable signal controlled by peripheral
LP_GPIO.func_out_sel_cfg[rtcio_num].val = reg.val;
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_GPIO.enable_w1ts, reg_gpio_enable_data_w1ts, BIT(rtcio_num));
}
/**
* @brief Configure peripheral signal input whether to bypass LP_GPIO matrix.
*
* @param signal_idx LP peripheral signal index.
* @param from_gpio_matrix True if not to bypass LP_GPIO matrix, otherwise False.
*/
static inline void rtcio_ll_set_input_signal_from(uint32_t signal_idx, bool from_gpio_matrix)
{
LP_GPIO.func_in_sel_cfg[signal_idx].sig_in_sel = from_gpio_matrix;
}
/**
* @brief Configure the source of output enable signal for the pad (only takes effect if func sel is selected to be LP_GPIO).
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
* @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 LP_GPIO_ENABLE_REG
* @param oen_inv True if the output enable needs to be inverted, otherwise False.
*/
* @brief Connect a LP GPIO input with a LP peripheral signal, which tagged as input attribute.
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
* @param signal_idx LP peripheral signal index.
* @param inv True to invert input signal; False then no invert.
*/
static inline void rtcio_ll_set_input_signal_matrix_source(int rtcio_num, uint32_t signal_idx, bool inv)
{
lp_gpio_func_in_sel_cfg_reg_t reg;
reg.func_in_sel = rtcio_num;
reg.in_inv_sel = inv;
LP_GPIO.func_in_sel_cfg[signal_idx].val = reg.val;
rtcio_ll_set_input_signal_from(signal_idx, true); // Signal should not bypass LP_GPIO matrix
}
/**
* @brief Configure the source of output enable signal for the pad (only takes effect if func sel is selected to be LP_GPIO).
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
* @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 LP_GPIO_ENABLE_REG
* @param oen_inv True if the output enable needs to be inverted, otherwise False.
*/
__attribute__((always_inline))
static inline void rtcio_ll_set_output_enable_ctrl(int rtcio_num, bool ctrl_by_periph, bool oen_inv)
{
@@ -118,6 +98,22 @@ static inline void rtcio_ll_set_output_enable_ctrl(int rtcio_num, bool ctrl_by_p
LP_GPIO.func_out_sel_cfg[rtcio_num].oe_sel = !ctrl_by_periph;
}
/**
* @brief Connect a LP peripheral signal which tagged as output attribute with a LP GPIO.
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
* @param signal_idx LP peripheral signal index.
* @param out_inv True to invert output signal; False then no invert.
*/
__attribute__((always_inline))
static inline void rtcio_ll_set_output_signal_matrix_source(int rtcio_num, uint32_t signal_idx, bool out_inv)
{
lp_gpio_func_out_sel_cfg_reg_t reg;
reg.func_out_sel = signal_idx;
reg.out_inv_sel = out_inv;
LP_GPIO.func_out_sel_cfg[rtcio_num].val = reg.val;
}
/**
* @brief Select a RTC IOMUX function for the RTC IO
*

View File

@@ -576,6 +576,7 @@ static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_n
* @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.
*/
__attribute__((always_inline))
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;

View File

@@ -578,6 +578,7 @@ static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_n
* @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.
*/
__attribute__((always_inline))
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;

View File

@@ -94,6 +94,7 @@ static inline void gpio_ll_pullup_en(gpio_dev_t *hw, uint32_t gpio_num)
* @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.
*/
__attribute__((always_inline))
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;

View File

@@ -435,59 +435,39 @@ static inline void rtcio_ll_clear_interrupt_status(void)
}
/**
* @brief Select RTC GPIO input to a signal.
* @brief Configure peripheral signal input whether to bypass LP_GPIO matrix.
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
* @param signal_idx LP peripheral input signal index (0 .. IN_SIGNAL_MAX - 1).
* @param inv True to invert input signal; False then no invert.
* @param signal_idx LP peripheral signal index.
* @param from_gpio_matrix True if not to bypass LP_GPIO matrix, otherwise False.
*/
static inline void rtcio_ll_matrix_in(int rtcio_num, uint32_t signal_idx, bool inv)
{
lp_gpio_funca_in_sel_cfg_reg_t reg;
reg.funca_in_sel = rtcio_num;
reg.funca_in_inv_sel = inv;
reg.siga_in_sel = 1; // Signal should not bypass LP_GPIO matrix
LP_GPIO.funca_in_sel_cfg[signal_idx].val = reg.val;
}
/**
* @brief Select signal output to a RTC GPIO
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
* @param signal_idx Peripheral output signal index (0 .. OUT_SIGNAL_MAX - 1).
* @param out_inv True to invert output signal; False then no invert.
* @param oen_inv True to invert output enable signal; False then no invert.
*/
static inline void rtcio_ll_matrix_out(int rtcio_num, uint32_t signal_idx, bool out_inv, bool oen_inv)
{
lp_gpio_funcn_out_sel_cfg_reg_t reg;
reg.funcn_out_sel = signal_idx;
reg.funcn_out_inv_sel = out_inv;
reg.funcn_oe_inv_sel = oen_inv;
reg.funcn_oe_sel = 0; // output enable signal controlled by peripheral
LP_GPIO.funcn_out_sel_cfg[rtcio_num].val = reg.val;
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_GPIO.enable_w1ts, enable_w1ts, BIT(rtcio_num));
}
/**
* @brief Configure peripheral signal input whether to bypass LP_GPIO matrix.
*
* @param signal_idx LP peripheral signal index.
* @param from_gpio_matrix True if not to bypass LP_GPIO matrix, otherwise False.
*/
static inline void rtcio_ll_set_input_signal_from(uint32_t signal_idx, bool from_gpio_matrix)
{
LP_GPIO.funca_in_sel_cfg[signal_idx].siga_in_sel = from_gpio_matrix;
}
/**
* @brief Configure the source of output enable signal for the pad (only takes effect if func sel is selected to be LP_GPIO).
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
* @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 LP_GPIO_ENABLE_REG
* @param oen_inv True if the output enable needs to be inverted, otherwise False.
*/
* @brief Connect a LP GPIO input with a LP peripheral signal, which tagged as input attribute.
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
* @param signal_idx LP peripheral input signal index (0 .. IN_SIGNAL_MAX - 1).
* @param inv True to invert input signal; False then no invert.
*/
static inline void rtcio_ll_set_input_signal_matrix_source(int rtcio_num, uint32_t signal_idx, bool inv)
{
lp_gpio_funca_in_sel_cfg_reg_t reg;
reg.funca_in_sel = rtcio_num;
reg.funca_in_inv_sel = inv;
LP_GPIO.funca_in_sel_cfg[signal_idx].val = reg.val;
rtcio_ll_set_input_signal_from(signal_idx, true); // Signal should not bypass LP_GPIO matrix
}
/**
* @brief Configure the source of output enable signal for the pad (only takes effect if func sel is selected to be LP_GPIO).
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
* @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 LP_GPIO_ENABLE_REG
* @param oen_inv True if the output enable needs to be inverted, otherwise False.
*/
__attribute__((always_inline))
static inline void rtcio_ll_set_output_enable_ctrl(int rtcio_num, bool ctrl_by_periph, bool oen_inv)
{
@@ -495,6 +475,22 @@ static inline void rtcio_ll_set_output_enable_ctrl(int rtcio_num, bool ctrl_by_p
LP_GPIO.funcn_out_sel_cfg[rtcio_num].funcn_oe_sel = !ctrl_by_periph;
}
/**
* @brief Connect a LP peripheral signal which tagged as output attribute with a LP GPIO.
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
* @param signal_idx Peripheral output signal index (0 .. OUT_SIGNAL_MAX - 1).
* @param out_inv True to invert output signal; False then no invert.
*/
__attribute__((always_inline))
static inline void rtcio_ll_set_output_signal_matrix_source(int rtcio_num, uint32_t signal_idx, bool out_inv)
{
lp_gpio_funcn_out_sel_cfg_reg_t reg;
reg.funcn_out_sel = signal_idx;
reg.funcn_out_inv_sel = out_inv;
LP_GPIO.funcn_out_sel_cfg[rtcio_num].val = reg.val;
}
#ifdef __cplusplus
}
#endif

View File

@@ -203,23 +203,23 @@ void rtcio_hal_iomux_output(int rtcio_num, int func);
#if SOC_LP_GPIO_MATRIX_SUPPORTED
/**
* Select RTC GPIO input to a signal
* @brief Set pad input to a LP peripheral signal through the LP GPIO matrix
*
* @param rtcio_num The index of rtcio. 0 ~ SOC_RTCIO_PIN_COUNT.
* @param signal_idx LP peripheral signal index.
* @param inv True to invert input signal; False then no invert.
*/
#define rtcio_hal_matrix_in(rtcio_num, signal_idx, inv) rtcio_ll_matrix_in(rtcio_num, signal_idx, inv)
void rtcio_hal_matrix_in(int rtcio_num, uint32_t signal_idx, bool inv);
/**
* Select signal output to a RTC GPIO
* @brief Set LP peripheral output to an RTC IO pad through the LP GPIO matrix
*
* @param rtcio_num The index of rtcio. 0 ~ SOC_RTCIO_PIN_COUNT.
* @param signal_idx LP peripheral signal index.
* @param out_inv True to invert output signal; False then no invert.
* @param oen_inv True to invert output enable signal; False then no invert.
*/
#define rtcio_hal_matrix_out(rtcio_num, signal_idx, out_inv, oen_inv) rtcio_ll_matrix_out(rtcio_num, signal_idx, out_inv, oen_inv)
void rtcio_hal_matrix_out(int rtcio_num, uint32_t signal_idx, bool out_inv, bool oen_inv);
#endif // SOC_LP_GPIO_MATRIX_SUPPORTED
#endif // SOC_RTCIO_INPUT_OUTPUT_SUPPORTED

View File

@@ -100,4 +100,21 @@ void rtcio_hal_iomux_output(int rtcio_num, int func)
// as long as the func sel is not RTC IO, the oe can only be controlled by the peripheral
}
#if SOC_LP_GPIO_MATRIX_SUPPORTED
void rtcio_hal_matrix_in(int rtcio_num, uint32_t signal_idx, bool inv)
{
if (rtcio_num < SOC_RTCIO_PIN_COUNT) {
rtcio_ll_input_enable(rtcio_num);
}
rtcio_ll_set_input_signal_matrix_source(rtcio_num, signal_idx, inv);
}
void rtcio_hal_matrix_out(int rtcio_num, uint32_t signal_idx, bool out_inv, bool oen_inv)
{
rtcio_ll_iomux_func_sel(rtcio_num, RTCIO_LL_PIN_FUNC);
rtcio_ll_set_output_signal_matrix_source(rtcio_num, signal_idx, out_inv);
rtcio_ll_set_output_enable_ctrl(rtcio_num, true, oen_inv); // output is enabled at the end to avoid undesired level change
}
#endif // SOC_LP_GPIO_MATRIX_SUPPORTED
#endif //SOC_RTCIO_INPUT_OUTPUT_SUPPORTED