From 8e58f8fb39f275a23c6209cc856e3464b188fdf5 Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Fri, 30 May 2025 15:56:12 -0400 Subject: [PATCH] rp2040: Fix spi overflow issue Completely filling the spi transmit fifo could lead to a situation where the rx fifo overflows. Make sure not to write past the rx fifo size. Also, be sure to wait for the transmission to fully complete before exiting spi_transfer(). Signed-off-by: Kevin O'Connor --- src/rp2040/spi.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/rp2040/spi.c b/src/rp2040/spi.c index a92a0358..9303e703 100644 --- a/src/rp2040/spi.c +++ b/src/rp2040/spi.c @@ -128,22 +128,27 @@ spi_prepare(struct spi_config config) ; } +#define MAX_FIFO 8 // Max rx fifo size (don't tx past this size) + void spi_transfer(struct spi_config config, uint8_t receive_data, uint8_t len, uint8_t *data) { - uint8_t* wptr = data; - uint8_t* end = data + len; + uint8_t *wptr = data, *end = data + len; spi_hw_t *spi = config.spi; while (data < end) { uint32_t sr = spi->sr & (SPI_SSPSR_TNF_BITS | SPI_SSPSR_RNE_BITS); - if ((sr == SPI_SSPSR_TNF_BITS) && wptr < end) + if (sr == SPI_SSPSR_TNF_BITS && wptr < end && wptr < data + MAX_FIFO) spi->dr = *wptr++; if (!(sr & SPI_SSPSR_RNE_BITS)) continue; uint8_t rdata = spi->dr; - if(receive_data) + if (receive_data) *data = rdata; data++; } + // Wait for any remaining SCLK updates before returning + while ((spi->sr & (SPI_SSPSR_TFE_BITS|SPI_SSPSR_BSY_BITS)) + != SPI_SSPSR_TFE_BITS) + ; }