diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index 3352b24d..3b39f0fd 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs @@ -4,11 +4,13 @@ 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::Spi as Regs; use crate::pac::spi::{regs, vals}; use crate::peripherals; use crate::rcc::RccPeripheral; @@ -16,14 +18,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)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Error { @@ -224,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); @@ -247,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); @@ -268,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); @@ -284,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); }); @@ -319,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); @@ -328,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); @@ -338,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 { @@ -371,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); }); @@ -413,64 +407,172 @@ 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.write_dma_u8(data).await + self.set_word_size(W::WORDSIZE); + 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> + pub async fn read(&mut self, data: &mut [W]) -> Result<(), Error> where Tx: TxDma, Rx: RxDma, { - self.read_dma_u8(data).await + self.set_word_size(W::WORDSIZE); + 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> + pub async fn transfer(&mut self, read: &mut [W], write: &[W]) -> Result<(), Error> where 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(W::WORDSIZE); + 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> { 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; } @@ -515,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(); @@ -614,6 +716,45 @@ 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 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); @@ -699,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) } } @@ -744,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) } @@ -777,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); @@ -791,7 +938,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 { @@ -854,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 {} @@ -869,9 +1016,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 {} diff --git a/embassy-stm32/src/spi/v1.rs b/embassy-stm32/src/spi/v1.rs deleted file mode 100644 index 5dd4dc2d..00000000 --- a/embassy-stm32/src/spi/v1.rs +++ /dev/null @@ -1,138 +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, - { - 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(); - unsafe { self.txdma.start_write(tx_request, write, tx_dst) } - let tx_f = Transfer::new(&mut self.txdma); - - unsafe { - T::regs().cr2().modify(|reg| { - reg.set_txdmaen(true); - }); - T::regs().cr1().modify(|w| { - w.set_spe(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, - { - unsafe { - T::regs().cr1().modify(|w| { - w.set_spe(false); - }); - T::regs().cr2().modify(|reg| { - reg.set_rxdmaen(true); - }); - } - self.set_word_size(WordSize::EightBit); - - 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 { - T::regs().cr2().modify(|reg| { - reg.set_txdmaen(true); - }); - T::regs().cr1().modify(|w| { - w.set_spe(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); - - unsafe { - T::regs().cr1().modify(|w| { - w.set_spe(false); - }); - T::regs().cr2().modify(|reg| { - reg.set_rxdmaen(true); - }); - } - self.set_word_size(WordSize::EightBit); - - 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 { - T::regs().cr2().modify(|reg| { - reg.set_txdmaen(true); - }); - T::regs().cr1().modify(|w| { - w.set_spe(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 3820fcac..00000000 --- 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, - { - unsafe { - 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(); - } - } - self.set_word_size(WordSize::EightBit); - - 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 { - T::regs().cr2().modify(|reg| { - reg.set_txdmaen(true); - }); - T::regs().cr1().modify(|w| { - w.set_spe(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, - { - unsafe { - T::regs().cr1().modify(|w| { - w.set_spe(false); - }); - T::regs().cr2().modify(|reg| { - reg.set_rxdmaen(true); - }); - } - self.set_word_size(WordSize::EightBit); - - 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 { - T::regs().cr2().modify(|reg| { - reg.set_txdmaen(true); - }); - T::regs().cr1().modify(|w| { - w.set_spe(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); - - unsafe { - T::regs().cr1().modify(|w| { - w.set_spe(false); - }); - 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(); - } - } - self.set_word_size(WordSize::EightBit); - - 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 { - T::regs().cr2().modify(|reg| { - reg.set_txdmaen(true); - }); - T::regs().cr1().modify(|w| { - w.set_spe(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 9e766cfd..00000000 --- a/embassy-stm32/src/spi/v3.rs +++ /dev/null @@ -1,157 +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); - }); - - // Flush the read buffer to avoid errornous data from being read - while T::regs().sr().read().rxp() { - let _ = T::regs().rxdr().read(); - } - } - - 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 { - T::regs().cfg1().modify(|reg| { - reg.set_txdmaen(true); - }); - T::regs().cr1().modify(|w| { - w.set_spe(true); - }); - 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); - }); - T::regs().cfg1().modify(|reg| { - reg.set_rxdmaen(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 { - T::regs().cfg1().modify(|reg| { - reg.set_txdmaen(true); - }); - T::regs().cr1().modify(|w| { - w.set_spe(true); - }); - 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); - }); - 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(); - } - } - - 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 { - T::regs().cfg1().modify(|reg| { - reg.set_txdmaen(true); - }); - T::regs().cr1().modify(|w| { - w.set_spe(true); - }); - T::regs().cr1().modify(|w| { - w.set_cstart(true); - }); - } - - join(tx_f, rx_f).await; - - finish_dma(T::regs()); - - Ok(()) - } -}