From 49ef19c0b284eeb6d97cec597bbb1f82d18397c5 Mon Sep 17 00:00:00 2001 From: Grant Miller Date: Mon, 14 Mar 2022 21:55:37 -0500 Subject: [PATCH 1/2] stm32/spi: Clear rx fifo in blocking methods --- embassy-stm32/src/spi/mod.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index d8ffabb1..a743a036 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs @@ -575,6 +575,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { } pub fn blocking_write(&mut self, words: &[W]) -> Result<(), Error> { + flush_rx_fifo(T::REGS); self.set_word_size(W::WORDSIZE); for word in words.iter() { let _ = transfer_word(T::REGS, *word)?; @@ -583,6 +584,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { } pub fn blocking_read(&mut self, words: &mut [W]) -> Result<(), Error> { + flush_rx_fifo(T::REGS); self.set_word_size(W::WORDSIZE); for word in words.iter_mut() { *word = transfer_word(T::REGS, W::default())?; @@ -591,6 +593,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { } pub fn blocking_transfer_in_place(&mut self, words: &mut [W]) -> Result<(), Error> { + flush_rx_fifo(T::REGS); self.set_word_size(W::WORDSIZE); for word in words.iter_mut() { *word = transfer_word(T::REGS, *word)?; @@ -599,6 +602,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { } pub fn blocking_transfer(&mut self, read: &mut [W], write: &[W]) -> Result<(), Error> { + flush_rx_fifo(T::REGS); self.set_word_size(W::WORDSIZE); let len = read.len().max(write.len()); for i in 0..len { @@ -727,7 +731,6 @@ fn spin_until_rx_ready(regs: Regs) -> Result<(), Error> { } } -#[cfg(not(spi_v3))] fn flush_rx_fifo(regs: Regs) { unsafe { #[cfg(not(spi_v3))] From 1dc618f0e4e045de63007893fb36fcaba82acfa4 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Tue, 15 Mar 2022 04:13:33 +0100 Subject: [PATCH 2/2] stm32/spi: fix blocking transfer hanging after async. --- embassy-stm32/src/spi/mod.rs | 4 ++++ tests/stm32/src/bin/spi_dma.rs | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index a743a036..764a967c 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs @@ -575,6 +575,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { } pub fn blocking_write(&mut self, words: &[W]) -> Result<(), Error> { + unsafe { T::REGS.cr1().modify(|w| w.set_spe(true)) } flush_rx_fifo(T::REGS); self.set_word_size(W::WORDSIZE); for word in words.iter() { @@ -584,6 +585,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { } pub fn blocking_read(&mut self, words: &mut [W]) -> Result<(), Error> { + unsafe { T::REGS.cr1().modify(|w| w.set_spe(true)) } flush_rx_fifo(T::REGS); self.set_word_size(W::WORDSIZE); for word in words.iter_mut() { @@ -593,6 +595,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { } pub fn blocking_transfer_in_place(&mut self, words: &mut [W]) -> Result<(), Error> { + unsafe { T::REGS.cr1().modify(|w| w.set_spe(true)) } flush_rx_fifo(T::REGS); self.set_word_size(W::WORDSIZE); for word in words.iter_mut() { @@ -602,6 +605,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { } pub fn blocking_transfer(&mut self, read: &mut [W], write: &[W]) -> Result<(), Error> { + unsafe { T::REGS.cr1().modify(|w| w.set_spe(true)) } flush_rx_fifo(T::REGS); self.set_word_size(W::WORDSIZE); let len = read.len().max(write.len()); diff --git a/tests/stm32/src/bin/spi_dma.rs b/tests/stm32/src/bin/spi_dma.rs index 3e9521ae..f4f1994c 100644 --- a/tests/stm32/src/bin/spi_dma.rs +++ b/tests/stm32/src/bin/spi_dma.rs @@ -68,6 +68,22 @@ async fn main(_spawner: Spawner, p: Peripherals) { spi.read::(&mut []).await.unwrap(); spi.write::(&[]).await.unwrap(); + // === Check mixing blocking with async. + spi.blocking_transfer(&mut buf, &data).unwrap(); + assert_eq!(buf, data); + spi.transfer(&mut buf, &data).await.unwrap(); + assert_eq!(buf, data); + spi.blocking_write(&buf).unwrap(); + spi.transfer(&mut buf, &data).await.unwrap(); + assert_eq!(buf, data); + spi.blocking_read(&mut buf).unwrap(); + spi.blocking_write(&buf).unwrap(); + spi.write(&buf).await.unwrap(); + spi.read(&mut buf).await.unwrap(); + spi.blocking_write(&buf).unwrap(); + spi.blocking_read(&mut buf).unwrap(); + spi.write(&buf).await.unwrap(); + info!("Test OK"); cortex_m::asm::bkpt(); }