From 141f826e10802a40ac1bca8fdcdfa3da821e0f28 Mon Sep 17 00:00:00 2001 From: Cristian Milatinov Date: Wed, 9 Jul 2025 20:35:01 -0400 Subject: feat: stm32 spi driver slave mode Add SPI slave constructors Fix SPI slave constructors Fix embedded hal async trait One more constructor fix Set SSM bit in SPI driver according to CommunicationMode Fix embedded_hal_async trait to be generic for both master and slave Fix I2S driver to use async master SPI Forgot import from spi mode Fix CommunicationMode associated const conditionals Duplicate doc for CommunicationMode const Add missing nss argument Fix existing SPI tests not compiling Fix stm32h7rs examples not compiling Fix failing stm32l4 example Fix stm32h7 example Fix stm32h7 spi_bdma example Fix stm32h7 spi example Fix stm32f4 example docs: added entry in changelog.md fix: spi_v3 vals mismatch + rise_fall_speed renamed to gpio_speed fix: added spi_v6 conditional compilation feature fix: use if_afio macro in slave constructors fix: add missing trait bound fix: if_afio for cs pin trait fix: changelog message fix: broken rebase --- embassy-stm32/CHANGELOG.md | 1 + embassy-stm32/src/i2s.rs | 3 +- embassy-stm32/src/spi/mod.rs | 147 ++++++++++++++++++--- examples/stm32f4/src/bin/eth_w5500.rs | 3 +- examples/stm32h7/src/bin/spi.rs | 2 +- examples/stm32h7/src/bin/spi_bdma.rs | 2 +- examples/stm32h7/src/bin/spi_dma.rs | 2 +- examples/stm32h7rs/src/bin/spi.rs | 2 +- examples/stm32h7rs/src/bin/spi_dma.rs | 2 +- .../stm32l4/src/bin/spe_adin1110_http_server.rs | 3 +- tests/stm32/src/bin/spi.rs | 7 +- tests/stm32/src/bin/spi_dma.rs | 7 +- 12 files changed, 145 insertions(+), 36 deletions(-) diff --git a/embassy-stm32/CHANGELOG.md b/embassy-stm32/CHANGELOG.md index ee76a5d1b..2a7a89bc9 100644 --- a/embassy-stm32/CHANGELOG.md +++ b/embassy-stm32/CHANGELOG.md @@ -44,6 +44,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - feat: Added RTC low-power support for STM32WLEx ([#4716](https://github.com/embassy-rs/embassy/pull/4716)) - fix: Correct STM32WBA VREFBUFTRIM values - low_power: remove stop_with rtc and initialize in init if low-power feature enabled. +- feat: stm32/spi: added support for slave mode ([#4388](https://github.com/embassy-rs/embassy/pull/4388)) ## 0.4.0 - 2025-08-26 diff --git a/embassy-stm32/src/i2s.rs b/embassy-stm32/src/i2s.rs index db22cfa11..df077a3ae 100644 --- a/embassy-stm32/src/i2s.rs +++ b/embassy-stm32/src/i2s.rs @@ -7,6 +7,7 @@ use crate::Peri; use crate::dma::{ChannelAndRequest, ReadableRingBuffer, TransferOptions, WritableRingBuffer, ringbuffer}; use crate::gpio::{AfType, AnyPin, OutputType, SealedPin, Speed}; use crate::mode::Async; +use crate::spi::mode::Master; use crate::spi::{Config as SpiConfig, RegsExt as _, *}; use crate::time::Hertz; @@ -225,7 +226,7 @@ impl<'s, 'd, W: Word> Reader<'s, 'd, W> { pub struct I2S<'d, W: Word> { #[allow(dead_code)] mode: Mode, - spi: Spi<'d, Async>, + spi: Spi<'d, Async, Master>, txsd: Option>, rxsd: Option>, ws: Option>, diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index c27d09ea7..abb80ed26 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs @@ -125,26 +125,69 @@ impl Config { ) } } + +/// SPI communication mode +pub mod mode { + use stm32_metapac::spi::vals; + + trait SealedMode {} + + /// Trait for SPI communication mode operations. + #[allow(private_bounds)] + pub trait CommunicationMode: SealedMode { + /// Spi communication mode + #[cfg(not(any(spi_v4, spi_v5, spi_v6)))] + const MASTER: vals::Mstr; + /// Spi communication mode + #[cfg(any(spi_v4, spi_v5, spi_v6))] + const MASTER: vals::Master; + } + + /// Mode allowing for SPI master operations. + pub struct Master; + /// Mode allowing for SPI slave operations. + pub struct Slave; + + impl SealedMode for Master {} + impl CommunicationMode for Master { + #[cfg(not(any(spi_v4, spi_v5, spi_v6)))] + const MASTER: vals::Mstr = vals::Mstr::MASTER; + #[cfg(any(spi_v4, spi_v5, spi_v6))] + const MASTER: vals::Master = vals::Master::MASTER; + } + + impl SealedMode for Slave {} + impl CommunicationMode for Slave { + #[cfg(not(any(spi_v4, spi_v5, spi_v6)))] + const MASTER: vals::Mstr = vals::Mstr::SLAVE; + #[cfg(any(spi_v4, spi_v5, spi_v6))] + const MASTER: vals::Master = vals::Master::SLAVE; + } +} +use mode::{CommunicationMode, Master, Slave}; + /// SPI driver. -pub struct Spi<'d, M: PeriMode> { +pub struct Spi<'d, M: PeriMode, CM: CommunicationMode> { pub(crate) info: &'static Info, kernel_clock: Hertz, sck: Option>, mosi: Option>, miso: Option>, + nss: Option>, tx_dma: Option>, rx_dma: Option>, - _phantom: PhantomData, + _phantom: PhantomData<(M, CM)>, current_word_size: word_impl::Config, gpio_speed: Speed, } -impl<'d, M: PeriMode> Spi<'d, M> { +impl<'d, M: PeriMode, CM: CommunicationMode> Spi<'d, M, CM> { fn new_inner( _peri: Peri<'d, T>, sck: Option>, mosi: Option>, miso: Option>, + nss: Option>, tx_dma: Option>, rx_dma: Option>, config: Config, @@ -155,6 +198,7 @@ impl<'d, M: PeriMode> Spi<'d, M> { sck, mosi, miso, + nss, tx_dma, rx_dma, current_word_size: ::CONFIG, @@ -183,12 +227,12 @@ impl<'d, M: PeriMode> Spi<'d, M> { w.set_cpha(cpha); w.set_cpol(cpol); - w.set_mstr(vals::Mstr::MASTER); + w.set_mstr(CM::MASTER); w.set_br(br); w.set_spe(true); w.set_lsbfirst(lsbfirst); - w.set_ssi(true); - w.set_ssm(true); + w.set_ssi(CM::MASTER == vals::Mstr::MASTER); + w.set_ssm(CM::MASTER == vals::Mstr::MASTER); w.set_crcen(false); w.set_bidimode(vals::Bidimode::UNIDIRECTIONAL); // we're doing "fake rxonly", by actually writing one @@ -210,11 +254,11 @@ impl<'d, M: PeriMode> Spi<'d, M> { w.set_cpha(cpha); w.set_cpol(cpol); - w.set_mstr(vals::Mstr::MASTER); + w.set_mstr(CM::MASTER); w.set_br(br); w.set_lsbfirst(lsbfirst); - w.set_ssi(true); - w.set_ssm(true); + w.set_ssi(CM::MASTER == vals::Mstr::MASTER); + w.set_ssm(CM::MASTER == vals::Mstr::MASTER); w.set_crcen(false); w.set_bidimode(vals::Bidimode::UNIDIRECTIONAL); w.set_spe(true); @@ -229,8 +273,8 @@ impl<'d, M: PeriMode> Spi<'d, M> { w.set_cpha(cpha); w.set_cpol(cpol); w.set_lsbfirst(lsbfirst); - w.set_ssm(true); - w.set_master(vals::Master::MASTER); + w.set_ssm(CM::MASTER == vals::Master::MASTER); + w.set_master(CM::MASTER); w.set_comm(vals::Comm::FULL_DUPLEX); w.set_ssom(vals::Ssom::ASSERTED); w.set_midi(0); @@ -469,7 +513,30 @@ impl<'d, M: PeriMode> Spi<'d, M> { } } -impl<'d> Spi<'d, Blocking> { +impl<'d> Spi<'d, Blocking, Slave> { + /// Create a new blocking SPI slave driver. + pub fn new_blocking_slave( + peri: Peri<'d, T>, + sck: Peri<'d, if_afio!(impl SckPin)>, + mosi: Peri<'d, if_afio!(impl MosiPin)>, + miso: Peri<'d, if_afio!(impl MisoPin)>, + cs: Peri<'d, if_afio!(impl CsPin)>, + config: Config, + ) -> Self { + Self::new_inner( + peri, + new_pin!(sck, config.sck_af()), + new_pin!(mosi, AfType::output(OutputType::PushPull, config.gpio_speed)), + new_pin!(miso, AfType::input(config.miso_pull)), + new_pin!(cs, AfType::input(Pull::None)), + None, + None, + config, + ) + } +} + +impl<'d> Spi<'d, Blocking, Master> { /// Create a new blocking SPI driver. pub fn new_blocking( peri: Peri<'d, T>, @@ -485,6 +552,7 @@ impl<'d> Spi<'d, Blocking> { new_pin!(miso, AfType::input(config.miso_pull)), None, None, + None, config, ) } @@ -503,6 +571,7 @@ impl<'d> Spi<'d, Blocking> { new_pin!(miso, AfType::input(config.miso_pull)), None, None, + None, config, ) } @@ -521,6 +590,7 @@ impl<'d> Spi<'d, Blocking> { None, None, None, + None, config, ) } @@ -540,12 +610,38 @@ impl<'d> Spi<'d, Blocking> { None, None, None, + None, + config, + ) + } +} + +impl<'d> Spi<'d, Async, Slave> { + /// Create a new SPI slave driver. + pub fn new_slave( + peri: Peri<'d, T>, + sck: Peri<'d, if_afio!(impl SckPin)>, + mosi: Peri<'d, if_afio!(impl MosiPin)>, + miso: Peri<'d, if_afio!(impl MisoPin)>, + cs: Peri<'d, if_afio!(impl CsPin)>, + tx_dma: Peri<'d, impl TxDma>, + rx_dma: Peri<'d, impl RxDma>, + config: Config, + ) -> Self { + Self::new_inner( + peri, + new_pin!(sck, config.sck_af()), + new_pin!(mosi, AfType::output(OutputType::PushPull, config.gpio_speed)), + new_pin!(miso, AfType::input(config.miso_pull)), + new_pin!(cs, AfType::input(Pull::None)), + new_dma!(tx_dma), + new_dma!(rx_dma), config, ) } } -impl<'d> Spi<'d, Async> { +impl<'d> Spi<'d, Async, Master> { /// Create a new SPI driver. pub fn new( peri: Peri<'d, T>, @@ -561,6 +657,7 @@ impl<'d> Spi<'d, Async> { new_pin!(sck, config.sck_af()), new_pin!(mosi, AfType::output(OutputType::PushPull, config.gpio_speed)), new_pin!(miso, AfType::input(config.miso_pull)), + None, new_dma!(tx_dma), new_dma!(rx_dma), config, @@ -581,6 +678,7 @@ impl<'d> Spi<'d, Async> { new_pin!(sck, config.sck_af()), None, new_pin!(miso, AfType::input(config.miso_pull)), + None, #[cfg(any(spi_v1, spi_v2, spi_v3))] new_dma!(tx_dma), #[cfg(any(spi_v4, spi_v5, spi_v6))] @@ -603,6 +701,7 @@ impl<'d> Spi<'d, Async> { new_pin!(sck, config.sck_af()), new_pin!(mosi, AfType::output(OutputType::PushPull, config.gpio_speed)), None, + None, new_dma!(tx_dma), None, config, @@ -623,6 +722,7 @@ impl<'d> Spi<'d, Async> { None, new_pin!(mosi, AfType::output(OutputType::PushPull, config.gpio_speed)), None, + None, new_dma!(tx_dma), None, config, @@ -646,7 +746,7 @@ impl<'d> Spi<'d, Async> { config.bit_order = BitOrder::MsbFirst; config.frequency = freq; - Self::new_inner(peri, None, None, None, new_dma!(tx_dma), new_dma!(rx_dma), config) + Self::new_inner(peri, None, None, None, None, new_dma!(tx_dma), new_dma!(rx_dma), config) } #[allow(dead_code)] @@ -656,9 +756,11 @@ impl<'d> Spi<'d, Async> { rx_dma: Option>, config: Config, ) -> Self { - Self::new_inner(peri, None, None, None, tx_dma, rx_dma, config) + Self::new_inner(peri, None, None, None, None, tx_dma, rx_dma, config) } +} +impl<'d, CM: CommunicationMode> Spi<'d, Async, CM> { /// SPI write, using DMA. pub async fn write(&mut self, data: &[W]) -> Result<(), Error> { if data.is_empty() { @@ -888,11 +990,12 @@ impl<'d> Spi<'d, Async> { } } -impl<'d, M: PeriMode> Drop for Spi<'d, M> { +impl<'d, M: PeriMode, CM: CommunicationMode> Drop for Spi<'d, M, CM> { fn drop(&mut self) { self.sck.as_ref().map(|x| x.set_as_disconnected()); self.mosi.as_ref().map(|x| x.set_as_disconnected()); self.miso.as_ref().map(|x| x.set_as_disconnected()); + self.nss.as_ref().map(|x| x.set_as_disconnected()); self.info.rcc.disable(); } @@ -1127,7 +1230,7 @@ fn write_word(regs: Regs, tx_word: W) -> Result<(), Error> { // some marker traits. For details, see https://github.com/rust-embedded/embedded-hal/pull/289 macro_rules! impl_blocking { ($w:ident) => { - impl<'d, M: PeriMode> embedded_hal_02::blocking::spi::Write<$w> for Spi<'d, M> { + impl<'d, M: PeriMode, CM: CommunicationMode> embedded_hal_02::blocking::spi::Write<$w> for Spi<'d, M, CM> { type Error = Error; fn write(&mut self, words: &[$w]) -> Result<(), Self::Error> { @@ -1135,7 +1238,7 @@ macro_rules! impl_blocking { } } - impl<'d, M: PeriMode> embedded_hal_02::blocking::spi::Transfer<$w> for Spi<'d, M> { + impl<'d, M: PeriMode, CM: CommunicationMode> embedded_hal_02::blocking::spi::Transfer<$w> for Spi<'d, M, CM> { type Error = Error; fn transfer<'w>(&mut self, words: &'w mut [$w]) -> Result<&'w [$w], Self::Error> { @@ -1149,11 +1252,11 @@ macro_rules! impl_blocking { impl_blocking!(u8); impl_blocking!(u16); -impl<'d, M: PeriMode> embedded_hal_1::spi::ErrorType for Spi<'d, M> { +impl<'d, M: PeriMode, CM: CommunicationMode> embedded_hal_1::spi::ErrorType for Spi<'d, M, CM> { type Error = Error; } -impl<'d, W: Word, M: PeriMode> embedded_hal_1::spi::SpiBus for Spi<'d, M> { +impl<'d, W: Word, M: PeriMode, CM: CommunicationMode> embedded_hal_1::spi::SpiBus for Spi<'d, M, CM> { fn flush(&mut self) -> Result<(), Self::Error> { Ok(()) } @@ -1186,7 +1289,7 @@ impl embedded_hal_1::spi::Error for Error { } } -impl<'d, W: Word> embedded_hal_async::spi::SpiBus for Spi<'d, Async> { +impl<'d, W: Word, CM: CommunicationMode> embedded_hal_async::spi::SpiBus for Spi<'d, Async, CM> { async fn flush(&mut self) -> Result<(), Self::Error> { Ok(()) } @@ -1328,7 +1431,7 @@ foreach_peripheral!( }; ); -impl<'d, M: PeriMode> SetConfig for Spi<'d, M> { +impl<'d, M: PeriMode, CM: CommunicationMode> SetConfig for Spi<'d, M, CM> { type Config = Config; type ConfigError = (); fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { diff --git a/examples/stm32f4/src/bin/eth_w5500.rs b/examples/stm32f4/src/bin/eth_w5500.rs index cccf20949..0adcda614 100644 --- a/examples/stm32f4/src/bin/eth_w5500.rs +++ b/examples/stm32f4/src/bin/eth_w5500.rs @@ -12,6 +12,7 @@ use embassy_stm32::gpio::{Level, Output, Pull, Speed}; use embassy_stm32::mode::Async; use embassy_stm32::rng::Rng; use embassy_stm32::spi::Spi; +use embassy_stm32::spi::mode::Master; use embassy_stm32::time::Hertz; use embassy_stm32::{Config, bind_interrupts, peripherals, rng, spi}; use embassy_time::{Delay, Timer}; @@ -24,7 +25,7 @@ bind_interrupts!(struct Irqs { HASH_RNG => rng::InterruptHandler; }); -type EthernetSPI = ExclusiveDevice, Output<'static>, Delay>; +type EthernetSPI = ExclusiveDevice, Output<'static>, Delay>; #[embassy_executor::task] async fn ethernet_task(runner: Runner<'static, W5500, EthernetSPI, ExtiInput<'static>, Output<'static>>) -> ! { runner.run().await diff --git a/examples/stm32h7/src/bin/spi.rs b/examples/stm32h7/src/bin/spi.rs index 61f31be24..f7ab20cdd 100644 --- a/examples/stm32h7/src/bin/spi.rs +++ b/examples/stm32h7/src/bin/spi.rs @@ -15,7 +15,7 @@ use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::task] -async fn main_task(mut spi: spi::Spi<'static, Blocking>) { +async fn main_task(mut spi: spi::Spi<'static, Blocking, spi::mode::Master>) { for n in 0u32.. { let mut write: String<128> = String::new(); core::write!(&mut write, "Hello DMA World {}!\r\n", n).unwrap(); diff --git a/examples/stm32h7/src/bin/spi_bdma.rs b/examples/stm32h7/src/bin/spi_bdma.rs index be6a26d82..cd9d6c789 100644 --- a/examples/stm32h7/src/bin/spi_bdma.rs +++ b/examples/stm32h7/src/bin/spi_bdma.rs @@ -20,7 +20,7 @@ use {defmt_rtt as _, panic_probe as _}; static mut RAM_D3: GroundedArrayCell = GroundedArrayCell::uninit(); #[embassy_executor::task] -async fn main_task(mut spi: spi::Spi<'static, Async>) { +async fn main_task(mut spi: spi::Spi<'static, Async, spi::mode::Master>) { let (read_buffer, write_buffer) = unsafe { let ram = &mut *core::ptr::addr_of_mut!(RAM_D3); ram.initialize_all_copied(0); diff --git a/examples/stm32h7/src/bin/spi_dma.rs b/examples/stm32h7/src/bin/spi_dma.rs index 20cb67ba0..3d3c2f43e 100644 --- a/examples/stm32h7/src/bin/spi_dma.rs +++ b/examples/stm32h7/src/bin/spi_dma.rs @@ -15,7 +15,7 @@ use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::task] -async fn main_task(mut spi: spi::Spi<'static, Async>) { +async fn main_task(mut spi: spi::Spi<'static, Async, spi::mode::Master>) { for n in 0u32.. { let mut write: String<128> = String::new(); let mut read = [0; 128]; diff --git a/examples/stm32h7rs/src/bin/spi.rs b/examples/stm32h7rs/src/bin/spi.rs index 8c280fdae..3253304eb 100644 --- a/examples/stm32h7rs/src/bin/spi.rs +++ b/examples/stm32h7rs/src/bin/spi.rs @@ -15,7 +15,7 @@ use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::task] -async fn main_task(mut spi: spi::Spi<'static, Blocking>) { +async fn main_task(mut spi: spi::Spi<'static, Blocking, spi::mode::Master>) { for n in 0u32.. { let mut write: String<128> = String::new(); core::write!(&mut write, "Hello DMA World {}!\r\n", n).unwrap(); diff --git a/examples/stm32h7rs/src/bin/spi_dma.rs b/examples/stm32h7rs/src/bin/spi_dma.rs index 3fa69fd15..ca644c6a8 100644 --- a/examples/stm32h7rs/src/bin/spi_dma.rs +++ b/examples/stm32h7rs/src/bin/spi_dma.rs @@ -15,7 +15,7 @@ use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::task] -async fn main_task(mut spi: spi::Spi<'static, Async>) { +async fn main_task(mut spi: spi::Spi<'static, Async, spi::mode::Master>) { for n in 0u32.. { let mut write: String<128> = String::new(); let mut read = [0; 128]; diff --git a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs index 8e54938d1..0dbf515cf 100644 --- a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs +++ b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs @@ -28,6 +28,7 @@ use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; use embassy_stm32::i2c::{self, Config as I2C_Config, I2c}; use embassy_stm32::mode::Async; use embassy_stm32::rng::{self, Rng}; +use embassy_stm32::spi::mode::Master; use embassy_stm32::spi::{Config as SPI_Config, Spi}; use embassy_stm32::time::Hertz; use embassy_stm32::{bind_interrupts, exti, pac, peripherals}; @@ -54,7 +55,7 @@ const IP_ADDRESS: Ipv4Cidr = Ipv4Cidr::new(Ipv4Address::new(192, 168, 1, 5), 24) // Listen port for the webserver const HTTP_LISTEN_PORT: u16 = 80; -pub type SpeSpi = Spi<'static, Async>; +pub type SpeSpi = Spi<'static, Async, Master>; pub type SpeSpiCs = ExclusiveDevice, Delay>; pub type SpeInt = exti::ExtiInput<'static>; pub type SpeRst = Output<'static>; diff --git a/tests/stm32/src/bin/spi.rs b/tests/stm32/src/bin/spi.rs index e8310866a..cedff772c 100644 --- a/tests/stm32/src/bin/spi.rs +++ b/tests/stm32/src/bin/spi.rs @@ -8,6 +8,7 @@ use defmt::assert_eq; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; use embassy_stm32::mode::Blocking; +use embassy_stm32::spi::mode::Master; use embassy_stm32::spi::{self, Spi, Word}; use embassy_stm32::time::Hertz; @@ -65,7 +66,7 @@ async fn main(_spawner: Spawner) { cortex_m::asm::bkpt(); } -fn test_txrx + defmt::Format + Eq>(spi: &mut Spi<'_, Blocking>) +fn test_txrx + defmt::Format + Eq>(spi: &mut Spi<'_, Blocking, Master>) where W: core::ops::Not, { @@ -109,7 +110,7 @@ where spi.blocking_write::(&[]).unwrap(); } -fn test_rx + defmt::Format + Eq>(spi: &mut Spi<'_, Blocking>, mosi_out: &mut Output<'_>) +fn test_rx + defmt::Format + Eq>(spi: &mut Spi<'_, Blocking, Master>, mosi_out: &mut Output<'_>) where W: core::ops::Not, { @@ -125,7 +126,7 @@ where spi.blocking_read::(&mut []).unwrap(); } -fn test_tx + defmt::Format + Eq>(spi: &mut Spi<'_, Blocking>) +fn test_tx + defmt::Format + Eq>(spi: &mut Spi<'_, Blocking, Master>) where W: core::ops::Not, { diff --git a/tests/stm32/src/bin/spi_dma.rs b/tests/stm32/src/bin/spi_dma.rs index b4fdb8faa..c8cd92401 100644 --- a/tests/stm32/src/bin/spi_dma.rs +++ b/tests/stm32/src/bin/spi_dma.rs @@ -8,6 +8,7 @@ use defmt::assert_eq; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; use embassy_stm32::mode::Async; +use embassy_stm32::spi::mode::Master; use embassy_stm32::spi::{self, Spi, Word}; use embassy_stm32::time::Hertz; @@ -78,7 +79,7 @@ async fn main(_spawner: Spawner) { cortex_m::asm::bkpt(); } -async fn test_txrx + defmt::Format + Eq>(spi: &mut Spi<'_, Async>) +async fn test_txrx + defmt::Format + Eq>(spi: &mut Spi<'_, Async, Master>) where W: core::ops::Not, { @@ -142,7 +143,7 @@ where spi.write(&buf).await.unwrap(); } -async fn test_rx + defmt::Format + Eq>(spi: &mut Spi<'_, Async>, mosi_out: &mut Output<'_>) +async fn test_rx + defmt::Format + Eq>(spi: &mut Spi<'_, Async, Master>, mosi_out: &mut Output<'_>) where W: core::ops::Not, { @@ -168,7 +169,7 @@ where spi.blocking_read::(&mut []).unwrap(); } -async fn test_tx + defmt::Format + Eq>(spi: &mut Spi<'_, Async>) +async fn test_tx + defmt::Format + Eq>(spi: &mut Spi<'_, Async, Master>) where W: core::ops::Not, { -- cgit