diff --git a/CHANGELOG.md b/CHANGELOG.md index c1703615..19b4db71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,9 +16,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - `serial` mod refactor [#833] [#839] - FMPI2c APB timings [#770] - Fefactor FMPI2c `embedded-hal` implementations [#784] + - remove `NoPin`, use `Option` instead [#813] [#770]: https://github.com/stm32-rs/stm32f4xx-hal/pull/770 [#784]: https://github.com/stm32-rs/stm32f4xx-hal/pull/784 +[#813]: https://github.com/stm32-rs/stm32f4xx-hal/pull/813 [#829]: https://github.com/stm32-rs/stm32f4xx-hal/pull/829 [#831]: https://github.com/stm32-rs/stm32f4xx-hal/pull/831 [#832]: https://github.com/stm32-rs/stm32f4xx-hal/pull/832 diff --git a/examples/analog-stopwatch-with-spi-ssd1306.rs b/examples/analog-stopwatch-with-spi-ssd1306.rs index 216f190d..8c09e2c8 100644 --- a/examples/analog-stopwatch-with-spi-ssd1306.rs +++ b/examples/analog-stopwatch-with-spi-ssd1306.rs @@ -111,7 +111,7 @@ fn main() -> ! { let spi = Spi::new( dp.SPI4, - (sck, miso, mosi), + (Some(sck), Some(miso), Some(mosi)), Mode { polarity: Polarity::IdleLow, phase: Phase::CaptureOnFirstTransition, diff --git a/examples/i2s-audio-out.rs b/examples/i2s-audio-out.rs index c887b807..5eada776 100644 --- a/examples/i2s-audio-out.rs +++ b/examples/i2s-audio-out.rs @@ -50,11 +50,10 @@ use cortex_m_rt::entry; use rtt_target::{rprintln, rtt_init_print}; -use stm32f4xx_hal::gpio::NoPin; use stm32f4xx_hal::i2s::stm32_i2s_v12x::transfer::*; use stm32f4xx_hal::i2s::I2s; use stm32f4xx_hal::nb::block; -use stm32f4xx_hal::pac::Peripherals; +use stm32f4xx_hal::pac::{Peripherals, SPI3}; use stm32f4xx_hal::prelude::*; const SAMPLE_RATE: u32 = 48_000; @@ -104,7 +103,7 @@ fn main() -> ! { .i2s_clk(61440.kHz()) .freeze(); - let i2s_pins = (gpioa.pa4, gpioc.pc10, NoPin::new(), gpioc.pc12); + let i2s_pins = (gpioa.pa4, gpioc.pc10, SPI3::NoMck, gpioc.pc12); let i2s = I2s::new(dp.SPI3, i2s_pins, &clocks); let i2s_config = I2sTransferConfig::new_master() .transmit() diff --git a/examples/ist7920-bidi-normal-spi.rs b/examples/ist7920-bidi-normal-spi.rs index 5d8612fe..b0fb740b 100644 --- a/examples/ist7920-bidi-normal-spi.rs +++ b/examples/ist7920-bidi-normal-spi.rs @@ -45,7 +45,9 @@ fn main() -> ! { // Change spi transfer mode to Bidi for more efficient operations. // let spi = Spi::new(dp.SPI1, (sck, miso, mosi), mode, 8.MHz(), &clocks).to_bidi_transfer_mode(); // or - let spi = dp.SPI1.spi_bidi((sck, mosi), mode, 8.MHz(), &clocks); + let spi = dp + .SPI1 + .spi_bidi((Some(sck), Some(mosi)), mode, 8.MHz(), &clocks); let iface = SPIInterface::new(spi, dc, cs); diff --git a/examples/rtic-dual-i2s-audio-in-out.rs b/examples/rtic-dual-i2s-audio-in-out.rs index aa327a60..de101d69 100644 --- a/examples/rtic-dual-i2s-audio-in-out.rs +++ b/examples/rtic-dual-i2s-audio-in-out.rs @@ -165,11 +165,11 @@ mod app { // I2S pins: (WS, CK, MCLK, SD) for I2S2 let i2s2_pins = ( - gpiob.pb12, //WS - gpiob.pb13, //CK - gpioc.pc6, //MCK - gpiob.pb15, //SD - gpiob.pb14, //ExtSD + gpiob.pb12, //WS + gpiob.pb13, //CK + Some(gpioc.pc6), //MCK + gpiob.pb15, //SD + gpiob.pb14, //ExtSD ); let i2s2 = DualI2s::new(device.SPI2, device.I2S2EXT, i2s2_pins, &clocks); let i2s2_config = DualI2sDriverConfig::new_master() diff --git a/examples/rtic-i2s-audio-in-out.rs b/examples/rtic-i2s-audio-in-out.rs index c89534ad..fd855aa6 100644 --- a/examples/rtic-i2s-audio-in-out.rs +++ b/examples/rtic-i2s-audio-in-out.rs @@ -80,7 +80,7 @@ mod app { use super::hal; - use hal::gpio::{Edge, NoPin}; + use hal::gpio::Edge; use hal::i2s::stm32_i2s_v12x::driver::*; use hal::i2s::I2s; use hal::pac::Interrupt; @@ -169,10 +169,10 @@ mod app { // I2S pins: (WS, CK, MCLK, SD) for I2S2 let i2s2_pins = ( - gpiob.pb12, //WS - gpiob.pb13, //CK - gpioc.pc6, //MCK - gpiob.pb15, //SD + gpiob.pb12, //WS + gpiob.pb13, //CK + Some(gpioc.pc6), //MCK + gpiob.pb15, //SD ); let i2s2 = I2s::new(device.SPI2, i2s2_pins, &clocks); let i2s2_config = I2sDriverConfig::new_master() @@ -186,8 +186,8 @@ mod app { i2s2_driver.set_rx_interrupt(true); i2s2_driver.set_error_interrupt(true); - // I2S3 pins: (WS, CK, NoPin, SD) for I2S3 - let i2s3_pins = (gpioa.pa4, gpioc.pc10, NoPin::new(), gpioc.pc12); + // I2S3 pins: (WS, CK, NoMck, SD) for I2S3 + let i2s3_pins = (gpioa.pa4, gpioc.pc10, SPI3::NoMck, gpioc.pc12); let i2s3 = I2s::new(device.SPI3, i2s3_pins, &clocks); let i2s3_config = i2s2_config.to_slave().transmit(); let mut i2s3_driver = I2sDriver::new(i2s3, i2s3_config); diff --git a/examples/rtic-spi-slave-dma.rs b/examples/rtic-spi-slave-dma.rs index ecfdc77d..914cc6c6 100644 --- a/examples/rtic-spi-slave-dma.rs +++ b/examples/rtic-spi-slave-dma.rs @@ -77,7 +77,7 @@ mod app { phase: Phase::CaptureOnFirstTransition, }; - let mut spi3 = SpiSlave::new(spi, (sck, miso, mosi, None), mode); + let mut spi3 = SpiSlave::new(spi, (Some(sck), Some(miso), Some(mosi), SPI3::NoNss), mode); spi3.set_internal_nss(false); let (tx, rx) = spi3.use_dma().txrx(); diff --git a/examples/sai-duplex.rs b/examples/sai-duplex.rs index f8143dd1..5f237e0b 100644 --- a/examples/sai-duplex.rs +++ b/examples/sai-duplex.rs @@ -43,7 +43,7 @@ fn main() -> ! { num_slots: 2, }; let tx = saia.master_tx( - (gpioe.pe2, gpioe.pe4, gpioe.pe5, gpioe.pe6), + (Some(gpioe.pe2), gpioe.pe4, gpioe.pe5, gpioe.pe6), protocol, 48.kHz(), &clocks, diff --git a/examples/spi-dma.rs b/examples/spi-dma.rs index a03ad703..0371a4ce 100644 --- a/examples/spi-dma.rs +++ b/examples/spi-dma.rs @@ -13,20 +13,15 @@ use stm32f4xx_hal::pac::interrupt; use stm32f4xx_hal::{ dma::{config, MemoryToPeripheral, Stream4, StreamsTuple, Transfer}, gpio::Speed, - pac, + pac::{self, SPI2}, prelude::*, spi::*, }; const ARRAY_SIZE: usize = 100; -type SpiDma = Transfer< - Stream4, - 0, - Tx, - MemoryToPeripheral, - &'static mut [u8; ARRAY_SIZE], ->; +type SpiDma = + Transfer, 0, Tx, MemoryToPeripheral, &'static mut [u8; ARRAY_SIZE]>; static G_TRANSFER: Mutex>> = Mutex::new(RefCell::new(None)); @@ -56,7 +51,13 @@ fn main() -> ! { phase: Phase::CaptureOnFirstTransition, }; - let spi2 = Spi::new(dp.SPI2, (pb13, NoMiso::new(), pb15), mode, 3.MHz(), &clocks); + let spi2 = Spi::new( + dp.SPI2, + (Some(pb13), SPI2::NoMiso, Some(pb15)), + mode, + 3.MHz(), + &clocks, + ); let buffer = cortex_m::singleton!(: [u8; ARRAY_SIZE] = [1; ARRAY_SIZE]).unwrap(); diff --git a/examples/spi_slave.rs b/examples/spi_slave.rs index bbf1668a..7b7c9996 100644 --- a/examples/spi_slave.rs +++ b/examples/spi_slave.rs @@ -29,8 +29,10 @@ fn main() -> ! { let mosi = gpioa.pa7.internal_resistor(Pull::Down); // clock speed is determined by the master - let nss = gpioa.pa4.internal_resistor(Pull::Up).into(); - let mut spi = p.SPI1.spi_slave((sck, miso, mosi, Some(nss)), MODE); + let nss = gpioa.pa4.internal_resistor(Pull::Up); + let mut spi = p + .SPI1 + .spi_slave((Some(sck), Some(miso), Some(mosi), Some(nss)), MODE); // alternativelly you could use software `chip select` // let mut spi = SpiSlave::new(p.SPI1, (sck, miso, mosi, None), MODE); // spi.set_internal_nss(false); diff --git a/examples/ws2812-spi.rs b/examples/ws2812-spi.rs index 940e9d53..5a5f0213 100644 --- a/examples/ws2812-spi.rs +++ b/examples/ws2812-spi.rs @@ -6,7 +6,10 @@ use panic_halt as _; use stm32f4xx_hal as hal; use cortex_m_rt::entry; -use hal::{gpio::NoPin, pac, prelude::*}; +use hal::{ + pac::{self, SPI1}, + prelude::*, +}; use smart_leds::{brightness, hsv::RGB8, SmartLedsWrite}; use ws2812_spi as ws2812; @@ -22,7 +25,7 @@ fn main() -> ! { let gpioa = dp.GPIOA.split(); let spi = dp.SPI1.spi( - (gpioa.pa5, NoPin::new(), gpioa.pa7), + (Some(gpioa.pa5), SPI1::NoMiso, Some(gpioa.pa7)), ws2812::MODE, 3000.kHz(), &clocks, diff --git a/src/can.rs b/src/can.rs index fd0c5a52..5decaf90 100644 --- a/src/can.rs +++ b/src/can.rs @@ -1,7 +1,7 @@ //! # Controller Area Network (CAN) Interface //! -use crate::gpio::{self, NoPin}; +use crate::gpio; use crate::pac; use crate::rcc; @@ -39,13 +39,9 @@ mod can3 { pub trait CanExt: Sized + Instance { fn can(self, pins: (impl Into, impl Into)) -> Can; - fn tx(self, tx_pin: impl Into) -> Can - where - NoPin: Into; + fn tx(self, tx_pin: impl Into) -> Can; - fn rx(self, rx_pin: impl Into) -> Can - where - NoPin: Into; + fn rx(self, rx_pin: impl Into) -> Can; } impl CanExt for CAN { @@ -53,17 +49,11 @@ impl CanExt for CAN { Can::new(self, pins) } - fn tx(self, tx_pin: impl Into) -> Can - where - NoPin: Into, - { + fn tx(self, tx_pin: impl Into) -> Can { Can::tx(self, tx_pin) } - fn rx(self, rx_pin: impl Into) -> Can - where - NoPin: Into, - { + fn rx(self, rx_pin: impl Into) -> Can { Can::rx(self, rx_pin) } } @@ -71,42 +61,35 @@ impl CanExt for CAN { /// Interface to the CAN peripheral. pub struct Can { can: CAN, - pins: (CAN::Tx, CAN::Rx), + pins: (Option, Option), } impl Can { /// Creates a CAN interface. pub fn new(can: CAN, pins: (impl Into, impl Into)) -> Self { + Self::_new(can, (Some(pins.0.into()), Some(pins.1.into()))) + } + fn _new(can: CAN, pins: (Option, Option)) -> Self { unsafe { CAN::enable_unchecked(); CAN::reset_unchecked(); } - let pins = (pins.0.into(), pins.1.into()); - Can { can, pins } } - pub fn release(self) -> (CAN, (CAN::Tx, CAN::Rx)) { + pub fn release(self) -> (CAN, (Option, Option)) { (self.can, self.pins) } } impl Can { - pub fn tx(usart: CAN, tx_pin: impl Into) -> Self - where - NoPin: Into, - { - Self::new(usart, (tx_pin, NoPin::new())) + pub fn tx(usart: CAN, tx_pin: impl Into) -> Self { + Self::_new(usart, (Some(tx_pin.into()), None)) } -} -impl Can { - pub fn rx(usart: CAN, rx_pin: impl Into) -> Self - where - NoPin: Into, - { - Self::new(usart, (NoPin::new(), rx_pin)) + pub fn rx(usart: CAN, rx_pin: impl Into) -> Self { + Self::_new(usart, (None, Some(rx_pin.into()))) } } diff --git a/src/gpio.rs b/src/gpio.rs index 9e30fd25..2b3b7c22 100644 --- a/src/gpio.rs +++ b/src/gpio.rs @@ -76,16 +76,6 @@ pub use embedded_hal_02::digital::v2::PinState; use core::fmt; -/// A filler pin type -#[derive(Debug, Default)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub struct NoPin(PhantomData); -impl NoPin { - pub fn new() -> Self { - Self(PhantomData) - } -} - /// Extension trait to split a GPIO peripheral in independent pins and registers pub trait GpioExt { /// The parts to split the GPIO into diff --git a/src/gpio/alt.rs b/src/gpio/alt.rs index 25b91f92..16d09163 100644 --- a/src/gpio/alt.rs +++ b/src/gpio/alt.rs @@ -65,17 +65,13 @@ macro_rules! extipin { use extipin; macro_rules! pin { - ( $($(#[$docs:meta])* <$name:ident, $Otype:ident> for $(no: $NoPin:ident,)? [$( + ( $($(#[$docs:meta])* <$name:ident, $Otype:ident> for [$( $(#[$attr:meta])* $PX:ident<$A:literal $(, Speed::$Speed:ident)?>, )*],)*) => { $( #[derive(Debug)] $(#[$docs])* pub enum $name { - $( - None($NoPin<$Otype>), - )? - $( $(#[$attr])* $PX(gpio::$PX<$crate::gpio::Alternate<$A, $Otype>>), @@ -128,14 +124,6 @@ macro_rules! pin { extipin! { $( $(#[$attr])* $PX, )* } } - $( - impl From<$NoPin<$Otype>> for $name { - fn from(p: $NoPin<$Otype>) -> Self { - Self::None(p) - } - } - )? - $( $(#[$attr])* impl From> for $name @@ -175,17 +163,13 @@ macro_rules! pin { )* }; - ( $($(#[$docs:meta])* <$name:ident> default:$DefaultOtype:ident for $(no: $NoPin:ident,)? [$( + ( $($(#[$docs:meta])* <$name:ident> default:$DefaultOtype:ident for [$( $(#[$attr:meta])* $PX:ident<$A:literal>, )*],)*) => { $( #[derive(Debug)] $(#[$docs])* pub enum $name { - $( - None($NoPin), - )? - $( $(#[$attr])* $PX(gpio::$PX<$crate::gpio::Alternate<$A, Otype>>), @@ -238,14 +222,6 @@ macro_rules! pin { extipin! { $( $(#[$attr])* $PX, )* } } - $( - impl From<$NoPin> for $name { - fn from(p: $NoPin) -> Self { - Self::None(p) - } - } - )? - $( $(#[$attr])* impl From> for $name @@ -387,6 +363,8 @@ pub trait SaiChannels { } #[cfg(feature = "sai1")] pub trait SaiChannel { + #[allow(non_upper_case_globals)] + const NoMclk: Option = None; type Fs; type Mclk; type Sck; diff --git a/src/gpio/alt/f4.rs b/src/gpio/alt/f4.rs index e631f5a0..4c62c039 100644 --- a/src/gpio/alt/f4.rs +++ b/src/gpio/alt/f4.rs @@ -1,12 +1,12 @@ use super::*; -use crate::gpio::{self, NoPin, OpenDrain, PushPull}; +use crate::gpio::{self, OpenDrain, PushPull}; #[cfg(feature = "can1")] pub mod can1 { use super::*; pin! { - for no:NoPin, [ + for [ PA11<9>, #[cfg(any(feature = "gpio-f412", feature = "gpio-f413"))] @@ -29,7 +29,7 @@ pub mod can1 { PI9<9>, ], - for no:NoPin, [ + for [ PA12<9>, #[cfg(any(feature = "gpio-f412", feature = "gpio-f413"))] @@ -64,7 +64,7 @@ pub mod can2 { use super::*; pin! { - for no:NoPin, [ + for [ PB5<9>, PB12<9>, @@ -73,7 +73,7 @@ pub mod can2 { PG11<9>, ], - for no:NoPin, [ + for [ PB6<9>, PB13<9>, @@ -94,13 +94,13 @@ pub mod can3 { use super::*; pin! { - for no:NoPin, [ + for [ PA8<11>, PB3<11>, ], - for no:NoPin, [ + for [ PA15<11>, PB4<11>, @@ -1553,7 +1553,7 @@ pub mod i2s1 { PB3<5>, ], - for no:NoPin, [ + for [ #[cfg(feature = "gpio-f410")] PB10<6>, @@ -1625,7 +1625,7 @@ pub mod i2s2 { PI1<5>, ], - for no:NoPin, [ + for [ #[cfg(any( feature = "gpio-f410", feature = "gpio-f411", @@ -1765,7 +1765,7 @@ pub mod i2s3 { PC10<6>, ], - for no:NoPin, [ + for [ #[cfg(any(feature = "gpio-f411", feature = "gpio-f412", feature = "gpio-f413"))] PB10<6>, @@ -1893,7 +1893,7 @@ pub mod i2s4 { PE14<5>, ], - for no:NoPin, [ ], + for [ ], for [ PB12<6>, @@ -1943,7 +1943,7 @@ pub mod i2s5 { PE14<6>, ], - for no:NoPin, [ ], + for [ ], for [ PB1<6>, @@ -2505,7 +2505,7 @@ pub mod sai1 { PF9<7>, ], - for no:NoPin, [ + for [ #[cfg(feature = "gpio-f413")] PA15<10>, @@ -2519,7 +2519,7 @@ pub mod sai1 { PG7<6>, ], - for no:NoPin, [ + for [ #[cfg(feature = "gpio-f446")] PC0<6>, @@ -2846,13 +2846,13 @@ pub mod spi1 { use super::*; pin! { - for no:NoPin, [ + for [ PA6<5>, PB4<5>, ], - for no:NoPin, [ + for [ PA7<5>, PB5<5>, @@ -2864,7 +2864,7 @@ pub mod spi1 { PA15<5>, ], - for no:NoPin, [ + for [ PA5<5>, PB3<5>, @@ -2883,7 +2883,7 @@ pub mod spi2 { use super::*; pin! { - for no:NoPin, [ + for [ #[cfg(feature = "gpio-f413")] PA12<5>, @@ -2895,7 +2895,7 @@ pub mod spi2 { PI2<5>, ], - for no:NoPin, [ + for [ #[cfg(feature = "gpio-f413")] PA10<5>, @@ -2931,7 +2931,7 @@ pub mod spi2 { PI0<5>, ], - for no:NoPin, [ + for [ #[cfg(any(feature = "gpio-f413", feature = "gpio-f446", feature = "gpio-f469"))] PA9<5>, @@ -2977,13 +2977,13 @@ pub mod spi3 { use super::*; pin! { - for no:NoPin, [ + for [ PB4<6>, PC11<6>, ], - for no:NoPin, [ + for [ #[cfg(feature = "gpio-f446")] PB0<7>, @@ -3018,7 +3018,7 @@ pub mod spi3 { PA15<6>, ], - for no:NoPin, [ + for [ PB3<6>, #[cfg(any(feature = "gpio-f411", feature = "gpio-f412", feature = "gpio-f413"))] @@ -3041,7 +3041,7 @@ pub mod spi4 { use super::*; pin! { - for no:NoPin, [ + for [ #[cfg(any(feature = "gpio-f411", feature = "gpio-f412", feature = "gpio-f413"))] PA11<6>, @@ -3056,7 +3056,7 @@ pub mod spi4 { PG12<6>, ], - for no:NoPin, [ + for [ #[cfg(any(feature = "gpio-f411", feature = "gpio-f412", feature = "gpio-f413"))] PA1<5>, @@ -3080,7 +3080,7 @@ pub mod spi4 { PG14<6>, ], - for no:NoPin, [ + for [ #[cfg(any(feature = "gpio-f411", feature = "gpio-f412", feature = "gpio-f413"))] PB13<6>, @@ -3106,7 +3106,7 @@ pub mod spi5 { use super::*; pin! { - for no:NoPin, [ + for [ #[cfg(any( feature = "gpio-f410", feature = "gpio-f411", @@ -3128,7 +3128,7 @@ pub mod spi5 { PH7<5>, ], - for no:NoPin, [ + for [ #[cfg(any( feature = "gpio-f410", feature = "gpio-f411", @@ -3180,7 +3180,7 @@ pub mod spi5 { PH5<5>, ], - for no:NoPin, [ + for [ #[cfg(any( feature = "gpio-f410", feature = "gpio-f411", @@ -3216,11 +3216,11 @@ pub mod spi6 { use super::*; pin! { - for no:NoPin, [ + for [ PG12<5>, ], - for no:NoPin, [ + for [ PG14<5>, ], @@ -3228,7 +3228,7 @@ pub mod spi6 { PG8<5>, ], - for no:NoPin, [ + for [ PG13<5>, ], } @@ -4013,7 +4013,7 @@ pub mod usart1 { } pin! { - default: PushPull for no:NoPin, [ + default: PushPull for [ PA10<7>, #[cfg(any( @@ -4027,7 +4027,7 @@ pub mod usart1 { PB7<7>, ], - default: PushPull for no:NoPin, [ + default: PushPull for [ PA9<7>, #[cfg(any( @@ -4083,14 +4083,14 @@ pub mod usart2 { } pin! { - default: PushPull for no:NoPin, [ + default: PushPull for [ PA3<7>, #[cfg(not(feature = "gpio-f410"))] PD6<7>, ], - default: PushPull for no:NoPin, [ + default: PushPull for [ PA2<7>, #[cfg(not(feature = "gpio-f410"))] @@ -4157,7 +4157,7 @@ pub mod usart3 { } pin! { - default: PushPull for no:NoPin, [ + default: PushPull for [ PB11<7>, #[cfg(any(feature = "gpio-f412", feature = "gpio-f413", feature = "gpio-f446"))] @@ -4168,7 +4168,7 @@ pub mod usart3 { PD9<7>, ], - default: PushPull for no:NoPin, [ + default: PushPull for [ PB10<7>, PC10<7>, @@ -4233,7 +4233,7 @@ pub mod usart6 { } pin! { - default: PushPull for no:NoPin, [ + default: PushPull for [ #[cfg(any( feature = "gpio-f401", feature = "gpio-f410", @@ -4256,7 +4256,7 @@ pub mod usart6 { PG9<8>, ], - default: PushPull for no:NoPin, [ + default: PushPull for [ #[cfg(any( feature = "gpio-f401", feature = "gpio-f410", @@ -4318,7 +4318,7 @@ pub mod uart4 { } pin! { - default: PushPull for no:NoPin, [ + default: PushPull for [ PA1<8>, #[cfg(feature = "gpio-f413")] @@ -4330,7 +4330,7 @@ pub mod uart4 { PD0<11>, ], - default: PushPull for no:NoPin, [ + default: PushPull for [ PA0<8>, #[cfg(feature = "gpio-f413")] @@ -4380,7 +4380,7 @@ pub mod uart5 { } pin! { - default: PushPull for no:NoPin, [ + default: PushPull for [ #[cfg(feature = "gpio-f413")] PB5<11>, @@ -4396,7 +4396,7 @@ pub mod uart5 { PE7<8>, ], - default: PushPull for no:NoPin, [ + default: PushPull for [ #[cfg(feature = "gpio-f413")] PB6<11>, @@ -4430,7 +4430,7 @@ pub mod uart7 { use super::*; pin! { - default: PushPull for no:NoPin, [ + default: PushPull for [ #[cfg(feature = "gpio-f413")] PA8<8>, @@ -4442,7 +4442,7 @@ pub mod uart7 { PF6<8>, ], - default: PushPull for no:NoPin, [ + default: PushPull for [ #[cfg(feature = "gpio-f413")] PA15<8>, @@ -4467,14 +4467,14 @@ pub mod uart8 { use super::*; pin! { - default: PushPull for no:NoPin, [ + default: PushPull for [ PE0<8>, #[cfg(feature = "gpio-f413")] PF8<8>, ], - default: PushPull for no:NoPin, [ + default: PushPull for [ PE1<8>, #[cfg(feature = "gpio-f413")] @@ -4494,13 +4494,13 @@ pub mod uart9 { use super::*; pin! { - default: PushPull for no:NoPin, [ + default: PushPull for [ PD14<11>, PG0<11>, ], - default: PushPull for no:NoPin, [ + default: PushPull for [ PD15<11>, PG1<11>, @@ -4519,13 +4519,13 @@ pub mod uart10 { use super::*; pin! { - default: PushPull for no:NoPin, [ + default: PushPull for [ PE2<11>, PG11<11>, ], - default: PushPull for no:NoPin, [ + default: PushPull for [ PE3<11>, PG12<11>, diff --git a/src/i2s.rs b/src/i2s.rs index 48fde593..083ab346 100644 --- a/src/i2s.rs +++ b/src/i2s.rs @@ -6,7 +6,7 @@ //! these chips because their `I2S2EXT` and `I2S3EXT` peripherals are missing from their package //! access crate. -use crate::gpio::{self, NoPin, PinSpeed, Speed}; +use crate::gpio::{self, PinSpeed, Speed}; use crate::pac; #[allow(unused)] use crate::rcc::{self, Clocks, Reset}; @@ -21,9 +21,6 @@ pub extern crate stm32_i2s_v12x; // SCK -> CK // The master clock output is separate. -/// A placeholder for when the MCLK pin is not needed -pub type NoMasterClock = NoPin; - /// Trait for SPI peripheral with i2s capability. pub trait Instance: I2sFreq + rcc::Enable + rcc::Reset + gpio::alt::I2sCommon + gpio::alt::I2sMaster @@ -82,12 +79,14 @@ impl I2sFreq for rcc::APB2 { /// Trait to build an [`I2s`] object from SPI peripheral, pins and clocks pub trait I2sExt: Sized + Instance { + #[allow(non_upper_case_globals)] + const NoMck: Option = None; fn i2s( self, pins: ( impl Into, impl Into, - impl Into, + Option>, impl Into, ), clocks: &Clocks, @@ -100,7 +99,7 @@ impl I2sExt for SPI { pins: ( impl Into, impl Into, - impl Into, + Option>, impl Into, ), clocks: &Clocks, @@ -117,7 +116,7 @@ pub trait DualI2sExt: Sized + DualInstance { pins: ( impl Into, impl Into, - impl Into, + Option>, impl Into, impl Into, ), @@ -132,7 +131,7 @@ impl DualI2sExt for SPI { pins: ( impl Into, impl Into, - impl Into, + Option>, impl Into, impl Into, ), @@ -145,7 +144,7 @@ impl DualI2sExt for SPI { /// An I2s wrapper around an SPI object and pins pub struct I2s { spi: I, - pins: (I::Ws, I::Ck, I::Mck, I::Sd), + pins: (I::Ws, I::Ck, Option, I::Sd), /// Frequency of clock input to this peripheral from the I2S PLL or related source input_clock: Hertz, } @@ -169,7 +168,7 @@ impl I2s { pins: ( impl Into, impl Into, - impl Into, + Option>, impl Into, ), clocks: &Clocks, @@ -185,7 +184,7 @@ impl I2s { pins.0.into(), // Workaround for corrupted last bit of data issue, see stm32f411 errata pins.1.into().speed(Speed::VeryHigh), - pins.2.into(), + pins.2.map(Into::into), pins.3.into(), ); @@ -197,7 +196,7 @@ impl I2s { } #[allow(clippy::type_complexity)] - pub fn release(self) -> (SPI, (SPI::Ws, SPI::Ck, SPI::Mck, SPI::Sd)) { + pub fn release(self) -> (SPI, (SPI::Ws, SPI::Ck, Option, SPI::Sd)) { (self.spi, self.pins) } } @@ -293,7 +292,7 @@ i2s!(pac::SPI5, I2s5, i2s5); pub struct DualI2s { spi: I, i2s_ext: I::I2sExtPeripheral, - pins: (I::Ws, I::Ck, I::Mck, I::Sd, I::ExtSd), + pins: (I::Ws, I::Ck, Option, I::Sd, I::ExtSd), /// Frequency of clock input to this peripheral from the I2S PLL or related source input_clock: Hertz, } @@ -316,7 +315,7 @@ impl DualI2s { pins: ( impl Into, impl Into, - impl Into, + Option>, impl Into, impl Into, ), @@ -334,7 +333,7 @@ impl DualI2s { pins.0.into(), // Workaround for corrupted last bit of data issue, see stm32f411 errata pins.1.into().speed(Speed::VeryHigh), - pins.2.into(), + pins.2.map(Into::into), pins.3.into(), pins.4.into(), ); @@ -353,7 +352,7 @@ impl DualI2s { ) -> ( SPI, SPI::I2sExtPeripheral, - (SPI::Ws, SPI::Ck, SPI::Mck, SPI::Sd, SPI::ExtSd), + (SPI::Ws, SPI::Ck, Option, SPI::Sd, SPI::ExtSd), ) { (self.spi, self.i2s_ext, self.pins) } diff --git a/src/sai.rs b/src/sai.rs index 343f7fb6..c3ea0be8 100644 --- a/src/sai.rs +++ b/src/sai.rs @@ -142,20 +142,25 @@ pub struct Asynchronous; pub struct AsyncMaster { // TODO: Remove attribute when destroy function is implemented. #[allow(unused)] - pins: (Ch::Mclk, Ch::Fs, Ch::Sck, Ch::Sd), + pins: (Option, Ch::Fs, Ch::Sck, Ch::Sd), } impl AsyncMaster { fn new( pins: ( - impl Into, + Option>, impl Into, impl Into, impl Into, ), ) -> Self { Self { - pins: (pins.0.into(), pins.1.into(), pins.2.into(), pins.3.into()), + pins: ( + pins.0.map(Into::into), + pins.1.into(), + pins.2.into(), + pins.3.into(), + ), } } } @@ -164,20 +169,25 @@ impl AsyncMaster { pub struct AsyncSlave { // TODO: Remove attribute when destroy function is implemented. #[allow(unused)] - pins: (Ch::Mclk, Ch::Fs, Ch::Sck, Ch::Sd), + pins: (Option, Ch::Fs, Ch::Sck, Ch::Sd), } impl AsyncSlave { fn new( pins: ( - impl Into, + Option>, impl Into, impl Into, impl Into, ), ) -> Self { Self { - pins: (pins.0.into(), pins.1.into(), pins.2.into(), pins.3.into()), + pins: ( + pins.0.map(Into::into), + pins.1.into(), + pins.2.into(), + pins.3.into(), + ), } } } @@ -609,7 +619,7 @@ where pub fn master_rx( self, pins: ( - impl Into, + Option>, impl Into, impl Into, impl Into, @@ -633,7 +643,7 @@ where pub fn master_tx( self, pins: ( - impl Into, + Option>, impl Into, impl Into, impl Into, @@ -657,7 +667,7 @@ where pub fn slave_rx( self, pins: ( - impl Into, + Option>, impl Into, impl Into, impl Into, @@ -678,7 +688,7 @@ where pub fn slave_tx( self, pins: ( - impl Into, + Option>, impl Into, impl Into, impl Into, diff --git a/src/serial.rs b/src/serial.rs index 06256733..4ddc53ea 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -29,7 +29,6 @@ use crate::gpio::{self, PushPull}; use crate::pac; -use crate::gpio::NoPin; use crate::rcc::{self, Clocks}; pub mod dma; @@ -123,11 +122,6 @@ pub mod config; pub use config::Config; -/// A filler type for when the Tx pin is unnecessary -pub use gpio::NoPin as NoTx; -/// A filler type for when the Rx pin is unnecessary -pub use gpio::NoPin as NoRx; - pub use gpio::alt::SerialAsync as CommonPins; // Implemented by all USART/UART instances @@ -209,14 +203,14 @@ pub struct Serial { pub struct Rx { _word: PhantomData, usart: USART, - pin: USART::Rx, + pin: Option>, } /// Serial transmitter containing TX pin pub struct Tx { _word: PhantomData, usart: USART, - pin: USART::Tx, + pin: Option>, } pub trait SerialExt: Sized + Instance { @@ -232,26 +226,14 @@ pub trait SerialExt: Sized + Instance { tx_pin: impl Into>, config: impl Into, clocks: &Clocks, - ) -> Result, config::InvalidConfig> - where - NoPin: Into>, - { - self.serial((tx_pin, NoPin::new()), config, clocks) - .map(|s| s.split().0) - } + ) -> Result, config::InvalidConfig>; fn rx( self, rx_pin: impl Into>, config: impl Into, clocks: &Clocks, - ) -> Result, config::InvalidConfig> - where - NoPin: Into>, - { - self.serial((NoPin::new(), rx_pin), config, clocks) - .map(|s| s.split().1) - } + ) -> Result, config::InvalidConfig>; } impl Serial { @@ -263,6 +245,17 @@ impl Serial { ), config: impl Into, clocks: &Clocks, + ) -> Result { + Self::_new(uart, (Some(pins.0), Some(pins.1)), config, clocks) + } + fn _new( + uart: USART, + pins: ( + Option>>, + Option>>, + ), + config: impl Into, + clocks: &Clocks, ) -> Result { use self::config::*; @@ -317,8 +310,8 @@ impl Serial { uart.enable_dma(config.dma); let serial = Serial { - tx: Tx::new(uart, pins.0.into()), - rx: Rx::new(unsafe { USART::steal() }, pins.1.into()), + tx: Tx::new(uart, pins.0.map(Into::into)), + rx: Rx::new(unsafe { USART::steal() }, pins.1.map(Into::into)), }; serial.tx.usart.set_stopbits(config.stopbits); Ok(serial) @@ -382,7 +375,12 @@ impl Serial { } #[allow(clippy::type_complexity)] - pub fn release(self) -> (UART, (UART::Tx, UART::Rx)) { + pub fn release( + self, + ) -> ( + UART, + (Option>, Option>), + ) { (self.tx.usart, (self.tx.pin, self.rx.pin)) } } @@ -454,7 +452,7 @@ impl Tx { } impl Rx { - pub(crate) fn new(usart: UART, pin: UART::Rx) -> Self { + pub(crate) fn new(usart: UART, pin: Option>) -> Self { Self { _word: PhantomData, usart, @@ -468,7 +466,7 @@ impl Rx { } impl Tx { - pub(crate) fn new(usart: UART, pin: UART::Tx) -> Self { + pub(crate) fn new(usart: UART, pin: Option>) -> Self { Self { _word: PhantomData, usart, @@ -674,6 +672,22 @@ impl SerialExt for UART { ) -> Result, config::InvalidConfig> { Serial::new(self, pins, config, clocks) } + fn tx( + self, + tx_pin: impl Into>, + config: impl Into, + clocks: &Clocks, + ) -> Result, config::InvalidConfig> { + Serial::tx(self, tx_pin, config, clocks) + } + fn rx( + self, + rx_pin: impl Into>, + config: impl Into, + clocks: &Clocks, + ) -> Result, config::InvalidConfig> { + Serial::rx(self, rx_pin, config, clocks) + } } impl Serial { @@ -682,11 +696,14 @@ impl Serial { tx_pin: impl Into>, config: impl Into, clocks: &Clocks, - ) -> Result, config::InvalidConfig> - where - NoPin: Into>, - { - Self::new(usart, (tx_pin, NoPin::new()), config, clocks).map(|s| s.split().0) + ) -> Result, config::InvalidConfig> { + Self::_new( + usart, + (Some(tx_pin), None::>), + config, + clocks, + ) + .map(|s| s.split().0) } } @@ -696,11 +713,14 @@ impl Serial { rx_pin: impl Into>, config: impl Into, clocks: &Clocks, - ) -> Result, config::InvalidConfig> - where - NoPin: Into>, - { - Self::new(usart, (NoPin::new(), rx_pin), config, clocks).map(|s| s.split().1) + ) -> Result, config::InvalidConfig> { + Self::_new( + usart, + (None::>, Some(rx_pin)), + config, + clocks, + ) + .map(|s| s.split().1) } } diff --git a/src/spi.rs b/src/spi.rs index 99f8eae9..662648dc 100644 --- a/src/spi.rs +++ b/src/spi.rs @@ -3,7 +3,7 @@ use core::ops::{Deref, DerefMut}; use crate::dma::traits::{DMASet, PeriAddress}; use crate::dma::{MemoryToPeripheral, PeripheralToMemory}; -use crate::gpio::{self, NoPin}; +use crate::gpio; use crate::pac; /// Clock polarity @@ -56,13 +56,6 @@ pub enum Error { Crc, } -/// A filler type for when the SCK pin is unnecessary -pub type NoSck = NoPin; -/// A filler type for when the Miso pin is unnecessary -pub type NoMiso = NoPin; -/// A filler type for when the Mosi pin is unnecessary -pub type NoMosi = NoPin; - /// SPI interrupt events #[enumflags2::bitflags] #[cfg_attr(feature = "defmt", derive(defmt::Format))] @@ -171,7 +164,7 @@ pub struct Inner { #[derive(Debug)] pub struct Spi { inner: Inner, - pins: (SPI::Sck, SPI::Miso, SPI::Mosi), + pins: (Option, Option, Option), _operation: PhantomData, } @@ -192,7 +185,12 @@ impl DerefMut for Spi { #[derive(Debug)] pub struct SpiSlave { inner: Inner, - pins: (SPI::Sck, SPI::Miso, SPI::Mosi, Option), + pins: ( + Option, + Option, + Option, + Option, + ), _operation: PhantomData, } @@ -246,13 +244,18 @@ spi! { pac::SPI5: Spi5, SpiSlave5 } #[cfg(feature = "spi6")] spi! { pac::SPI6: Spi6, SpiSlave6 } +#[allow(non_upper_case_globals)] pub trait SpiExt: Sized + Instance { + const NoSck: Option = None; + const NoMiso: Option = None; + const NoMosi: Option = None; + const NoNss: Option = None; fn spi( self, pins: ( - impl Into, - impl Into, - impl Into, + Option>, + Option>, + Option>, ), mode: impl Into, freq: Hertz, @@ -261,21 +264,19 @@ pub trait SpiExt: Sized + Instance { fn spi_bidi( self, - pins: (impl Into, impl Into), + pins: (Option>, Option>), mode: impl Into, freq: Hertz, clocks: &Clocks, - ) -> Spi - where - NoPin: Into; + ) -> Spi; fn spi_slave( self, pins: ( - impl Into, - impl Into, - impl Into, - Option, + Option>, + Option>, + Option>, + Option>, ), mode: impl Into, ) -> SpiSlave; @@ -283,14 +284,12 @@ pub trait SpiExt: Sized + Instance { fn spi_bidi_slave( self, pins: ( - impl Into, - impl Into, - Option, + Option>, + Option>, + Option>, ), mode: impl Into, - ) -> SpiSlave - where - NoPin: Into; + ) -> SpiSlave; } impl SpiExt for SPI { @@ -302,9 +301,9 @@ impl SpiExt for SPI { fn spi( self, pins: ( - impl Into, - impl Into, - impl Into, + Option>, + Option>, + Option>, ), mode: impl Into, freq: Hertz, @@ -319,14 +318,11 @@ impl SpiExt for SPI { /// Otherwise it may lead to the 'wrong last bit in every received byte' problem. fn spi_bidi( self, - pins: (impl Into, impl Into), + pins: (Option>, Option>), mode: impl Into, freq: Hertz, clocks: &Clocks, - ) -> Spi - where - NoPin: Into, - { + ) -> Spi { Spi::new_bidi(self, pins, mode, freq, clocks) } /// Enables the SPI clock, resets the peripheral, sets `Alternate` mode for `pins` and initialize the peripheral as SPI Slave Normal mode. @@ -337,10 +333,10 @@ impl SpiExt for SPI { fn spi_slave( self, pins: ( - impl Into, - impl Into, - impl Into, - Option, + Option>, + Option>, + Option>, + Option>, ), mode: impl Into, ) -> SpiSlave { @@ -354,15 +350,12 @@ impl SpiExt for SPI { fn spi_bidi_slave( self, pins: ( - impl Into, - impl Into, - Option, + Option>, + Option>, + Option>, ), mode: impl Into, - ) -> SpiSlave - where - NoPin: Into, - { + ) -> SpiSlave { SpiSlave::new_bidi(self, pins, mode) } } @@ -472,9 +465,9 @@ impl Spi { pub fn new( spi: SPI, pins: ( - impl Into, - impl Into, - impl Into, + Option>, + Option>, + Option>, ), mode: impl Into, freq: Hertz, @@ -485,7 +478,7 @@ impl Spi { SPI::reset_unchecked(); } - let pins = (pins.0.into(), pins.1.into(), pins.2.into()); + let pins = (pins.0, pins.1, pins.2); Self::_new(spi, pins) .pre_init(mode.into(), freq, SPI::clock(clocks)) @@ -501,20 +494,17 @@ impl Spi { /// Otherwise it may lead to the 'wrong last bit in every received byte' problem. pub fn new_bidi( spi: SPI, - pins: (impl Into, impl Into), + pins: (Option>, Option>), mode: impl Into, freq: Hertz, clocks: &Clocks, - ) -> Self - where - NoPin: Into, - { + ) -> Self { unsafe { SPI::enable_unchecked(); SPI::reset_unchecked(); } - let pins = (pins.0.into(), NoPin::new().into(), pins.1.into()); + let pins = (pins.0, SPI::NoMiso, pins.1); Self::_new(spi, pins) .pre_init(mode.into(), freq, SPI::clock(clocks)) @@ -531,10 +521,10 @@ impl SpiSlave { pub fn new( spi: SPI, pins: ( - impl Into, - impl Into, - impl Into, - Option, + Option>, + Option>, + Option>, + Option>, ), mode: impl Into, ) -> Self { @@ -543,7 +533,7 @@ impl SpiSlave { SPI::reset_unchecked(); } - let pins = (pins.0.into(), pins.1.into(), pins.2.into(), pins.3); + let pins = (pins.0, pins.1, pins.2, pins.3); Self::_new(spi, pins).pre_init(mode.into()).init() } @@ -557,18 +547,19 @@ impl SpiSlave { /// Otherwise it may lead to the 'wrong last bit in every received byte' problem. pub fn new_bidi( spi: SPI, - pins: (impl Into, impl Into, Option), + pins: ( + Option>, + Option>, + Option>, + ), mode: impl Into, - ) -> Self - where - NoPin: Into, - { + ) -> Self { unsafe { SPI::enable_unchecked(); SPI::reset_unchecked(); } - let pins = (pins.0.into(), pins.1.into(), NoPin::new().into(), pins.2); + let pins = (pins.0, pins.1, SPI::NoMosi, pins.2); Self::_new(spi, pins).pre_init(mode.into()).init() } @@ -576,23 +567,49 @@ impl SpiSlave { impl Spi { #[allow(clippy::type_complexity)] - pub fn release(self) -> (SPI, (SPI::Sck, SPI::Miso, SPI::Mosi)) { + pub fn release( + self, + ) -> ( + SPI, + (Option, Option, Option), + ) { (self.inner.spi, self.pins) } } impl SpiSlave { #[allow(clippy::type_complexity)] - pub fn release(self) -> (SPI, (SPI::Sck, SPI::Miso, SPI::Mosi, Option)) { + pub fn release( + self, + ) -> ( + SPI, + ( + Option, + Option, + Option, + Option, + ), + ) { (self.inner.spi, self.pins) } } impl Spi { - fn _new(spi: SPI, pins: (SPI::Sck, SPI::Miso, SPI::Mosi)) -> Self { + fn _new( + spi: SPI, + pins: ( + Option>, + Option>, + Option>, + ), + ) -> Self { Self { inner: Inner::new(spi), - pins, + pins: ( + pins.0.map(Into::into), + pins.1.map(Into::into), + pins.2.map(Into::into), + ), _operation: PhantomData, } } @@ -606,10 +623,23 @@ impl Spi { } impl SpiSlave { - fn _new(spi: SPI, pins: (SPI::Sck, SPI::Miso, SPI::Mosi, Option)) -> Self { + fn _new( + spi: SPI, + pins: ( + Option>, + Option>, + Option>, + Option>, + ), + ) -> Self { Self { inner: Inner::new(spi), - pins, + pins: ( + pins.0.map(Into::into), + pins.1.map(Into::into), + pins.2.map(Into::into), + pins.3.map(Into::into), + ), _operation: PhantomData, } }