From 683c11f3997bc550d5ed716ee6e3059af4a8051c Mon Sep 17 00:00:00 2001 From: Grant Miller Date: Mon, 14 Mar 2022 14:55:05 -0500 Subject: [PATCH 1/7] Call `set_word_size` before disabling SPE --- embassy-stm32/src/spi/v1.rs | 6 +++--- embassy-stm32/src/spi/v2.rs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/embassy-stm32/src/spi/v1.rs b/embassy-stm32/src/spi/v1.rs index 5dd4dc2db..33cf9c50e 100644 --- a/embassy-stm32/src/spi/v1.rs +++ b/embassy-stm32/src/spi/v1.rs @@ -10,12 +10,12 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { where Tx: TxDma, { + self.set_word_size(WordSize::EightBit); unsafe { T::regs().cr1().modify(|w| { w.set_spe(false); }); } - self.set_word_size(WordSize::EightBit); let tx_request = self.txdma.request(); let tx_dst = T::regs().tx_ptr(); @@ -43,6 +43,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { Tx: TxDma, Rx: RxDma, { + self.set_word_size(WordSize::EightBit); unsafe { T::regs().cr1().modify(|w| { w.set_spe(false); @@ -51,7 +52,6 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { reg.set_rxdmaen(true); }); } - self.set_word_size(WordSize::EightBit); let (_, clock_byte_count) = slice_ptr_parts_mut(read); @@ -100,6 +100,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { let (_, tx_len) = slice_ptr_parts(write); assert_eq!(rx_len, tx_len); + self.set_word_size(WordSize::EightBit); unsafe { T::regs().cr1().modify(|w| { w.set_spe(false); @@ -108,7 +109,6 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { reg.set_rxdmaen(true); }); } - self.set_word_size(WordSize::EightBit); let rx_request = self.rxdma.request(); let rx_src = T::regs().rx_ptr(); diff --git a/embassy-stm32/src/spi/v2.rs b/embassy-stm32/src/spi/v2.rs index 3820fcac1..7ffc52be8 100644 --- a/embassy-stm32/src/spi/v2.rs +++ b/embassy-stm32/src/spi/v2.rs @@ -10,6 +10,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { where Tx: TxDma, { + self.set_word_size(WordSize::EightBit); unsafe { T::regs().cr1().modify(|w| { w.set_spe(false); @@ -20,7 +21,6 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { let _ = T::regs().dr().read(); } } - self.set_word_size(WordSize::EightBit); let tx_request = self.txdma.request(); let tx_dst = T::regs().tx_ptr(); @@ -48,6 +48,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { Tx: TxDma, Rx: RxDma, { + self.set_word_size(WordSize::EightBit); unsafe { T::regs().cr1().modify(|w| { w.set_spe(false); @@ -56,7 +57,6 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { reg.set_rxdmaen(true); }); } - self.set_word_size(WordSize::EightBit); let (_, clock_byte_count) = slice_ptr_parts_mut(read); @@ -105,6 +105,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { let (_, tx_len) = slice_ptr_parts(write); assert_eq!(rx_len, tx_len); + self.set_word_size(WordSize::EightBit); unsafe { T::regs().cr1().modify(|w| { w.set_spe(false); @@ -118,7 +119,6 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { let _ = T::regs().dr().read(); } } - self.set_word_size(WordSize::EightBit); let rx_request = self.rxdma.request(); let rx_src = T::regs().rx_ptr(); From 444b37fcdf744128347fd685a14874f44e5e05af Mon Sep 17 00:00:00 2001 From: Grant Miller Date: Mon, 14 Mar 2022 15:10:56 -0500 Subject: [PATCH 2/7] Add `flush_rx_fifo` function --- embassy-stm32/src/spi/mod.rs | 13 +++++++++++++ embassy-stm32/src/spi/v1.rs | 8 ++++++++ embassy-stm32/src/spi/v2.rs | 18 ++++++++---------- embassy-stm32/src/spi/v3.rs | 18 ++++++++---------- 4 files changed, 37 insertions(+), 20 deletions(-) diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index 3352b24d2..24efb09d2 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs @@ -614,6 +614,19 @@ fn spin_until_idle(regs: Regs) { } } +fn flush_rx_fifo(regs: Regs) { + unsafe { + #[cfg(not(spi_v3))] + while regs.sr().read().rxne() { + let _ = regs.dr().read(); + } + #[cfg(spi_v3)] + while regs.sr().read().rxp() { + let _ = regs.rxdr().read(); + } + } +} + fn finish_dma(regs: Regs) { spin_until_idle(regs); diff --git a/embassy-stm32/src/spi/v1.rs b/embassy-stm32/src/spi/v1.rs index 33cf9c50e..19562b8a0 100644 --- a/embassy-stm32/src/spi/v1.rs +++ b/embassy-stm32/src/spi/v1.rs @@ -17,6 +17,10 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { }); } + // TODO: This is unnecessary in some versions because + // clearing SPE automatically clears the fifos + flush_rx_fifo(T::regs()); + let tx_request = self.txdma.request(); let tx_dst = T::regs().tx_ptr(); unsafe { self.txdma.start_write(tx_request, write, tx_dst) } @@ -110,6 +114,10 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { }); } + // TODO: This is unnecessary in some versions because + // clearing SPE automatically clears the fifos + flush_rx_fifo(T::regs()); + let rx_request = self.rxdma.request(); let rx_src = T::regs().rx_ptr(); unsafe { self.rxdma.start_read(rx_request, rx_src, read) }; diff --git a/embassy-stm32/src/spi/v2.rs b/embassy-stm32/src/spi/v2.rs index 7ffc52be8..19562b8a0 100644 --- a/embassy-stm32/src/spi/v2.rs +++ b/embassy-stm32/src/spi/v2.rs @@ -15,13 +15,12 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { T::regs().cr1().modify(|w| { w.set_spe(false); }); - - // Flush the read buffer to avoid errornous data from being read - while T::regs().sr().read().rxne() { - let _ = T::regs().dr().read(); - } } + // TODO: This is unnecessary in some versions because + // clearing SPE automatically clears the fifos + flush_rx_fifo(T::regs()); + let tx_request = self.txdma.request(); let tx_dst = T::regs().tx_ptr(); unsafe { self.txdma.start_write(tx_request, write, tx_dst) } @@ -113,13 +112,12 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { T::regs().cr2().modify(|reg| { reg.set_rxdmaen(true); }); - - // Flush the read buffer to avoid errornous data from being read - while T::regs().sr().read().rxne() { - let _ = T::regs().dr().read(); - } } + // TODO: This is unnecessary in some versions because + // clearing SPE automatically clears the fifos + flush_rx_fifo(T::regs()); + let rx_request = self.rxdma.request(); let rx_src = T::regs().rx_ptr(); unsafe { self.rxdma.start_read(rx_request, rx_src, read) }; diff --git a/embassy-stm32/src/spi/v3.rs b/embassy-stm32/src/spi/v3.rs index 9e766cfdb..5c7472cc0 100644 --- a/embassy-stm32/src/spi/v3.rs +++ b/embassy-stm32/src/spi/v3.rs @@ -15,13 +15,12 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { T::regs().cr1().modify(|w| { w.set_spe(false); }); - - // Flush the read buffer to avoid errornous data from being read - while T::regs().sr().read().rxp() { - let _ = T::regs().rxdr().read(); - } } + // TODO: This is unnecessary in some versions because + // clearing SPE automatically clears the fifos + flush_rx_fifo(T::regs()); + let tx_request = self.txdma.request(); let tx_dst = T::regs().tx_ptr(); unsafe { self.txdma.start_write(tx_request, write, tx_dst) } @@ -119,13 +118,12 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { T::regs().cfg1().modify(|reg| { reg.set_rxdmaen(true); }); - - // Flush the read buffer to avoid errornous data from being read - while T::regs().sr().read().rxp() { - let _ = T::regs().rxdr().read(); - } } + // TODO: This is unnecessary in some versions because + // clearing SPE automatically clears the fifos + flush_rx_fifo(T::regs()); + let rx_request = self.rxdma.request(); let rx_src = T::regs().rx_ptr(); unsafe { self.rxdma.start_read(rx_request, rx_src, read) }; From 7cd6f00a902d719a463463d7766f70dd7b5f295b Mon Sep 17 00:00:00 2001 From: Grant Miller Date: Mon, 14 Mar 2022 15:25:20 -0500 Subject: [PATCH 3/7] Add `set_txdmaen` and `set_rxdmaen` functions --- embassy-stm32/src/spi/mod.rs | 26 ++++++++++++++++++++++++++ embassy-stm32/src/spi/v1.rs | 20 +++++--------------- embassy-stm32/src/spi/v2.rs | 20 +++++--------------- embassy-stm32/src/spi/v3.rs | 20 +++++--------------- 4 files changed, 41 insertions(+), 45 deletions(-) diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index 24efb09d2..3499c8d24 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs @@ -627,6 +627,32 @@ fn flush_rx_fifo(regs: Regs) { } } +fn set_txdmaen(regs: Regs, val: bool) { + unsafe { + #[cfg(not(spi_v3))] + regs.cr2().modify(|reg| { + reg.set_txdmaen(val); + }); + #[cfg(spi_v3)] + regs.cfg1().modify(|reg| { + reg.set_txdmaen(val); + }); + } +} + +fn set_rxdmaen(regs: Regs, val: bool) { + unsafe { + #[cfg(not(spi_v3))] + regs.cr2().modify(|reg| { + reg.set_rxdmaen(val); + }); + #[cfg(spi_v3)] + regs.cfg1().modify(|reg| { + reg.set_rxdmaen(val); + }); + } +} + fn finish_dma(regs: Regs) { spin_until_idle(regs); diff --git a/embassy-stm32/src/spi/v1.rs b/embassy-stm32/src/spi/v1.rs index 19562b8a0..853f639ad 100644 --- a/embassy-stm32/src/spi/v1.rs +++ b/embassy-stm32/src/spi/v1.rs @@ -27,9 +27,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { let tx_f = Transfer::new(&mut self.txdma); unsafe { - T::regs().cr2().modify(|reg| { - reg.set_txdmaen(true); - }); + set_txdmaen(T::regs(), true); T::regs().cr1().modify(|w| { w.set_spe(true); }); @@ -52,9 +50,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { T::regs().cr1().modify(|w| { w.set_spe(false); }); - T::regs().cr2().modify(|reg| { - reg.set_rxdmaen(true); - }); + set_rxdmaen(T::regs(), true); } let (_, clock_byte_count) = slice_ptr_parts_mut(read); @@ -76,9 +72,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { ); unsafe { - T::regs().cr2().modify(|reg| { - reg.set_txdmaen(true); - }); + set_txdmaen(T::regs(), true); T::regs().cr1().modify(|w| { w.set_spe(true); }); @@ -109,9 +103,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { T::regs().cr1().modify(|w| { w.set_spe(false); }); - T::regs().cr2().modify(|reg| { - reg.set_rxdmaen(true); - }); + set_rxdmaen(T::regs(), true); } // TODO: This is unnecessary in some versions because @@ -129,9 +121,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { let tx_f = Transfer::new(&mut self.txdma); unsafe { - T::regs().cr2().modify(|reg| { - reg.set_txdmaen(true); - }); + set_txdmaen(T::regs(), true); T::regs().cr1().modify(|w| { w.set_spe(true); }); diff --git a/embassy-stm32/src/spi/v2.rs b/embassy-stm32/src/spi/v2.rs index 19562b8a0..853f639ad 100644 --- a/embassy-stm32/src/spi/v2.rs +++ b/embassy-stm32/src/spi/v2.rs @@ -27,9 +27,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { let tx_f = Transfer::new(&mut self.txdma); unsafe { - T::regs().cr2().modify(|reg| { - reg.set_txdmaen(true); - }); + set_txdmaen(T::regs(), true); T::regs().cr1().modify(|w| { w.set_spe(true); }); @@ -52,9 +50,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { T::regs().cr1().modify(|w| { w.set_spe(false); }); - T::regs().cr2().modify(|reg| { - reg.set_rxdmaen(true); - }); + set_rxdmaen(T::regs(), true); } let (_, clock_byte_count) = slice_ptr_parts_mut(read); @@ -76,9 +72,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { ); unsafe { - T::regs().cr2().modify(|reg| { - reg.set_txdmaen(true); - }); + set_txdmaen(T::regs(), true); T::regs().cr1().modify(|w| { w.set_spe(true); }); @@ -109,9 +103,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { T::regs().cr1().modify(|w| { w.set_spe(false); }); - T::regs().cr2().modify(|reg| { - reg.set_rxdmaen(true); - }); + set_rxdmaen(T::regs(), true); } // TODO: This is unnecessary in some versions because @@ -129,9 +121,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { let tx_f = Transfer::new(&mut self.txdma); unsafe { - T::regs().cr2().modify(|reg| { - reg.set_txdmaen(true); - }); + set_txdmaen(T::regs(), true); T::regs().cr1().modify(|w| { w.set_spe(true); }); diff --git a/embassy-stm32/src/spi/v3.rs b/embassy-stm32/src/spi/v3.rs index 5c7472cc0..5a19355f9 100644 --- a/embassy-stm32/src/spi/v3.rs +++ b/embassy-stm32/src/spi/v3.rs @@ -27,9 +27,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { let tx_f = Transfer::new(&mut self.txdma); unsafe { - T::regs().cfg1().modify(|reg| { - reg.set_txdmaen(true); - }); + set_txdmaen(T::regs(), true); T::regs().cr1().modify(|w| { w.set_spe(true); }); @@ -55,9 +53,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { T::regs().cr1().modify(|w| { w.set_spe(false); }); - T::regs().cfg1().modify(|reg| { - reg.set_rxdmaen(true); - }); + set_rxdmaen(T::regs(), true); } let (_, clock_byte_count) = slice_ptr_parts_mut(read); @@ -79,9 +75,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { ); unsafe { - T::regs().cfg1().modify(|reg| { - reg.set_txdmaen(true); - }); + set_txdmaen(T::regs(), true); T::regs().cr1().modify(|w| { w.set_spe(true); }); @@ -115,9 +109,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { T::regs().cr1().modify(|w| { w.set_spe(false); }); - T::regs().cfg1().modify(|reg| { - reg.set_rxdmaen(true); - }); + set_rxdmaen(T::regs(), true); } // TODO: This is unnecessary in some versions because @@ -135,9 +127,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { let tx_f = Transfer::new(&mut self.txdma); unsafe { - T::regs().cfg1().modify(|reg| { - reg.set_txdmaen(true); - }); + set_txdmaen(T::regs(), true); T::regs().cr1().modify(|w| { w.set_spe(true); }); From 406b1b3dd2c076d4eef3b77028dc6ff6575d7802 Mon Sep 17 00:00:00 2001 From: Grant Miller Date: Mon, 14 Mar 2022 15:22:52 -0500 Subject: [PATCH 4/7] Finish matching versions --- embassy-stm32/src/spi/v1.rs | 12 ++++++++++++ embassy-stm32/src/spi/v2.rs | 12 ++++++++++++ embassy-stm32/src/spi/v3.rs | 3 +++ 3 files changed, 27 insertions(+) diff --git a/embassy-stm32/src/spi/v1.rs b/embassy-stm32/src/spi/v1.rs index 853f639ad..9c9674fd8 100644 --- a/embassy-stm32/src/spi/v1.rs +++ b/embassy-stm32/src/spi/v1.rs @@ -31,6 +31,10 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { T::regs().cr1().modify(|w| { w.set_spe(true); }); + #[cfg(spi_v3)] + T::regs().cr1().modify(|w| { + w.set_cstart(true); + }); } tx_f.await; @@ -76,6 +80,10 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { T::regs().cr1().modify(|w| { w.set_spe(true); }); + #[cfg(spi_v3)] + T::regs().cr1().modify(|w| { + w.set_cstart(true); + }); } join(tx_f, rx_f).await; @@ -125,6 +133,10 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { T::regs().cr1().modify(|w| { w.set_spe(true); }); + #[cfg(spi_v3)] + T::regs().cr1().modify(|w| { + w.set_cstart(true); + }); } join(tx_f, rx_f).await; diff --git a/embassy-stm32/src/spi/v2.rs b/embassy-stm32/src/spi/v2.rs index 853f639ad..9c9674fd8 100644 --- a/embassy-stm32/src/spi/v2.rs +++ b/embassy-stm32/src/spi/v2.rs @@ -31,6 +31,10 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { T::regs().cr1().modify(|w| { w.set_spe(true); }); + #[cfg(spi_v3)] + T::regs().cr1().modify(|w| { + w.set_cstart(true); + }); } tx_f.await; @@ -76,6 +80,10 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { T::regs().cr1().modify(|w| { w.set_spe(true); }); + #[cfg(spi_v3)] + T::regs().cr1().modify(|w| { + w.set_cstart(true); + }); } join(tx_f, rx_f).await; @@ -125,6 +133,10 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { T::regs().cr1().modify(|w| { w.set_spe(true); }); + #[cfg(spi_v3)] + T::regs().cr1().modify(|w| { + w.set_cstart(true); + }); } join(tx_f, rx_f).await; diff --git a/embassy-stm32/src/spi/v3.rs b/embassy-stm32/src/spi/v3.rs index 5a19355f9..9c9674fd8 100644 --- a/embassy-stm32/src/spi/v3.rs +++ b/embassy-stm32/src/spi/v3.rs @@ -31,6 +31,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { T::regs().cr1().modify(|w| { w.set_spe(true); }); + #[cfg(spi_v3)] T::regs().cr1().modify(|w| { w.set_cstart(true); }); @@ -79,6 +80,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { T::regs().cr1().modify(|w| { w.set_spe(true); }); + #[cfg(spi_v3)] T::regs().cr1().modify(|w| { w.set_cstart(true); }); @@ -131,6 +133,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { T::regs().cr1().modify(|w| { w.set_spe(true); }); + #[cfg(spi_v3)] T::regs().cr1().modify(|w| { w.set_cstart(true); }); From 482ffea4dd9f6cfe816d9e86a3dff5ce45746409 Mon Sep 17 00:00:00 2001 From: Grant Miller Date: Mon, 14 Mar 2022 15:36:39 -0500 Subject: [PATCH 5/7] Finish unification --- embassy-stm32/src/spi/mod.rs | 128 +++++++++++++++++++++++++++--- embassy-stm32/src/spi/v1.rs | 148 ----------------------------------- embassy-stm32/src/spi/v2.rs | 148 ----------------------------------- embassy-stm32/src/spi/v3.rs | 148 ----------------------------------- 4 files changed, 118 insertions(+), 454 deletions(-) delete mode 100644 embassy-stm32/src/spi/v1.rs delete mode 100644 embassy-stm32/src/spi/v2.rs delete mode 100644 embassy-stm32/src/spi/v3.rs diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index 3499c8d24..a180c1d02 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs @@ -4,9 +4,10 @@ use core::marker::PhantomData; use core::ptr; use embassy::util::Unborrow; use embassy_hal_common::unborrow; +use futures::future::join; use self::sealed::WordSize; -use crate::dma::NoDma; +use crate::dma::{slice_ptr_parts, slice_ptr_parts_mut, NoDma, Transfer}; use crate::gpio::sealed::{AFType, Pin as _}; use crate::gpio::AnyPin; use crate::pac::spi::{regs, vals}; @@ -16,12 +17,6 @@ use crate::time::Hertz; pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; -#[cfg_attr(spi_v1, path = "v1.rs")] -#[cfg_attr(spi_f1, path = "v1.rs")] -#[cfg_attr(spi_v2, path = "v2.rs")] -#[cfg_attr(spi_v3, path = "v3.rs")] -mod _version; - type Regs = &'static crate::pac::spi::Spi; #[derive(Debug)] @@ -417,7 +412,38 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { where Tx: TxDma, { - self.write_dma_u8(data).await + self.set_word_size(WordSize::EightBit); + unsafe { + T::regs().cr1().modify(|w| { + w.set_spe(false); + }); + } + + // TODO: This is unnecessary in some versions because + // clearing SPE automatically clears the fifos + flush_rx_fifo(T::regs()); + + let tx_request = self.txdma.request(); + let tx_dst = T::regs().tx_ptr(); + unsafe { self.txdma.start_write(tx_request, data, tx_dst) } + let tx_f = Transfer::new(&mut self.txdma); + + unsafe { + set_txdmaen(T::regs(), true); + T::regs().cr1().modify(|w| { + w.set_spe(true); + }); + #[cfg(spi_v3)] + T::regs().cr1().modify(|w| { + w.set_cstart(true); + }); + } + + tx_f.await; + + finish_dma(T::regs()); + + Ok(()) } pub async fn read(&mut self, data: &mut [u8]) -> Result<(), Error> @@ -425,7 +451,48 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { Tx: TxDma, Rx: RxDma, { - self.read_dma_u8(data).await + self.set_word_size(WordSize::EightBit); + unsafe { + T::regs().cr1().modify(|w| { + w.set_spe(false); + }); + set_rxdmaen(T::regs(), true); + } + + let (_, clock_byte_count) = slice_ptr_parts_mut(data); + + let rx_request = self.rxdma.request(); + let rx_src = T::regs().rx_ptr(); + unsafe { self.rxdma.start_read(rx_request, rx_src, data) }; + let rx_f = Transfer::new(&mut self.rxdma); + + let tx_request = self.txdma.request(); + let tx_dst = T::regs().tx_ptr(); + let clock_byte = 0x00u8; + let tx_f = crate::dma::write_repeated( + &mut self.txdma, + tx_request, + clock_byte, + clock_byte_count, + tx_dst, + ); + + unsafe { + set_txdmaen(T::regs(), true); + T::regs().cr1().modify(|w| { + w.set_spe(true); + }); + #[cfg(spi_v3)] + T::regs().cr1().modify(|w| { + w.set_cstart(true); + }); + } + + join(tx_f, rx_f).await; + + finish_dma(T::regs()); + + Ok(()) } pub async fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Error> @@ -433,7 +500,48 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { Tx: TxDma, Rx: RxDma, { - self.transfer_dma_u8(read, write).await + let (_, rx_len) = slice_ptr_parts(read); + let (_, tx_len) = slice_ptr_parts(write); + assert_eq!(rx_len, tx_len); + + self.set_word_size(WordSize::EightBit); + unsafe { + T::regs().cr1().modify(|w| { + w.set_spe(false); + }); + set_rxdmaen(T::regs(), true); + } + + // TODO: This is unnecessary in some versions because + // clearing SPE automatically clears the fifos + flush_rx_fifo(T::regs()); + + let rx_request = self.rxdma.request(); + let rx_src = T::regs().rx_ptr(); + unsafe { self.rxdma.start_read(rx_request, rx_src, read) }; + let rx_f = Transfer::new(&mut self.rxdma); + + let tx_request = self.txdma.request(); + let tx_dst = T::regs().tx_ptr(); + unsafe { self.txdma.start_write(tx_request, write, tx_dst) } + let tx_f = Transfer::new(&mut self.txdma); + + unsafe { + set_txdmaen(T::regs(), true); + T::regs().cr1().modify(|w| { + w.set_spe(true); + }); + #[cfg(spi_v3)] + T::regs().cr1().modify(|w| { + w.set_cstart(true); + }); + } + + join(tx_f, rx_f).await; + + finish_dma(T::regs()); + + Ok(()) } pub fn blocking_write(&mut self, words: &[W]) -> Result<(), Error> { diff --git a/embassy-stm32/src/spi/v1.rs b/embassy-stm32/src/spi/v1.rs deleted file mode 100644 index 9c9674fd8..000000000 --- a/embassy-stm32/src/spi/v1.rs +++ /dev/null @@ -1,148 +0,0 @@ -#![macro_use] - -use futures::future::join; - -use super::*; -use crate::dma::{slice_ptr_parts, slice_ptr_parts_mut, Transfer}; - -impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { - pub(super) async fn write_dma_u8(&mut self, write: *const [u8]) -> Result<(), Error> - where - Tx: TxDma, - { - self.set_word_size(WordSize::EightBit); - unsafe { - T::regs().cr1().modify(|w| { - w.set_spe(false); - }); - } - - // TODO: This is unnecessary in some versions because - // clearing SPE automatically clears the fifos - flush_rx_fifo(T::regs()); - - let tx_request = self.txdma.request(); - let tx_dst = T::regs().tx_ptr(); - unsafe { self.txdma.start_write(tx_request, write, tx_dst) } - let tx_f = Transfer::new(&mut self.txdma); - - unsafe { - set_txdmaen(T::regs(), true); - T::regs().cr1().modify(|w| { - w.set_spe(true); - }); - #[cfg(spi_v3)] - T::regs().cr1().modify(|w| { - w.set_cstart(true); - }); - } - - tx_f.await; - - finish_dma(T::regs()); - - Ok(()) - } - - pub(super) async fn read_dma_u8(&mut self, read: *mut [u8]) -> Result<(), Error> - where - Tx: TxDma, - Rx: RxDma, - { - self.set_word_size(WordSize::EightBit); - unsafe { - T::regs().cr1().modify(|w| { - w.set_spe(false); - }); - set_rxdmaen(T::regs(), true); - } - - let (_, clock_byte_count) = slice_ptr_parts_mut(read); - - let rx_request = self.rxdma.request(); - let rx_src = T::regs().rx_ptr(); - unsafe { self.rxdma.start_read(rx_request, rx_src, read) }; - let rx_f = Transfer::new(&mut self.rxdma); - - let tx_request = self.txdma.request(); - let tx_dst = T::regs().tx_ptr(); - let clock_byte = 0x00u8; - let tx_f = crate::dma::write_repeated( - &mut self.txdma, - tx_request, - clock_byte, - clock_byte_count, - tx_dst, - ); - - unsafe { - set_txdmaen(T::regs(), true); - T::regs().cr1().modify(|w| { - w.set_spe(true); - }); - #[cfg(spi_v3)] - T::regs().cr1().modify(|w| { - w.set_cstart(true); - }); - } - - join(tx_f, rx_f).await; - - finish_dma(T::regs()); - - Ok(()) - } - - pub(super) async fn transfer_dma_u8( - &mut self, - read: *mut [u8], - write: *const [u8], - ) -> Result<(), Error> - where - Tx: TxDma, - Rx: RxDma, - { - let (_, rx_len) = slice_ptr_parts(read); - let (_, tx_len) = slice_ptr_parts(write); - assert_eq!(rx_len, tx_len); - - self.set_word_size(WordSize::EightBit); - unsafe { - T::regs().cr1().modify(|w| { - w.set_spe(false); - }); - set_rxdmaen(T::regs(), true); - } - - // TODO: This is unnecessary in some versions because - // clearing SPE automatically clears the fifos - flush_rx_fifo(T::regs()); - - let rx_request = self.rxdma.request(); - let rx_src = T::regs().rx_ptr(); - unsafe { self.rxdma.start_read(rx_request, rx_src, read) }; - let rx_f = Transfer::new(&mut self.rxdma); - - let tx_request = self.txdma.request(); - let tx_dst = T::regs().tx_ptr(); - unsafe { self.txdma.start_write(tx_request, write, tx_dst) } - let tx_f = Transfer::new(&mut self.txdma); - - unsafe { - set_txdmaen(T::regs(), true); - T::regs().cr1().modify(|w| { - w.set_spe(true); - }); - #[cfg(spi_v3)] - T::regs().cr1().modify(|w| { - w.set_cstart(true); - }); - } - - join(tx_f, rx_f).await; - - finish_dma(T::regs()); - - Ok(()) - } -} diff --git a/embassy-stm32/src/spi/v2.rs b/embassy-stm32/src/spi/v2.rs deleted file mode 100644 index 9c9674fd8..000000000 --- a/embassy-stm32/src/spi/v2.rs +++ /dev/null @@ -1,148 +0,0 @@ -#![macro_use] - -use futures::future::join; - -use super::*; -use crate::dma::{slice_ptr_parts, slice_ptr_parts_mut, Transfer}; - -impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { - pub(super) async fn write_dma_u8(&mut self, write: *const [u8]) -> Result<(), Error> - where - Tx: TxDma, - { - self.set_word_size(WordSize::EightBit); - unsafe { - T::regs().cr1().modify(|w| { - w.set_spe(false); - }); - } - - // TODO: This is unnecessary in some versions because - // clearing SPE automatically clears the fifos - flush_rx_fifo(T::regs()); - - let tx_request = self.txdma.request(); - let tx_dst = T::regs().tx_ptr(); - unsafe { self.txdma.start_write(tx_request, write, tx_dst) } - let tx_f = Transfer::new(&mut self.txdma); - - unsafe { - set_txdmaen(T::regs(), true); - T::regs().cr1().modify(|w| { - w.set_spe(true); - }); - #[cfg(spi_v3)] - T::regs().cr1().modify(|w| { - w.set_cstart(true); - }); - } - - tx_f.await; - - finish_dma(T::regs()); - - Ok(()) - } - - pub(super) async fn read_dma_u8(&mut self, read: *mut [u8]) -> Result<(), Error> - where - Tx: TxDma, - Rx: RxDma, - { - self.set_word_size(WordSize::EightBit); - unsafe { - T::regs().cr1().modify(|w| { - w.set_spe(false); - }); - set_rxdmaen(T::regs(), true); - } - - let (_, clock_byte_count) = slice_ptr_parts_mut(read); - - let rx_request = self.rxdma.request(); - let rx_src = T::regs().rx_ptr(); - unsafe { self.rxdma.start_read(rx_request, rx_src, read) }; - let rx_f = Transfer::new(&mut self.rxdma); - - let tx_request = self.txdma.request(); - let tx_dst = T::regs().tx_ptr(); - let clock_byte = 0x00u8; - let tx_f = crate::dma::write_repeated( - &mut self.txdma, - tx_request, - clock_byte, - clock_byte_count, - tx_dst, - ); - - unsafe { - set_txdmaen(T::regs(), true); - T::regs().cr1().modify(|w| { - w.set_spe(true); - }); - #[cfg(spi_v3)] - T::regs().cr1().modify(|w| { - w.set_cstart(true); - }); - } - - join(tx_f, rx_f).await; - - finish_dma(T::regs()); - - Ok(()) - } - - pub(super) async fn transfer_dma_u8( - &mut self, - read: *mut [u8], - write: *const [u8], - ) -> Result<(), Error> - where - Tx: TxDma, - Rx: RxDma, - { - let (_, rx_len) = slice_ptr_parts(read); - let (_, tx_len) = slice_ptr_parts(write); - assert_eq!(rx_len, tx_len); - - self.set_word_size(WordSize::EightBit); - unsafe { - T::regs().cr1().modify(|w| { - w.set_spe(false); - }); - set_rxdmaen(T::regs(), true); - } - - // TODO: This is unnecessary in some versions because - // clearing SPE automatically clears the fifos - flush_rx_fifo(T::regs()); - - let rx_request = self.rxdma.request(); - let rx_src = T::regs().rx_ptr(); - unsafe { self.rxdma.start_read(rx_request, rx_src, read) }; - let rx_f = Transfer::new(&mut self.rxdma); - - let tx_request = self.txdma.request(); - let tx_dst = T::regs().tx_ptr(); - unsafe { self.txdma.start_write(tx_request, write, tx_dst) } - let tx_f = Transfer::new(&mut self.txdma); - - unsafe { - set_txdmaen(T::regs(), true); - T::regs().cr1().modify(|w| { - w.set_spe(true); - }); - #[cfg(spi_v3)] - T::regs().cr1().modify(|w| { - w.set_cstart(true); - }); - } - - join(tx_f, rx_f).await; - - finish_dma(T::regs()); - - Ok(()) - } -} diff --git a/embassy-stm32/src/spi/v3.rs b/embassy-stm32/src/spi/v3.rs deleted file mode 100644 index 9c9674fd8..000000000 --- a/embassy-stm32/src/spi/v3.rs +++ /dev/null @@ -1,148 +0,0 @@ -#![macro_use] - -use futures::future::join; - -use super::*; -use crate::dma::{slice_ptr_parts, slice_ptr_parts_mut, Transfer}; - -impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { - pub(super) async fn write_dma_u8(&mut self, write: *const [u8]) -> Result<(), Error> - where - Tx: TxDma, - { - self.set_word_size(WordSize::EightBit); - unsafe { - T::regs().cr1().modify(|w| { - w.set_spe(false); - }); - } - - // TODO: This is unnecessary in some versions because - // clearing SPE automatically clears the fifos - flush_rx_fifo(T::regs()); - - let tx_request = self.txdma.request(); - let tx_dst = T::regs().tx_ptr(); - unsafe { self.txdma.start_write(tx_request, write, tx_dst) } - let tx_f = Transfer::new(&mut self.txdma); - - unsafe { - set_txdmaen(T::regs(), true); - T::regs().cr1().modify(|w| { - w.set_spe(true); - }); - #[cfg(spi_v3)] - T::regs().cr1().modify(|w| { - w.set_cstart(true); - }); - } - - tx_f.await; - - finish_dma(T::regs()); - - Ok(()) - } - - pub(super) async fn read_dma_u8(&mut self, read: *mut [u8]) -> Result<(), Error> - where - Tx: TxDma, - Rx: RxDma, - { - self.set_word_size(WordSize::EightBit); - unsafe { - T::regs().cr1().modify(|w| { - w.set_spe(false); - }); - set_rxdmaen(T::regs(), true); - } - - let (_, clock_byte_count) = slice_ptr_parts_mut(read); - - let rx_request = self.rxdma.request(); - let rx_src = T::regs().rx_ptr(); - unsafe { self.rxdma.start_read(rx_request, rx_src, read) }; - let rx_f = Transfer::new(&mut self.rxdma); - - let tx_request = self.txdma.request(); - let tx_dst = T::regs().tx_ptr(); - let clock_byte = 0x00u8; - let tx_f = crate::dma::write_repeated( - &mut self.txdma, - tx_request, - clock_byte, - clock_byte_count, - tx_dst, - ); - - unsafe { - set_txdmaen(T::regs(), true); - T::regs().cr1().modify(|w| { - w.set_spe(true); - }); - #[cfg(spi_v3)] - T::regs().cr1().modify(|w| { - w.set_cstart(true); - }); - } - - join(tx_f, rx_f).await; - - finish_dma(T::regs()); - - Ok(()) - } - - pub(super) async fn transfer_dma_u8( - &mut self, - read: *mut [u8], - write: *const [u8], - ) -> Result<(), Error> - where - Tx: TxDma, - Rx: RxDma, - { - let (_, rx_len) = slice_ptr_parts(read); - let (_, tx_len) = slice_ptr_parts(write); - assert_eq!(rx_len, tx_len); - - self.set_word_size(WordSize::EightBit); - unsafe { - T::regs().cr1().modify(|w| { - w.set_spe(false); - }); - set_rxdmaen(T::regs(), true); - } - - // TODO: This is unnecessary in some versions because - // clearing SPE automatically clears the fifos - flush_rx_fifo(T::regs()); - - let rx_request = self.rxdma.request(); - let rx_src = T::regs().rx_ptr(); - unsafe { self.rxdma.start_read(rx_request, rx_src, read) }; - let rx_f = Transfer::new(&mut self.rxdma); - - let tx_request = self.txdma.request(); - let tx_dst = T::regs().tx_ptr(); - unsafe { self.txdma.start_write(tx_request, write, tx_dst) } - let tx_f = Transfer::new(&mut self.txdma); - - unsafe { - set_txdmaen(T::regs(), true); - T::regs().cr1().modify(|w| { - w.set_spe(true); - }); - #[cfg(spi_v3)] - T::regs().cr1().modify(|w| { - w.set_cstart(true); - }); - } - - join(tx_f, rx_f).await; - - finish_dma(T::regs()); - - Ok(()) - } -} From f0b62bc8e06b3d75e13fd8e36738104923d56174 Mon Sep 17 00:00:00 2001 From: Grant Miller Date: Mon, 14 Mar 2022 14:27:24 -0500 Subject: [PATCH 6/7] Use const REGS --- embassy-stm32/src/spi/mod.rs | 118 ++++++++++++++++------------------- 1 file changed, 55 insertions(+), 63 deletions(-) diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index a180c1d02..24819513c 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs @@ -10,6 +10,7 @@ use self::sealed::WordSize; use crate::dma::{slice_ptr_parts, slice_ptr_parts_mut, NoDma, Transfer}; use crate::gpio::sealed::{AFType, Pin as _}; use crate::gpio::AnyPin; +use crate::pac::spi::Spi as Regs; use crate::pac::spi::{regs, vals}; use crate::peripherals; use crate::rcc::RccPeripheral; @@ -17,8 +18,6 @@ use crate::time::Hertz; pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; -type Regs = &'static crate::pac::spi::Spi; - #[derive(Debug)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Error { @@ -219,10 +218,10 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { #[cfg(any(spi_v1, spi_f1))] unsafe { - T::regs().cr2().modify(|w| { + T::REGS.cr2().modify(|w| { w.set_ssoe(false); }); - T::regs().cr1().modify(|w| { + T::REGS.cr1().modify(|w| { w.set_cpha(cpha); w.set_cpol(cpol); @@ -242,12 +241,12 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { } #[cfg(spi_v2)] unsafe { - T::regs().cr2().modify(|w| { + 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| { + T::REGS.cr1().modify(|w| { w.set_cpha(cpha); w.set_cpol(cpol); @@ -263,8 +262,8 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { } #[cfg(spi_v3)] unsafe { - T::regs().ifcr().write(|w| w.0 = 0xffff_ffff); - T::regs().cfg2().modify(|w| { + 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(cpha); @@ -279,16 +278,16 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { w.set_afcntr(vals::Afcntr::CONTROLLED); w.set_ssiop(vals::Ssiop::ACTIVEHIGH); }); - T::regs().cfg1().modify(|w| { + T::REGS.cfg1().modify(|w| { w.set_crcen(false); w.set_mbr(br); w.set_dsize(WordSize::EightBit.dsize()); }); - T::regs().cr2().modify(|w| { + T::REGS.cr2().modify(|w| { w.set_tsize(0); w.set_tser(0); }); - T::regs().cr1().modify(|w| { + T::REGS.cr1().modify(|w| { w.set_ssi(false); w.set_spe(true); }); @@ -314,7 +313,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { #[cfg(any(spi_v1, spi_f1, spi_v2))] unsafe { - T::regs().cr1().modify(|w| { + T::REGS.cr1().modify(|w| { w.set_cpha(cpha); w.set_cpol(cpol); w.set_lsbfirst(lsbfirst); @@ -323,7 +322,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { #[cfg(spi_v3)] unsafe { - T::regs().cfg2().modify(|w| { + T::REGS.cfg2().modify(|w| { w.set_cpha(cpha); w.set_cpol(cpol); w.set_lsbfirst(lsbfirst); @@ -333,9 +332,9 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { pub fn get_current_config(&self) -> Config { #[cfg(any(spi_v1, spi_f1, spi_v2))] - let cfg = unsafe { T::regs().cr1().read() }; + let cfg = unsafe { T::REGS.cr1().read() }; #[cfg(spi_v3)] - let cfg = unsafe { T::regs().cfg2().read() }; + let cfg = unsafe { T::REGS.cfg2().read() }; let polarity = if cfg.cpol() == vals::Cpol::IDLELOW { Polarity::IdleLow } else { @@ -366,40 +365,40 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { #[cfg(any(spi_v1, spi_f1))] unsafe { - T::regs().cr1().modify(|reg| { + T::REGS.cr1().modify(|reg| { reg.set_spe(false); reg.set_dff(word_size.dff()) }); - T::regs().cr1().modify(|reg| { + T::REGS.cr1().modify(|reg| { reg.set_spe(true); }); } #[cfg(spi_v2)] unsafe { - T::regs().cr1().modify(|w| { + T::REGS.cr1().modify(|w| { w.set_spe(false); }); - T::regs().cr2().modify(|w| { + T::REGS.cr2().modify(|w| { w.set_frxth(word_size.frxth()); w.set_ds(word_size.ds()); }); - T::regs().cr1().modify(|w| { + T::REGS.cr1().modify(|w| { w.set_spe(true); }); } #[cfg(spi_v3)] unsafe { - T::regs().cr1().modify(|w| { + T::REGS.cr1().modify(|w| { w.set_csusp(true); }); - while T::regs().sr().read().eot() {} - T::regs().cr1().modify(|w| { + while T::REGS.sr().read().eot() {} + T::REGS.cr1().modify(|w| { w.set_spe(false); }); - T::regs().cfg1().modify(|w| { + T::REGS.cfg1().modify(|w| { w.set_dsize(word_size.dsize()); }); - T::regs().cr1().modify(|w| { + T::REGS.cr1().modify(|w| { w.set_csusp(false); w.set_spe(true); }); @@ -414,34 +413,34 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { { self.set_word_size(WordSize::EightBit); unsafe { - T::regs().cr1().modify(|w| { + T::REGS.cr1().modify(|w| { w.set_spe(false); }); } // TODO: This is unnecessary in some versions because // clearing SPE automatically clears the fifos - flush_rx_fifo(T::regs()); + flush_rx_fifo(T::REGS); let tx_request = self.txdma.request(); - let tx_dst = T::regs().tx_ptr(); + let tx_dst = T::REGS.tx_ptr(); unsafe { self.txdma.start_write(tx_request, data, tx_dst) } let tx_f = Transfer::new(&mut self.txdma); unsafe { - set_txdmaen(T::regs(), true); - T::regs().cr1().modify(|w| { + set_txdmaen(T::REGS, true); + T::REGS.cr1().modify(|w| { w.set_spe(true); }); #[cfg(spi_v3)] - T::regs().cr1().modify(|w| { + T::REGS.cr1().modify(|w| { w.set_cstart(true); }); } tx_f.await; - finish_dma(T::regs()); + finish_dma(T::REGS); Ok(()) } @@ -453,21 +452,21 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { { self.set_word_size(WordSize::EightBit); unsafe { - T::regs().cr1().modify(|w| { + T::REGS.cr1().modify(|w| { w.set_spe(false); }); - set_rxdmaen(T::regs(), true); + set_rxdmaen(T::REGS, true); } let (_, clock_byte_count) = slice_ptr_parts_mut(data); let rx_request = self.rxdma.request(); - let rx_src = T::regs().rx_ptr(); + let rx_src = T::REGS.rx_ptr(); unsafe { self.rxdma.start_read(rx_request, rx_src, data) }; let rx_f = Transfer::new(&mut self.rxdma); let tx_request = self.txdma.request(); - let tx_dst = T::regs().tx_ptr(); + let tx_dst = T::REGS.tx_ptr(); let clock_byte = 0x00u8; let tx_f = crate::dma::write_repeated( &mut self.txdma, @@ -478,19 +477,19 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { ); unsafe { - set_txdmaen(T::regs(), true); - T::regs().cr1().modify(|w| { + set_txdmaen(T::REGS, true); + T::REGS.cr1().modify(|w| { w.set_spe(true); }); #[cfg(spi_v3)] - T::regs().cr1().modify(|w| { + T::REGS.cr1().modify(|w| { w.set_cstart(true); }); } join(tx_f, rx_f).await; - finish_dma(T::regs()); + finish_dma(T::REGS); Ok(()) } @@ -506,79 +505,74 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { self.set_word_size(WordSize::EightBit); unsafe { - T::regs().cr1().modify(|w| { + T::REGS.cr1().modify(|w| { w.set_spe(false); }); - set_rxdmaen(T::regs(), true); + set_rxdmaen(T::REGS, true); } // TODO: This is unnecessary in some versions because // clearing SPE automatically clears the fifos - flush_rx_fifo(T::regs()); + flush_rx_fifo(T::REGS); let rx_request = self.rxdma.request(); - let rx_src = T::regs().rx_ptr(); + let rx_src = T::REGS.rx_ptr(); unsafe { self.rxdma.start_read(rx_request, rx_src, read) }; let rx_f = Transfer::new(&mut self.rxdma); let tx_request = self.txdma.request(); - let tx_dst = T::regs().tx_ptr(); + let tx_dst = T::REGS.tx_ptr(); unsafe { self.txdma.start_write(tx_request, write, tx_dst) } let tx_f = Transfer::new(&mut self.txdma); unsafe { - set_txdmaen(T::regs(), true); - T::regs().cr1().modify(|w| { + set_txdmaen(T::REGS, true); + T::REGS.cr1().modify(|w| { w.set_spe(true); }); #[cfg(spi_v3)] - T::regs().cr1().modify(|w| { + T::REGS.cr1().modify(|w| { w.set_cstart(true); }); } join(tx_f, rx_f).await; - finish_dma(T::regs()); + finish_dma(T::REGS); Ok(()) } pub fn blocking_write(&mut self, words: &[W]) -> Result<(), Error> { self.set_word_size(W::WORDSIZE); - let regs = T::regs(); for word in words.iter() { - let _ = transfer_word(regs, *word)?; + let _ = transfer_word(T::REGS, *word)?; } Ok(()) } pub fn blocking_read(&mut self, words: &mut [W]) -> Result<(), Error> { self.set_word_size(W::WORDSIZE); - let regs = T::regs(); for word in words.iter_mut() { - *word = transfer_word(regs, W::default())?; + *word = transfer_word(T::REGS, W::default())?; } Ok(()) } pub fn blocking_transfer_in_place(&mut self, words: &mut [W]) -> Result<(), Error> { self.set_word_size(W::WORDSIZE); - let regs = T::regs(); for word in words.iter_mut() { - *word = transfer_word(regs, *word)?; + *word = transfer_word(T::REGS, *word)?; } Ok(()) } pub fn blocking_transfer(&mut self, read: &mut [W], write: &[W]) -> Result<(), Error> { self.set_word_size(W::WORDSIZE); - let regs = T::regs(); - let len = read.len().max(write.len()); for i in 0..len { let wb = write.get(i).copied().unwrap_or_default(); - let rb = transfer_word(regs, wb)?; + let rb = transfer_word(T::REGS, wb)?; if let Some(r) = read.get_mut(i) { *r = rb; } @@ -623,7 +617,7 @@ trait RegsExt { fn rx_ptr(&self) -> *mut W; } -impl RegsExt for crate::pac::spi::Spi { +impl RegsExt for Regs { fn tx_ptr(&self) -> *mut W { #[cfg(not(spi_v3))] let dr = self.dr(); @@ -938,7 +932,7 @@ pub(crate) mod sealed { use super::*; pub trait Instance { - fn regs() -> &'static crate::pac::spi::Spi; + const REGS: Regs; } pub trait Word: Copy + 'static { @@ -1016,9 +1010,7 @@ dma_trait!(TxDma, Instance); foreach_peripheral!( (spi, $inst:ident) => { impl sealed::Instance for peripherals::$inst { - fn regs() -> &'static crate::pac::spi::Spi { - &crate::pac::$inst - } + const REGS: Regs = crate::pac::$inst; } impl Instance for peripherals::$inst {} From 6e00c5885459927ab79aa31bf9b0c1564d70c35b Mon Sep 17 00:00:00 2001 From: Grant Miller Date: Mon, 14 Mar 2022 16:24:43 -0500 Subject: [PATCH 7/7] Make all functions generic over word size --- embassy-stm32/src/spi/mod.rs | 48 ++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index 24819513c..3b39f0fd2 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs @@ -407,11 +407,11 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { self.current_word_size = word_size; } - pub async fn write(&mut self, data: &[u8]) -> Result<(), Error> + pub async fn write(&mut self, data: &[W]) -> Result<(), Error> where Tx: TxDma, { - self.set_word_size(WordSize::EightBit); + self.set_word_size(W::WORDSIZE); unsafe { T::REGS.cr1().modify(|w| { w.set_spe(false); @@ -445,12 +445,12 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { Ok(()) } - pub async fn read(&mut self, data: &mut [u8]) -> Result<(), Error> + pub async fn read(&mut self, data: &mut [W]) -> Result<(), Error> where Tx: TxDma, Rx: RxDma, { - self.set_word_size(WordSize::EightBit); + self.set_word_size(W::WORDSIZE); unsafe { T::REGS.cr1().modify(|w| { w.set_spe(false); @@ -494,7 +494,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { Ok(()) } - pub async fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Error> + pub async fn transfer(&mut self, read: &mut [W], write: &[W]) -> Result<(), Error> where Tx: TxDma, Rx: RxDma, @@ -503,7 +503,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { let (_, tx_len) = slice_ptr_parts(write); assert_eq!(rx_len, tx_len); - self.set_word_size(WordSize::EightBit); + self.set_word_size(W::WORDSIZE); unsafe { T::REGS.cr1().modify(|w| { w.set_spe(false); @@ -840,24 +840,30 @@ mod eh1 { } } - impl<'d, T: Instance> embedded_hal_1::spi::blocking::SpiBusRead for Spi<'d, T, NoDma, NoDma> { - fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> { + impl<'d, T: Instance, W: Word> embedded_hal_1::spi::blocking::SpiBusRead + for Spi<'d, T, NoDma, NoDma> + { + fn read(&mut self, words: &mut [W]) -> Result<(), Self::Error> { self.blocking_read(words) } } - impl<'d, T: Instance> embedded_hal_1::spi::blocking::SpiBusWrite for Spi<'d, T, NoDma, NoDma> { - fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> { + impl<'d, T: Instance, W: Word> embedded_hal_1::spi::blocking::SpiBusWrite + for Spi<'d, T, NoDma, NoDma> + { + fn write(&mut self, words: &[W]) -> Result<(), Self::Error> { self.blocking_write(words) } } - impl<'d, T: Instance> embedded_hal_1::spi::blocking::SpiBus for Spi<'d, T, NoDma, NoDma> { - fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> { + impl<'d, T: Instance, W: Word> embedded_hal_1::spi::blocking::SpiBus + for Spi<'d, T, NoDma, NoDma> + { + fn transfer(&mut self, read: &mut [W], write: &[W]) -> Result<(), Self::Error> { self.blocking_transfer(read, write) } - fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Self::Error> { + fn transfer_in_place(&mut self, words: &mut [W]) -> Result<(), Self::Error> { self.blocking_transfer_in_place(words) } } @@ -885,32 +891,32 @@ cfg_if::cfg_if! { } } - impl<'d, T: Instance, Tx: TxDma, Rx> embedded_hal_async::spi::SpiBusWrite + impl<'d, T: Instance, Tx: TxDma, Rx, W: Word> embedded_hal_async::spi::SpiBusWrite for Spi<'d, T, Tx, Rx> { type WriteFuture<'a> = impl Future> + 'a where Self: 'a; - fn write<'a>(&'a mut self, data: &'a [u8]) -> Self::WriteFuture<'a> { + fn write<'a>(&'a mut self, data: &'a [W]) -> Self::WriteFuture<'a> { self.write(data) } } - impl<'d, T: Instance, Tx: TxDma, Rx: RxDma> embedded_hal_async::spi::SpiBusRead + impl<'d, T: Instance, Tx: TxDma, Rx: RxDma, W: Word> embedded_hal_async::spi::SpiBusRead for Spi<'d, T, Tx, Rx> { type ReadFuture<'a> = impl Future> + 'a where Self: 'a; - fn read<'a>(&'a mut self, data: &'a mut [u8]) -> Self::ReadFuture<'a> { + fn read<'a>(&'a mut self, data: &'a mut [W]) -> Self::ReadFuture<'a> { self.read(data) } } - impl<'d, T: Instance, Tx: TxDma, Rx: RxDma> embedded_hal_async::spi::SpiBus + impl<'d, T: Instance, Tx: TxDma, Rx: RxDma, W: Word> embedded_hal_async::spi::SpiBus for Spi<'d, T, Tx, Rx> { type TransferFuture<'a> = impl Future> + 'a where Self: 'a; - fn transfer<'a>(&'a mut self, rx: &'a mut [u8], tx: &'a [u8]) -> Self::TransferFuture<'a> { + fn transfer<'a>(&'a mut self, rx: &'a mut [W], tx: &'a [W]) -> Self::TransferFuture<'a> { self.transfer(rx, tx) } @@ -918,7 +924,7 @@ cfg_if::cfg_if! { fn transfer_in_place<'a>( &'a mut self, - words: &'a mut [u8], + words: &'a mut [W], ) -> Self::TransferInPlaceFuture<'a> { // TODO: Implement async version let result = self.blocking_transfer_in_place(words); @@ -995,7 +1001,7 @@ pub(crate) mod sealed { } } -pub trait Word: Copy + 'static + sealed::Word + Default {} +pub trait Word: Copy + 'static + sealed::Word + Default + crate::dma::Word {} impl Word for u8 {} impl Word for u16 {}