diff options
| -rw-r--r-- | embassy-stm32/src/can/bxcan.rs | 6 | ||||
| -rw-r--r-- | embassy-stm32/src/eth/v2/mod.rs | 4 | ||||
| -rw-r--r-- | embassy-stm32/src/gpio.rs | 45 | ||||
| -rw-r--r-- | embassy-stm32/src/i2c/mod.rs | 13 | ||||
| -rw-r--r-- | embassy-stm32/src/i2c/v1.rs | 6 | ||||
| -rw-r--r-- | embassy-stm32/src/spi/mod.rs | 25 | ||||
| -rw-r--r-- | embassy-stm32/src/spi/v1.rs | 93 | ||||
| -rw-r--r-- | embassy-stm32/src/spi/v2.rs | 38 | ||||
| -rw-r--r-- | embassy-stm32/src/spi/v3.rs | 42 | ||||
| -rw-r--r-- | embassy-stm32/src/usart/mod.rs | 40 | ||||
| -rw-r--r-- | embassy-stm32/src/usart/v1.rs | 6 | ||||
| -rw-r--r-- | embassy-stm32/src/usart/v2.rs | 6 | ||||
| m--------- | stm32-data | 0 |
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; | |||
| 5 | use embassy_hal_common::unborrow; | 5 | use embassy_hal_common::unborrow; |
| 6 | 6 | ||
| 7 | use crate::gpio::{ | 7 | use crate::gpio::{ |
| 8 | sealed::OutputType::{OpenDrain, PushPull}, | 8 | sealed::AFType::{OutputOpenDrain, OutputPushPull}, |
| 9 | Pin, | 9 | Pin, |
| 10 | }; | 10 | }; |
| 11 | use crate::{peripherals, rcc::RccPeripheral}; | 11 | use 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 | ||
| 11 | use crate::gpio::sealed::Pin as __GpioPin; | 11 | use crate::gpio::sealed::Pin as __GpioPin; |
| 12 | use crate::gpio::Pin as GpioPin; | 12 | use crate::gpio::Pin as GpioPin; |
| 13 | use crate::gpio::{sealed::OutputType::PushPull, AnyPin}; | 13 | use crate::gpio::{sealed::AFType::OutputPushPull, AnyPin}; |
| 14 | use crate::pac::gpio::vals::Ospeedr; | 14 | use crate::pac::gpio::vals::Ospeedr; |
| 15 | use crate::pac::{ETH, RCC, SYSCFG}; | 15 | use crate::pac::{ETH, RCC, SYSCFG}; |
| 16 | use crate::peripherals; | 16 | use 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> { | |||
| 350 | pub(crate) mod sealed { | 350 | pub(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))] | ||
| 100 | macro_rules! impl_pin { | 99 | macro_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))] | ||
| 112 | crate::pac::peripheral_pins!( | 112 | crate::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)] | ||
| 123 | crate::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 | |||
| 122 | macro_rules! impl_dma { | 133 | macro_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 | ||
| 10 | use crate::pac::i2c; | 10 | use crate::pac::i2c; |
| 11 | 11 | ||
| 12 | use crate::gpio::sealed::OutputType::OpenDrain; | 12 | use crate::gpio::sealed::AFType::OutputOpenDrain; |
| 13 | 13 | ||
| 14 | pub struct I2c<'d, T: Instance> { | 14 | pub 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")] |
| 6 | mod _version; | 7 | mod _version; |
| 7 | use crate::{dma, peripherals, rcc::RccPeripheral}; | 8 | use crate::{dma, peripherals, rcc::RccPeripheral}; |
| 8 | pub use _version::*; | 9 | pub use _version::*; |
| 9 | 10 | ||
| 10 | use crate::gpio::Pin; | 11 | use 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))] | ||
| 107 | crate::pac::peripheral_pins!( | 109 | crate::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)] | ||
| 124 | crate::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 | |||
| 121 | macro_rules! impl_dma { | 138 | macro_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 | ||
| 3 | use crate::dma::NoDma; | 3 | use crate::dma::NoDma; |
| 4 | use crate::gpio::{ | 4 | use crate::gpio::sealed::AFType; |
| 5 | sealed::{ | 5 | use crate::gpio::sealed::Pin; |
| 6 | OutputType::{OpenDrain, PushPull}, | 6 | use crate::gpio::{AnyPin, NoPin}; |
| 7 | Pin, | ||
| 8 | }, | ||
| 9 | AnyPin, | ||
| 10 | }; | ||
| 11 | use crate::pac::spi; | 7 | use crate::pac::spi; |
| 8 | use crate::peripherals; | ||
| 12 | use crate::spi::{ | 9 | use 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; | |||
| 20 | use embassy::util::Unborrow; | 17 | use embassy::util::Unborrow; |
| 21 | use embassy_hal_common::unborrow; | 18 | use embassy_hal_common::unborrow; |
| 22 | use embassy_traits::spi as traits; | 19 | use embassy_traits::spi as traits; |
| 20 | pub use embedded_hal::blocking; | ||
| 23 | pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; | 21 | pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; |
| 24 | use futures::future::join3; | 22 | use futures::future::join3; |
| 25 | 23 | ||
| @@ -32,10 +30,29 @@ impl WordSize { | |||
| 32 | } | 30 | } |
| 33 | } | 31 | } |
| 34 | 32 | ||
| 33 | macro_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 | } | ||
| 44 | crate::pac::peripherals!( | ||
| 45 | (spi, $inst:ident) => { | ||
| 46 | impl_nopin!($inst, SckPin); | ||
| 47 | impl_nopin!($inst, MosiPin); | ||
| 48 | impl_nopin!($inst, MisoPin); | ||
| 49 | }; | ||
| 50 | ); | ||
| 51 | |||
| 35 | pub struct Spi<'d, T: Instance, Tx, Rx> { | 52 | pub 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> { | |||
| 294 | impl<'d, T: Instance, Tx, Rx> Drop for Spi<'d, T, Tx, Rx> { | 319 | impl<'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 | ||
| 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 | } |
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))] | ||
| 131 | macro_rules! impl_pin { | 130 | macro_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))] | ||
| 143 | crate::pac::peripheral_pins!( | 143 | crate::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)] | ||
| 181 | crate::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 | |||
| 180 | macro_rules! impl_dma { | 218 | macro_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 @@ | |||
| 1 | use crate::gpio::sealed::OutputType::{OpenDrain, PushPull}; | 1 | use crate::gpio::sealed::AFType::{OutputOpenDrain, OutputPushPull}; |
| 2 | use core::future::Future; | 2 | use core::future::Future; |
| 3 | use core::marker::PhantomData; | 3 | use core::marker::PhantomData; |
| 4 | use embassy::util::Unborrow; | 4 | use 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 | ||
| 14 | use super::*; | 14 | use super::*; |
| 15 | use crate::dma::NoDma; | 15 | use crate::dma::NoDma; |
| 16 | use crate::gpio::sealed::OutputType::{OpenDrain, PushPull}; | 16 | use crate::gpio::sealed::AFType::{OutputOpenDrain, OutputPushPull}; |
| 17 | use crate::pac::usart::{regs, vals}; | 17 | use crate::pac::usart::{regs, vals}; |
| 18 | 18 | ||
| 19 | pub struct Uart<'d, T: Instance, TxDma = NoDma, RxDma = NoDma> { | 19 | pub 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 | ||
