fix(lp_core): repair LP UART read_bytes RX handling

Made-with: Cursor
This commit is contained in:
Sudeep Mohanty
2026-04-29 09:12:41 +02:00
committed by BOT
parent 1d2fb75846
commit 00df6f1220

View File

@@ -167,45 +167,49 @@ int lp_core_uart_read_bytes(uart_port_t lp_uart_num, void *buf, size_t size, int
uint32_t to = 0;
while (remaining_bytes > 0) {
/* Read from the Rx FIFO
* We set rx_len to -1 to read all bytes in the Rx FIFO
*/
rx_len = -1;
uart_hal_read_rxfifo(&hal, (uint8_t *)(buf + bytes_rcvd), &rx_len);
/* Drain only as many bytes as fit in the remaining buffer space */
int fifo_len = uart_ll_get_rxfifo_len(hal.dev);
rx_len = (fifo_len < remaining_bytes) ? fifo_len : remaining_bytes;
if (rx_len) {
/* We have some data to read from the Rx FIFO. Check Rx interrupt status */
intr_status = uart_hal_get_intraw_mask(&hal);
if ((intr_status & UART_INTR_RXFIFO_FULL) ||
(intr_status & UART_INTR_RXFIFO_TOUT)) {
/* This is expected. Clear interrupt status and break */
uart_hal_clr_intsts_mask(&hal, intr_mask);
if (rx_len > 0) {
uart_hal_read_rxfifo(&hal, (uint8_t *)(buf + bytes_rcvd), &rx_len);
bytes_rcvd += rx_len;
remaining_bytes -= rx_len;
/* RXFIFO_FULL / RXFIFO_TOUT raw bits are sticky; acknowledge them
* so they do not short-circuit the next iteration. */
uart_hal_clr_intsts_mask(&hal, LP_UART_RX_INT_FLAG);
if (remaining_bytes <= 0) {
break;
} else if ((intr_status & UART_INTR_RXFIFO_OVF)) {
/* We reset the Rx FIFO if it overflows */
}
/* FIFO overflow and parity/framing errors are terminal */
intr_status = uart_hal_get_intraw_mask(&hal);
if (intr_status & UART_INTR_RXFIFO_OVF) {
uart_hal_clr_intsts_mask(&hal, intr_mask);
uart_hal_rxfifo_rst(&hal);
break;
} else if ((intr_status & LP_UART_ERR_INT_FLAG)) {
/* Transaction error. Abort */
} else if (intr_status & LP_UART_ERR_INT_FLAG) {
uart_hal_clr_intsts_mask(&hal, intr_mask);
return -1;
}
/* Update the byte counters */
bytes_rcvd += rx_len;
remaining_bytes -= rx_len;
/* Progress was made; restart the timeout window so callers with
* a finite timeout can tolerate gaps between bursts. */
to = 0;
} else {
/* We have no data to read from the Rx FIFO. Check for transaction timeout */
/* FIFO empty. Honour the caller's timeout. */
ret = lp_core_uart_check_timeout(intr_mask, timeout, &to);
if (ret == ESP_ERR_TIMEOUT) {
/* Timeout. Clear interrupt status and break */
uart_hal_clr_intsts_mask(&hal, intr_mask);
break;
}
}
}
/* Return the number of bytes received */
return bytes_rcvd;
if (bytes_rcvd > size) {
bytes_rcvd = size;
}
return (int)bytes_rcvd;
}