stm32/spi: fix spiv1 rxonly hanging.

This commit is contained in:
Dario Nieuwenhuis 2024-05-31 21:43:03 +02:00
parent 999a2ad829
commit da197b6016
3 changed files with 45 additions and 60 deletions

View File

@ -148,9 +148,10 @@ impl<'d, M: PeriMode> Spi<'d, M> {
w.set_ssm(true); w.set_ssm(true);
w.set_crcen(false); w.set_crcen(false);
w.set_bidimode(vals::Bidimode::UNIDIRECTIONAL); w.set_bidimode(vals::Bidimode::UNIDIRECTIONAL);
if mosi.is_none() { // we're doing "fake rxonly", by actually writing one
w.set_rxonly(vals::Rxonly::OUTPUTDISABLED); // 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(<u8 as SealedWord>::CONFIG) w.set_dff(<u8 as SealedWord>::CONFIG)
}); });
} }

View File

@ -14,6 +14,7 @@ fn main() -> Result<(), Box<dyn Error>> {
feature = "stm32c031c6", feature = "stm32c031c6",
feature = "stm32wb55rg", feature = "stm32wb55rg",
feature = "stm32l073rz", feature = "stm32l073rz",
feature = "stm32h503rb",
// wrong ram size in stm32-data // wrong ram size in stm32-data
feature = "stm32wl55jc", feature = "stm32wl55jc",
feature = "stm32u5a5zj", feature = "stm32u5a5zj",

View File

@ -6,34 +6,32 @@ mod common;
use common::*; use common::*;
use defmt::assert_eq; use defmt::assert_eq;
use embassy_executor::Spawner; use embassy_executor::Spawner;
use embassy_stm32::gpio::{Level, Output, Speed};
use embassy_stm32::spi::{self, Spi}; use embassy_stm32::spi::{self, Spi};
use embassy_stm32::time::Hertz; use embassy_stm32::time::Hertz;
use embassy_stm32::{into_ref, Peripheral as _};
#[embassy_executor::main] #[embassy_executor::main]
async fn main(_spawner: Spawner) { async fn main(_spawner: Spawner) {
let p = embassy_stm32::init(config()); let p = embassy_stm32::init(config());
info!("Hello World!"); info!("Hello World!");
let spi_peri = peri!(p, SPI); let mut spi_peri = peri!(p, SPI);
let sck = peri!(p, SPI_SCK); let mut sck = peri!(p, SPI_SCK);
let mosi = peri!(p, SPI_MOSI); let mut mosi = peri!(p, SPI_MOSI);
let miso = peri!(p, SPI_MISO); let mut miso = peri!(p, SPI_MISO);
let tx_dma = peri!(p, SPI_TX_DMA); let mut tx_dma = peri!(p, SPI_TX_DMA);
let rx_dma = peri!(p, SPI_RX_DMA); let mut rx_dma = peri!(p, SPI_RX_DMA);
into_ref!(spi_peri, sck, mosi, miso, tx_dma, rx_dma);
let mut spi_config = spi::Config::default(); let mut spi_config = spi::Config::default();
spi_config.frequency = Hertz(1_000_000); spi_config.frequency = Hertz(1_000_000);
let mut spi = Spi::new( let mut spi = Spi::new(
spi_peri.reborrow(), &mut spi_peri,
sck.reborrow(), // Arduino D13 &mut sck, // Arduino D13
mosi.reborrow(), // Arduino D11 &mut mosi, // Arduino D11
miso.reborrow(), // Arduino D12 &mut miso, // Arduino D12
tx_dma.reborrow(), &mut tx_dma,
rx_dma.reborrow(), &mut rx_dma,
spi_config, spi_config,
); );
@ -85,51 +83,36 @@ async fn main(_spawner: Spawner) {
core::mem::drop(spi); core::mem::drop(spi);
// test rx-only configuration // 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 let mut mosi = Output::new(&mut mosi, Level::Low, Speed::VeryHigh);
// stm32f103c8 - spi_f1
// stm32g491re - spi_v2
// stm32h753zi - spi_v3
// stm32h563zi - spi_v4
// stm32wba52cg - spi_v5
#[cfg(any(stm32f207zg, stm32f103c8, stm32g491re, stm32h753zi, stm32h563zi, stm32wba52cg))] mosi.set_high();
{ spi.read(&mut buf).await.unwrap();
let mut spi = { assert_eq!(buf, [0xff; 9]);
#[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,
)
}
};
use embassy_stm32::gpio; mosi.set_low();
let mut mosi = gpio::Output::new(mosi.reborrow(), gpio::Level::Low, gpio::Speed::Low); spi.read(&mut buf).await.unwrap();
assert_eq!(buf, [0x00; 9]);
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]);
};
info!("Test OK"); info!("Test OK");
cortex_m::asm::bkpt(); cortex_m::asm::bkpt();