summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaarten van der Schrieck <maarten@thingsconnected.nl>2023-10-24 10:16:00 +0200
committerDamien George <damien@micropython.org>2023-11-03 17:33:28 +1100
commitd95f5aa01131f3aa669867ebdde391f9db277846 (patch)
tree7b0013f905f431b07e48b5d70db9dc7a7c9a8137
parent47ea831c0e741722a9e7a94bb453947cff5f66d8 (diff)
rp2/machine_uart: Fix handling of serial break condition.
The FIFO reports not only the bytes read, but also 4 error bits. These were not checked, leading to NUL value read in case of break and possible garbage bytes being written on parity/framing error. This patch addresses the issue that NUL bytes are incorrectly read on break, and at least provides the boilerplate code and comments for error handling, that may be implemented in the future. Signed-off-by: Maarten van der Schrieck <maarten@thingsconnected.nl>
-rw-r--r--ports/rp2/machine_uart.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/ports/rp2/machine_uart.c b/ports/rp2/machine_uart.c
index 044c905ff..dae57012a 100644
--- a/ports/rp2/machine_uart.c
+++ b/ports/rp2/machine_uart.c
@@ -140,8 +140,27 @@ static inline void read_mutex_unlock(machine_uart_obj_t *u) {
STATIC void uart_drain_rx_fifo(machine_uart_obj_t *self) {
if (read_mutex_try_lock(self)) {
while (uart_is_readable(self->uart) && ringbuf_free(&self->read_buffer) > 0) {
- // get a byte from uart and put into the buffer
- ringbuf_put(&(self->read_buffer), uart_get_hw(self->uart)->dr);
+ // Get a byte from uart and put into the buffer. Every entry from
+ // the FIFO is accompanied by 4 error bits, that may be used for
+ // error handling.
+ uint16_t c = uart_get_hw(self->uart)->dr;
+ if (c & UART_UARTDR_OE_BITS) {
+ // Overrun Error: We missed at least one byte. Not much we can do here.
+ }
+ if (c & UART_UARTDR_BE_BITS) {
+ // Break Error: RX was held low for longer than one character
+ // (11 bits). We did *not* read the zero byte that we seemed to
+ // read from dr.
+ continue;
+ }
+ if (c & UART_UARTDR_PE_BITS) {
+ // Parity Error: The byte we read is invalid.
+ }
+ if (c & UART_UARTDR_FE_BITS) {
+ // Framing Error: We did not receive a valid stop bit.
+ }
+
+ ringbuf_put(&(self->read_buffer), c);
}
read_mutex_unlock(self);
}