aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2021-10-12 01:28:29 +0200
committerGitHub <[email protected]>2021-10-12 01:28:29 +0200
commit3cf130ecfeb7c54cbf0c0509f142c778091e45da (patch)
treeb04e9f1524c9750c9eeabd88216aab4e781dfbd2
parenta7c37d2ff49de0cb002b27c2cf536d8371748485 (diff)
parent43a7226d8b8e5a2dabae8afbaf9e81651b59ca6e (diff)
Merge pull request #413 from topisani/master
feat: Add spi support for STM32F1 variants
-rw-r--r--embassy-stm32/src/can/bxcan.rs6
-rw-r--r--embassy-stm32/src/eth/v2/mod.rs4
-rw-r--r--embassy-stm32/src/gpio.rs45
-rw-r--r--embassy-stm32/src/i2c/mod.rs13
-rw-r--r--embassy-stm32/src/i2c/v1.rs6
-rw-r--r--embassy-stm32/src/spi/mod.rs25
-rw-r--r--embassy-stm32/src/spi/v1.rs93
-rw-r--r--embassy-stm32/src/spi/v2.rs38
-rw-r--r--embassy-stm32/src/spi/v3.rs42
-rw-r--r--embassy-stm32/src/usart/mod.rs40
-rw-r--r--embassy-stm32/src/usart/v1.rs6
-rw-r--r--embassy-stm32/src/usart/v2.rs6
m---------stm32-data0
13 files changed, 238 insertions, 86 deletions
diff --git a/embassy-stm32/src/can/bxcan.rs b/embassy-stm32/src/can/bxcan.rs
index 9e10a8b02..b73b88391 100644
--- a/embassy-stm32/src/can/bxcan.rs
+++ b/embassy-stm32/src/can/bxcan.rs
@@ -5,7 +5,7 @@ use embassy::util::Unborrow;
5use embassy_hal_common::unborrow; 5use embassy_hal_common::unborrow;
6 6
7use crate::gpio::{ 7use crate::gpio::{
8 sealed::OutputType::{OpenDrain, PushPull}, 8 sealed::AFType::{OutputOpenDrain, OutputPushPull},
9 Pin, 9 Pin,
10}; 10};
11use crate::{peripherals, rcc::RccPeripheral}; 11use crate::{peripherals, rcc::RccPeripheral};
@@ -26,8 +26,8 @@ impl<'d, T: Instance + bxcan::Instance> Can<'d, T> {
26 unborrow!(peri, rx, tx); 26 unborrow!(peri, rx, tx);
27 27
28 unsafe { 28 unsafe {
29 rx.set_as_af(rx.af_num(), OpenDrain); 29 rx.set_as_af(rx.af_num(), OutputOpenDrain);
30 tx.set_as_af(tx.af_num(), PushPull); 30 tx.set_as_af(tx.af_num(), OutputPushPull);
31 } 31 }
32 32
33 T::enable(); 33 T::enable();
diff --git a/embassy-stm32/src/eth/v2/mod.rs b/embassy-stm32/src/eth/v2/mod.rs
index 8eb7c3393..001ac3154 100644
--- a/embassy-stm32/src/eth/v2/mod.rs
+++ b/embassy-stm32/src/eth/v2/mod.rs
@@ -10,7 +10,7 @@ use embassy_net::{Device, DeviceCapabilities, LinkState, PacketBuf, MTU};
10 10
11use crate::gpio::sealed::Pin as __GpioPin; 11use crate::gpio::sealed::Pin as __GpioPin;
12use crate::gpio::Pin as GpioPin; 12use crate::gpio::Pin as GpioPin;
13use crate::gpio::{sealed::OutputType::PushPull, AnyPin}; 13use crate::gpio::{sealed::AFType::OutputPushPull, AnyPin};
14use crate::pac::gpio::vals::Ospeedr; 14use crate::pac::gpio::vals::Ospeedr;
15use crate::pac::{ETH, RCC, SYSCFG}; 15use crate::pac::{ETH, RCC, SYSCFG};
16use crate::peripherals; 16use crate::peripherals;
@@ -416,7 +416,7 @@ macro_rules! impl_pin {
416 fn configure(&mut self) { 416 fn configure(&mut self) {
417 // NOTE(unsafe) Exclusive access to the registers 417 // NOTE(unsafe) Exclusive access to the registers
418 critical_section::with(|_| unsafe { 418 critical_section::with(|_| unsafe {
419 self.set_as_af($af, PushPull); 419 self.set_as_af($af, OutputPushPull);
420 self.block() 420 self.block()
421 .ospeedr() 421 .ospeedr()
422 .modify(|w| w.set_ospeedr(self.pin() as usize, Ospeedr::VERYHIGHSPEED)); 422 .modify(|w| w.set_ospeedr(self.pin() as usize, Ospeedr::VERYHIGHSPEED));
diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs
index c7b644e94..246cdb041 100644
--- a/embassy-stm32/src/gpio.rs
+++ b/embassy-stm32/src/gpio.rs
@@ -350,12 +350,13 @@ impl<'d, T: Pin> InputPin for OutputOpenDrain<'d, T> {
350pub(crate) mod sealed { 350pub(crate) mod sealed {
351 use super::*; 351 use super::*;
352 352
353 /// Output type settings 353 /// Alternate function type settings
354 #[derive(Debug)] 354 #[derive(Debug)]
355 #[cfg_attr(feature = "defmt", derive(defmt::Format))] 355 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
356 pub enum OutputType { 356 pub enum AFType {
357 PushPull, 357 Input,
358 OpenDrain, 358 OutputPushPull,
359 OutputOpenDrain,
359 } 360 }
360 361
361 pub trait Pin { 362 pub trait Pin {
@@ -394,21 +395,47 @@ pub(crate) mod sealed {
394 } 395 }
395 396
396 #[cfg(gpio_v1)] 397 #[cfg(gpio_v1)]
397 unsafe fn set_as_af(&self, _af_num: u8, _af_type: OutputType) { 398 unsafe fn set_as_af(&self, _af_num: u8, af_type: AFType) {
398 panic!("F1 alternate GPIO functions not supported yet!"); 399 // F1 uses the AFIO register for remapping.
400 // For now, this is not implemented, so af_num is ignored
401 // _af_num should be zero here, since it is not set by stm32-data
402 let r = self.block();
403 let n = self._pin() as usize;
404 let crlh = if n < 8 { 0 } else { 1 };
405 match af_type {
406 AFType::Input => {
407 r.cr(crlh).modify(|w| {
408 w.set_mode(n % 8, vals::Mode::INPUT);
409 w.set_cnf(n % 8, vals::Cnf::PUSHPULL);
410 });
411 }
412 AFType::OutputPushPull => {
413 r.cr(crlh).modify(|w| {
414 w.set_mode(n % 8, vals::Mode::OUTPUT50);
415 w.set_cnf(n % 8, vals::Cnf::ALTPUSHPULL);
416 });
417 }
418 AFType::OutputOpenDrain => {
419 r.cr(crlh).modify(|w| {
420 w.set_mode(n % 8, vals::Mode::OUTPUT50);
421 w.set_cnf(n % 8, vals::Cnf::ALTOPENDRAIN);
422 });
423 }
424 }
399 } 425 }
400 #[cfg(gpio_v2)] 426 #[cfg(gpio_v2)]
401 unsafe fn set_as_af(&self, af_num: u8, af_type: OutputType) { 427 unsafe fn set_as_af(&self, af_num: u8, af_type: AFType) {
402 let pin = self._pin() as usize; 428 let pin = self._pin() as usize;
403 let block = self.block(); 429 let block = self.block();
404 block 430 block
405 .afr(pin / 8) 431 .afr(pin / 8)
406 .modify(|w| w.set_afr(pin % 8, vals::Afr(af_num))); 432 .modify(|w| w.set_afr(pin % 8, vals::Afr(af_num)));
407 match af_type { 433 match af_type {
408 OutputType::PushPull => { 434 AFType::Input => {}
435 AFType::OutputPushPull => {
409 block.otyper().modify(|w| w.set_ot(pin, vals::Ot::PUSHPULL)) 436 block.otyper().modify(|w| w.set_ot(pin, vals::Ot::PUSHPULL))
410 } 437 }
411 OutputType::OpenDrain => block 438 AFType::OutputOpenDrain => block
412 .otyper() 439 .otyper()
413 .modify(|w| w.set_ot(pin, vals::Ot::OPENDRAIN)), 440 .modify(|w| w.set_ot(pin, vals::Ot::OPENDRAIN)),
414 } 441 }
diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs
index 4af5051db..e922fe429 100644
--- a/embassy-stm32/src/i2c/mod.rs
+++ b/embassy-stm32/src/i2c/mod.rs
@@ -96,7 +96,6 @@ crate::pac::interrupts!(
96 }; 96 };
97); 97);
98 98
99#[cfg(not(rcc_f1))]
100macro_rules! impl_pin { 99macro_rules! impl_pin {
101 ($inst:ident, $pin:ident, $signal:ident, $af:expr) => { 100 ($inst:ident, $pin:ident, $signal:ident, $af:expr) => {
102 impl $signal<peripherals::$inst> for peripherals::$pin {} 101 impl $signal<peripherals::$inst> for peripherals::$pin {}
@@ -109,6 +108,7 @@ macro_rules! impl_pin {
109 }; 108 };
110} 109}
111 110
111#[cfg(not(rcc_f1))]
112crate::pac::peripheral_pins!( 112crate::pac::peripheral_pins!(
113 ($inst:ident, i2c, I2C, $pin:ident, SDA, $af:expr) => { 113 ($inst:ident, i2c, I2C, $pin:ident, SDA, $af:expr) => {
114 impl_pin!($inst, $pin, SdaPin, $af); 114 impl_pin!($inst, $pin, SdaPin, $af);
@@ -119,6 +119,17 @@ crate::pac::peripheral_pins!(
119 }; 119 };
120); 120);
121 121
122#[cfg(rcc_f1)]
123crate::pac::peripheral_pins!(
124 ($inst:ident, i2c, I2C, $pin:ident, SDA) => {
125 impl_pin!($inst, $pin, SdaPin, 0);
126 };
127
128 ($inst:ident, i2c, I2C, $pin:ident, SCL) => {
129 impl_pin!($inst, $pin, SclPin, 0);
130 };
131);
132
122macro_rules! impl_dma { 133macro_rules! impl_dma {
123 ($inst:ident, {dmamux: $dmamux:ident}, $signal:ident, $request:expr) => { 134 ($inst:ident, {dmamux: $dmamux:ident}, $signal:ident, $request:expr) => {
124 impl<T> sealed::$signal<peripherals::$inst> for T 135 impl<T> sealed::$signal<peripherals::$inst> for T
diff --git a/embassy-stm32/src/i2c/v1.rs b/embassy-stm32/src/i2c/v1.rs
index c5d5dee0c..6fa269fc2 100644
--- a/embassy-stm32/src/i2c/v1.rs
+++ b/embassy-stm32/src/i2c/v1.rs
@@ -9,7 +9,7 @@ use embedded_hal::blocking::i2c::WriteRead;
9 9
10use crate::pac::i2c; 10use crate::pac::i2c;
11 11
12use crate::gpio::sealed::OutputType::OpenDrain; 12use crate::gpio::sealed::AFType::OutputOpenDrain;
13 13
14pub struct I2c<'d, T: Instance> { 14pub struct I2c<'d, T: Instance> {
15 phantom: PhantomData<&'d mut T>, 15 phantom: PhantomData<&'d mut T>,
@@ -30,8 +30,8 @@ impl<'d, T: Instance> I2c<'d, T> {
30 T::enable(); 30 T::enable();
31 31
32 unsafe { 32 unsafe {
33 scl.set_as_af(scl.af_num(), OpenDrain); 33 scl.set_as_af(scl.af_num(), OutputOpenDrain);
34 sda.set_as_af(sda.af_num(), OpenDrain); 34 sda.set_as_af(sda.af_num(), OutputOpenDrain);
35 } 35 }
36 36
37 unsafe { 37 unsafe {
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs
index 6249de84e..e881a5235 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_f1, path = "v1.rs")]
4#[cfg_attr(spi_v2, path = "v2.rs")] 5#[cfg_attr(spi_v2, path = "v2.rs")]
5#[cfg_attr(spi_v3, path = "v3.rs")] 6#[cfg_attr(spi_v3, path = "v3.rs")]
6mod _version; 7mod _version;
7use crate::{dma, peripherals, rcc::RccPeripheral}; 8use crate::{dma, peripherals, rcc::RccPeripheral};
8pub use _version::*; 9pub use _version::*;
9 10
10use crate::gpio::Pin; 11use crate::gpio::OptionalPin;
11 12
12#[derive(Debug)] 13#[derive(Debug)]
13#[cfg_attr(feature = "defmt", derive(defmt::Format))] 14#[cfg_attr(feature = "defmt", derive(defmt::Format))]
@@ -52,15 +53,15 @@ pub(crate) mod sealed {
52 fn regs() -> &'static crate::pac::spi::Spi; 53 fn regs() -> &'static crate::pac::spi::Spi;
53 } 54 }
54 55
55 pub trait SckPin<T: Instance>: Pin { 56 pub trait SckPin<T: Instance>: OptionalPin {
56 fn af_num(&self) -> u8; 57 fn af_num(&self) -> u8;
57 } 58 }
58 59
59 pub trait MosiPin<T: Instance>: Pin { 60 pub trait MosiPin<T: Instance>: OptionalPin {
60 fn af_num(&self) -> u8; 61 fn af_num(&self) -> u8;
61 } 62 }
62 63
63 pub trait MisoPin<T: Instance>: Pin { 64 pub trait MisoPin<T: Instance>: OptionalPin {
64 fn af_num(&self) -> u8; 65 fn af_num(&self) -> u8;
65 } 66 }
66 67
@@ -104,6 +105,7 @@ macro_rules! impl_pin {
104 }; 105 };
105} 106}
106 107
108#[cfg(not(rcc_f1))]
107crate::pac::peripheral_pins!( 109crate::pac::peripheral_pins!(
108 ($inst:ident, spi, SPI, $pin:ident, SCK, $af:expr) => { 110 ($inst:ident, spi, SPI, $pin:ident, SCK, $af:expr) => {
109 impl_pin!($inst, $pin, SckPin, $af); 111 impl_pin!($inst, $pin, SckPin, $af);
@@ -118,6 +120,21 @@ crate::pac::peripheral_pins!(
118 }; 120 };
119); 121);
120 122
123#[cfg(rcc_f1)]
124crate::pac::peripheral_pins!(
125 ($inst:ident, spi, SPI, $pin:ident, SCK) => {
126 impl_pin!($inst, $pin, SckPin, 0);
127 };
128
129 ($inst:ident, spi, SPI, $pin:ident, MOSI) => {
130 impl_pin!($inst, $pin, MosiPin, 0);
131 };
132
133 ($inst:ident, spi, SPI, $pin:ident, MISO) => {
134 impl_pin!($inst, $pin, MisoPin, 0);
135 };
136);
137
121macro_rules! impl_dma { 138macro_rules! impl_dma {
122 ($inst:ident, {dmamux: $dmamux:ident}, $signal:ident, $request:expr) => { 139 ($inst:ident, {dmamux: $dmamux:ident}, $signal:ident, $request:expr) => {
123 impl<T> sealed::$signal<peripherals::$inst> for T 140 impl<T> sealed::$signal<peripherals::$inst> for T
diff --git a/embassy-stm32/src/spi/v1.rs b/embassy-stm32/src/spi/v1.rs
index 53d8252e6..b727f2008 100644
--- a/embassy-stm32/src/spi/v1.rs
+++ b/embassy-stm32/src/spi/v1.rs
@@ -1,14 +1,11 @@
1#![macro_use] 1#![macro_use]
2 2
3use crate::dma::NoDma; 3use crate::dma::NoDma;
4use crate::gpio::{ 4use crate::gpio::sealed::AFType;
5 sealed::{ 5use crate::gpio::sealed::Pin;
6 OutputType::{OpenDrain, PushPull}, 6use crate::gpio::{AnyPin, NoPin};
7 Pin,
8 },
9 AnyPin,
10};
11use crate::pac::spi; 7use crate::pac::spi;
8use crate::peripherals;
12use crate::spi::{ 9use crate::spi::{
13 ByteOrder, Config, Error, Instance, MisoPin, MosiPin, RxDmaChannel, SckPin, TxDmaChannel, 10 ByteOrder, Config, Error, Instance, MisoPin, MosiPin, RxDmaChannel, SckPin, TxDmaChannel,
14 WordSize, 11 WordSize,
@@ -20,6 +17,7 @@ use core::ptr;
20use embassy::util::Unborrow; 17use embassy::util::Unborrow;
21use embassy_hal_common::unborrow; 18use embassy_hal_common::unborrow;
22use embassy_traits::spi as traits; 19use embassy_traits::spi as traits;
20pub use embedded_hal::blocking;
23pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; 21pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
24use futures::future::join3; 22use futures::future::join3;
25 23
@@ -32,10 +30,29 @@ impl WordSize {
32 } 30 }
33} 31}
34 32
33macro_rules! impl_nopin {
34 ($inst:ident, $signal:ident) => {
35 impl $signal<peripherals::$inst> for NoPin {}
36
37 impl super::sealed::$signal<peripherals::$inst> for NoPin {
38 fn af_num(&self) -> u8 {
39 0
40 }
41 }
42 };
43}
44crate::pac::peripherals!(
45 (spi, $inst:ident) => {
46 impl_nopin!($inst, SckPin);
47 impl_nopin!($inst, MosiPin);
48 impl_nopin!($inst, MisoPin);
49 };
50);
51
35pub struct Spi<'d, T: Instance, Tx, Rx> { 52pub struct Spi<'d, T: Instance, Tx, Rx> {
36 sck: AnyPin, 53 sck: Option<AnyPin>,
37 mosi: AnyPin, 54 mosi: Option<AnyPin>,
38 miso: AnyPin, 55 miso: Option<AnyPin>,
39 txdma: Tx, 56 txdma: Tx,
40 rxdma: Rx, 57 rxdma: Rx,
41 current_word_size: WordSize, 58 current_word_size: WordSize,
@@ -58,16 +75,21 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
58 { 75 {
59 unborrow!(sck, mosi, miso, txdma, rxdma); 76 unborrow!(sck, mosi, miso, txdma, rxdma);
60 77
78 let sck_af = sck.af_num();
79 let mosi_af = mosi.af_num();
80 let miso_af = miso.af_num();
81 let sck = sck.degrade_optional();
82 let mosi = mosi.degrade_optional();
83 let miso = miso.degrade_optional();
84
61 unsafe { 85 unsafe {
62 sck.set_as_af(sck.af_num(), PushPull); 86 sck.as_ref()
63 mosi.set_as_af(mosi.af_num(), PushPull); 87 .map(|x| x.set_as_af(sck_af, AFType::OutputPushPull));
64 miso.set_as_af(miso.af_num(), OpenDrain); 88 mosi.as_ref()
89 .map(|x| x.set_as_af(mosi_af, AFType::OutputPushPull));
90 miso.as_ref().map(|x| x.set_as_af(miso_af, AFType::Input));
65 } 91 }
66 92
67 let sck = sck.degrade();
68 let mosi = mosi.degrade();
69 let miso = miso.degrade();
70
71 unsafe { 93 unsafe {
72 T::regs().cr2().modify(|w| { 94 T::regs().cr2().modify(|w| {
73 w.set_ssoe(false); 95 w.set_ssoe(false);
@@ -103,6 +125,9 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
103 w.set_ssm(true); 125 w.set_ssm(true);
104 w.set_crcen(false); 126 w.set_crcen(false);
105 w.set_bidimode(spi::vals::Bidimode::UNIDIRECTIONAL); 127 w.set_bidimode(spi::vals::Bidimode::UNIDIRECTIONAL);
128 if mosi.is_none() {
129 w.set_rxonly(spi::vals::Rxonly::OUTPUTDISABLED);
130 }
106 w.set_dff(WordSize::EightBit.dff()) 131 w.set_dff(WordSize::EightBit.dff())
107 }); 132 });
108 } 133 }
@@ -294,9 +319,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> { 319impl<'d, T: Instance, Tx, Rx> Drop for Spi<'d, T, Tx, Rx> {
295 fn drop(&mut self) { 320 fn drop(&mut self) {
296 unsafe { 321 unsafe {
297 self.sck.set_as_analog(); 322 self.sck.as_ref().map(|x| x.set_as_analog());
298 self.mosi.set_as_analog(); 323 self.mosi.as_ref().map(|x| x.set_as_analog());
299 self.miso.set_as_analog(); 324 self.miso.as_ref().map(|x| x.set_as_analog());
300 } 325 }
301 } 326 }
302} 327}
@@ -414,13 +439,18 @@ fn write_word<W: Word>(regs: &'static crate::pac::spi::Spi, word: W) -> Result<(
414 let sr = unsafe { regs.sr().read() }; 439 let sr = unsafe { regs.sr().read() };
415 if sr.ovr() { 440 if sr.ovr() {
416 return Err(Error::Overrun); 441 return Err(Error::Overrun);
417 } else if sr.fre() { 442 }
443 #[cfg(not(spi_f1))]
444 if sr.fre() {
418 return Err(Error::Framing); 445 return Err(Error::Framing);
419 } else if sr.modf() { 446 }
447 if sr.modf() {
420 return Err(Error::ModeFault); 448 return Err(Error::ModeFault);
421 } else if sr.crcerr() { 449 }
450 if sr.crcerr() {
422 return Err(Error::Crc); 451 return Err(Error::Crc);
423 } else if sr.txe() { 452 }
453 if sr.txe() {
424 unsafe { 454 unsafe {
425 let dr = regs.dr().ptr() as *mut W; 455 let dr = regs.dr().ptr() as *mut W;
426 ptr::write_volatile(dr, word); 456 ptr::write_volatile(dr, word);
@@ -436,13 +466,18 @@ fn read_word<W: Word>(regs: &'static crate::pac::spi::Spi) -> Result<W, Error> {
436 let sr = unsafe { regs.sr().read() }; 466 let sr = unsafe { regs.sr().read() };
437 if sr.ovr() { 467 if sr.ovr() {
438 return Err(Error::Overrun); 468 return Err(Error::Overrun);
439 } else if sr.modf() { 469 }
440 return Err(Error::ModeFault); 470 #[cfg(not(spi_f1))]
441 } else if sr.fre() { 471 if sr.fre() {
442 return Err(Error::Framing); 472 return Err(Error::Framing);
443 } else if sr.crcerr() { 473 }
474 if sr.modf() {
475 return Err(Error::ModeFault);
476 }
477 if sr.crcerr() {
444 return Err(Error::Crc); 478 return Err(Error::Crc);
445 } else if sr.rxne() { 479 }
480 if sr.rxne() {
446 unsafe { 481 unsafe {
447 let dr = regs.dr().ptr() as *const W; 482 let dr = regs.dr().ptr() as *const W;
448 return Ok(ptr::read_volatile(dr)); 483 return Ok(ptr::read_volatile(dr));
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}
diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs
index e64f8d1d9..a6955729d 100644
--- a/embassy-stm32/src/usart/mod.rs
+++ b/embassy-stm32/src/usart/mod.rs
@@ -127,7 +127,6 @@ crate::pac::interrupts!(
127 }; 127 };
128); 128);
129 129
130#[cfg(not(rcc_f1))]
131macro_rules! impl_pin { 130macro_rules! impl_pin {
132 ($inst:ident, $pin:ident, $signal:ident, $af:expr) => { 131 ($inst:ident, $pin:ident, $signal:ident, $af:expr) => {
133 impl sealed::$signal<peripherals::$inst> for peripherals::$pin { 132 impl sealed::$signal<peripherals::$inst> for peripherals::$pin {
@@ -140,6 +139,7 @@ macro_rules! impl_pin {
140 }; 139 };
141} 140}
142 141
142#[cfg(not(rcc_f1))]
143crate::pac::peripheral_pins!( 143crate::pac::peripheral_pins!(
144 144
145 // USART 145 // USART
@@ -177,6 +177,44 @@ crate::pac::peripheral_pins!(
177 }; 177 };
178); 178);
179 179
180#[cfg(rcc_f1)]
181crate::pac::peripheral_pins!(
182
183 // USART
184 ($inst:ident, usart, USART, $pin:ident, TX) => {
185 impl_pin!($inst, $pin, TxPin, 0);
186 };
187 ($inst:ident, usart, USART, $pin:ident, RX) => {
188 impl_pin!($inst, $pin, RxPin, 0);
189 };
190 ($inst:ident, usart, USART, $pin:ident, CTS) => {
191 impl_pin!($inst, $pin, CtsPin, 0);
192 };
193 ($inst:ident, usart, USART, $pin:ident, RTS) => {
194 impl_pin!($inst, $pin, RtsPin, 0);
195 };
196 ($inst:ident, usart, USART, $pin:ident, CK) => {
197 impl_pin!($inst, $pin, CkPin, 0);
198 };
199
200 // UART
201 ($inst:ident, uart, UART, $pin:ident, TX) => {
202 impl_pin!($inst, $pin, TxPin, 0);
203 };
204 ($inst:ident, uart, UART, $pin:ident, RX) => {
205 impl_pin!($inst, $pin, RxPin, 0);
206 };
207 ($inst:ident, uart, UART, $pin:ident, CTS) => {
208 impl_pin!($inst, $pin, CtsPin, 0);
209 };
210 ($inst:ident, uart, UART, $pin:ident, RTS) => {
211 impl_pin!($inst, $pin, RtsPin, 0);
212 };
213 ($inst:ident, uart, UART, $pin:ident, CK) => {
214 impl_pin!($inst, $pin, CkPin, 0);
215 };
216);
217
180macro_rules! impl_dma { 218macro_rules! impl_dma {
181 ($inst:ident, {dmamux: $dmamux:ident}, $signal:ident, $request:expr) => { 219 ($inst:ident, {dmamux: $dmamux:ident}, $signal:ident, $request:expr) => {
182 impl<T> sealed::$signal<peripherals::$inst> for T 220 impl<T> sealed::$signal<peripherals::$inst> for T
diff --git a/embassy-stm32/src/usart/v1.rs b/embassy-stm32/src/usart/v1.rs
index d1dd68305..8cd392d18 100644
--- a/embassy-stm32/src/usart/v1.rs
+++ b/embassy-stm32/src/usart/v1.rs
@@ -1,4 +1,4 @@
1use crate::gpio::sealed::OutputType::{OpenDrain, PushPull}; 1use crate::gpio::sealed::AFType::{OutputOpenDrain, OutputPushPull};
2use core::future::Future; 2use core::future::Future;
3use core::marker::PhantomData; 3use core::marker::PhantomData;
4use embassy::util::Unborrow; 4use embassy::util::Unborrow;
@@ -37,8 +37,8 @@ impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
37 let r = inner.regs(); 37 let r = inner.regs();
38 38
39 unsafe { 39 unsafe {
40 rx.set_as_af(rx.af_num(), OpenDrain); 40 rx.set_as_af(rx.af_num(), OutputOpenDrain);
41 tx.set_as_af(tx.af_num(), PushPull); 41 tx.set_as_af(tx.af_num(), OutputPushPull);
42 42
43 r.brr().write_value(regs::Brr(div)); 43 r.brr().write_value(regs::Brr(div));
44 r.cr1().write(|w| { 44 r.cr1().write(|w| {
diff --git a/embassy-stm32/src/usart/v2.rs b/embassy-stm32/src/usart/v2.rs
index 5e6696351..e6e5f69db 100644
--- a/embassy-stm32/src/usart/v2.rs
+++ b/embassy-stm32/src/usart/v2.rs
@@ -13,7 +13,7 @@ use futures::TryFutureExt;
13 13
14use super::*; 14use super::*;
15use crate::dma::NoDma; 15use crate::dma::NoDma;
16use crate::gpio::sealed::OutputType::{OpenDrain, PushPull}; 16use crate::gpio::sealed::AFType::{OutputOpenDrain, OutputPushPull};
17use crate::pac::usart::{regs, vals}; 17use crate::pac::usart::{regs, vals};
18 18
19pub struct Uart<'d, T: Instance, TxDma = NoDma, RxDma = NoDma> { 19pub struct Uart<'d, T: Instance, TxDma = NoDma, RxDma = NoDma> {
@@ -43,8 +43,8 @@ impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
43 let r = inner.regs(); 43 let r = inner.regs();
44 44
45 unsafe { 45 unsafe {
46 rx.set_as_af(rx.af_num(), OpenDrain); 46 rx.set_as_af(rx.af_num(), OutputOpenDrain);
47 tx.set_as_af(tx.af_num(), PushPull); 47 tx.set_as_af(tx.af_num(), OutputPushPull);
48 48
49 r.cr2().write(|_w| {}); 49 r.cr2().write(|_w| {});
50 r.cr3().write(|_w| {}); 50 r.cr3().write(|_w| {});
diff --git a/stm32-data b/stm32-data
Subproject e78ea6f05058dc1eff1dd4a4f07227d502a3b65 Subproject bae2d34445f87e7b9a88b683c789c5d0c7560fb