Merge pull request #413 from topisani/master
feat: Add spi support for STM32F1 variants
This commit is contained in:
		| @@ -5,7 +5,7 @@ use embassy::util::Unborrow; | ||||
| use embassy_hal_common::unborrow; | ||||
|  | ||||
| use crate::gpio::{ | ||||
|     sealed::OutputType::{OpenDrain, PushPull}, | ||||
|     sealed::AFType::{OutputOpenDrain, OutputPushPull}, | ||||
|     Pin, | ||||
| }; | ||||
| use crate::{peripherals, rcc::RccPeripheral}; | ||||
| @@ -26,8 +26,8 @@ impl<'d, T: Instance + bxcan::Instance> Can<'d, T> { | ||||
|         unborrow!(peri, rx, tx); | ||||
|  | ||||
|         unsafe { | ||||
|             rx.set_as_af(rx.af_num(), OpenDrain); | ||||
|             tx.set_as_af(tx.af_num(), PushPull); | ||||
|             rx.set_as_af(rx.af_num(), OutputOpenDrain); | ||||
|             tx.set_as_af(tx.af_num(), OutputPushPull); | ||||
|         } | ||||
|  | ||||
|         T::enable(); | ||||
|   | ||||
| @@ -10,7 +10,7 @@ use embassy_net::{Device, DeviceCapabilities, LinkState, PacketBuf, MTU}; | ||||
|  | ||||
| use crate::gpio::sealed::Pin as __GpioPin; | ||||
| use crate::gpio::Pin as GpioPin; | ||||
| use crate::gpio::{sealed::OutputType::PushPull, AnyPin}; | ||||
| use crate::gpio::{sealed::AFType::OutputPushPull, AnyPin}; | ||||
| use crate::pac::gpio::vals::Ospeedr; | ||||
| use crate::pac::{ETH, RCC, SYSCFG}; | ||||
| use crate::peripherals; | ||||
| @@ -416,7 +416,7 @@ macro_rules! impl_pin { | ||||
|             fn configure(&mut self) { | ||||
|                 // NOTE(unsafe) Exclusive access to the registers | ||||
|                 critical_section::with(|_| unsafe { | ||||
|                     self.set_as_af($af, PushPull); | ||||
|                     self.set_as_af($af, OutputPushPull); | ||||
|                     self.block() | ||||
|                         .ospeedr() | ||||
|                         .modify(|w| w.set_ospeedr(self.pin() as usize, Ospeedr::VERYHIGHSPEED)); | ||||
|   | ||||
| @@ -350,12 +350,13 @@ impl<'d, T: Pin> InputPin for OutputOpenDrain<'d, T> { | ||||
| pub(crate) mod sealed { | ||||
|     use super::*; | ||||
|  | ||||
|     /// Output type settings | ||||
|     /// Alternate function type settings | ||||
|     #[derive(Debug)] | ||||
|     #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||
|     pub enum OutputType { | ||||
|         PushPull, | ||||
|         OpenDrain, | ||||
|     pub enum AFType { | ||||
|         Input, | ||||
|         OutputPushPull, | ||||
|         OutputOpenDrain, | ||||
|     } | ||||
|  | ||||
|     pub trait Pin { | ||||
| @@ -394,21 +395,47 @@ pub(crate) mod sealed { | ||||
|         } | ||||
|  | ||||
|         #[cfg(gpio_v1)] | ||||
|         unsafe fn set_as_af(&self, _af_num: u8, _af_type: OutputType) { | ||||
|             panic!("F1 alternate GPIO functions not supported yet!"); | ||||
|         unsafe fn set_as_af(&self, _af_num: u8, af_type: AFType) { | ||||
|             // F1 uses the AFIO register for remapping. | ||||
|             // For now, this is not implemented, so af_num is ignored | ||||
|             // _af_num should be zero here, since it is not set by stm32-data | ||||
|             let r = self.block(); | ||||
|             let n = self._pin() as usize; | ||||
|             let crlh = if n < 8 { 0 } else { 1 }; | ||||
|             match af_type { | ||||
|                 AFType::Input => { | ||||
|                     r.cr(crlh).modify(|w| { | ||||
|                         w.set_mode(n % 8, vals::Mode::INPUT); | ||||
|                         w.set_cnf(n % 8, vals::Cnf::PUSHPULL); | ||||
|                     }); | ||||
|                 } | ||||
|                 AFType::OutputPushPull => { | ||||
|                     r.cr(crlh).modify(|w| { | ||||
|                         w.set_mode(n % 8, vals::Mode::OUTPUT50); | ||||
|                         w.set_cnf(n % 8, vals::Cnf::ALTPUSHPULL); | ||||
|                     }); | ||||
|                 } | ||||
|                 AFType::OutputOpenDrain => { | ||||
|                     r.cr(crlh).modify(|w| { | ||||
|                         w.set_mode(n % 8, vals::Mode::OUTPUT50); | ||||
|                         w.set_cnf(n % 8, vals::Cnf::ALTOPENDRAIN); | ||||
|                     }); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         #[cfg(gpio_v2)] | ||||
|         unsafe fn set_as_af(&self, af_num: u8, af_type: OutputType) { | ||||
|         unsafe fn set_as_af(&self, af_num: u8, af_type: AFType) { | ||||
|             let pin = self._pin() as usize; | ||||
|             let block = self.block(); | ||||
|             block | ||||
|                 .afr(pin / 8) | ||||
|                 .modify(|w| w.set_afr(pin % 8, vals::Afr(af_num))); | ||||
|             match af_type { | ||||
|                 OutputType::PushPull => { | ||||
|                 AFType::Input => {} | ||||
|                 AFType::OutputPushPull => { | ||||
|                     block.otyper().modify(|w| w.set_ot(pin, vals::Ot::PUSHPULL)) | ||||
|                 } | ||||
|                 OutputType::OpenDrain => block | ||||
|                 AFType::OutputOpenDrain => block | ||||
|                     .otyper() | ||||
|                     .modify(|w| w.set_ot(pin, vals::Ot::OPENDRAIN)), | ||||
|             } | ||||
|   | ||||
| @@ -96,7 +96,6 @@ crate::pac::interrupts!( | ||||
|     }; | ||||
| ); | ||||
|  | ||||
| #[cfg(not(rcc_f1))] | ||||
| macro_rules! impl_pin { | ||||
|     ($inst:ident, $pin:ident, $signal:ident, $af:expr) => { | ||||
|         impl $signal<peripherals::$inst> for peripherals::$pin {} | ||||
| @@ -109,6 +108,7 @@ macro_rules! impl_pin { | ||||
|     }; | ||||
| } | ||||
|  | ||||
| #[cfg(not(rcc_f1))] | ||||
| crate::pac::peripheral_pins!( | ||||
|     ($inst:ident, i2c, I2C, $pin:ident, SDA, $af:expr) => { | ||||
|         impl_pin!($inst, $pin, SdaPin, $af); | ||||
| @@ -119,6 +119,17 @@ crate::pac::peripheral_pins!( | ||||
|     }; | ||||
| ); | ||||
|  | ||||
| #[cfg(rcc_f1)] | ||||
| crate::pac::peripheral_pins!( | ||||
|     ($inst:ident, i2c, I2C, $pin:ident, SDA) => { | ||||
|         impl_pin!($inst, $pin, SdaPin, 0); | ||||
|     }; | ||||
|  | ||||
|     ($inst:ident, i2c, I2C, $pin:ident, SCL) => { | ||||
|         impl_pin!($inst, $pin, SclPin, 0); | ||||
|     }; | ||||
| ); | ||||
|  | ||||
| macro_rules! impl_dma { | ||||
|     ($inst:ident, {dmamux: $dmamux:ident}, $signal:ident, $request:expr) => { | ||||
|         impl<T> sealed::$signal<peripherals::$inst> for T | ||||
|   | ||||
| @@ -9,7 +9,7 @@ use embedded_hal::blocking::i2c::WriteRead; | ||||
|  | ||||
| use crate::pac::i2c; | ||||
|  | ||||
| use crate::gpio::sealed::OutputType::OpenDrain; | ||||
| use crate::gpio::sealed::AFType::OutputOpenDrain; | ||||
|  | ||||
| pub struct I2c<'d, T: Instance> { | ||||
|     phantom: PhantomData<&'d mut T>, | ||||
| @@ -30,8 +30,8 @@ impl<'d, T: Instance> I2c<'d, T> { | ||||
|         T::enable(); | ||||
|  | ||||
|         unsafe { | ||||
|             scl.set_as_af(scl.af_num(), OpenDrain); | ||||
|             sda.set_as_af(sda.af_num(), OpenDrain); | ||||
|             scl.set_as_af(scl.af_num(), OutputOpenDrain); | ||||
|             sda.set_as_af(sda.af_num(), OutputOpenDrain); | ||||
|         } | ||||
|  | ||||
|         unsafe { | ||||
|   | ||||
| @@ -1,13 +1,14 @@ | ||||
| #![macro_use] | ||||
|  | ||||
| #[cfg_attr(spi_v1, path = "v1.rs")] | ||||
| #[cfg_attr(spi_f1, path = "v1.rs")] | ||||
| #[cfg_attr(spi_v2, path = "v2.rs")] | ||||
| #[cfg_attr(spi_v3, path = "v3.rs")] | ||||
| mod _version; | ||||
| use crate::{dma, peripherals, rcc::RccPeripheral}; | ||||
| pub use _version::*; | ||||
|  | ||||
| use crate::gpio::Pin; | ||||
| use crate::gpio::OptionalPin; | ||||
|  | ||||
| #[derive(Debug)] | ||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||
| @@ -52,15 +53,15 @@ pub(crate) mod sealed { | ||||
|         fn regs() -> &'static crate::pac::spi::Spi; | ||||
|     } | ||||
|  | ||||
|     pub trait SckPin<T: Instance>: Pin { | ||||
|     pub trait SckPin<T: Instance>: OptionalPin { | ||||
|         fn af_num(&self) -> u8; | ||||
|     } | ||||
|  | ||||
|     pub trait MosiPin<T: Instance>: Pin { | ||||
|     pub trait MosiPin<T: Instance>: OptionalPin { | ||||
|         fn af_num(&self) -> u8; | ||||
|     } | ||||
|  | ||||
|     pub trait MisoPin<T: Instance>: Pin { | ||||
|     pub trait MisoPin<T: Instance>: OptionalPin { | ||||
|         fn af_num(&self) -> u8; | ||||
|     } | ||||
|  | ||||
| @@ -104,6 +105,7 @@ macro_rules! impl_pin { | ||||
|     }; | ||||
| } | ||||
|  | ||||
| #[cfg(not(rcc_f1))] | ||||
| crate::pac::peripheral_pins!( | ||||
|     ($inst:ident, spi, SPI, $pin:ident, SCK, $af:expr) => { | ||||
|         impl_pin!($inst, $pin, SckPin, $af); | ||||
| @@ -118,6 +120,21 @@ crate::pac::peripheral_pins!( | ||||
|     }; | ||||
| ); | ||||
|  | ||||
| #[cfg(rcc_f1)] | ||||
| crate::pac::peripheral_pins!( | ||||
|     ($inst:ident, spi, SPI, $pin:ident, SCK) => { | ||||
|         impl_pin!($inst, $pin, SckPin, 0); | ||||
|     }; | ||||
|  | ||||
|     ($inst:ident, spi, SPI, $pin:ident, MOSI) => { | ||||
|         impl_pin!($inst, $pin, MosiPin, 0); | ||||
|     }; | ||||
|  | ||||
|     ($inst:ident, spi, SPI, $pin:ident, MISO) => { | ||||
|         impl_pin!($inst, $pin, MisoPin, 0); | ||||
|     }; | ||||
| ); | ||||
|  | ||||
| macro_rules! impl_dma { | ||||
|     ($inst:ident, {dmamux: $dmamux:ident}, $signal:ident, $request:expr) => { | ||||
|         impl<T> sealed::$signal<peripherals::$inst> for T | ||||
|   | ||||
| @@ -1,14 +1,11 @@ | ||||
| #![macro_use] | ||||
|  | ||||
| use crate::dma::NoDma; | ||||
| use crate::gpio::{ | ||||
|     sealed::{ | ||||
|         OutputType::{OpenDrain, PushPull}, | ||||
|         Pin, | ||||
|     }, | ||||
|     AnyPin, | ||||
| }; | ||||
| use crate::gpio::sealed::AFType; | ||||
| use crate::gpio::sealed::Pin; | ||||
| use crate::gpio::{AnyPin, NoPin}; | ||||
| use crate::pac::spi; | ||||
| use crate::peripherals; | ||||
| use crate::spi::{ | ||||
|     ByteOrder, Config, Error, Instance, MisoPin, MosiPin, RxDmaChannel, SckPin, TxDmaChannel, | ||||
|     WordSize, | ||||
| @@ -20,6 +17,7 @@ use core::ptr; | ||||
| use embassy::util::Unborrow; | ||||
| use embassy_hal_common::unborrow; | ||||
| use embassy_traits::spi as traits; | ||||
| pub use embedded_hal::blocking; | ||||
| pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; | ||||
| use futures::future::join3; | ||||
|  | ||||
| @@ -32,10 +30,29 @@ impl WordSize { | ||||
|     } | ||||
| } | ||||
|  | ||||
| macro_rules! impl_nopin { | ||||
|     ($inst:ident, $signal:ident) => { | ||||
|         impl $signal<peripherals::$inst> for NoPin {} | ||||
|  | ||||
|         impl super::sealed::$signal<peripherals::$inst> for NoPin { | ||||
|             fn af_num(&self) -> u8 { | ||||
|                 0 | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| crate::pac::peripherals!( | ||||
|     (spi, $inst:ident) => { | ||||
|         impl_nopin!($inst, SckPin); | ||||
|         impl_nopin!($inst, MosiPin); | ||||
|         impl_nopin!($inst, MisoPin); | ||||
|     }; | ||||
| ); | ||||
|  | ||||
| pub struct Spi<'d, T: Instance, Tx, Rx> { | ||||
|     sck: AnyPin, | ||||
|     mosi: AnyPin, | ||||
|     miso: AnyPin, | ||||
|     sck: Option<AnyPin>, | ||||
|     mosi: Option<AnyPin>, | ||||
|     miso: Option<AnyPin>, | ||||
|     txdma: Tx, | ||||
|     rxdma: Rx, | ||||
|     current_word_size: WordSize, | ||||
| @@ -58,15 +75,20 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | ||||
|     { | ||||
|         unborrow!(sck, mosi, miso, txdma, rxdma); | ||||
|  | ||||
|         unsafe { | ||||
|             sck.set_as_af(sck.af_num(), PushPull); | ||||
|             mosi.set_as_af(mosi.af_num(), PushPull); | ||||
|             miso.set_as_af(miso.af_num(), OpenDrain); | ||||
|         } | ||||
|         let sck_af = sck.af_num(); | ||||
|         let mosi_af = mosi.af_num(); | ||||
|         let miso_af = miso.af_num(); | ||||
|         let sck = sck.degrade_optional(); | ||||
|         let mosi = mosi.degrade_optional(); | ||||
|         let miso = miso.degrade_optional(); | ||||
|  | ||||
|         let sck = sck.degrade(); | ||||
|         let mosi = mosi.degrade(); | ||||
|         let miso = miso.degrade(); | ||||
|         unsafe { | ||||
|             sck.as_ref() | ||||
|                 .map(|x| x.set_as_af(sck_af, AFType::OutputPushPull)); | ||||
|             mosi.as_ref() | ||||
|                 .map(|x| x.set_as_af(mosi_af, AFType::OutputPushPull)); | ||||
|             miso.as_ref().map(|x| x.set_as_af(miso_af, AFType::Input)); | ||||
|         } | ||||
|  | ||||
|         unsafe { | ||||
|             T::regs().cr2().modify(|w| { | ||||
| @@ -103,6 +125,9 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | ||||
|                 w.set_ssm(true); | ||||
|                 w.set_crcen(false); | ||||
|                 w.set_bidimode(spi::vals::Bidimode::UNIDIRECTIONAL); | ||||
|                 if mosi.is_none() { | ||||
|                     w.set_rxonly(spi::vals::Rxonly::OUTPUTDISABLED); | ||||
|                 } | ||||
|                 w.set_dff(WordSize::EightBit.dff()) | ||||
|             }); | ||||
|         } | ||||
| @@ -294,9 +319,9 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | ||||
| impl<'d, T: Instance, Tx, Rx> Drop for Spi<'d, T, Tx, Rx> { | ||||
|     fn drop(&mut self) { | ||||
|         unsafe { | ||||
|             self.sck.set_as_analog(); | ||||
|             self.mosi.set_as_analog(); | ||||
|             self.miso.set_as_analog(); | ||||
|             self.sck.as_ref().map(|x| x.set_as_analog()); | ||||
|             self.mosi.as_ref().map(|x| x.set_as_analog()); | ||||
|             self.miso.as_ref().map(|x| x.set_as_analog()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -414,13 +439,18 @@ fn write_word<W: Word>(regs: &'static crate::pac::spi::Spi, word: W) -> Result<( | ||||
|         let sr = unsafe { regs.sr().read() }; | ||||
|         if sr.ovr() { | ||||
|             return Err(Error::Overrun); | ||||
|         } else if sr.fre() { | ||||
|         } | ||||
|         #[cfg(not(spi_f1))] | ||||
|         if sr.fre() { | ||||
|             return Err(Error::Framing); | ||||
|         } else if sr.modf() { | ||||
|         } | ||||
|         if sr.modf() { | ||||
|             return Err(Error::ModeFault); | ||||
|         } else if sr.crcerr() { | ||||
|         } | ||||
|         if sr.crcerr() { | ||||
|             return Err(Error::Crc); | ||||
|         } else if sr.txe() { | ||||
|         } | ||||
|         if sr.txe() { | ||||
|             unsafe { | ||||
|                 let dr = regs.dr().ptr() as *mut W; | ||||
|                 ptr::write_volatile(dr, word); | ||||
| @@ -436,13 +466,18 @@ fn read_word<W: Word>(regs: &'static crate::pac::spi::Spi) -> Result<W, Error> { | ||||
|         let sr = unsafe { regs.sr().read() }; | ||||
|         if sr.ovr() { | ||||
|             return Err(Error::Overrun); | ||||
|         } else if sr.modf() { | ||||
|             return Err(Error::ModeFault); | ||||
|         } else if sr.fre() { | ||||
|         } | ||||
|         #[cfg(not(spi_f1))] | ||||
|         if sr.fre() { | ||||
|             return Err(Error::Framing); | ||||
|         } else if sr.crcerr() { | ||||
|         } | ||||
|         if sr.modf() { | ||||
|             return Err(Error::ModeFault); | ||||
|         } | ||||
|         if sr.crcerr() { | ||||
|             return Err(Error::Crc); | ||||
|         } else if sr.rxne() { | ||||
|         } | ||||
|         if sr.rxne() { | ||||
|             unsafe { | ||||
|                 let dr = regs.dr().ptr() as *const W; | ||||
|                 return Ok(ptr::read_volatile(dr)); | ||||
|   | ||||
| @@ -36,9 +36,9 @@ impl WordSize { | ||||
| } | ||||
|  | ||||
| pub struct Spi<'d, T: Instance, Tx, Rx> { | ||||
|     sck: AnyPin, | ||||
|     mosi: AnyPin, | ||||
|     miso: AnyPin, | ||||
|     sck: Option<AnyPin>, | ||||
|     mosi: Option<AnyPin>, | ||||
|     miso: Option<AnyPin>, | ||||
|     txdma: Tx, | ||||
|     rxdma: Rx, | ||||
|     phantom: PhantomData<&'d mut T>, | ||||
| @@ -60,15 +60,21 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | ||||
|     { | ||||
|         unborrow!(sck, mosi, miso, txdma, rxdma); | ||||
|  | ||||
|         unsafe { | ||||
|             Self::configure_pin(sck.block(), sck.pin() as _, sck.af_num()); | ||||
|             Self::configure_pin(mosi.block(), mosi.pin() as _, mosi.af_num()); | ||||
|             Self::configure_pin(miso.block(), miso.pin() as _, miso.af_num()); | ||||
|         } | ||||
|         let sck_af = sck.af_num(); | ||||
|         let mosi_af = mosi.af_num(); | ||||
|         let miso_af = miso.af_num(); | ||||
|         let sck = sck.degrade_optional(); | ||||
|         let mosi = mosi.degrade_optional(); | ||||
|         let miso = miso.degrade_optional(); | ||||
|  | ||||
|         let sck = sck.degrade(); | ||||
|         let mosi = mosi.degrade(); | ||||
|         let miso = miso.degrade(); | ||||
|         unsafe { | ||||
|             sck.as_ref() | ||||
|                 .map(|x| Self::configure_pin(x.block(), x.pin() as _, sck_af)); | ||||
|             sck.as_ref() | ||||
|                 .map(|x| Self::configure_pin(x.block(), x.pin() as _, mosi_af)); | ||||
|             sck.as_ref() | ||||
|                 .map(|x| Self::configure_pin(x.block(), x.pin() as _, miso_af)); | ||||
|         } | ||||
|  | ||||
|         let pclk = T::frequency(); | ||||
|         let freq = freq.into(); | ||||
| @@ -307,9 +313,15 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | ||||
| impl<'d, T: Instance, Tx, Rx> Drop for Spi<'d, T, Tx, Rx> { | ||||
|     fn drop(&mut self) { | ||||
|         unsafe { | ||||
|             Self::unconfigure_pin(self.sck.block(), self.sck.pin() as _); | ||||
|             Self::unconfigure_pin(self.mosi.block(), self.mosi.pin() as _); | ||||
|             Self::unconfigure_pin(self.miso.block(), self.miso.pin() as _); | ||||
|             self.sck | ||||
|                 .as_ref() | ||||
|                 .map(|x| Self::unconfigure_pin(x.block(), x.pin() as _)); | ||||
|             self.mosi | ||||
|                 .as_ref() | ||||
|                 .map(|x| Self::unconfigure_pin(x.block(), x.pin() as _)); | ||||
|             self.miso | ||||
|                 .as_ref() | ||||
|                 .map(|x| Self::unconfigure_pin(x.block(), x.pin() as _)); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -38,9 +38,9 @@ impl WordSize { | ||||
|  | ||||
| #[allow(unused)] | ||||
| pub struct Spi<'d, T: Instance, Tx = NoDma, Rx = NoDma> { | ||||
|     sck: AnyPin, | ||||
|     mosi: AnyPin, | ||||
|     miso: AnyPin, | ||||
|     sck: Option<AnyPin>, | ||||
|     mosi: Option<AnyPin>, | ||||
|     miso: Option<AnyPin>, | ||||
|     txdma: Tx, | ||||
|     rxdma: Rx, | ||||
|     phantom: PhantomData<&'d mut T>, | ||||
| @@ -62,17 +62,23 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | ||||
|     { | ||||
|         unborrow!(sck, mosi, miso, txdma, rxdma); | ||||
|  | ||||
|         unsafe { | ||||
|             Self::configure_pin(sck.block(), sck.pin() as _, sck.af_num()); | ||||
|             //sck.block().otyper().modify(|w| w.set_ot(sck.pin() as _, crate::pac::gpio::vals::Ot::PUSHPULL)); | ||||
|             Self::configure_pin(mosi.block(), mosi.pin() as _, mosi.af_num()); | ||||
|             //mosi.block().otyper().modify(|w| w.set_ot(mosi.pin() as _, crate::pac::gpio::vals::Ot::PUSHPULL)); | ||||
|             Self::configure_pin(miso.block(), miso.pin() as _, miso.af_num()); | ||||
|         } | ||||
|         let sck_af = sck.af_num(); | ||||
|         let mosi_af = mosi.af_num(); | ||||
|         let miso_af = miso.af_num(); | ||||
|         let sck = sck.degrade_optional(); | ||||
|         let mosi = mosi.degrade_optional(); | ||||
|         let miso = miso.degrade_optional(); | ||||
|  | ||||
|         let sck = sck.degrade(); | ||||
|         let mosi = mosi.degrade(); | ||||
|         let miso = miso.degrade(); | ||||
|         unsafe { | ||||
|             sck.as_ref() | ||||
|                 .map(|x| Self::configure_pin(x.block(), x.pin() as _, sck_af)); | ||||
|             //sck.block().otyper().modify(|w| w.set_ot(Pin::pin(sck) as _, crate::pac::gpio::vals::Ot::PUSHPULL)); | ||||
|             sck.as_ref() | ||||
|                 .map(|x| Self::configure_pin(x.block(), x.pin() as _, mosi_af)); | ||||
|             //mosi.block().otyper().modify(|w| w.set_ot(Pin::pin(mosi) as _, crate::pac::gpio::vals::Ot::PUSHPULL)); | ||||
|             sck.as_ref() | ||||
|                 .map(|x| Self::configure_pin(x.block(), x.pin() as _, miso_af)); | ||||
|         } | ||||
|  | ||||
|         let pclk = T::frequency(); | ||||
|         let br = Self::compute_baud_rate(pclk, freq.into()); | ||||
| @@ -340,9 +346,15 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | ||||
| impl<'d, T: Instance, Tx, Rx> Drop for Spi<'d, T, Tx, Rx> { | ||||
|     fn drop(&mut self) { | ||||
|         unsafe { | ||||
|             Self::unconfigure_pin(self.sck.block(), self.sck.pin() as _); | ||||
|             Self::unconfigure_pin(self.mosi.block(), self.mosi.pin() as _); | ||||
|             Self::unconfigure_pin(self.miso.block(), self.miso.pin() as _); | ||||
|             self.sck | ||||
|                 .as_ref() | ||||
|                 .map(|x| Self::unconfigure_pin(x.block(), x.pin() as _)); | ||||
|             self.mosi | ||||
|                 .as_ref() | ||||
|                 .map(|x| Self::unconfigure_pin(x.block(), x.pin() as _)); | ||||
|             self.miso | ||||
|                 .as_ref() | ||||
|                 .map(|x| Self::unconfigure_pin(x.block(), x.pin() as _)); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -127,7 +127,6 @@ crate::pac::interrupts!( | ||||
|     }; | ||||
| ); | ||||
|  | ||||
| #[cfg(not(rcc_f1))] | ||||
| macro_rules! impl_pin { | ||||
|     ($inst:ident, $pin:ident, $signal:ident, $af:expr) => { | ||||
|         impl sealed::$signal<peripherals::$inst> for peripherals::$pin { | ||||
| @@ -140,6 +139,7 @@ macro_rules! impl_pin { | ||||
|     }; | ||||
| } | ||||
|  | ||||
| #[cfg(not(rcc_f1))] | ||||
| crate::pac::peripheral_pins!( | ||||
|  | ||||
|     // USART | ||||
| @@ -177,6 +177,44 @@ crate::pac::peripheral_pins!( | ||||
|     }; | ||||
| ); | ||||
|  | ||||
| #[cfg(rcc_f1)] | ||||
| crate::pac::peripheral_pins!( | ||||
|  | ||||
|     // USART | ||||
|     ($inst:ident, usart, USART, $pin:ident, TX) => { | ||||
|         impl_pin!($inst, $pin, TxPin, 0); | ||||
|     }; | ||||
|     ($inst:ident, usart, USART, $pin:ident, RX) => { | ||||
|         impl_pin!($inst, $pin, RxPin, 0); | ||||
|     }; | ||||
|     ($inst:ident, usart, USART, $pin:ident, CTS) => { | ||||
|         impl_pin!($inst, $pin, CtsPin, 0); | ||||
|     }; | ||||
|     ($inst:ident, usart, USART, $pin:ident, RTS) => { | ||||
|         impl_pin!($inst, $pin, RtsPin, 0); | ||||
|     }; | ||||
|     ($inst:ident, usart, USART, $pin:ident, CK) => { | ||||
|         impl_pin!($inst, $pin, CkPin, 0); | ||||
|     }; | ||||
|  | ||||
|     // UART | ||||
|     ($inst:ident, uart, UART, $pin:ident, TX) => { | ||||
|         impl_pin!($inst, $pin, TxPin, 0); | ||||
|     }; | ||||
|     ($inst:ident, uart, UART, $pin:ident, RX) => { | ||||
|         impl_pin!($inst, $pin, RxPin, 0); | ||||
|     }; | ||||
|     ($inst:ident, uart, UART, $pin:ident, CTS) => { | ||||
|         impl_pin!($inst, $pin, CtsPin, 0); | ||||
|     }; | ||||
|     ($inst:ident, uart, UART, $pin:ident, RTS) => { | ||||
|         impl_pin!($inst, $pin, RtsPin, 0); | ||||
|     }; | ||||
|     ($inst:ident, uart, UART, $pin:ident, CK) => { | ||||
|         impl_pin!($inst, $pin, CkPin, 0); | ||||
|     }; | ||||
| ); | ||||
|  | ||||
| macro_rules! impl_dma { | ||||
|     ($inst:ident, {dmamux: $dmamux:ident}, $signal:ident, $request:expr) => { | ||||
|         impl<T> sealed::$signal<peripherals::$inst> for T | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| use crate::gpio::sealed::OutputType::{OpenDrain, PushPull}; | ||||
| use crate::gpio::sealed::AFType::{OutputOpenDrain, OutputPushPull}; | ||||
| use core::future::Future; | ||||
| use core::marker::PhantomData; | ||||
| use embassy::util::Unborrow; | ||||
| @@ -37,8 +37,8 @@ impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { | ||||
|         let r = inner.regs(); | ||||
|  | ||||
|         unsafe { | ||||
|             rx.set_as_af(rx.af_num(), OpenDrain); | ||||
|             tx.set_as_af(tx.af_num(), PushPull); | ||||
|             rx.set_as_af(rx.af_num(), OutputOpenDrain); | ||||
|             tx.set_as_af(tx.af_num(), OutputPushPull); | ||||
|  | ||||
|             r.brr().write_value(regs::Brr(div)); | ||||
|             r.cr1().write(|w| { | ||||
|   | ||||
| @@ -13,7 +13,7 @@ use futures::TryFutureExt; | ||||
|  | ||||
| use super::*; | ||||
| use crate::dma::NoDma; | ||||
| use crate::gpio::sealed::OutputType::{OpenDrain, PushPull}; | ||||
| use crate::gpio::sealed::AFType::{OutputOpenDrain, OutputPushPull}; | ||||
| use crate::pac::usart::{regs, vals}; | ||||
|  | ||||
| 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> { | ||||
|         let r = inner.regs(); | ||||
|  | ||||
|         unsafe { | ||||
|             rx.set_as_af(rx.af_num(), OpenDrain); | ||||
|             tx.set_as_af(tx.af_num(), PushPull); | ||||
|             rx.set_as_af(rx.af_num(), OutputOpenDrain); | ||||
|             tx.set_as_af(tx.af_num(), OutputPushPull); | ||||
|  | ||||
|             r.cr2().write(|_w| {}); | ||||
|             r.cr3().write(|_w| {}); | ||||
|   | ||||
 Submodule stm32-data updated: e78ea6f050...bae2d34445
									
								
							
		Reference in New Issue
	
	Block a user