diff options
| author | Bob McWhirter <[email protected]> | 2021-07-20 09:19:23 -0400 |
|---|---|---|
| committer | Bob McWhirter <[email protected]> | 2021-07-23 13:22:39 -0400 |
| commit | fe66f0f8f83e03d3ab9bf766ffe41ecd6a0c7a38 (patch) | |
| tree | accd203e2d7505427f61dc5cbb9c048ee7f48e80 | |
| parent | a345dd9e2baa7f3b3b249012cf69d39876658571 (diff) | |
Checkpoint.
| -rw-r--r-- | embassy-stm32/src/spi/mod.rs | 29 | ||||
| -rw-r--r-- | embassy-stm32/src/spi/v3.rs | 50 |
2 files changed, 68 insertions, 11 deletions
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index 9b04c03aa..91b3d4ab3 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs | |||
| @@ -1,13 +1,14 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | 2 | ||
| 3 | #[cfg_attr(spi_v1, path = "v1.rs")] | 3 | //#[cfg_attr(spi_v1, path = "v1.rs")] |
| 4 | #[cfg_attr(spi_v2, path = "v2.rs")] | 4 | //#[cfg_attr(spi_v2, path = "v2.rs")] |
| 5 | #[cfg_attr(spi_v3, path = "v3.rs")] | 5 | #[cfg_attr(spi_v3, path = "v3.rs")] |
| 6 | mod _version; | 6 | mod _version; |
| 7 | use crate::{peripherals, rcc::RccPeripheral}; | 7 | 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; | ||
| 11 | 12 | ||
| 12 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 13 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 13 | pub enum Error { | 14 | pub enum Error { |
| @@ -62,6 +63,14 @@ pub(crate) mod sealed { | |||
| 62 | pub trait MisoPin<T: Instance>: Pin { | 63 | pub trait MisoPin<T: Instance>: Pin { |
| 63 | fn af_num(&self) -> u8; | 64 | fn af_num(&self) -> u8; |
| 64 | } | 65 | } |
| 66 | |||
| 67 | pub trait TxDmaChannel<T: Instance> { | ||
| 68 | fn request(&self) -> dma::Request; | ||
| 69 | } | ||
| 70 | |||
| 71 | pub trait RxDmaChannel<T: Instance> { | ||
| 72 | fn request(&self) -> dma::Request; | ||
| 73 | } | ||
| 65 | } | 74 | } |
| 66 | 75 | ||
| 67 | pub trait Instance: sealed::Instance + RccPeripheral + 'static {} | 76 | pub trait Instance: sealed::Instance + RccPeripheral + 'static {} |
| @@ -72,6 +81,20 @@ pub trait MosiPin<T: Instance>: sealed::MosiPin<T> + 'static {} | |||
| 72 | 81 | ||
| 73 | pub trait MisoPin<T: Instance>: sealed::MisoPin<T> + 'static {} | 82 | pub trait MisoPin<T: Instance>: sealed::MisoPin<T> + 'static {} |
| 74 | 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 | |||
| 75 | crate::pac::peripherals!( | 98 | crate::pac::peripherals!( |
| 76 | (spi, $inst:ident) => { | 99 | (spi, $inst:ident) => { |
| 77 | impl sealed::Instance for peripherals::$inst { | 100 | impl sealed::Instance for peripherals::$inst { |
diff --git a/embassy-stm32/src/spi/v3.rs b/embassy-stm32/src/spi/v3.rs index 0b4a71457..2c6d4415f 100644 --- a/embassy-stm32/src/spi/v3.rs +++ b/embassy-stm32/src/spi/v3.rs | |||
| @@ -4,7 +4,10 @@ use crate::gpio::{AnyPin, Pin}; | |||
| 4 | use crate::pac::gpio::vals::{Afr, Moder}; | 4 | use crate::pac::gpio::vals::{Afr, Moder}; |
| 5 | use crate::pac::gpio::Gpio; | 5 | use crate::pac::gpio::Gpio; |
| 6 | use crate::pac::spi; | 6 | use crate::pac::spi; |
| 7 | use crate::spi::{ByteOrder, Config, Error, Instance, MisoPin, MosiPin, SckPin, WordSize}; | 7 | use crate::spi::{ |
| 8 | ByteOrder, Config, DmaPair, Error, Instance, MisoPin, MosiPin, RxDmaChannel, SckPin, SpiDma, | ||
| 9 | TxDmaChannel, WordSize, | ||
| 10 | }; | ||
| 8 | use crate::time::Hertz; | 11 | use crate::time::Hertz; |
| 9 | use core::marker::PhantomData; | 12 | use core::marker::PhantomData; |
| 10 | use core::ptr; | 13 | use core::ptr; |
| @@ -28,26 +31,28 @@ impl WordSize { | |||
| 28 | } | 31 | } |
| 29 | } | 32 | } |
| 30 | 33 | ||
| 31 | pub struct Spi<'d, T: Instance> { | 34 | pub struct Spi<'d, T: Instance, D = NoDma> { |
| 32 | sck: AnyPin, | 35 | sck: AnyPin, |
| 33 | mosi: AnyPin, | 36 | mosi: AnyPin, |
| 34 | miso: AnyPin, | 37 | miso: AnyPin, |
| 38 | dma: D, | ||
| 35 | phantom: PhantomData<&'d mut T>, | 39 | phantom: PhantomData<&'d mut T>, |
| 36 | } | 40 | } |
| 37 | 41 | ||
| 38 | impl<'d, T: Instance> Spi<'d, T> { | 42 | impl<'d, T: Instance, D> Spi<'d, T, D> { |
| 39 | pub fn new<F>( | 43 | pub fn new<F>( |
| 40 | _peri: impl Unborrow<Target = T> + 'd, | 44 | _peri: impl Unborrow<Target = T> + 'd, |
| 41 | sck: impl Unborrow<Target = impl SckPin<T>>, | 45 | sck: impl Unborrow<Target = impl SckPin<T>>, |
| 42 | mosi: impl Unborrow<Target = impl MosiPin<T>>, | 46 | mosi: impl Unborrow<Target = impl MosiPin<T>>, |
| 43 | miso: impl Unborrow<Target = impl MisoPin<T>>, | 47 | miso: impl Unborrow<Target = impl MisoPin<T>>, |
| 48 | dma: impl Unborrow<Target = D>, | ||
| 44 | freq: F, | 49 | freq: F, |
| 45 | config: Config, | 50 | config: Config, |
| 46 | ) -> Self | 51 | ) -> Self |
| 47 | where | 52 | where |
| 48 | F: Into<Hertz>, | 53 | F: Into<Hertz>, |
| 49 | { | 54 | { |
| 50 | unborrow!(sck, mosi, miso); | 55 | unborrow!(sck, mosi, miso, dma); |
| 51 | 56 | ||
| 52 | unsafe { | 57 | unsafe { |
| 53 | Self::configure_pin(sck.block(), sck.pin() as _, sck.af_num()); | 58 | Self::configure_pin(sck.block(), sck.pin() as _, sck.af_num()); |
| @@ -113,6 +118,7 @@ impl<'d, T: Instance> Spi<'d, T> { | |||
| 113 | sck, | 118 | sck, |
| 114 | mosi, | 119 | mosi, |
| 115 | miso, | 120 | miso, |
| 121 | dma, | ||
| 116 | phantom: PhantomData, | 122 | phantom: PhantomData, |
| 117 | } | 123 | } |
| 118 | } | 124 | } |
| @@ -173,7 +179,7 @@ impl<'d, T: Instance> Drop for Spi<'d, T> { | |||
| 173 | } | 179 | } |
| 174 | } | 180 | } |
| 175 | 181 | ||
| 176 | impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u8> for Spi<'d, T> { | 182 | impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u8> for Spi<'d, T, NoDma> { |
| 177 | type Error = Error; | 183 | type Error = Error; |
| 178 | 184 | ||
| 179 | fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> { | 185 | fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> { |
| @@ -210,7 +216,7 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u8> for Spi<'d, T> { | |||
| 210 | } | 216 | } |
| 211 | } | 217 | } |
| 212 | 218 | ||
| 213 | impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u8> for Spi<'d, T> { | 219 | impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u8> for Spi<'d, T, NoDma> { |
| 214 | type Error = Error; | 220 | type Error = Error; |
| 215 | 221 | ||
| 216 | fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> { | 222 | fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> { |
| @@ -267,7 +273,7 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u8> for Spi<'d, T> { | |||
| 267 | } | 273 | } |
| 268 | } | 274 | } |
| 269 | 275 | ||
| 270 | impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u16> for Spi<'d, T> { | 276 | impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u16> for Spi<'d, T, NoDma> { |
| 271 | type Error = Error; | 277 | type Error = Error; |
| 272 | 278 | ||
| 273 | fn write(&mut self, words: &[u16]) -> Result<(), Self::Error> { | 279 | fn write(&mut self, words: &[u16]) -> Result<(), Self::Error> { |
| @@ -304,7 +310,7 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u16> for Spi<'d, T> { | |||
| 304 | } | 310 | } |
| 305 | } | 311 | } |
| 306 | 312 | ||
| 307 | impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u16> for Spi<'d, T> { | 313 | impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u16> for Spi<'d, T, NoDma> { |
| 308 | type Error = Error; | 314 | type Error = Error; |
| 309 | 315 | ||
| 310 | fn transfer<'w>(&mut self, words: &'w mut [u16]) -> Result<&'w [u16], Self::Error> { | 316 | fn transfer<'w>(&mut self, words: &'w mut [u16]) -> Result<&'w [u16], Self::Error> { |
| @@ -357,3 +363,31 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u16> for Spi<'d, T> | |||
| 357 | Ok(words) | 363 | Ok(words) |
| 358 | } | 364 | } |
| 359 | } | 365 | } |
| 366 | |||
| 367 | use crate::dma::NoDma; | ||
| 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; | ||
| 374 | type WriteFuture<'a> where Self: 'a = impl Future<Output = Result<(), Self::Error>> + 'a; | ||
| 375 | 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 | |||
| 378 | fn read<'a>(&'a mut self, data: &'a mut [u8]) -> Self::ReadFuture<'a> { | ||
| 379 | unimplemented!() | ||
| 380 | } | ||
| 381 | |||
| 382 | fn write<'a>(&'a mut self, data: &'a [u8]) -> Self::WriteFuture<'a> { | ||
| 383 | unimplemented!() | ||
| 384 | } | ||
| 385 | |||
| 386 | fn read_write<'a>( | ||
| 387 | &'a mut self, | ||
| 388 | read: &'a mut [u8], | ||
| 389 | write: &'a [u8], | ||
| 390 | ) -> Self::WriteReadFuture<'a> { | ||
| 391 | unimplemented!() | ||
| 392 | } | ||
| 393 | } | ||
