From da197b60165b74d05c3d12b046b5cfda0b9cb126 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Fri, 31 May 2024 21:43:03 +0200 Subject: [PATCH] stm32/spi: fix spiv1 rxonly hanging. --- embassy-stm32/src/spi/mod.rs | 7 +-- tests/stm32/build.rs | 1 + tests/stm32/src/bin/spi_dma.rs | 97 ++++++++++++++-------------------- 3 files changed, 45 insertions(+), 60 deletions(-) diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index af8e3fc30..3729ed8de 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs @@ -148,9 +148,10 @@ impl<'d, M: PeriMode> Spi<'d, M> { w.set_ssm(true); w.set_crcen(false); w.set_bidimode(vals::Bidimode::UNIDIRECTIONAL); - if mosi.is_none() { - w.set_rxonly(vals::Rxonly::OUTPUTDISABLED); - } + // we're doing "fake rxonly", by actually writing one + // byte to TXDR for each byte we want to receive. if we + // set OUTPUTDISABLED here, this hangs. + w.set_rxonly(vals::Rxonly::FULLDUPLEX); w.set_dff(::CONFIG) }); } diff --git a/tests/stm32/build.rs b/tests/stm32/build.rs index 176adff62..675115568 100644 --- a/tests/stm32/build.rs +++ b/tests/stm32/build.rs @@ -14,6 +14,7 @@ fn main() -> Result<(), Box> { feature = "stm32c031c6", feature = "stm32wb55rg", feature = "stm32l073rz", + feature = "stm32h503rb", // wrong ram size in stm32-data feature = "stm32wl55jc", feature = "stm32u5a5zj", diff --git a/tests/stm32/src/bin/spi_dma.rs b/tests/stm32/src/bin/spi_dma.rs index 30e679f2a..92f741af5 100644 --- a/tests/stm32/src/bin/spi_dma.rs +++ b/tests/stm32/src/bin/spi_dma.rs @@ -6,34 +6,32 @@ mod common; use common::*; use defmt::assert_eq; use embassy_executor::Spawner; +use embassy_stm32::gpio::{Level, Output, Speed}; use embassy_stm32::spi::{self, Spi}; use embassy_stm32::time::Hertz; -use embassy_stm32::{into_ref, Peripheral as _}; #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_stm32::init(config()); info!("Hello World!"); - let spi_peri = peri!(p, SPI); - let sck = peri!(p, SPI_SCK); - let mosi = peri!(p, SPI_MOSI); - let miso = peri!(p, SPI_MISO); - let tx_dma = peri!(p, SPI_TX_DMA); - let rx_dma = peri!(p, SPI_RX_DMA); - - into_ref!(spi_peri, sck, mosi, miso, tx_dma, rx_dma); + let mut spi_peri = peri!(p, SPI); + let mut sck = peri!(p, SPI_SCK); + let mut mosi = peri!(p, SPI_MOSI); + let mut miso = peri!(p, SPI_MISO); + let mut tx_dma = peri!(p, SPI_TX_DMA); + let mut rx_dma = peri!(p, SPI_RX_DMA); let mut spi_config = spi::Config::default(); spi_config.frequency = Hertz(1_000_000); let mut spi = Spi::new( - spi_peri.reborrow(), - sck.reborrow(), // Arduino D13 - mosi.reborrow(), // Arduino D11 - miso.reborrow(), // Arduino D12 - tx_dma.reborrow(), - rx_dma.reborrow(), + &mut spi_peri, + &mut sck, // Arduino D13 + &mut mosi, // Arduino D11 + &mut miso, // Arduino D12 + &mut tx_dma, + &mut rx_dma, spi_config, ); @@ -85,51 +83,36 @@ async fn main(_spawner: Spawner) { core::mem::drop(spi); // test rx-only configuration + let mut spi = Spi::new_rxonly( + &mut spi_peri, + &mut sck, + &mut miso, + // SPIv1/f1 requires txdma even if rxonly. + #[cfg(not(any( + feature = "stm32h503rb", + feature = "stm32h563zi", + feature = "stm32h753zi", + feature = "stm32h755zi", + feature = "stm32h7a3zi", + feature = "stm32h7s3l8", + feature = "stm32u585ai", + feature = "stm32u5a5zj", + feature = "stm32wba52cg", + )))] + &mut tx_dma, + &mut rx_dma, + spi_config, + ); - // stm32f207zg - spi_v1 - // stm32f103c8 - spi_f1 - // stm32g491re - spi_v2 - // stm32h753zi - spi_v3 - // stm32h563zi - spi_v4 - // stm32wba52cg - spi_v5 + let mut mosi = Output::new(&mut mosi, Level::Low, Speed::VeryHigh); - #[cfg(any(stm32f207zg, stm32f103c8, stm32g491re, stm32h753zi, stm32h563zi, stm32wba52cg))] - { - let mut spi = { - #[cfg(stm32f207zg, stm32f103c8, stm32g491re)] - { - Spi::new_rxonly( - spi_peri.reborrow(), - sck.reborrow(), - miso.reborrow(), - tx_dma.reborrow(), - rx_dma.reborrow(), - spi_config, - ) - } - #[cfg(stm32h753zi, stm32h563zi, stm32wba52cg)] - { - Spi::new_rxonly( - spi_peri.reborrow(), - sck.reborrow(), - miso.reborrow(), - rx_dma.reborrow(), - spi_config, - ) - } - }; + mosi.set_high(); + spi.read(&mut buf).await.unwrap(); + assert_eq!(buf, [0xff; 9]); - use embassy_stm32::gpio; - let mut mosi = gpio::Output::new(mosi.reborrow(), gpio::Level::Low, gpio::Speed::Low); - - mosi.set_high(); - spi.read(&mut buf).await.unwrap(); - assert_eq!(buf, [0xff; 9]); - - mosi.set_low(); - spi.read(&mut buf).await.unwrap(); - assert_eq!(buf, [0x00; 9]); - }; + mosi.set_low(); + spi.read(&mut buf).await.unwrap(); + assert_eq!(buf, [0x00; 9]); info!("Test OK"); cortex_m::asm::bkpt();