diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2025-05-30 15:56:12 -0400 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2025-05-30 16:34:49 -0400 |
commit | 8e58f8fb39f275a23c6209cc856e3464b188fdf5 (patch) | |
tree | 323a3080e56dee452bdd133cc580c99726210cb1 /src | |
parent | f4130aa9487bed4210eedc01af4b9c88141a5771 (diff) | |
download | kutter-8e58f8fb39f275a23c6209cc856e3464b188fdf5.tar.gz kutter-8e58f8fb39f275a23c6209cc856e3464b188fdf5.tar.xz kutter-8e58f8fb39f275a23c6209cc856e3464b188fdf5.zip |
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 <kevin@koconnor.net>
Diffstat (limited to 'src')
-rw-r--r-- | src/rp2040/spi.c | 13 |
1 files 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) + ; } |