aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/spi/mod.rs8
-rw-r--r--embassy-stm32/src/spi/v1.rs55
-rw-r--r--embassy-stm32/src/spi/v2.rs38
-rw-r--r--embassy-stm32/src/spi/v3.rs42
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;
8use crate::{dma, peripherals, rcc::RccPeripheral}; 8use crate::{dma, peripherals, rcc::RccPeripheral};
9pub use _version::*; 9pub use _version::*;
10 10
11use crate::gpio::Pin; 11use 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};
11use crate::pac::spi; 11use crate::pac::spi;
12use crate::peripherals;
12use crate::spi::{ 13use 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;
20use embassy::util::Unborrow; 21use embassy::util::Unborrow;
21use embassy_hal_common::unborrow; 22use embassy_hal_common::unborrow;
22use embassy_traits::spi as traits; 23use embassy_traits::spi as traits;
24pub use embedded_hal::blocking;
23pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; 25pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
24use futures::future::join3; 26use futures::future::join3;
25 27
@@ -32,10 +34,29 @@ impl WordSize {
32 } 34 }
33} 35}
34 36
37macro_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}
48crate::pac::peripherals!(
49 (spi, $inst:ident) => {
50 impl_nopin!($inst, SckPin);
51 impl_nopin!($inst, MosiPin);
52 impl_nopin!($inst, MisoPin);
53 };
54);
55
35pub struct Spi<'d, T: Instance, Tx, Rx> { 56pub 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> {
294impl<'d, T: Instance, Tx, Rx> Drop for Spi<'d, T, Tx, Rx> { 321impl<'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
38pub struct Spi<'d, T: Instance, Tx, Rx> { 38pub 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> {
307impl<'d, T: Instance, Tx, Rx> Drop for Spi<'d, T, Tx, Rx> { 313impl<'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)]
40pub struct Spi<'d, T: Instance, Tx = NoDma, Rx = NoDma> { 40pub 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> {
340impl<'d, T: Instance, Tx, Rx> Drop for Spi<'d, T, Tx, Rx> { 346impl<'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}