diff options
| author | Bob McWhirter <[email protected]> | 2021-07-20 13:38:44 -0400 |
|---|---|---|
| committer | Bob McWhirter <[email protected]> | 2021-07-23 13:22:39 -0400 |
| commit | 3f379e06b0351ca21c9d1001c68d39c9c26cdc02 (patch) | |
| tree | 3f9c5840ae4d6915d190f2018ce250cc11652569 | |
| parent | fe66f0f8f83e03d3ab9bf766ffe41ecd6a0c7a38 (diff) | |
Begin reworking SPI to add DMA for stm32.
| -rw-r--r-- | embassy-stm32/src/spi/mod.rs | 28 | ||||
| -rw-r--r-- | embassy-stm32/src/spi/v3.rs | 71 | ||||
| -rw-r--r-- | embassy-traits/src/spi.rs | 2 |
3 files changed, 57 insertions, 44 deletions
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index 91b3d4ab3..f84d820b5 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}; | |||
| 8 | pub use _version::*; | 8 | pub use _version::*; |
| 9 | 9 | ||
| 10 | use crate::gpio::Pin; | 10 | use crate::gpio::Pin; |
| 11 | use core::marker::PhantomData; | ||
| 12 | 11 | ||
| 13 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 12 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 14 | pub enum Error { | 13 | pub enum Error { |
| @@ -73,27 +72,12 @@ pub(crate) mod sealed { | |||
| 73 | } | 72 | } |
| 74 | } | 73 | } |
| 75 | 74 | ||
| 76 | pub trait Instance: sealed::Instance + RccPeripheral + 'static {} | 75 | pub trait Instance: sealed::Instance + RccPeripheral {} |
| 77 | 76 | pub trait SckPin<T: Instance>: sealed::SckPin<T> {} | |
| 78 | pub trait SckPin<T: Instance>: sealed::SckPin<T> + 'static {} | 77 | pub trait MosiPin<T: Instance>: sealed::MosiPin<T> {} |
| 79 | 78 | pub trait MisoPin<T: Instance>: sealed::MisoPin<T> {} | |
| 80 | pub trait MosiPin<T: Instance>: sealed::MosiPin<T> + 'static {} | 79 | pub trait TxDmaChannel<T: Instance>: sealed::TxDmaChannel<T> + dma::Channel {} |
| 81 | 80 | pub trait RxDmaChannel<T: Instance>: sealed::RxDmaChannel<T> + dma::Channel {} | |
| 82 | pub trait MisoPin<T: Instance>: sealed::MisoPin<T> + 'static {} | ||
| 83 | |||
| 84 | pub trait TxDmaChannel<T: Instance>: sealed::TxDmaChannel<T> + 'static {} | ||
| 85 | |||
| 86 | pub trait RxDmaChannel<T: Instance>: sealed::RxDmaChannel<T> + 'static {} | ||
| 87 | |||
| 88 | pub trait SpiDma {} | ||
| 89 | |||
| 90 | pub struct DmaPair<T: Instance, Tx: TxDmaChannel<T>, Rx: RxDmaChannel<T>> { | ||
| 91 | tx: Tx, | ||
| 92 | rx: Rx, | ||
| 93 | _phantom: PhantomData<T>, | ||
| 94 | } | ||
| 95 | |||
| 96 | impl<T: Instance, Tx: TxDmaChannel<T>, Rx: RxDmaChannel<T>> SpiDma for DmaPair<T, Tx, Rx> {} | ||
| 97 | 81 | ||
| 98 | crate::pac::peripherals!( | 82 | crate::pac::peripherals!( |
| 99 | (spi, $inst:ident) => { | 83 | (spi, $inst:ident) => { |
diff --git a/embassy-stm32/src/spi/v3.rs b/embassy-stm32/src/spi/v3.rs index 2c6d4415f..6a6a01550 100644 --- a/embassy-stm32/src/spi/v3.rs +++ b/embassy-stm32/src/spi/v3.rs | |||
| @@ -1,18 +1,21 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | 2 | ||
| 3 | use crate::dma::NoDma; | ||
| 3 | use crate::gpio::{AnyPin, Pin}; | 4 | use crate::gpio::{AnyPin, Pin}; |
| 4 | use crate::pac::gpio::vals::{Afr, Moder}; | 5 | use crate::pac::gpio::vals::{Afr, Moder}; |
| 5 | use crate::pac::gpio::Gpio; | 6 | use crate::pac::gpio::Gpio; |
| 6 | use crate::pac::spi; | 7 | use crate::pac::spi; |
| 7 | use crate::spi::{ | 8 | use crate::spi::{ |
| 8 | ByteOrder, Config, DmaPair, Error, Instance, MisoPin, MosiPin, RxDmaChannel, SckPin, SpiDma, | 9 | ByteOrder, Config, Error, Instance, MisoPin, MosiPin, RxDmaChannel, SckPin, TxDmaChannel, |
| 9 | TxDmaChannel, WordSize, | 10 | WordSize, |
| 10 | }; | 11 | }; |
| 11 | use crate::time::Hertz; | 12 | use crate::time::Hertz; |
| 13 | use core::future::Future; | ||
| 12 | use core::marker::PhantomData; | 14 | use core::marker::PhantomData; |
| 13 | use core::ptr; | 15 | use core::ptr; |
| 14 | use embassy::util::Unborrow; | 16 | use embassy::util::Unborrow; |
| 15 | use embassy_extras::unborrow; | 17 | use embassy_extras::unborrow; |
| 18 | use embassy_traits::spi as traits; | ||
| 16 | pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; | 19 | pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; |
| 17 | 20 | ||
| 18 | impl WordSize { | 21 | impl WordSize { |
| @@ -31,28 +34,30 @@ impl WordSize { | |||
| 31 | } | 34 | } |
| 32 | } | 35 | } |
| 33 | 36 | ||
| 34 | pub struct Spi<'d, T: Instance, D = NoDma> { | 37 | pub struct Spi<'d, T: Instance, Tx = NoDma, Rx = NoDma> { |
| 35 | sck: AnyPin, | 38 | sck: AnyPin, |
| 36 | mosi: AnyPin, | 39 | mosi: AnyPin, |
| 37 | miso: AnyPin, | 40 | miso: AnyPin, |
| 38 | dma: D, | 41 | txdma: Tx, |
| 42 | rxdma: Rx, | ||
| 39 | phantom: PhantomData<&'d mut T>, | 43 | phantom: PhantomData<&'d mut T>, |
| 40 | } | 44 | } |
| 41 | 45 | ||
| 42 | impl<'d, T: Instance, D> Spi<'d, T, D> { | 46 | impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { |
| 43 | pub fn new<F>( | 47 | pub fn new<F>( |
| 44 | _peri: impl Unborrow<Target = T> + 'd, | 48 | _peri: impl Unborrow<Target = T> + 'd, |
| 45 | sck: impl Unborrow<Target = impl SckPin<T>>, | 49 | sck: impl Unborrow<Target = impl SckPin<T>>, |
| 46 | mosi: impl Unborrow<Target = impl MosiPin<T>>, | 50 | mosi: impl Unborrow<Target = impl MosiPin<T>>, |
| 47 | miso: impl Unborrow<Target = impl MisoPin<T>>, | 51 | miso: impl Unborrow<Target = impl MisoPin<T>>, |
| 48 | dma: impl Unborrow<Target = D>, | 52 | txdma: impl Unborrow<Target = Tx>, |
| 53 | rxdma: impl Unborrow<Target = Rx>, | ||
| 49 | freq: F, | 54 | freq: F, |
| 50 | config: Config, | 55 | config: Config, |
| 51 | ) -> Self | 56 | ) -> Self |
| 52 | where | 57 | where |
| 53 | F: Into<Hertz>, | 58 | F: Into<Hertz>, |
| 54 | { | 59 | { |
| 55 | unborrow!(sck, mosi, miso, dma); | 60 | unborrow!(sck, mosi, miso, txdma, rxdma); |
| 56 | 61 | ||
| 57 | unsafe { | 62 | unsafe { |
| 58 | Self::configure_pin(sck.block(), sck.pin() as _, sck.af_num()); | 63 | Self::configure_pin(sck.block(), sck.pin() as _, sck.af_num()); |
| @@ -118,7 +123,8 @@ impl<'d, T: Instance, D> Spi<'d, T, D> { | |||
| 118 | sck, | 123 | sck, |
| 119 | mosi, | 124 | mosi, |
| 120 | miso, | 125 | miso, |
| 121 | dma, | 126 | txdma, |
| 127 | rxdma, | ||
| 122 | phantom: PhantomData, | 128 | phantom: PhantomData, |
| 123 | } | 129 | } |
| 124 | } | 130 | } |
| @@ -167,9 +173,21 @@ impl<'d, T: Instance, D> Spi<'d, T, D> { | |||
| 167 | }); | 173 | }); |
| 168 | } | 174 | } |
| 169 | } | 175 | } |
| 176 | |||
| 177 | async fn write_dma_u8(&mut self, write: &[u8]) -> Result<(), Error> { | ||
| 178 | unimplemented!() | ||
| 179 | } | ||
| 180 | |||
| 181 | async fn read_dma_u8(&mut self, read: &mut [u8]) -> Result<(), Error> { | ||
| 182 | unimplemented!() | ||
| 183 | } | ||
| 184 | |||
| 185 | async fn read_write_dma_u8(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Error> { | ||
| 186 | unimplemented!() | ||
| 187 | } | ||
| 170 | } | 188 | } |
| 171 | 189 | ||
| 172 | impl<'d, T: Instance> Drop for Spi<'d, T> { | 190 | impl<'d, T: Instance, Tx, Rx> Drop for Spi<'d, T, Tx, Rx> { |
| 173 | fn drop(&mut self) { | 191 | fn drop(&mut self) { |
| 174 | unsafe { | 192 | unsafe { |
| 175 | Self::unconfigure_pin(self.sck.block(), self.sck.pin() as _); | 193 | Self::unconfigure_pin(self.sck.block(), self.sck.pin() as _); |
| @@ -364,30 +382,41 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u16> for Spi<'d, T, | |||
| 364 | } | 382 | } |
| 365 | } | 383 | } |
| 366 | 384 | ||
| 367 | use crate::dma::NoDma; | 385 | impl<'d, T: Instance, Tx, Rx> traits::Spi<u8> for Spi<'d, T, Tx, Rx> { |
| 368 | use core::future::Future; | ||
| 369 | use embassy_traits::spi::FullDuplex; | ||
| 370 | |||
| 371 | #[rustfmt::skip] | ||
| 372 | impl<'d, T: Instance, Tx: TxDmaChannel<T>, Rx: RxDmaChannel<T>> FullDuplex<u8> for Spi<'d, T, DmaPair<T, Tx, Rx>> { | ||
| 373 | type Error = super::Error; | 386 | type Error = super::Error; |
| 387 | } | ||
| 388 | |||
| 389 | impl<'d, T: Instance, Tx: TxDmaChannel<T>, Rx> traits::Write<u8> for Spi<'d, T, Tx, Rx> { | ||
| 390 | #[rustfmt::skip] | ||
| 374 | type WriteFuture<'a> where Self: 'a = impl Future<Output = Result<(), Self::Error>> + 'a; | 391 | type WriteFuture<'a> where Self: 'a = impl Future<Output = Result<(), Self::Error>> + 'a; |
| 392 | |||
| 393 | fn write<'a>(&'a mut self, data: &'a [u8]) -> Self::WriteFuture<'a> { | ||
| 394 | self.write_dma_u8(data) | ||
| 395 | } | ||
| 396 | } | ||
| 397 | |||
| 398 | impl<'d, T: Instance, Tx: TxDmaChannel<T>, Rx: RxDmaChannel<T>> traits::Read<u8> | ||
| 399 | for Spi<'d, T, Tx, Rx> | ||
| 400 | { | ||
| 401 | #[rustfmt::skip] | ||
| 375 | type ReadFuture<'a> where Self: 'a = impl Future<Output = Result<(), Self::Error>> + 'a; | 402 | type ReadFuture<'a> where Self: 'a = impl Future<Output = Result<(), Self::Error>> + 'a; |
| 376 | type WriteReadFuture<'a> where Self: 'a = impl Future<Output = Result<(), Self::Error>> + 'a; | ||
| 377 | 403 | ||
| 378 | fn read<'a>(&'a mut self, data: &'a mut [u8]) -> Self::ReadFuture<'a> { | 404 | fn read<'a>(&'a mut self, data: &'a mut [u8]) -> Self::ReadFuture<'a> { |
| 379 | unimplemented!() | 405 | self.read_dma_u8(data) |
| 380 | } | 406 | } |
| 407 | } | ||
| 381 | 408 | ||
| 382 | fn write<'a>(&'a mut self, data: &'a [u8]) -> Self::WriteFuture<'a> { | 409 | impl<'d, T: Instance, Tx: TxDmaChannel<T>, Rx: RxDmaChannel<T>> traits::FullDuplex<u8> |
| 383 | unimplemented!() | 410 | for Spi<'d, T, Tx, Rx> |
| 384 | } | 411 | { |
| 412 | #[rustfmt::skip] | ||
| 413 | type WriteReadFuture<'a> where Self: 'a = impl Future<Output = Result<(), Self::Error>> + 'a; | ||
| 385 | 414 | ||
| 386 | fn read_write<'a>( | 415 | fn read_write<'a>( |
| 387 | &'a mut self, | 416 | &'a mut self, |
| 388 | read: &'a mut [u8], | 417 | read: &'a mut [u8], |
| 389 | write: &'a [u8], | 418 | write: &'a [u8], |
| 390 | ) -> Self::WriteReadFuture<'a> { | 419 | ) -> Self::WriteReadFuture<'a> { |
| 391 | unimplemented!() | 420 | self.read_write_dma_u8(read, write) |
| 392 | } | 421 | } |
| 393 | } | 422 | } |
diff --git a/embassy-traits/src/spi.rs b/embassy-traits/src/spi.rs index 961da38c4..9d044dfd3 100644 --- a/embassy-traits/src/spi.rs +++ b/embassy-traits/src/spi.rs | |||
| @@ -44,7 +44,7 @@ pub trait Write<Word>: Spi<Word> { | |||
| 44 | fn write<'a>(&'a mut self, data: &'a [Word]) -> Self::WriteFuture<'a>; | 44 | fn write<'a>(&'a mut self, data: &'a [Word]) -> Self::WriteFuture<'a>; |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | pub trait Read<Word>: Spi<Word> { | 47 | pub trait Read<Word>: Write<Word> { |
| 48 | type ReadFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a | 48 | type ReadFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a |
| 49 | where | 49 | where |
| 50 | Self: 'a; | 50 | Self: 'a; |
