From 3f379e06b0351ca21c9d1001c68d39c9c26cdc02 Mon Sep 17 00:00:00 2001 From: Bob McWhirter Date: Tue, 20 Jul 2021 13:38:44 -0400 Subject: [PATCH] Begin reworking SPI to add DMA for stm32. --- embassy-stm32/src/spi/mod.rs | 28 +++----------- embassy-stm32/src/spi/v3.rs | 75 +++++++++++++++++++++++++----------- embassy-traits/src/spi.rs | 2 +- 3 files changed, 59 insertions(+), 46 deletions(-) diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index 91b3d4ab..f84d820b 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs @@ -8,7 +8,6 @@ use crate::{dma, peripherals, rcc::RccPeripheral}; pub use _version::*; use crate::gpio::Pin; -use core::marker::PhantomData; #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Error { @@ -73,27 +72,12 @@ pub(crate) mod sealed { } } -pub trait Instance: sealed::Instance + RccPeripheral + 'static {} - -pub trait SckPin: sealed::SckPin + 'static {} - -pub trait MosiPin: sealed::MosiPin + 'static {} - -pub trait MisoPin: sealed::MisoPin + 'static {} - -pub trait TxDmaChannel: sealed::TxDmaChannel + 'static {} - -pub trait RxDmaChannel: sealed::RxDmaChannel + 'static {} - -pub trait SpiDma {} - -pub struct DmaPair, Rx: RxDmaChannel> { - tx: Tx, - rx: Rx, - _phantom: PhantomData, -} - -impl, Rx: RxDmaChannel> SpiDma for DmaPair {} +pub trait Instance: sealed::Instance + RccPeripheral {} +pub trait SckPin: sealed::SckPin {} +pub trait MosiPin: sealed::MosiPin {} +pub trait MisoPin: sealed::MisoPin {} +pub trait TxDmaChannel: sealed::TxDmaChannel + dma::Channel {} +pub trait RxDmaChannel: sealed::RxDmaChannel + dma::Channel {} crate::pac::peripherals!( (spi, $inst:ident) => { diff --git a/embassy-stm32/src/spi/v3.rs b/embassy-stm32/src/spi/v3.rs index 2c6d4415..6a6a0155 100644 --- a/embassy-stm32/src/spi/v3.rs +++ b/embassy-stm32/src/spi/v3.rs @@ -1,18 +1,21 @@ #![macro_use] +use crate::dma::NoDma; use crate::gpio::{AnyPin, Pin}; use crate::pac::gpio::vals::{Afr, Moder}; use crate::pac::gpio::Gpio; use crate::pac::spi; use crate::spi::{ - ByteOrder, Config, DmaPair, Error, Instance, MisoPin, MosiPin, RxDmaChannel, SckPin, SpiDma, - TxDmaChannel, WordSize, + ByteOrder, Config, Error, Instance, MisoPin, MosiPin, RxDmaChannel, SckPin, TxDmaChannel, + WordSize, }; use crate::time::Hertz; +use core::future::Future; use core::marker::PhantomData; use core::ptr; use embassy::util::Unborrow; use embassy_extras::unborrow; +use embassy_traits::spi as traits; pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; impl WordSize { @@ -31,28 +34,30 @@ impl WordSize { } } -pub struct Spi<'d, T: Instance, D = NoDma> { +pub struct Spi<'d, T: Instance, Tx = NoDma, Rx = NoDma> { sck: AnyPin, mosi: AnyPin, miso: AnyPin, - dma: D, + txdma: Tx, + rxdma: Rx, phantom: PhantomData<&'d mut T>, } -impl<'d, T: Instance, D> Spi<'d, T, D> { +impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { pub fn new( _peri: impl Unborrow + 'd, sck: impl Unborrow>, mosi: impl Unborrow>, miso: impl Unborrow>, - dma: impl Unborrow, + txdma: impl Unborrow, + rxdma: impl Unborrow, freq: F, config: Config, ) -> Self where F: Into, { - unborrow!(sck, mosi, miso, dma); + unborrow!(sck, mosi, miso, txdma, rxdma); unsafe { Self::configure_pin(sck.block(), sck.pin() as _, sck.af_num()); @@ -118,7 +123,8 @@ impl<'d, T: Instance, D> Spi<'d, T, D> { sck, mosi, miso, - dma, + txdma, + rxdma, phantom: PhantomData, } } @@ -167,9 +173,21 @@ impl<'d, T: Instance, D> Spi<'d, T, D> { }); } } + + async fn write_dma_u8(&mut self, write: &[u8]) -> Result<(), Error> { + unimplemented!() + } + + async fn read_dma_u8(&mut self, read: &mut [u8]) -> Result<(), Error> { + unimplemented!() + } + + async fn read_write_dma_u8(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Error> { + unimplemented!() + } } -impl<'d, T: Instance> Drop for Spi<'d, T> { +impl<'d, T: Instance, Tx, Rx> Drop for Spi<'d, T, Tx, Rx> { fn drop(&mut self) { unsafe { Self::unconfigure_pin(self.sck.block(), self.sck.pin() as _); @@ -364,30 +382,41 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer for Spi<'d, T, } } -use crate::dma::NoDma; -use core::future::Future; -use embassy_traits::spi::FullDuplex; - -#[rustfmt::skip] -impl<'d, T: Instance, Tx: TxDmaChannel, Rx: RxDmaChannel> FullDuplex for Spi<'d, T, DmaPair> { +impl<'d, T: Instance, Tx, Rx> traits::Spi for Spi<'d, T, Tx, Rx> { type Error = super::Error; - type WriteFuture<'a> where Self: 'a = impl Future> + 'a; - type ReadFuture<'a> where Self: 'a = impl Future> + 'a; - type WriteReadFuture<'a> where Self: 'a = impl Future> + 'a; +} - fn read<'a>(&'a mut self, data: &'a mut [u8]) -> Self::ReadFuture<'a> { - unimplemented!() - } +impl<'d, T: Instance, Tx: TxDmaChannel, Rx> traits::Write for Spi<'d, T, Tx, Rx> { + #[rustfmt::skip] + type WriteFuture<'a> where Self: 'a = impl Future> + 'a; fn write<'a>(&'a mut self, data: &'a [u8]) -> Self::WriteFuture<'a> { - unimplemented!() + self.write_dma_u8(data) } +} + +impl<'d, T: Instance, Tx: TxDmaChannel, Rx: RxDmaChannel> traits::Read + for Spi<'d, T, Tx, Rx> +{ + #[rustfmt::skip] + type ReadFuture<'a> where Self: 'a = impl Future> + 'a; + + fn read<'a>(&'a mut self, data: &'a mut [u8]) -> Self::ReadFuture<'a> { + self.read_dma_u8(data) + } +} + +impl<'d, T: Instance, Tx: TxDmaChannel, Rx: RxDmaChannel> traits::FullDuplex + for Spi<'d, T, Tx, Rx> +{ + #[rustfmt::skip] + type WriteReadFuture<'a> where Self: 'a = impl Future> + 'a; fn read_write<'a>( &'a mut self, read: &'a mut [u8], write: &'a [u8], ) -> Self::WriteReadFuture<'a> { - unimplemented!() + self.read_write_dma_u8(read, write) } } diff --git a/embassy-traits/src/spi.rs b/embassy-traits/src/spi.rs index 961da38c..9d044dfd 100644 --- a/embassy-traits/src/spi.rs +++ b/embassy-traits/src/spi.rs @@ -44,7 +44,7 @@ pub trait Write: Spi { fn write<'a>(&'a mut self, data: &'a [Word]) -> Self::WriteFuture<'a>; } -pub trait Read: Spi { +pub trait Read: Write { type ReadFuture<'a>: Future> + 'a where Self: 'a;