mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 19:13:21 +00:00
fix(uart): lp uart rx iomux pin was not working as expected
Introduced in 8818157e42
The workaround in the commit routes the signal to LP GPIO matrix first.
When uses LP IOMUX pin as UART RX, the signal did not bypass the matrix,
which caused the issue.
This commit adds rtc_gpio_iomux_input and rtc_gpio_iomux_output APIs
to align with existing GPIO driver APIs.
This commit is contained in:
@@ -208,6 +208,31 @@ esp_err_t rtc_gpio_get_drive_capability(gpio_num_t gpio_num, gpio_drive_cap_t* s
|
||||
*/
|
||||
esp_err_t rtc_gpio_iomux_func_sel(gpio_num_t gpio_num, int func);
|
||||
|
||||
/**
|
||||
* @brief Set pad input to an LP peripheral signal through the LP(RTC) IOMUX.
|
||||
*
|
||||
* @param gpio_num GPIO number
|
||||
* @param func The index number of the LP(RTC) IOMUX function to be selected for the pin
|
||||
* @param signal_idx Peripheral signal index to input. One of the ``*_IN_IDX`` signals in ``soc/lp_gpio_sig_map.h``.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG GPIO number error
|
||||
*/
|
||||
esp_err_t rtc_gpio_iomux_input(gpio_num_t gpio_num, int func, uint32_t signal_idx);
|
||||
|
||||
/**
|
||||
* @brief Set LP peripheral output to an RTC IO pad through the LP(RTC) IOMUX.
|
||||
*
|
||||
* @param gpio_num GPIO number
|
||||
* @param func The index number of the LP(RTC) IOMUX function to be selected for the pin
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG GPIO number error
|
||||
*/
|
||||
esp_err_t rtc_gpio_iomux_output(gpio_num_t gpio_num, int func);
|
||||
|
||||
#endif // SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
|
||||
|
||||
#if SOC_RTCIO_HOLD_SUPPORTED
|
||||
|
||||
@@ -191,6 +191,24 @@ esp_err_t rtc_gpio_iomux_func_sel(gpio_num_t gpio_num, int func)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t rtc_gpio_iomux_input(gpio_num_t gpio_num, int func, uint32_t signal_idx)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
|
||||
RTCIO_ENTER_CRITICAL();
|
||||
rtcio_hal_iomux_input(rtc_io_number_get(gpio_num), func, signal_idx);
|
||||
RTCIO_EXIT_CRITICAL();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t rtc_gpio_iomux_output(gpio_num_t gpio_num, int func)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
|
||||
RTCIO_ENTER_CRITICAL();
|
||||
rtcio_hal_iomux_output(rtc_io_number_get(gpio_num), func);
|
||||
RTCIO_EXIT_CRITICAL();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#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)
|
||||
{
|
||||
|
||||
@@ -732,13 +732,12 @@ static bool uart_try_set_iomux_pin(uart_port_t uart_num, int io_num, uint32_t id
|
||||
}
|
||||
#if (SOC_UART_LP_NUM >= 1) && (SOC_RTCIO_PIN_COUNT >= 1)
|
||||
else {
|
||||
if (upin->input) {
|
||||
rtc_gpio_set_direction(io_num, RTC_GPIO_MODE_INPUT_ONLY);
|
||||
} else {
|
||||
rtc_gpio_set_direction(io_num, RTC_GPIO_MODE_OUTPUT_ONLY);
|
||||
}
|
||||
rtc_gpio_init(io_num);
|
||||
rtc_gpio_iomux_func_sel(io_num, upin->iomux_func);
|
||||
if (upin->input) {
|
||||
rtc_gpio_iomux_input(io_num, upin->iomux_func, upin->signal);
|
||||
} else {
|
||||
rtc_gpio_iomux_output(io_num, upin->iomux_func);
|
||||
}
|
||||
// undo the workaround done in uart_module_enable for RX pin
|
||||
#if !SOC_LP_GPIO_MATRIX_SUPPORTED
|
||||
if (upin->input) {
|
||||
|
||||
@@ -727,7 +727,7 @@ IRAM_ATTR static void uart_signal_inject_glitch_task(void *param)
|
||||
#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);
|
||||
LP_GPIO.func_out_sel_cfg[rtc_gpio_num].oe_sel = 1;
|
||||
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);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -73,11 +73,37 @@ static inline void rtcio_ll_matrix_out(int rtcio_num, uint32_t signal_idx, bool
|
||||
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.
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void rtcio_ll_set_output_enable_ctrl(int rtcio_num, bool ctrl_by_periph, bool oen_inv)
|
||||
{
|
||||
LP_GPIO.func_out_sel_cfg[rtcio_num].oe_inv_sel = oen_inv; // control valid only when using lp gpio matrix to route signal to the LP IO
|
||||
LP_GPIO.func_out_sel_cfg[rtcio_num].oe_sel = !ctrl_by_periph;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Select a RTC IOMUX function for the RTC IO
|
||||
*
|
||||
|
||||
@@ -71,11 +71,7 @@ static inline void _rtcio_ll_enable_io_clock(bool enable)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void rtcio_ll_enable_io_clock(bool enable)
|
||||
{
|
||||
_rtcio_ll_enable_io_clock(enable);
|
||||
}
|
||||
#define rtcio_ll_enable_io_clock(...) _rtcio_ll_enable_io_clock(__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* @brief Select the rtcio function.
|
||||
@@ -446,7 +442,7 @@ static inline void rtcio_ll_clear_interrupt_status(void)
|
||||
* @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_matrix_in(int rtcio_num, int signal_idx, bool inv)
|
||||
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;
|
||||
@@ -463,17 +459,43 @@ static inline void rtcio_ll_matrix_in(int rtcio_num, int signal_idx, bool inv)
|
||||
* @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, int signal_idx, bool out_inv, bool oen_inv)
|
||||
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.
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void rtcio_ll_set_output_enable_ctrl(int rtcio_num, bool ctrl_by_periph, bool oen_inv)
|
||||
{
|
||||
LP_GPIO.funcn_out_sel_cfg[rtcio_num].funcn_oe_inv_sel = oen_inv; // control valid only when using lp gpio matrix to route signal to the LP IO
|
||||
LP_GPIO.funcn_out_sel_cfg[rtcio_num].funcn_oe_sel = !ctrl_by_periph;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -184,6 +184,23 @@ void rtcio_hal_set_direction_in_sleep(int rtcio_num, rtc_gpio_mode_t mode);
|
||||
*/
|
||||
#define rtcio_hal_iomux_func_sel(rtcio_num, func) rtcio_ll_iomux_func_sel(rtcio_num, func)
|
||||
|
||||
/**
|
||||
* @brief Set pad input to an LP peripheral signal through the LP(RTC) IOMUX
|
||||
*
|
||||
* @param rtcio_num The index of rtcio. 0 ~ SOC_RTCIO_PIN_COUNT.
|
||||
* @param func The index number of the IOMUX function to be selected for the pin.
|
||||
* @param signal_idx Peripheral signal index to input. One of the ``*_IN_IDX`` signals in ``soc/lp_gpio_sig_map.h``.
|
||||
*/
|
||||
void rtcio_hal_iomux_input(int rtcio_num, int func, uint32_t signal_idx);
|
||||
|
||||
/**
|
||||
* @brief Set LP peripheral output to an RTC IO pad through the LP(RTC) IOMUX
|
||||
*
|
||||
* @param rtcio_num The index of rtcio. 0 ~ SOC_RTCIO_PIN_COUNT.
|
||||
* @param func The index number of the LP(RTC) IOMUX function to be selected for the pin
|
||||
*/
|
||||
void rtcio_hal_iomux_output(int rtcio_num, int func);
|
||||
|
||||
#if SOC_LP_GPIO_MATRIX_SUPPORTED
|
||||
/**
|
||||
* Select RTC GPIO input to a signal
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -85,4 +85,19 @@ void rtcio_hal_isolate(int rtcio_num)
|
||||
rtcio_ll_input_disable(rtcio_num);
|
||||
}
|
||||
|
||||
void rtcio_hal_iomux_input(int rtcio_num, int func, uint32_t signal_idx)
|
||||
{
|
||||
rtcio_ll_input_enable(rtcio_num);
|
||||
rtcio_ll_iomux_func_sel(rtcio_num, func);
|
||||
#if SOC_LP_GPIO_MATRIX_SUPPORTED
|
||||
rtcio_ll_set_input_signal_from(signal_idx, false);
|
||||
#endif
|
||||
}
|
||||
|
||||
void rtcio_hal_iomux_output(int rtcio_num, int func)
|
||||
{
|
||||
rtcio_ll_iomux_func_sel(rtcio_num, func);
|
||||
// as long as the func sel is not RTC IO, the oe can only be controlled by the peripheral
|
||||
}
|
||||
|
||||
#endif //SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
|
||||
|
||||
Reference in New Issue
Block a user