diff --git a/src/shared/drivers/spi/SPIBus.h b/src/shared/drivers/spi/SPIBus.h
index 2781a9c7a8d670a55e61ca3cd9c0cf568d297599..ef71a7d4c52e00ca0eda587308651b7ee2f6c676 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)