Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(uart): uart rx timeout validation with proper log message #11141

Merged
merged 5 commits into from
Mar 20, 2025
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion cores/esp32/esp32-hal-uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -757,7 +757,11 @@ bool uartSetRxTimeout(uart_t *uart, uint8_t numSymbTimeout) {
if (uart == NULL) {
return false;
}

uint16_t maxRXTimeout = uart_get_max_rx_timeout(uart->num);
if (numSymbTimeout > maxRXTimeout) {
log_e("Invalid RX Timeout value, its limit is %d", maxRXTimeout);
return false;
}
UART_MUTEX_LOCK();
bool retCode = (ESP_OK == uart_set_rx_timeout(uart->num, numSymbTimeout));
UART_MUTEX_UNLOCK();
Expand Down Expand Up @@ -1382,4 +1386,24 @@ int uart_send_msg_with_break(uint8_t uartNum, uint8_t *msg, size_t msgSize) {
return uart_write_bytes_with_break(uartNum, (const void *)msg, msgSize, 12);
}

// returns the maximum valid uart RX Timeout based on the UART Source Clock and Baudrate
uint16_t uart_get_max_rx_timeout(uint8_t uartNum) {
if (uartNum >= SOC_UART_NUM) {
log_e("UART%d does not exist. This device has %d UARTs, from 0 to %d.", uartNum, SOC_UART_NUM, SOC_UART_NUM - 1);
return (uint16_t) -1;
}
uint16_t tout_max_thresh = uart_ll_max_tout_thrd(UART_LL_GET_HW(uartNum));
uint8_t symbol_len = 1; // number of bits per symbol including start
uart_parity_t parity_mode;
uart_stop_bits_t stop_bit;
uart_word_length_t data_bit;
uart_ll_get_data_bit_num(UART_LL_GET_HW(uartNum), &data_bit);
uart_ll_get_stop_bits(UART_LL_GET_HW(uartNum), &stop_bit);
uart_ll_get_parity(UART_LL_GET_HW(uartNum), &parity_mode);
symbol_len += (data_bit < UART_DATA_BITS_MAX) ? (uint8_t)data_bit + 5 : 8;
symbol_len += (stop_bit > UART_STOP_BITS_1) ? 2 : 1;
symbol_len += (parity_mode > UART_PARITY_DISABLE) ? 1 : 0;
return (uint16_t) (tout_max_thresh / symbol_len);
}

#endif /* SOC_UART_SUPPORTED */
4 changes: 4 additions & 0 deletions cores/esp32/esp32-hal-uart.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ void uart_send_break(uint8_t uartNum);
// Sends a buffer and at the end of the stream, it generates BREAK in the line
int uart_send_msg_with_break(uint8_t uartNum, uint8_t *msg, size_t msgSize);

// UART RX Timeout (in UART Symbols) depends on the UART Clock Source and the SoC that is used
// This is a helper function that calculates what is the maximum RX Timeout that a running UART IDF driver allows.
uint16_t uart_get_max_rx_timeout(uint8_t uartNum);

#ifdef __cplusplus
}
#endif
Expand Down
Loading