From 8974851c8a5160e567f4ba615686728c09b47dd9 Mon Sep 17 00:00:00 2001 From: Song Ruo Jing Date: Wed, 11 Feb 2026 21:07:16 +0800 Subject: [PATCH 1/3] fix(uart): tx write bytes fails to use non-default tx fifo empty threshold Users may see tx write bytes fails to feed data into tx fifo in time even if the tx fifo empty threshold has been set to a large value. --- components/esp_driver_uart/include/driver/uart.h | 10 +++++----- components/esp_driver_uart/src/uart.c | 9 ++++++--- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/components/esp_driver_uart/include/driver/uart.h b/components/esp_driver_uart/include/driver/uart.h index ca668019ca7..cab5565774d 100644 --- a/components/esp_driver_uart/include/driver/uart.h +++ b/components/esp_driver_uart/include/driver/uart.h @@ -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 */ @@ -367,7 +367,7 @@ esp_err_t uart_enable_rx_intr(uart_port_t uart_num); esp_err_t uart_disable_rx_intr(uart_port_t uart_num); /** - * @brief Disable UART TX interrupt (TX_FULL & TX_TIMEOUT INTERRUPT) + * @brief Disable UART TX interrupt (TX_FIFO_EMPTY INTERRUPT) * * @param uart_num UART port number * @@ -378,11 +378,11 @@ esp_err_t uart_disable_rx_intr(uart_port_t uart_num); esp_err_t uart_disable_tx_intr(uart_port_t uart_num); /** - * @brief Enable UART TX interrupt (TX_FULL & TX_TIMEOUT INTERRUPT) + * @brief Enable UART TX interrupt (TX_FIFO_EMPTY INTERRUPT) * * @param uart_num UART port number, the max port number is (UART_NUM_MAX -1). - * @param enable 1: enable; 0: disable - * @param thresh Threshold of TX interrupt, 0 ~ UART_HW_FIFO_LEN(uart_num) + * @param enable Set to 1 to enable the interrupt + * @param thresh Threshold of TX FIFO empty interrupt, 0 ~ UART_HW_FIFO_LEN(uart_num). If -1 is given, threshold configuration will be skipped. * * @return * - ESP_OK Success diff --git a/components/esp_driver_uart/src/uart.c b/components/esp_driver_uart/src/uart.c index 77715f82fd2..16bbc2ea975 100644 --- a/components/esp_driver_uart/src/uart.c +++ b/components/esp_driver_uart/src/uart.c @@ -690,11 +690,14 @@ esp_err_t uart_disable_tx_intr(uart_port_t uart_num) esp_err_t uart_enable_tx_intr(uart_port_t uart_num, int enable, int thresh) { + (void)enable; ESP_RETURN_ON_FALSE((uart_num < UART_NUM_MAX), ESP_FAIL, UART_TAG, "uart_num error"); ESP_RETURN_ON_FALSE((thresh < UART_HW_FIFO_LEN(uart_num)), ESP_FAIL, UART_TAG, "empty intr threshold error"); uart_hal_clr_intsts_mask(&(uart_context[uart_num].hal), UART_INTR_TXFIFO_EMPTY); UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock)); - uart_hal_set_txfifo_empty_thr(&(uart_context[uart_num].hal), thresh); + if (thresh != -1) { + uart_hal_set_txfifo_empty_thr(&(uart_context[uart_num].hal), thresh); + } uart_hal_ena_intr_mask(&(uart_context[uart_num].hal), UART_INTR_TXFIFO_EMPTY); UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock)); return ESP_OK; @@ -1590,7 +1593,7 @@ static int uart_tx_all(uart_port_t uart_num, const char *src, size_t size, bool xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void *)(src + offset), send_size, portMAX_DELAY); size -= send_size; offset += send_size; - uart_enable_tx_intr(uart_num, 1, UART_THRESHOLD_NUM(uart_num, UART_EMPTY_THRESH_DEFAULT)); + uart_enable_tx_intr(uart_num, 1, -1); } } } else { @@ -1600,7 +1603,7 @@ static int uart_tx_all(uart_port_t uart_num, const char *src, size_t size, bool uint32_t sent = uart_enable_tx_write_fifo(uart_num, (const uint8_t *) src, size); if (sent < size) { p_uart_obj[uart_num]->tx_waiting_fifo = true; - uart_enable_tx_intr(uart_num, 1, UART_THRESHOLD_NUM(uart_num, UART_EMPTY_THRESH_DEFAULT)); + uart_enable_tx_intr(uart_num, 1, -1); } size -= sent; src += sent; From de878df848db68516cfd8dc3af76a684cf568a83 Mon Sep 17 00:00:00 2001 From: Song Ruo Jing Date: Fri, 28 Nov 2025 20:34:06 +0800 Subject: [PATCH 2/3] fix(uart): Avoid division by zero error when calling uart_get_baudrate If uart_driver_install is not called before uart_get_baudrate, the UART port may not be ready. In such cases, the register values cannot be read out, leading to a division by zero error in uart_ll_get_baudrate. This commit adds a check to ensure the UART port is enabled before attempting to read its registers. Closes https://github.com/espressif/esp-idf/issues/17513 --- components/esp_driver_uart/include/driver/uart.h | 2 +- components/esp_driver_uart/src/uart.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/components/esp_driver_uart/include/driver/uart.h b/components/esp_driver_uart/include/driver/uart.h index cab5565774d..e5ff9c3d435 100644 --- a/components/esp_driver_uart/include/driver/uart.h +++ b/components/esp_driver_uart/include/driver/uart.h @@ -250,7 +250,7 @@ esp_err_t uart_set_baudrate(uart_port_t uart_num, uint32_t baudrate); * @param baudrate Pointer to accept value of UART baud rate * * @return - * - ESP_FAIL Parameter error + * - ESP_FAIL Parameter error or the UART port is not enabled * - ESP_OK Success, result will be put in (*baudrate) * */ diff --git a/components/esp_driver_uart/src/uart.c b/components/esp_driver_uart/src/uart.c index 16bbc2ea975..396170698e5 100644 --- a/components/esp_driver_uart/src/uart.c +++ b/components/esp_driver_uart/src/uart.c @@ -400,6 +400,7 @@ esp_err_t uart_set_baudrate(uart_port_t uart_num, uint32_t baud_rate) esp_err_t uart_get_baudrate(uart_port_t uart_num, uint32_t *baudrate) { ESP_RETURN_ON_FALSE((uart_num < UART_NUM_MAX), ESP_FAIL, UART_TAG, "uart_num error"); + ESP_RETURN_ON_FALSE(uart_ll_is_enabled(uart_num), ESP_FAIL, UART_TAG, "uart port not enabled, unable to get register values"); soc_module_clk_t src_clk; uint32_t sclk_freq; From 9a9b104f8cbc62065a069594880c34a183758e07 Mon Sep 17 00:00:00 2001 From: Song Ruo Jing Date: Thu, 25 Dec 2025 16:54:10 +0800 Subject: [PATCH 3/3] fix(uart): fix autobaud detection unable to trigger LOGE when counts unreliable --- .../esp_driver_ledc/test_apps/ledc/main/test_ledc.c | 2 +- components/esp_driver_uart/src/uart.c | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/components/esp_driver_ledc/test_apps/ledc/main/test_ledc.c b/components/esp_driver_ledc/test_apps/ledc/main/test_ledc.c index 5c5952be24c..1b5b09ff97e 100644 --- a/components/esp_driver_ledc/test_apps/ledc/main/test_ledc.c +++ b/components/esp_driver_ledc/test_apps/ledc/main/test_ledc.c @@ -511,7 +511,7 @@ static void timer_frequency_test(ledc_channel_t channel, ledc_timer_bit_t timer_ } else if (clk_src_freq == 60 * 1000 * 1000) { theoretical_freq = 8993; } - frequency_set_get(speed_mode, timer, 9000, theoretical_freq, 60); + frequency_set_get(speed_mode, timer, 9000, theoretical_freq, 80); #endif // Pause and de-configure the timer so that it won't affect the following test cases diff --git a/components/esp_driver_uart/src/uart.c b/components/esp_driver_uart/src/uart.c index 396170698e5..1b397a27cde 100644 --- a/components/esp_driver_uart/src/uart.c +++ b/components/esp_driver_uart/src/uart.c @@ -2309,10 +2309,11 @@ esp_err_t uart_detect_bitrate_stop(uart_port_t uart_num, bool deinit, uart_bitra ESP_RETURN_ON_FALSE(uart_context[uart_num].hw_enabled && ret_res, ESP_ERR_INVALID_ARG, UART_TAG, "invalid arg"); esp_err_t ret = ESP_OK; - ret_res->low_period = uart_hal_get_low_pulse_cnt(&(uart_context[uart_num].hal)) + 1; - ret_res->high_period = uart_hal_get_high_pulse_cnt(&(uart_context[uart_num].hal)) + 1; - ret_res->pos_period = uart_hal_get_pos_pulse_cnt(&(uart_context[uart_num].hal)) + 1; - ret_res->neg_period = uart_hal_get_neg_pulse_cnt(&(uart_context[uart_num].hal)) + 1; + // For period count values, we will later add 1 to always over-count instead of under-count + ret_res->low_period = uart_hal_get_low_pulse_cnt(&(uart_context[uart_num].hal)); + ret_res->high_period = uart_hal_get_high_pulse_cnt(&(uart_context[uart_num].hal)); + ret_res->pos_period = uart_hal_get_pos_pulse_cnt(&(uart_context[uart_num].hal)); + ret_res->neg_period = uart_hal_get_neg_pulse_cnt(&(uart_context[uart_num].hal)); ret_res->edge_cnt = uart_hal_get_rxd_edge_cnt(&(uart_context[uart_num].hal)); // stop auto baud rate detection @@ -2321,11 +2322,11 @@ esp_err_t uart_detect_bitrate_stop(uart_port_t uart_num, bool deinit, uart_bitra const char *err_str = ""; if (ret_res->low_period == 0 || ret_res->high_period == 0 || ret_res->pos_period == 0 || ret_res->neg_period == 0) { err_str = "fast"; - } else if (ret_res->low_period == UART_LL_PULSE_TICK_CNT_MAX || ret_res->high_period == UART_LL_PULSE_TICK_CNT_MAX || ret_res->pos_period == UART_LL_PULSE_TICK_CNT_MAX || ret_res->neg_period == UART_LL_PULSE_TICK_CNT_MAX) { + } else if (ret_res->low_period++ == UART_LL_PULSE_TICK_CNT_MAX || ret_res->high_period++ == UART_LL_PULSE_TICK_CNT_MAX || ret_res->pos_period++ == UART_LL_PULSE_TICK_CNT_MAX || ret_res->neg_period++ == UART_LL_PULSE_TICK_CNT_MAX) { err_str = "slow"; } if (strcmp(err_str, "") != 0) { - ESP_LOGE(UART_TAG, "bitrate too %s, unable to count ticks, please try to adjust source_clk", err_str); + ESP_LOGW(UART_TAG, "bitrate too %s, unreliable xxx_period values, please try to adjust source_clk", err_str); } soc_module_clk_t src_clk;