From d184e581d8abed1392ccee27e06c78c85633b70e Mon Sep 17 00:00:00 2001 From: John Polstra Date: Wed, 19 Aug 2020 11:30:29 -0700 Subject: [PATCH] Fix a bug that caused uartTotalRxBytesWaiting() to return a grossly incorrect value when DMA was used. For example, if one byte was waiting, the function returned one less than the size of the buffer. The reason the bug didn't cause serious problems is that almost all calls to this function check only whether the returned value is zero or not. (The only exceptions I found were in "src/main/telemetry/hott.c". Perhaps that code was tested on a target that did not use DMA.) The case of zero bytes waiting was the only case in which the correct result was returned. --- src/main/drivers/serial_uart.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/drivers/serial_uart.c b/src/main/drivers/serial_uart.c index e516262c0c..2ac46f13e1 100644 --- a/src/main/drivers/serial_uart.c +++ b/src/main/drivers/serial_uart.c @@ -156,10 +156,12 @@ static uint32_t uartTotalRxBytesWaiting(const serialPort_t *instance) uint32_t rxDMAHead = xDMA_GetCurrDataCounter(s->rxDMAResource); #endif - if (rxDMAHead >= s->rxDMAPos) { - return rxDMAHead - s->rxDMAPos; + // s->rxDMAPos and rxDMAHead represent distances from the end + // of the buffer. They count DOWN as they advance. + if (s->rxDMAPos >= rxDMAHead) { + return s->rxDMAPos - rxDMAHead; } else { - return s->port.rxBufferSize + rxDMAHead - s->rxDMAPos; + return s->port.rxBufferSize + s->rxDMAPos - rxDMAHead; } } #endif