drivers: serial: nrf uarte: avoid dropping RX chars/overruns
In some cases (eg at high baud rate, no HW flow control, and when BLE radio/ints running) data could be lost between when enough characters have been RX'd to fill the DMA buffer and when the ENDRX event was fired, where the the STARTRX task is invoked to start filling the next buffer (which is set up earlier, but I think will not be filled until STARTRX). To fix this, the SHORT is enabled between ENDRX and STARTRX whenever the 'next' buffer is available, so that STARTRX is invoked automatically and subsequent chars go into the next buffer via EasyDMA. To make this work properly, uarte_nrfx_isr_async() now handles the ENDRX event _before_ the STARTRX event. There was also an issue in rx_timeout() where the received character count (rx_total_byte_count) could be incremented greater than the actual buffer size. This arises from rx_total_byte_count value coming from the counting the RXDRDY events (either by PPI/timer counter or counting the RXDRDY ints themselves) and so if chars are received in the rx_timeout() (or before ENDRX is handled) the rx_timeout() could increment rx_offset past the length of the buffer. This could result the remaining 'len' being calculated incorrectly (an underflow due to unsigned - signed , where signed > unsigned). To fix this, we now store the lengths of the buffers and don't invoke the UART_RX_RDY callback when the buffers are full; its handled by ENDRX. (Also note that the buffer size should be available via the RXD.MAXCNT register on the nrf, but this register is not exposed through the nrfx HAL and is also double buffered, so it seemed clearer to just track the buffer lengths explicitly here in the driver). Signed-off-by:Marc Reilly <marc@cpdesign.com.au> for fixup Signed-off-by:
Marc Reilly <marc@cpdesign.com.au>
Loading
Please sign in to comment