diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index 3352b24d..24efb09d 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs @@ -614,6 +614,19 @@ fn spin_until_idle(regs: Regs) { } } +fn flush_rx_fifo(regs: Regs) { + unsafe { + #[cfg(not(spi_v3))] + while regs.sr().read().rxne() { + let _ = regs.dr().read(); + } + #[cfg(spi_v3)] + while regs.sr().read().rxp() { + let _ = regs.rxdr().read(); + } + } +} + fn finish_dma(regs: Regs) { spin_until_idle(regs); diff --git a/embassy-stm32/src/spi/v1.rs b/embassy-stm32/src/spi/v1.rs index 33cf9c50..19562b8a 100644 --- a/embassy-stm32/src/spi/v1.rs +++ b/embassy-stm32/src/spi/v1.rs @@ -17,6 +17,10 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { }); } + // TODO: This is unnecessary in some versions because + // clearing SPE automatically clears the fifos + flush_rx_fifo(T::regs()); + let tx_request = self.txdma.request(); let tx_dst = T::regs().tx_ptr(); unsafe { self.txdma.start_write(tx_request, write, tx_dst) } @@ -110,6 +114,10 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { }); } + // TODO: This is unnecessary in some versions because + // clearing SPE automatically clears the fifos + flush_rx_fifo(T::regs()); + let rx_request = self.rxdma.request(); let rx_src = T::regs().rx_ptr(); unsafe { self.rxdma.start_read(rx_request, rx_src, read) }; diff --git a/embassy-stm32/src/spi/v2.rs b/embassy-stm32/src/spi/v2.rs index 7ffc52be..19562b8a 100644 --- a/embassy-stm32/src/spi/v2.rs +++ b/embassy-stm32/src/spi/v2.rs @@ -15,13 +15,12 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { T::regs().cr1().modify(|w| { w.set_spe(false); }); - - // Flush the read buffer to avoid errornous data from being read - while T::regs().sr().read().rxne() { - let _ = T::regs().dr().read(); - } } + // TODO: This is unnecessary in some versions because + // clearing SPE automatically clears the fifos + flush_rx_fifo(T::regs()); + let tx_request = self.txdma.request(); let tx_dst = T::regs().tx_ptr(); unsafe { self.txdma.start_write(tx_request, write, tx_dst) } @@ -113,13 +112,12 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { T::regs().cr2().modify(|reg| { reg.set_rxdmaen(true); }); - - // Flush the read buffer to avoid errornous data from being read - while T::regs().sr().read().rxne() { - let _ = T::regs().dr().read(); - } } + // TODO: This is unnecessary in some versions because + // clearing SPE automatically clears the fifos + flush_rx_fifo(T::regs()); + let rx_request = self.rxdma.request(); let rx_src = T::regs().rx_ptr(); unsafe { self.rxdma.start_read(rx_request, rx_src, read) }; diff --git a/embassy-stm32/src/spi/v3.rs b/embassy-stm32/src/spi/v3.rs index 9e766cfd..5c7472cc 100644 --- a/embassy-stm32/src/spi/v3.rs +++ b/embassy-stm32/src/spi/v3.rs @@ -15,13 +15,12 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { T::regs().cr1().modify(|w| { w.set_spe(false); }); - - // Flush the read buffer to avoid errornous data from being read - while T::regs().sr().read().rxp() { - let _ = T::regs().rxdr().read(); - } } + // TODO: This is unnecessary in some versions because + // clearing SPE automatically clears the fifos + flush_rx_fifo(T::regs()); + let tx_request = self.txdma.request(); let tx_dst = T::regs().tx_ptr(); unsafe { self.txdma.start_write(tx_request, write, tx_dst) } @@ -119,13 +118,12 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { T::regs().cfg1().modify(|reg| { reg.set_rxdmaen(true); }); - - // Flush the read buffer to avoid errornous data from being read - while T::regs().sr().read().rxp() { - let _ = T::regs().rxdr().read(); - } } + // TODO: This is unnecessary in some versions because + // clearing SPE automatically clears the fifos + flush_rx_fifo(T::regs()); + let rx_request = self.rxdma.request(); let rx_src = T::regs().rx_ptr(); unsafe { self.rxdma.start_read(rx_request, rx_src, read) };