Skip to content

Commit b9eb99d

Browse files
committed
Merge branch 'bugfix/s3_uart2_rx_break_on_rst' into 'master'
fix(uart): fix some uart port generate a RX BRK_DET intr on reset issue See merge request espressif/esp-idf!43064
2 parents 27baa4a + d308465 commit b9eb99d

File tree

2 files changed

+34
-12
lines changed

2 files changed

+34
-12
lines changed

components/esp_driver_uart/src/uart.c

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,10 @@ static bool uart_module_enable(uart_port_t uart_num)
223223
uart_ll_enable_bus_clock(uart_num, true);
224224
}
225225
if (uart_num != CONFIG_ESP_CONSOLE_UART_NUM) {
226+
// Workaround: Set RX signal to high to avoid false RX BRK_DET interrupt raised after register reset
227+
if (uart_context[uart_num].rx_io_num == -1) {
228+
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, UART_PERIPH_SIGNAL(uart_num, SOC_UART_PERIPH_SIGNAL_RX), false);
229+
}
226230
HP_UART_BUS_CLK_ATOMIC() {
227231
uart_ll_reset_register(uart_num);
228232
}
@@ -253,6 +257,16 @@ static bool uart_module_enable(uart_port_t uart_num)
253257
}
254258
#if (SOC_UART_LP_NUM >= 1)
255259
else {
260+
// Workaround: Set RX signal to high to avoid false RX BRK_DET interrupt raised after register reset
261+
if (uart_context[uart_num].rx_io_num == -1) { // if RX pin is already configured, then workaround not needed, skip
262+
#if SOC_LP_GPIO_MATRIX_SUPPORTED
263+
lp_gpio_connect_in_signal(LP_GPIO_MATRIX_CONST_ONE_INPUT, UART_PERIPH_SIGNAL(uart_num, SOC_UART_PERIPH_SIGNAL_RX), false);
264+
#else
265+
// the signal is directly connected to its LP IO pin, the only way is to enable its pullup
266+
uint32_t io_num = uart_periph_signal[uart_num].pins[SOC_UART_PERIPH_SIGNAL_RX].default_gpio;
267+
gpio_pullup_en(io_num);
268+
#endif
269+
}
256270
LP_UART_BUS_CLK_ATOMIC() {
257271
lp_uart_ll_enable_bus_clock(TO_LP_UART_NUM(uart_num), true);
258272
lp_uart_ll_reset_register(TO_LP_UART_NUM(uart_num));
@@ -718,6 +732,12 @@ static bool uart_try_set_iomux_pin(uart_port_t uart_num, int io_num, uint32_t id
718732
}
719733
rtc_gpio_init(io_num);
720734
rtc_gpio_iomux_func_sel(io_num, upin->iomux_func);
735+
// undo the workaround done in uart_module_enable for RX pin
736+
#if !SOC_LP_GPIO_MATRIX_SUPPORTED
737+
if (upin->input) {
738+
gpio_pullup_dis(io_num);
739+
}
740+
#endif
721741
}
722742
#endif
723743

@@ -1619,10 +1639,12 @@ static int uart_tx_all(uart_port_t uart_num, const char *src, size_t size, bool
16191639
xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void *) &evt, sizeof(uart_tx_data_t), portMAX_DELAY);
16201640
while (size > 0) {
16211641
size_t send_size = MIN(size, xRingbufferGetCurFreeSize(p_uart_obj[uart_num]->tx_ring_buf));
1622-
xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void *)(src + offset), send_size, portMAX_DELAY);
1623-
size -= send_size;
1624-
offset += send_size;
1625-
uart_enable_tx_intr(uart_num, 1, UART_THRESHOLD_NUM(uart_num, UART_EMPTY_THRESH_DEFAULT));
1642+
if (send_size > 0) {
1643+
xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void *)(src + offset), send_size, portMAX_DELAY);
1644+
size -= send_size;
1645+
offset += send_size;
1646+
uart_enable_tx_intr(uart_num, 1, UART_THRESHOLD_NUM(uart_num, UART_EMPTY_THRESH_DEFAULT));
1647+
}
16261648
}
16271649
} else {
16281650
while (size) {
@@ -2016,12 +2038,6 @@ esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_b
20162038
return ESP_FAIL;
20172039
}
20182040

2019-
uart_intr_config_t uart_intr = {
2020-
.intr_enable_mask = UART_INTR_CONFIG_FLAG,
2021-
.rxfifo_full_thresh = UART_THRESHOLD_NUM(uart_num, UART_FULL_THRESH_DEFAULT),
2022-
.rx_timeout_thresh = UART_TOUT_THRESH_DEFAULT,
2023-
.txfifo_empty_intr_thresh = UART_THRESHOLD_NUM(uart_num, UART_EMPTY_THRESH_DEFAULT),
2024-
};
20252041
uart_module_enable(uart_num);
20262042
uart_hal_disable_intr_mask(&(uart_context[uart_num].hal), UART_LL_INTR_MASK);
20272043
uart_hal_clr_intsts_mask(&(uart_context[uart_num].hal), UART_LL_INTR_MASK);
@@ -2031,6 +2047,12 @@ esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_b
20312047
&p_uart_obj[uart_num]->intr_handle);
20322048
ESP_GOTO_ON_ERROR(ret, err, UART_TAG, "Could not allocate an interrupt for UART");
20332049

2050+
uart_intr_config_t uart_intr = {
2051+
.intr_enable_mask = UART_INTR_CONFIG_FLAG,
2052+
.rxfifo_full_thresh = UART_THRESHOLD_NUM(uart_num, UART_FULL_THRESH_DEFAULT),
2053+
.rx_timeout_thresh = UART_TOUT_THRESH_DEFAULT,
2054+
.txfifo_empty_intr_thresh = UART_THRESHOLD_NUM(uart_num, UART_EMPTY_THRESH_DEFAULT),
2055+
};
20342056
ret = uart_intr_config(uart_num, &uart_intr);
20352057
ESP_GOTO_ON_ERROR(ret, err, UART_TAG, "Could not configure the interrupt for UART");
20362058

components/esp_driver_uart/test_apps/uart/main/test_uart.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,7 @@ TEST_CASE("uart tx ring buffer free space test", "[uart]")
440440
uart_port_t uart_num = port_param.port_num;
441441
uint8_t *rd_data = (uint8_t *)malloc(1024);
442442
TEST_ASSERT_NOT_NULL(rd_data);
443-
uint8_t *wr_data = (uint8_t *)malloc(256);
443+
uint8_t *wr_data = (uint8_t *)malloc(2048);
444444
TEST_ASSERT_NOT_NULL(wr_data);
445445
uart_config_t uart_config = {
446446
.baud_rate = 2000000,
@@ -475,7 +475,7 @@ TEST_CASE("uart tx ring buffer free space test", "[uart]")
475475
TEST_ASSERT_EQUAL_INT(0, tx_buffer_free_space); // tx buffer is full
476476

477477
// Let CTS be low, so that transmission is unblocked
478-
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, uart_periph_signal[uart_num].pins[SOC_UART_PERIPH_SIGNAL_CTS].signal, true);
478+
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ZERO_INPUT, uart_periph_signal[uart_num].pins[SOC_UART_PERIPH_SIGNAL_CTS].signal, false);
479479
uart_wait_tx_done(uart_num, portMAX_DELAY);
480480
uart_get_tx_buffer_free_size(uart_num, &tx_buffer_free_space);
481481
TEST_ASSERT_EQUAL_INT(2020, tx_buffer_free_space); // tx buffer is back to full capacity

0 commit comments

Comments
 (0)