mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-05 13:44:32 +02:00
feat(uart): add pin release process to uart driver
This commit is contained in:
@@ -86,10 +86,14 @@ static const char *UART_TAG = "uart";
|
|||||||
// Check actual UART mode set
|
// Check actual UART mode set
|
||||||
#define UART_IS_MODE_SET(uart_number, mode) ((p_uart_obj[uart_number]->uart_mode == mode))
|
#define UART_IS_MODE_SET(uart_number, mode) ((p_uart_obj[uart_number]->uart_mode == mode))
|
||||||
|
|
||||||
#define UART_CONTEX_INIT_DEF(uart_num) {\
|
#define UART_CONTEX_INIT_DEF(uart_num) { \
|
||||||
.hal.dev = UART_LL_GET_HW(uart_num),\
|
.hal.dev = UART_LL_GET_HW(uart_num), \
|
||||||
INIT_CRIT_SECTION_LOCK_IN_STRUCT(spinlock)\
|
INIT_CRIT_SECTION_LOCK_IN_STRUCT(spinlock) \
|
||||||
.hw_enabled = false,\
|
.hw_enabled = false, \
|
||||||
|
.tx_io_num = -1, \
|
||||||
|
.rx_io_num = -1, \
|
||||||
|
.rts_io_num = -1, \
|
||||||
|
.cts_io_num = -1, \
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -162,6 +166,10 @@ typedef struct {
|
|||||||
uart_hal_context_t hal; /*!< UART hal context*/
|
uart_hal_context_t hal; /*!< UART hal context*/
|
||||||
DECLARE_CRIT_SECTION_LOCK_IN_STRUCT(spinlock)
|
DECLARE_CRIT_SECTION_LOCK_IN_STRUCT(spinlock)
|
||||||
bool hw_enabled;
|
bool hw_enabled;
|
||||||
|
int tx_io_num;
|
||||||
|
int rx_io_num;
|
||||||
|
int rts_io_num;
|
||||||
|
int cts_io_num;
|
||||||
} uart_context_t;
|
} uart_context_t;
|
||||||
|
|
||||||
static uart_obj_t *p_uart_obj[UART_NUM_MAX] = {0};
|
static uart_obj_t *p_uart_obj[UART_NUM_MAX] = {0};
|
||||||
@@ -614,8 +622,33 @@ static bool uart_try_set_iomux_pin(uart_port_t uart_num, int io_num, uint32_t id
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//internal signal can be output to multiple GPIO pads
|
static void uart_release_pin(uart_port_t uart_num)
|
||||||
//only one GPIO pad can connect with input signal
|
{
|
||||||
|
if (uart_num >= UART_NUM_MAX) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (uart_context[uart_num].tx_io_num >= 0) {
|
||||||
|
gpio_ll_output_disable(&GPIO, uart_context[uart_num].tx_io_num);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uart_context[uart_num].rx_io_num >= 0) {
|
||||||
|
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RX_PIN_IDX), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uart_context[uart_num].rts_io_num >= 0) {
|
||||||
|
gpio_ll_output_disable(&GPIO, uart_context[uart_num].rts_io_num);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uart_context[uart_num].cts_io_num >= 0) {
|
||||||
|
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ZERO_INPUT, UART_PERIPH_SIGNAL(uart_num, SOC_UART_CTS_PIN_IDX), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
uart_context[uart_num].tx_io_num = -1;
|
||||||
|
uart_context[uart_num].rx_io_num = -1;
|
||||||
|
uart_context[uart_num].rts_io_num = -1;
|
||||||
|
uart_context[uart_num].cts_io_num = -1;
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int rts_io_num, int cts_io_num)
|
esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int rts_io_num, int cts_io_num)
|
||||||
{
|
{
|
||||||
ESP_RETURN_ON_FALSE((uart_num >= 0), ESP_FAIL, UART_TAG, "uart_num error");
|
ESP_RETURN_ON_FALSE((uart_num >= 0), ESP_FAIL, UART_TAG, "uart_num error");
|
||||||
@@ -625,31 +658,40 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r
|
|||||||
ESP_RETURN_ON_FALSE((rts_io_num < 0 || (GPIO_IS_VALID_OUTPUT_GPIO(rts_io_num))), ESP_FAIL, UART_TAG, "rts_io_num error");
|
ESP_RETURN_ON_FALSE((rts_io_num < 0 || (GPIO_IS_VALID_OUTPUT_GPIO(rts_io_num))), ESP_FAIL, UART_TAG, "rts_io_num error");
|
||||||
ESP_RETURN_ON_FALSE((cts_io_num < 0 || (GPIO_IS_VALID_GPIO(cts_io_num))), ESP_FAIL, UART_TAG, "cts_io_num error");
|
ESP_RETURN_ON_FALSE((cts_io_num < 0 || (GPIO_IS_VALID_GPIO(cts_io_num))), ESP_FAIL, UART_TAG, "cts_io_num error");
|
||||||
|
|
||||||
|
// First, release previously configured IOs if there is
|
||||||
|
uart_release_pin(uart_num);
|
||||||
|
|
||||||
// Since an IO cannot route peripheral signals via IOMUX and GPIO matrix at the same time,
|
// Since an IO cannot route peripheral signals via IOMUX and GPIO matrix at the same time,
|
||||||
// if tx and rx share the same IO, both signals need to be route to IOs through GPIO matrix
|
// if tx and rx share the same IO, both signals need to be route to IOs through GPIO matrix
|
||||||
bool tx_rx_same_io = (tx_io_num == rx_io_num);
|
bool tx_rx_same_io = (tx_io_num == rx_io_num);
|
||||||
|
|
||||||
/* In the following statements, if the io_num is negative, no need to configure anything. */
|
/* In the following statements, if the io_num is negative, no need to configure anything. */
|
||||||
if (tx_io_num >= 0 && (tx_rx_same_io || !uart_try_set_iomux_pin(uart_num, tx_io_num, SOC_UART_TX_PIN_IDX))) {
|
if (tx_io_num >= 0) {
|
||||||
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[tx_io_num], PIN_FUNC_GPIO);
|
uart_context[uart_num].tx_io_num = tx_io_num;
|
||||||
esp_rom_gpio_connect_out_signal(tx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_TX_PIN_IDX), 0, 0);
|
if (tx_rx_same_io || !uart_try_set_iomux_pin(uart_num, tx_io_num, SOC_UART_TX_PIN_IDX)) {
|
||||||
// output enable is set inside esp_rom_gpio_connect_out_signal func after the signal is connected
|
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[tx_io_num], PIN_FUNC_GPIO);
|
||||||
// (output enabled too early may cause unnecessary level change at the pad)
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rx_io_num >= 0 && (tx_rx_same_io || !uart_try_set_iomux_pin(uart_num, rx_io_num, SOC_UART_RX_PIN_IDX))) {
|
if (rx_io_num >= 0) {
|
||||||
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[rx_io_num], PIN_FUNC_GPIO);
|
uart_context[uart_num].rx_io_num = rx_io_num;
|
||||||
gpio_ll_input_enable(&GPIO, rx_io_num);
|
if (tx_rx_same_io || !uart_try_set_iomux_pin(uart_num, rx_io_num, SOC_UART_RX_PIN_IDX)) {
|
||||||
esp_rom_gpio_connect_in_signal(rx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RX_PIN_IDX), 0);
|
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[rx_io_num], PIN_FUNC_GPIO);
|
||||||
|
gpio_ll_input_enable(&GPIO, rx_io_num);
|
||||||
|
esp_rom_gpio_connect_in_signal(rx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RX_PIN_IDX), 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rts_io_num >= 0 && !uart_try_set_iomux_pin(uart_num, rts_io_num, SOC_UART_RTS_PIN_IDX)) {
|
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))) {
|
||||||
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[rts_io_num], PIN_FUNC_GPIO);
|
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[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);
|
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
|
// output enable is set inside esp_rom_gpio_connect_out_signal func after the signal is connected
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cts_io_num >= 0 && !uart_try_set_iomux_pin(uart_num, cts_io_num, SOC_UART_CTS_PIN_IDX)) {
|
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))) {
|
||||||
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[cts_io_num], PIN_FUNC_GPIO);
|
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[cts_io_num], PIN_FUNC_GPIO);
|
||||||
gpio_set_pull_mode(cts_io_num, GPIO_PULLUP_ONLY);
|
gpio_set_pull_mode(cts_io_num, GPIO_PULLUP_ONLY);
|
||||||
gpio_set_direction(cts_io_num, GPIO_MODE_INPUT);
|
gpio_set_direction(cts_io_num, GPIO_MODE_INPUT);
|
||||||
@@ -1638,6 +1680,9 @@ esp_err_t uart_driver_delete(uart_port_t uart_num)
|
|||||||
ESP_LOGI(UART_TAG, "ALREADY NULL");
|
ESP_LOGI(UART_TAG, "ALREADY NULL");
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uart_release_pin(uart_num);
|
||||||
|
|
||||||
esp_intr_free(p_uart_obj[uart_num]->intr_handle);
|
esp_intr_free(p_uart_obj[uart_num]->intr_handle);
|
||||||
uart_disable_rx_intr(uart_num);
|
uart_disable_rx_intr(uart_num);
|
||||||
uart_disable_tx_intr(uart_num);
|
uart_disable_tx_intr(uart_num);
|
||||||
|
Reference in New Issue
Block a user