From fde561c181b9506e4c89e67e1efca218e3f42edf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2=20Betto?= <niccolo.betto@skywarder.eu> Date: Fri, 26 Apr 2024 22:37:23 +0200 Subject: [PATCH] [SPI] Workaround for non-empty FIFO after re-configure --- src/shared/drivers/spi/SPIBus.h | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/shared/drivers/spi/SPIBus.h b/src/shared/drivers/spi/SPIBus.h index 2781a9c7a..ef71a7d4c 100644 --- a/src/shared/drivers/spi/SPIBus.h +++ b/src/shared/drivers/spi/SPIBus.h @@ -132,6 +132,8 @@ public: void waitPeripheral(); + void flushRxBuffer(); + /** * @brief Configures and enables the bus with the provided configuration. * @@ -402,6 +404,12 @@ inline void SPIBus::waitPeripheral() ; } +inline void SPIBus::flushRxBuffer() +{ + while ((spi->SR & SPI_SR_RXNE) != 0) + spi->DR; +} + inline void SPIBus::configure(SPIBusConfig newConfig) { // Do not reconfigure if already in the correct configuration. @@ -520,8 +528,18 @@ inline void SPIBus::write16(const uint16_t* data, size_t nBytes) inline uint8_t SPIBus::transfer(uint8_t data) { - // At the start of the transfer we assume that the RX FIFO is empty - assert((spi->SR & SPI_SR_RXNE) == 0); + /* + * On STM32F7xx and STM32F4xx series chips, on SPI3 only, the RXNE flag + * may be erroneously set at the beginning of the transaction with the + * RX buffer containing garbage data. + * On F7xx chips the issue can be reproduced by re-configuring the SPI from + * Mode 0 (CPOL=0, CPHA=0) to Mode 3 (CPOL=1, CPHA=1), after performing at + * least one transaction in Mode 0. + * + * We work around this issue by flushing the RX buffer at the beginning of + * the transaction. + */ + flushRxBuffer(); // Wait until the peripheral is ready to transmit while ((spi->SR & SPI_SR_TXE) == 0) -- GitLab