diff options
| author | Tobias Pisani <[email protected]> | 2021-10-09 22:04:25 +0200 |
|---|---|---|
| committer | Tobias Pisani <[email protected]> | 2021-10-11 22:57:21 +0200 |
| commit | 259e84e68e32894a77b6050ee7cbdc9211865447 (patch) | |
| tree | 13b9d717e9e7ea7eb2aeaacb3862d9e17b9caad6 | |
| parent | c44bed300b17ef0cb0004758fd085b150533252f (diff) | |
Make miso/mosi optional when for unidirectional spi
Only suported on v1 currently
| -rw-r--r-- | embassy-stm32/src/spi/mod.rs | 8 | ||||
| -rw-r--r-- | embassy-stm32/src/spi/v1.rs | 55 | ||||
| -rw-r--r-- | embassy-stm32/src/spi/v2.rs | 38 | ||||
| -rw-r--r-- | embassy-stm32/src/spi/v3.rs | 42 |
4 files changed, 97 insertions, 46 deletions
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index 492fc41c6..e881a5235 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs | |||
| @@ -8,7 +8,7 @@ mod _version; | |||
| 8 | use crate::{dma, peripherals, rcc::RccPeripheral}; | 8 | use crate::{dma, peripherals, rcc::RccPeripheral}; |
| 9 | pub use _version::*; | 9 | pub use _version::*; |
| 10 | 10 | ||
| 11 | use crate::gpio::Pin; | 11 | use crate::gpio::OptionalPin; |
| 12 | 12 | ||
| 13 | #[derive(Debug)] | 13 | #[derive(Debug)] |
| 14 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 14 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| @@ -53,15 +53,15 @@ pub(crate) mod sealed { | |||
| 53 | fn regs() -> &'static crate::pac::spi::Spi; | 53 | fn regs() -> &'static crate::pac::spi::Spi; |
| 54 | } | 54 | } |
| 55 | 55 | ||
| 56 | pub trait SckPin<T: Instance>: Pin { | 56 | pub trait SckPin<T: Instance>: OptionalPin { |
| 57 | fn af_num(&self) -> u8; | 57 | fn af_num(&self) -> u8; |
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | pub trait MosiPin<T: Instance>: Pin { | 60 | pub trait MosiPin<T: Instance>: OptionalPin { |
| 61 | fn af_num(&self) -> u8; | 61 | fn af_num(&self) -> u8; |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | pub trait MisoPin<T: Instance>: Pin { | 64 | pub trait MisoPin<T: Instance>: OptionalPin { |
| 65 | fn af_num(&self) -> u8; | 65 | fn af_num(&self) -> u8; |
| 66 | } | 66 | } |
| 67 | 67 | ||
diff --git a/embassy-stm32/src/spi/v1.rs b/embassy-stm32/src/spi/v1.rs index 560d99a2f..6f8f8afb6 100644 --- a/embassy-stm32/src/spi/v1.rs +++ b/embassy-stm32/src/spi/v1.rs | |||
| @@ -6,9 +6,10 @@ use crate::gpio::{ | |||
| 6 | AFType::{OutputOpenDrain, OutputPushPull}, | 6 | AFType::{OutputOpenDrain, OutputPushPull}, |
| 7 | Pin, | 7 | Pin, |
| 8 | }, | 8 | }, |
| 9 | AnyPin, | 9 | AnyPin, NoPin, |
| 10 | }; | 10 | }; |
| 11 | use crate::pac::spi; | 11 | use crate::pac::spi; |
| 12 | use crate::peripherals; | ||
| 12 | use crate::spi::{ | 13 | use crate::spi::{ |
| 13 | ByteOrder, Config, Error, Instance, MisoPin, MosiPin, RxDmaChannel, SckPin, TxDmaChannel, | 14 | ByteOrder, Config, Error, Instance, MisoPin, MosiPin, RxDmaChannel, SckPin, TxDmaChannel, |
| 14 | WordSize, | 15 | WordSize, |
| @@ -20,6 +21,7 @@ use core::ptr; | |||
| 20 | use embassy::util::Unborrow; | 21 | use embassy::util::Unborrow; |
| 21 | use embassy_hal_common::unborrow; | 22 | use embassy_hal_common::unborrow; |
| 22 | use embassy_traits::spi as traits; | 23 | use embassy_traits::spi as traits; |
| 24 | pub use embedded_hal::blocking; | ||
| 23 | pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; | 25 | pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; |
| 24 | use futures::future::join3; | 26 | use futures::future::join3; |
| 25 | 27 | ||
| @@ -32,10 +34,29 @@ impl WordSize { | |||
| 32 | } | 34 | } |
| 33 | } | 35 | } |
| 34 | 36 | ||
| 37 | macro_rules! impl_nopin { | ||
| 38 | ($inst:ident, $signal:ident) => { | ||
| 39 | impl $signal<peripherals::$inst> for NoPin {} | ||
| 40 | |||
| 41 | impl super::sealed::$signal<peripherals::$inst> for NoPin { | ||
| 42 | fn af_num(&self) -> u8 { | ||
| 43 | 0 | ||
| 44 | } | ||
| 45 | } | ||
| 46 | }; | ||
| 47 | } | ||
| 48 | crate::pac::peripherals!( | ||
| 49 | (spi, $inst:ident) => { | ||
| 50 | impl_nopin!($inst, SckPin); | ||
| 51 | impl_nopin!($inst, MosiPin); | ||
| 52 | impl_nopin!($inst, MisoPin); | ||
| 53 | }; | ||
| 54 | ); | ||
| 55 | |||
| 35 | pub struct Spi<'d, T: Instance, Tx, Rx> { | 56 | pub struct Spi<'d, T: Instance, Tx, Rx> { |
| 36 | sck: AnyPin, | 57 | sck: Option<AnyPin>, |
| 37 | mosi: AnyPin, | 58 | mosi: Option<AnyPin>, |
| 38 | miso: AnyPin, | 59 | miso: Option<AnyPin>, |
| 39 | txdma: Tx, | 60 | txdma: Tx, |
| 40 | rxdma: Rx, | 61 | rxdma: Rx, |
| 41 | current_word_size: WordSize, | 62 | current_word_size: WordSize, |
| @@ -58,16 +79,19 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | |||
| 58 | { | 79 | { |
| 59 | unborrow!(sck, mosi, miso, txdma, rxdma); | 80 | unborrow!(sck, mosi, miso, txdma, rxdma); |
| 60 | 81 | ||
| 82 | let sck_af = sck.af_num(); | ||
| 83 | let mosi_af = mosi.af_num(); | ||
| 84 | let miso_af = miso.af_num(); | ||
| 85 | let sck = sck.degrade_optional(); | ||
| 86 | let mosi = mosi.degrade_optional(); | ||
| 87 | let miso = miso.degrade_optional(); | ||
| 88 | |||
| 61 | unsafe { | 89 | unsafe { |
| 62 | sck.set_as_af(sck.af_num(), OutputPushPull); | 90 | sck.as_ref().map(|x| x.set_as_af(sck_af, OutputPushPull)); |
| 63 | mosi.set_as_af(mosi.af_num(), OutputPushPull); | 91 | mosi.as_ref().map(|x| x.set_as_af(mosi_af, OutputPushPull)); |
| 64 | miso.set_as_af(miso.af_num(), OutputOpenDrain); | 92 | miso.as_ref().map(|x| x.set_as_af(miso_af, OutputOpenDrain)); |
| 65 | } | 93 | } |
| 66 | 94 | ||
| 67 | let sck = sck.degrade(); | ||
| 68 | let mosi = mosi.degrade(); | ||
| 69 | let miso = miso.degrade(); | ||
| 70 | |||
| 71 | unsafe { | 95 | unsafe { |
| 72 | T::regs().cr2().modify(|w| { | 96 | T::regs().cr2().modify(|w| { |
| 73 | w.set_ssoe(false); | 97 | w.set_ssoe(false); |
| @@ -103,6 +127,9 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | |||
| 103 | w.set_ssm(true); | 127 | w.set_ssm(true); |
| 104 | w.set_crcen(false); | 128 | w.set_crcen(false); |
| 105 | w.set_bidimode(spi::vals::Bidimode::UNIDIRECTIONAL); | 129 | w.set_bidimode(spi::vals::Bidimode::UNIDIRECTIONAL); |
| 130 | if mosi.is_none() { | ||
| 131 | w.set_rxonly(spi::vals::Rxonly::OUTPUTDISABLED); | ||
| 132 | } | ||
| 106 | w.set_dff(WordSize::EightBit.dff()) | 133 | w.set_dff(WordSize::EightBit.dff()) |
| 107 | }); | 134 | }); |
| 108 | } | 135 | } |
| @@ -294,9 +321,9 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | |||
| 294 | impl<'d, T: Instance, Tx, Rx> Drop for Spi<'d, T, Tx, Rx> { | 321 | impl<'d, T: Instance, Tx, Rx> Drop for Spi<'d, T, Tx, Rx> { |
| 295 | fn drop(&mut self) { | 322 | fn drop(&mut self) { |
| 296 | unsafe { | 323 | unsafe { |
| 297 | self.sck.set_as_analog(); | 324 | self.sck.as_ref().map(|x| x.set_as_analog()); |
| 298 | self.mosi.set_as_analog(); | 325 | self.mosi.as_ref().map(|x| x.set_as_analog()); |
| 299 | self.miso.set_as_analog(); | 326 | self.miso.as_ref().map(|x| x.set_as_analog()); |
| 300 | } | 327 | } |
| 301 | } | 328 | } |
| 302 | } | 329 | } |
diff --git a/embassy-stm32/src/spi/v2.rs b/embassy-stm32/src/spi/v2.rs index 9df71ef25..cb871a9a0 100644 --- a/embassy-stm32/src/spi/v2.rs +++ b/embassy-stm32/src/spi/v2.rs | |||
| @@ -36,9 +36,9 @@ impl WordSize { | |||
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | pub struct Spi<'d, T: Instance, Tx, Rx> { | 38 | pub struct Spi<'d, T: Instance, Tx, Rx> { |
| 39 | sck: AnyPin, | 39 | sck: Option<AnyPin>, |
| 40 | mosi: AnyPin, | 40 | mosi: Option<AnyPin>, |
| 41 | miso: AnyPin, | 41 | miso: Option<AnyPin>, |
| 42 | txdma: Tx, | 42 | txdma: Tx, |
| 43 | rxdma: Rx, | 43 | rxdma: Rx, |
| 44 | phantom: PhantomData<&'d mut T>, | 44 | phantom: PhantomData<&'d mut T>, |
| @@ -60,16 +60,22 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | |||
| 60 | { | 60 | { |
| 61 | unborrow!(sck, mosi, miso, txdma, rxdma); | 61 | unborrow!(sck, mosi, miso, txdma, rxdma); |
| 62 | 62 | ||
| 63 | let sck_af = sck.af_num(); | ||
| 64 | let mosi_af = mosi.af_num(); | ||
| 65 | let miso_af = miso.af_num(); | ||
| 66 | let sck = sck.degrade_optional(); | ||
| 67 | let mosi = mosi.degrade_optional(); | ||
| 68 | let miso = miso.degrade_optional(); | ||
| 69 | |||
| 63 | unsafe { | 70 | unsafe { |
| 64 | Self::configure_pin(sck.block(), sck.pin() as _, sck.af_num()); | 71 | sck.as_ref() |
| 65 | Self::configure_pin(mosi.block(), mosi.pin() as _, mosi.af_num()); | 72 | .map(|x| Self::configure_pin(x.block(), x.pin() as _, sck_af)); |
| 66 | Self::configure_pin(miso.block(), miso.pin() as _, miso.af_num()); | 73 | sck.as_ref() |
| 74 | .map(|x| Self::configure_pin(x.block(), x.pin() as _, mosi_af)); | ||
| 75 | sck.as_ref() | ||
| 76 | .map(|x| Self::configure_pin(x.block(), x.pin() as _, miso_af)); | ||
| 67 | } | 77 | } |
| 68 | 78 | ||
| 69 | let sck = sck.degrade(); | ||
| 70 | let mosi = mosi.degrade(); | ||
| 71 | let miso = miso.degrade(); | ||
| 72 | |||
| 73 | let pclk = T::frequency(); | 79 | let pclk = T::frequency(); |
| 74 | let freq = freq.into(); | 80 | let freq = freq.into(); |
| 75 | let br = Self::compute_baud_rate(pclk, freq); | 81 | let br = Self::compute_baud_rate(pclk, freq); |
| @@ -307,9 +313,15 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | |||
| 307 | impl<'d, T: Instance, Tx, Rx> Drop for Spi<'d, T, Tx, Rx> { | 313 | impl<'d, T: Instance, Tx, Rx> Drop for Spi<'d, T, Tx, Rx> { |
| 308 | fn drop(&mut self) { | 314 | fn drop(&mut self) { |
| 309 | unsafe { | 315 | unsafe { |
| 310 | Self::unconfigure_pin(self.sck.block(), self.sck.pin() as _); | 316 | self.sck |
| 311 | Self::unconfigure_pin(self.mosi.block(), self.mosi.pin() as _); | 317 | .as_ref() |
| 312 | Self::unconfigure_pin(self.miso.block(), self.miso.pin() as _); | 318 | .map(|x| Self::unconfigure_pin(x.block(), x.pin() as _)); |
| 319 | self.mosi | ||
| 320 | .as_ref() | ||
| 321 | .map(|x| Self::unconfigure_pin(x.block(), x.pin() as _)); | ||
| 322 | self.miso | ||
| 323 | .as_ref() | ||
| 324 | .map(|x| Self::unconfigure_pin(x.block(), x.pin() as _)); | ||
| 313 | } | 325 | } |
| 314 | } | 326 | } |
| 315 | } | 327 | } |
diff --git a/embassy-stm32/src/spi/v3.rs b/embassy-stm32/src/spi/v3.rs index b0e57254e..ef0f123f1 100644 --- a/embassy-stm32/src/spi/v3.rs +++ b/embassy-stm32/src/spi/v3.rs | |||
| @@ -38,9 +38,9 @@ impl WordSize { | |||
| 38 | 38 | ||
| 39 | #[allow(unused)] | 39 | #[allow(unused)] |
| 40 | pub struct Spi<'d, T: Instance, Tx = NoDma, Rx = NoDma> { | 40 | pub struct Spi<'d, T: Instance, Tx = NoDma, Rx = NoDma> { |
| 41 | sck: AnyPin, | 41 | sck: Option<AnyPin>, |
| 42 | mosi: AnyPin, | 42 | mosi: Option<AnyPin>, |
| 43 | miso: AnyPin, | 43 | miso: Option<AnyPin>, |
| 44 | txdma: Tx, | 44 | txdma: Tx, |
| 45 | rxdma: Rx, | 45 | rxdma: Rx, |
| 46 | phantom: PhantomData<&'d mut T>, | 46 | phantom: PhantomData<&'d mut T>, |
| @@ -62,18 +62,24 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | |||
| 62 | { | 62 | { |
| 63 | unborrow!(sck, mosi, miso, txdma, rxdma); | 63 | unborrow!(sck, mosi, miso, txdma, rxdma); |
| 64 | 64 | ||
| 65 | let sck_af = sck.af_num(); | ||
| 66 | let mosi_af = mosi.af_num(); | ||
| 67 | let miso_af = miso.af_num(); | ||
| 68 | let sck = sck.degrade_optional(); | ||
| 69 | let mosi = mosi.degrade_optional(); | ||
| 70 | let miso = miso.degrade_optional(); | ||
| 71 | |||
| 65 | unsafe { | 72 | unsafe { |
| 66 | Self::configure_pin(sck.block(), sck.pin() as _, sck.af_num()); | 73 | sck.as_ref() |
| 67 | //sck.block().otyper().modify(|w| w.set_ot(sck.pin() as _, crate::pac::gpio::vals::Ot::PUSHPULL)); | 74 | .map(|x| Self::configure_pin(x.block(), x.pin() as _, sck_af)); |
| 68 | Self::configure_pin(mosi.block(), mosi.pin() as _, mosi.af_num()); | 75 | //sck.block().otyper().modify(|w| w.set_ot(Pin::pin(sck) as _, crate::pac::gpio::vals::Ot::PUSHPULL)); |
| 69 | //mosi.block().otyper().modify(|w| w.set_ot(mosi.pin() as _, crate::pac::gpio::vals::Ot::PUSHPULL)); | 76 | sck.as_ref() |
| 70 | Self::configure_pin(miso.block(), miso.pin() as _, miso.af_num()); | 77 | .map(|x| Self::configure_pin(x.block(), x.pin() as _, mosi_af)); |
| 78 | //mosi.block().otyper().modify(|w| w.set_ot(Pin::pin(mosi) as _, crate::pac::gpio::vals::Ot::PUSHPULL)); | ||
| 79 | sck.as_ref() | ||
| 80 | .map(|x| Self::configure_pin(x.block(), x.pin() as _, miso_af)); | ||
| 71 | } | 81 | } |
| 72 | 82 | ||
| 73 | let sck = sck.degrade(); | ||
| 74 | let mosi = mosi.degrade(); | ||
| 75 | let miso = miso.degrade(); | ||
| 76 | |||
| 77 | let pclk = T::frequency(); | 83 | let pclk = T::frequency(); |
| 78 | let br = Self::compute_baud_rate(pclk, freq.into()); | 84 | let br = Self::compute_baud_rate(pclk, freq.into()); |
| 79 | unsafe { | 85 | unsafe { |
| @@ -340,9 +346,15 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | |||
| 340 | impl<'d, T: Instance, Tx, Rx> Drop for Spi<'d, T, Tx, Rx> { | 346 | impl<'d, T: Instance, Tx, Rx> Drop for Spi<'d, T, Tx, Rx> { |
| 341 | fn drop(&mut self) { | 347 | fn drop(&mut self) { |
| 342 | unsafe { | 348 | unsafe { |
| 343 | Self::unconfigure_pin(self.sck.block(), self.sck.pin() as _); | 349 | self.sck |
| 344 | Self::unconfigure_pin(self.mosi.block(), self.mosi.pin() as _); | 350 | .as_ref() |
| 345 | Self::unconfigure_pin(self.miso.block(), self.miso.pin() as _); | 351 | .map(|x| Self::unconfigure_pin(x.block(), x.pin() as _)); |
| 352 | self.mosi | ||
| 353 | .as_ref() | ||
| 354 | .map(|x| Self::unconfigure_pin(x.block(), x.pin() as _)); | ||
| 355 | self.miso | ||
| 356 | .as_ref() | ||
| 357 | .map(|x| Self::unconfigure_pin(x.block(), x.pin() as _)); | ||
| 346 | } | 358 | } |
| 347 | } | 359 | } |
| 348 | } | 360 | } |
