From b06658c1958014f2b4dea7ec522c858457312373 Mon Sep 17 00:00:00 2001 From: Grant Miller Date: Tue, 7 Dec 2021 13:22:59 -0600 Subject: [PATCH 1/4] Refactor new --- embassy-stm32/src/spi/mod.rs | 122 ++++++++++++++++------------------- 1 file changed, 56 insertions(+), 66 deletions(-) diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index 5d919f92..8befaf52 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs @@ -152,34 +152,43 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { } let pclk = T::frequency(); - let br = Self::compute_baud_rate(pclk, freq.into()); + let br = compute_baud_rate(pclk, freq.into()); + + let cpha = match config.mode.phase { + Phase::CaptureOnSecondTransition => vals::Cpha::SECONDEDGE, + Phase::CaptureOnFirstTransition => vals::Cpha::FIRSTEDGE, + }; + let cpol = match config.mode.polarity { + Polarity::IdleHigh => vals::Cpol::IDLEHIGH, + Polarity::IdleLow => vals::Cpol::IDLELOW, + }; + + #[cfg(not(spi_v3))] + use vals::Lsbfirst; + #[cfg(spi_v3)] + use vals::Lsbfrst as Lsbfirst; + + let lsbfirst = match config.byte_order { + ByteOrder::LsbFirst => Lsbfirst::LSBFIRST, + ByteOrder::MsbFirst => Lsbfirst::MSBFIRST, + }; + + T::enable(); + T::reset(); #[cfg(any(spi_v1, spi_f1))] unsafe { - T::enable(); - T::reset(); T::regs().cr2().modify(|w| { w.set_ssoe(false); }); T::regs().cr1().modify(|w| { - w.set_cpha( - match config.mode.phase == Phase::CaptureOnSecondTransition { - true => vals::Cpha::SECONDEDGE, - false => vals::Cpha::FIRSTEDGE, - }, - ); - w.set_cpol(match config.mode.polarity == Polarity::IdleHigh { - true => vals::Cpol::IDLEHIGH, - false => vals::Cpol::IDLELOW, - }); + w.set_cpha(cpha); + w.set_cpol(cpol); w.set_mstr(vals::Mstr::MASTER); - w.set_br(vals::Br(br)); + w.set_br(br); w.set_spe(true); - w.set_lsbfirst(match config.byte_order { - ByteOrder::LsbFirst => vals::Lsbfirst::LSBFIRST, - ByteOrder::MsbFirst => vals::Lsbfirst::MSBFIRST, - }); + w.set_lsbfirst(lsbfirst); w.set_ssi(true); w.set_ssm(true); w.set_crcen(false); @@ -192,31 +201,18 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { } #[cfg(spi_v2)] unsafe { - T::enable(); - T::reset(); T::regs().cr2().modify(|w| { w.set_frxth(WordSize::EightBit.frxth()); w.set_ds(WordSize::EightBit.ds()); w.set_ssoe(false); }); T::regs().cr1().modify(|w| { - w.set_cpha( - match config.mode.phase == Phase::CaptureOnSecondTransition { - true => vals::Cpha::SECONDEDGE, - false => vals::Cpha::FIRSTEDGE, - }, - ); - w.set_cpol(match config.mode.polarity == Polarity::IdleHigh { - true => vals::Cpol::IDLEHIGH, - false => vals::Cpol::IDLELOW, - }); + w.set_cpha(cpha); + w.set_cpol(cpol); w.set_mstr(vals::Mstr::MASTER); - w.set_br(vals::Br(br)); - w.set_lsbfirst(match config.byte_order { - ByteOrder::LsbFirst => vals::Lsbfirst::LSBFIRST, - ByteOrder::MsbFirst => vals::Lsbfirst::MSBFIRST, - }); + w.set_br(br); + w.set_lsbfirst(lsbfirst); w.set_ssi(true); w.set_ssm(true); w.set_crcen(false); @@ -226,26 +222,13 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { } #[cfg(spi_v3)] unsafe { - T::enable(); - T::reset(); T::regs().ifcr().write(|w| w.0 = 0xffff_ffff); T::regs().cfg2().modify(|w| { //w.set_ssoe(true); w.set_ssoe(false); - w.set_cpha( - match config.mode.phase == Phase::CaptureOnSecondTransition { - true => vals::Cpha::SECONDEDGE, - false => vals::Cpha::FIRSTEDGE, - }, - ); - w.set_cpol(match config.mode.polarity == Polarity::IdleHigh { - true => vals::Cpol::IDLEHIGH, - false => vals::Cpol::IDLELOW, - }); - w.set_lsbfrst(match config.byte_order { - ByteOrder::LsbFirst => vals::Lsbfrst::LSBFIRST, - ByteOrder::MsbFirst => vals::Lsbfrst::MSBFIRST, - }); + w.set_cpha(cpha); + w.set_cpol(cpol); + w.set_lsbfrst(lsbfirst); w.set_ssm(true); w.set_master(vals::Master::MASTER); w.set_comm(vals::Comm::FULLDUPLEX); @@ -257,7 +240,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { }); T::regs().cfg1().modify(|w| { w.set_crcen(false); - w.set_mbr(vals::Mbr(br)); + w.set_mbr(br); w.set_dsize(WordSize::EightBit.dsize()); }); T::regs().cr2().modify(|w| { @@ -281,20 +264,6 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { } } - fn compute_baud_rate(clocks: Hertz, freq: Hertz) -> u8 { - match clocks.0 / freq.0 { - 0 => unreachable!(), - 1..=2 => 0b000, - 3..=5 => 0b001, - 6..=11 => 0b010, - 12..=23 => 0b011, - 24..=39 => 0b100, - 40..=95 => 0b101, - 96..=191 => 0b110, - _ => 0b111, - } - } - fn set_word_size(&mut self, word_size: WordSize) { if self.current_word_size == word_size { return; @@ -355,6 +324,27 @@ impl<'d, T: Instance, Tx, Rx> Drop for Spi<'d, T, Tx, Rx> { } } +#[cfg(not(spi_v3))] +use vals::Br; +#[cfg(spi_v3)] +use vals::Mbr as Br; + +fn compute_baud_rate(clocks: Hertz, freq: Hertz) -> Br { + let val = match clocks.0 / freq.0 { + 0 => unreachable!(), + 1..=2 => 0b000, + 3..=5 => 0b001, + 6..=11 => 0b010, + 12..=23 => 0b011, + 24..=39 => 0b100, + 40..=95 => 0b101, + 96..=191 => 0b110, + _ => 0b111, + }; + + Br(val) +} + trait RegsExt { fn tx_ptr(&self) -> *mut W; fn rx_ptr(&self) -> *mut W; From e75cb1a56498a2f0b48e63426e9c10c6520aead0 Mon Sep 17 00:00:00 2001 From: Grant Miller Date: Tue, 7 Dec 2021 00:48:44 -0600 Subject: [PATCH 2/4] Regs type alias --- embassy-stm32/src/spi/mod.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index 8befaf52..f4734726 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs @@ -22,6 +22,8 @@ use embassy_traits::spi as traits; mod _version; pub use _version::*; +type Regs = &'static crate::pac::spi::Spi; + #[derive(Debug)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Error { @@ -395,7 +397,7 @@ fn check_error_flags(sr: regs::Sr) -> Result<(), Error> { Ok(()) } -fn spin_until_tx_ready(regs: &'static crate::pac::spi::Spi) -> Result<(), Error> { +fn spin_until_tx_ready(regs: Regs) -> Result<(), Error> { loop { let sr = unsafe { regs.sr().read() }; @@ -412,7 +414,7 @@ fn spin_until_tx_ready(regs: &'static crate::pac::spi::Spi) -> Result<(), Error> } } -fn spin_until_rx_ready(regs: &'static crate::pac::spi::Spi) -> Result<(), Error> { +fn spin_until_rx_ready(regs: Regs) -> Result<(), Error> { loop { let sr = unsafe { regs.sr().read() }; @@ -440,7 +442,7 @@ impl Word for u16 { const WORDSIZE: WordSize = WordSize::SixteenBit; } -fn transfer_word(regs: &'static crate::pac::spi::Spi, tx_word: W) -> Result { +fn transfer_word(regs: Regs, tx_word: W) -> Result { spin_until_tx_ready(regs)?; unsafe { From a13a7a661604f4fa626c27a3330acb194912f66e Mon Sep 17 00:00:00 2001 From: Grant Miller Date: Tue, 14 Dec 2021 16:05:39 -0600 Subject: [PATCH 3/4] Replace wait_for_idle with spin_until_idle --- embassy-stm32/src/spi/mod.rs | 20 ++++++++++++++++++++ embassy-stm32/src/spi/v1.rs | 18 +++++++----------- embassy-stm32/src/spi/v2.rs | 28 ++++++++++------------------ embassy-stm32/src/spi/v3.rs | 23 +++++++++-------------- 4 files changed, 46 insertions(+), 43 deletions(-) diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index f4734726..a2a475e2 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs @@ -431,6 +431,26 @@ fn spin_until_rx_ready(regs: Regs) -> Result<(), Error> { } } +fn spin_until_idle(regs: Regs) { + #[cfg(any(spi_v1, spi_f1))] + unsafe { + while regs.sr().read().bsy() {} + } + + #[cfg(spi_v2)] + unsafe { + while regs.sr().read().ftlvl() > 0 {} + while regs.sr().read().frlvl() > 0 {} + while regs.sr().read().bsy() {} + } + + #[cfg(spi_v3)] + unsafe { + while !regs.sr().read().txc() {} + while regs.sr().read().rxplvl().0 > 0 {} + } +} + trait Word { const WORDSIZE: WordSize; } diff --git a/embassy-stm32/src/spi/v1.rs b/embassy-stm32/src/spi/v1.rs index 98f05770..94359261 100644 --- a/embassy-stm32/src/spi/v1.rs +++ b/embassy-stm32/src/spi/v1.rs @@ -2,7 +2,7 @@ pub use embedded_hal::blocking; pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; -use futures::future::join3; +use futures::future::join; use super::*; @@ -76,7 +76,9 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { }); } - join3(tx_f, rx_f, Self::wait_for_idle()).await; + join(tx_f, rx_f).await; + + spin_until_idle(T::regs()); unsafe { T::regs().cr2().modify(|reg| { @@ -134,7 +136,9 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { }); } - join3(tx_f, rx_f, Self::wait_for_idle()).await; + join(tx_f, rx_f).await; + + spin_until_idle(T::regs()); unsafe { T::regs().cr2().modify(|reg| { @@ -148,12 +152,4 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { Ok(()) } - - async fn wait_for_idle() { - unsafe { - while T::regs().sr().read().bsy() { - // spin - } - } - } } diff --git a/embassy-stm32/src/spi/v2.rs b/embassy-stm32/src/spi/v2.rs index 28697632..d9f5b46f 100644 --- a/embassy-stm32/src/spi/v2.rs +++ b/embassy-stm32/src/spi/v2.rs @@ -1,7 +1,7 @@ #![macro_use] pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; -use futures::future::{join, join3}; +use futures::future::join; use super::*; @@ -35,7 +35,9 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { }); } - join(f, Self::wait_for_idle()).await; + f.await; + + spin_until_idle(T::regs()); unsafe { T::regs().cr2().modify(|reg| { @@ -89,7 +91,9 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { }); } - join3(tx_f, rx_f, Self::wait_for_idle()).await; + join(tx_f, rx_f).await; + + spin_until_idle(T::regs()); unsafe { T::regs().cr2().modify(|reg| { @@ -152,7 +156,9 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { }); } - join3(tx_f, rx_f, Self::wait_for_idle()).await; + join(tx_f, rx_f).await; + + spin_until_idle(T::regs()); unsafe { T::regs().cr2().modify(|reg| { @@ -166,18 +172,4 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { Ok(()) } - - async fn wait_for_idle() { - unsafe { - while T::regs().sr().read().ftlvl() > 0 { - // spin - } - while T::regs().sr().read().frlvl() > 0 { - // spin - } - while T::regs().sr().read().bsy() { - // spin - } - } - } } diff --git a/embassy-stm32/src/spi/v3.rs b/embassy-stm32/src/spi/v3.rs index c31415a2..a3e39b21 100644 --- a/embassy-stm32/src/spi/v3.rs +++ b/embassy-stm32/src/spi/v3.rs @@ -1,7 +1,7 @@ #![macro_use] pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; -use futures::future::join3; +use futures::future::join; use super::*; @@ -95,7 +95,10 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { }); } - join3(tx_f, rx_f, Self::wait_for_idle()).await; + join(tx_f, rx_f).await; + + spin_until_idle(T::regs()); + unsafe { T::regs().cfg1().modify(|reg| { reg.set_rxdmaen(false); @@ -159,7 +162,10 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { }); } - join3(tx_f, rx_f, Self::wait_for_idle()).await; + join(tx_f, rx_f).await; + + spin_until_idle(T::regs()); + unsafe { T::regs().cfg1().modify(|reg| { reg.set_rxdmaen(false); @@ -171,15 +177,4 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { } Ok(()) } - - async fn wait_for_idle() { - unsafe { - while !T::regs().sr().read().txc() { - // spin - } - while T::regs().sr().read().rxplvl().0 > 0 { - // spin - } - } - } } From 6597e67036a875924757ace7c7550a0cd69c47a5 Mon Sep 17 00:00:00 2001 From: Grant Miller Date: Tue, 14 Dec 2021 16:59:31 -0600 Subject: [PATCH 4/4] Add finish_dma function --- embassy-stm32/src/spi/mod.rs | 21 +++++++++++++++++++++ embassy-stm32/src/spi/v1.rs | 27 +++++---------------------- embassy-stm32/src/spi/v2.rs | 34 +++------------------------------- embassy-stm32/src/spi/v3.rs | 32 ++++---------------------------- 4 files changed, 33 insertions(+), 81 deletions(-) diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index a2a475e2..e74b2e15 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs @@ -451,6 +451,27 @@ fn spin_until_idle(regs: Regs) { } } +fn finish_dma(regs: Regs) { + spin_until_idle(regs); + + unsafe { + regs.cr1().modify(|w| { + w.set_spe(false); + }); + + #[cfg(not(spi_v3))] + regs.cr2().modify(|reg| { + reg.set_txdmaen(false); + reg.set_rxdmaen(false); + }); + #[cfg(spi_v3)] + regs.cfg1().modify(|reg| { + reg.set_txdmaen(false); + reg.set_rxdmaen(false); + }); + } +} + trait Word { const WORDSIZE: WordSize; } diff --git a/embassy-stm32/src/spi/v1.rs b/embassy-stm32/src/spi/v1.rs index 94359261..ef7e0f59 100644 --- a/embassy-stm32/src/spi/v1.rs +++ b/embassy-stm32/src/spi/v1.rs @@ -32,6 +32,9 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { } f.await; + + finish_dma(T::regs()); + Ok(()) } @@ -78,17 +81,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { join(tx_f, rx_f).await; - spin_until_idle(T::regs()); - - unsafe { - T::regs().cr2().modify(|reg| { - reg.set_txdmaen(false); - reg.set_rxdmaen(false); - }); - T::regs().cr1().modify(|w| { - w.set_spe(false); - }); - } + finish_dma(T::regs()); Ok(()) } @@ -138,17 +131,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { join(tx_f, rx_f).await; - spin_until_idle(T::regs()); - - unsafe { - T::regs().cr2().modify(|reg| { - reg.set_txdmaen(false); - reg.set_rxdmaen(false); - }); - T::regs().cr1().modify(|w| { - w.set_spe(false); - }); - } + finish_dma(T::regs()); Ok(()) } diff --git a/embassy-stm32/src/spi/v2.rs b/embassy-stm32/src/spi/v2.rs index d9f5b46f..f2ba3ac6 100644 --- a/embassy-stm32/src/spi/v2.rs +++ b/embassy-stm32/src/spi/v2.rs @@ -37,16 +37,8 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { f.await; - spin_until_idle(T::regs()); + finish_dma(T::regs()); - unsafe { - T::regs().cr2().modify(|reg| { - reg.set_txdmaen(false); - }); - T::regs().cr1().modify(|w| { - w.set_spe(false); - }); - } Ok(()) } @@ -93,17 +85,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { join(tx_f, rx_f).await; - spin_until_idle(T::regs()); - - unsafe { - T::regs().cr2().modify(|reg| { - reg.set_txdmaen(false); - reg.set_rxdmaen(false); - }); - T::regs().cr1().modify(|w| { - w.set_spe(false); - }); - } + finish_dma(T::regs()); Ok(()) } @@ -158,17 +140,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { join(tx_f, rx_f).await; - spin_until_idle(T::regs()); - - unsafe { - T::regs().cr2().modify(|reg| { - reg.set_txdmaen(false); - reg.set_rxdmaen(false); - }); - T::regs().cr1().modify(|w| { - w.set_spe(false); - }); - } + finish_dma(T::regs()); Ok(()) } diff --git a/embassy-stm32/src/spi/v3.rs b/embassy-stm32/src/spi/v3.rs index a3e39b21..b42eeed8 100644 --- a/embassy-stm32/src/spi/v3.rs +++ b/embassy-stm32/src/spi/v3.rs @@ -39,14 +39,8 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { } f.await; - unsafe { - T::regs().cfg1().modify(|reg| { - reg.set_txdmaen(false); - }); - T::regs().cr1().modify(|w| { - w.set_spe(false); - }); - } + + finish_dma(T::regs()); Ok(()) } @@ -97,17 +91,8 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { join(tx_f, rx_f).await; - spin_until_idle(T::regs()); + finish_dma(T::regs()); - unsafe { - T::regs().cfg1().modify(|reg| { - reg.set_rxdmaen(false); - reg.set_txdmaen(false); - }); - T::regs().cr1().modify(|w| { - w.set_spe(false); - }); - } Ok(()) } @@ -164,17 +149,8 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { join(tx_f, rx_f).await; - spin_until_idle(T::regs()); + finish_dma(T::regs()); - unsafe { - T::regs().cfg1().modify(|reg| { - reg.set_rxdmaen(false); - reg.set_txdmaen(false); - }); - T::regs().cr1().modify(|w| { - w.set_spe(false); - }); - } Ok(()) } }