From dbd18f69a34edd3104701c18b3581377abf0a7ff Mon Sep 17 00:00:00 2001 From: Andrey Zgarbul Date: Sat, 5 Oct 2024 23:03:15 +0300 Subject: [PATCH 1/3] clean --- examples/serial-dma-tx.rs | 27 ++++++++++----------------- examples/serial.rs | 20 +++++++++----------- 2 files changed, 19 insertions(+), 28 deletions(-) diff --git a/examples/serial-dma-tx.rs b/examples/serial-dma-tx.rs index 5e839638..757f8525 100644 --- a/examples/serial-dma-tx.rs +++ b/examples/serial-dma-tx.rs @@ -10,11 +10,7 @@ use panic_halt as _; use cortex_m::asm; use cortex_m_rt::entry; -use stm32f1xx_hal::{ - pac, - prelude::*, - serial::{Config, Serial}, -}; +use stm32f1xx_hal::{pac, prelude::*}; #[entry] fn main() -> ! { @@ -28,31 +24,28 @@ fn main() -> ! { let mut afio = p.AFIO.constrain(); let channels = p.DMA1.split(); - let mut gpioa = p.GPIOA.split(); - // let mut gpiob = p.GPIOB.split(); + let gpioa = p.GPIOA.split(); + // let gpiob = p.GPIOB.split(); // USART1 - let tx = gpioa.pa9.into_alternate_push_pull(&mut gpioa.crh); + let tx = gpioa.pa9; let rx = gpioa.pa10; // USART1 - // let tx = gpiob.pb6.into_alternate_push_pull(&mut gpiob.crl); + // let tx = gpiob.pb6; // let rx = gpiob.pb7; // USART2 - // let tx = gpioa.pa2.into_alternate_push_pull(&mut gpioa.crl); + // let tx = gpioa.pa2; // let rx = gpioa.pa3; // USART3 - // let tx = gpiob.pb10.into_alternate_push_pull(&mut gpiob.crh); + // let tx = gpiob.pb10; // let rx = gpiob.pb11; - let serial = Serial::new( - p.USART1, - (tx, rx, &mut afio.mapr), - Config::default().baudrate(9600.bps()), - &clocks, - ); + let serial = p + .USART1 + .serial((tx, rx, &mut afio.mapr), 9600.bps(), &clocks); let tx = serial.tx.with_dma(channels.4); diff --git a/examples/serial.rs b/examples/serial.rs index e62e0cf2..e7672eaa 100644 --- a/examples/serial.rs +++ b/examples/serial.rs @@ -14,7 +14,7 @@ use cortex_m::asm; use nb::block; use cortex_m_rt::entry; -use stm32f1xx_hal::{pac, prelude::*, serial::Config}; +use stm32f1xx_hal::{pac, prelude::*}; #[entry] fn main() -> ! { @@ -34,33 +34,31 @@ fn main() -> ! { let mut afio = p.AFIO.constrain(); // Prepare the GPIOB peripheral - let mut gpiob = p.GPIOB.split(); + let gpiob = p.GPIOB.split(); // USART1 - // let tx = gpioa.pa9.into_alternate_push_pull(&mut gpioa.crh); + // let tx = gpioa.pa9; // let rx = gpioa.pa10; // USART1 - // let tx = gpiob.pb6.into_alternate_push_pull(&mut gpiob.crl); + // let tx = gpiob.pb6; // let rx = gpiob.pb7; // USART2 - // let tx = gpioa.pa2.into_alternate_push_pull(&mut gpioa.crl); + // let tx = gpioa.pa2; // let rx = gpioa.pa3; // USART3 // Configure pb10 as a push_pull output, this will be the tx pin - let tx = gpiob.pb10.into_alternate_push_pull(&mut gpiob.crh); + let tx = gpiob.pb10; // Take ownership over pb11 let rx = gpiob.pb11; // Set up the usart device. Take ownership over the USART register and tx/rx pins. The rest of // the registers are used to enable and configure the device. - let mut serial = p.USART3.serial( - (tx, rx, &mut afio.mapr), - Config::default().baudrate(9600.bps()), - &clocks, - ); + let mut serial = p + .USART3 + .serial((tx, rx, &mut afio.mapr), 9600.bps(), &clocks); // Loopback test. Write `X` and wait until the write is successful. let sent = b'X'; From 36aecc8e6210c54a445a6e206a4e464b9a8fb67c Mon Sep 17 00:00:00 2001 From: Andrey Zgarbul Date: Wed, 12 Apr 2023 21:33:18 +0300 Subject: [PATCH 2/3] pwm --- CHANGELOG.md | 5 +- examples/pwm.rs | 19 +- examples/pwm_custom.rs | 9 +- examples/pwm_input.rs | 12 +- examples/qei.rs | 6 +- src/prelude.rs | 2 + src/qei.rs | 142 ++++++----- src/timer/hal_02.rs | 14 +- src/timer/pins.rs | 538 +++++++++++++++++++++++++++++++++++++---- src/timer/pwm.rs | 203 ++++------------ src/timer/pwm_input.rs | 146 ++++++----- 11 files changed, 748 insertions(+), 348 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5feee07a..065f4276 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,9 +9,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Breaking changes -- Relax pin type generics for `Serial`, `I2c`, `Spi`, `Can`. [#462] +- Relax pin type generics for `Serial`, `I2c`, `Spi`, `Can`, `Pwm`, `Qei`, `PwmInput`. Use enums of pin tuples and `Enum::from<(tuple)>` for pin remap before passing to peripheral. - Remove `RemapStruct`s. [#462] [#506] [#509] + Remove `RemapStruct`s. [#462] [#506] [#507] [#509] - Use independent `Spi` and `SpiSlave` structures instead of `OP` generic [#462] - Take `&Clocks` instead of `Clocks` [#498] - Temporary replace `stm32f1` with `stm32f1-staging` [#503] @@ -56,6 +56,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). [#503]: https://github.com/stm32-rs/stm32f1xx-hal/pull/503 [#505]: https://github.com/stm32-rs/stm32f1xx-hal/pull/505 [#506]: https://github.com/stm32-rs/stm32f1xx-hal/pull/506 +[#507]: https://github.com/stm32-rs/stm32f1xx-hal/pull/507 [#509]: https://github.com/stm32-rs/stm32f1xx-hal/pull/509 [#511]: https://github.com/stm32-rs/stm32f1xx-hal/pull/511 diff --git a/examples/pwm.rs b/examples/pwm.rs index d15b899a..e4f6a140 100644 --- a/examples/pwm.rs +++ b/examples/pwm.rs @@ -9,12 +9,7 @@ use panic_halt as _; use cortex_m::asm; use cortex_m_rt::entry; -use stm32f1xx_hal::{ - pac, - prelude::*, - time::ms, - timer::{Channel, Tim2NoRemap}, -}; +use stm32f1xx_hal::{pac, prelude::*, time::ms, timer, timer::Channel}; #[entry] fn main() -> ! { @@ -27,16 +22,16 @@ fn main() -> ! { let mut afio = p.AFIO.constrain(); - let mut gpioa = p.GPIOA.split(); + let gpioa = p.GPIOA.split(); // let mut gpiob = p.GPIOB.split(); // TIM2 - let c1 = gpioa.pa0.into_alternate_push_pull(&mut gpioa.crl); - let c2 = gpioa.pa1.into_alternate_push_pull(&mut gpioa.crl); - let c3 = gpioa.pa2.into_alternate_push_pull(&mut gpioa.crl); + let c1 = gpioa.pa0; + let c2 = gpioa.pa1; + let c3 = gpioa.pa2; // If you don't want to use all channels, just leave some out // let c4 = gpioa.pa3.into_alternate_push_pull(&mut gpioa.crl); - let pins = (c1, c2, c3); + let pins = (c1, c2, c3, &mut afio.mapr); // TIM3 // let c1 = gpioa.pa6.into_alternate_push_pull(&mut gpioa.crl); @@ -55,7 +50,7 @@ fn main() -> ! { // or let mut pwm = p .TIM2 - .pwm_hz::(pins, &mut afio.mapr, 1.kHz(), &clocks); + .pwm_hz::(pins, 1.kHz(), &clocks); // Enable clock on each of the channels pwm.enable(Channel::C1); diff --git a/examples/pwm_custom.rs b/examples/pwm_custom.rs index 95d3e2f0..54822e31 100644 --- a/examples/pwm_custom.rs +++ b/examples/pwm_custom.rs @@ -8,7 +8,11 @@ use panic_halt as _; use cortex_m::asm; -use stm32f1xx_hal::{pac, prelude::*, timer::Timer}; +use stm32f1xx_hal::{ + pac, + prelude::*, + timer::{self, Timer}, +}; use cortex_m_rt::entry; @@ -30,7 +34,8 @@ fn main() -> ! { let p0 = pb4.into_alternate_push_pull(&mut gpiob.crl); let p1 = gpiob.pb5.into_alternate_push_pull(&mut gpiob.crl); - let pwm = Timer::new(p.TIM3, &clocks).pwm_hz((p0, p1), &mut afio.mapr, 1.kHz()); + let pwm = Timer::new(p.TIM3, &clocks) + .pwm_hz::((p0, p1, &mut afio.mapr), 1.kHz()); let max = pwm.get_max_duty(); diff --git a/examples/pwm_input.rs b/examples/pwm_input.rs index 7e34230f..52bd15c4 100644 --- a/examples/pwm_input.rs +++ b/examples/pwm_input.rs @@ -7,11 +7,7 @@ use panic_halt as _; use cortex_m_rt::entry; -use stm32f1xx_hal::{ - pac, - prelude::*, - timer::{pwm_input::*, Timer}, -}; +use stm32f1xx_hal::{pac, prelude::*, timer::pwm_input::*}; #[entry] fn main() -> ! { @@ -31,11 +27,11 @@ fn main() -> ! { let (_pa15, _pb3, pb4) = afio.mapr.disable_jtag(gpioa.pa15, gpiob.pb3, gpiob.pb4); let pb5 = gpiob.pb5; - let pwm_input = Timer::new(p.TIM3, &clocks).pwm_input( - (pb4, pb5), - &mut afio.mapr, + let pwm_input = p.TIM3.pwm_input( + (pb4, pb5, &mut afio.mapr), &mut dbg, Configuration::Frequency(10.kHz()), + &clocks, ); loop { diff --git a/examples/qei.rs b/examples/qei.rs index 766e6f74..48f8a8c7 100644 --- a/examples/qei.rs +++ b/examples/qei.rs @@ -9,7 +9,7 @@ use panic_semihosting as _; use cortex_m_semihosting::hprintln; use cortex_m_rt::entry; -use stm32f1xx_hal::{pac, prelude::*, qei::QeiOptions, timer::Timer}; +use stm32f1xx_hal::{pac, prelude::*, qei::QeiOptions}; #[entry] fn main() -> ! { @@ -38,7 +38,9 @@ fn main() -> ! { let c1 = gpiob.pb6; let c2 = gpiob.pb7; - let qei = Timer::new(dp.TIM4, &clocks).qei((c1, c2), &mut afio.mapr, QeiOptions::default()); + let qei = dp + .TIM4 + .qei((c1, c2, &mut afio.mapr), QeiOptions::default(), &clocks); let mut delay = cp.SYST.delay(&clocks); loop { diff --git a/src/prelude.rs b/src/prelude.rs index 1da61912..59792134 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -13,10 +13,12 @@ pub use crate::gpio::GpioExt as _stm32_hal_gpio_GpioExt; pub use crate::hal_02::adc::OneShot as _embedded_hal_adc_OneShot; pub use crate::hal_02::prelude::*; pub use crate::i2c::I2cExt as _; +pub use crate::qei::QeiExt as _; pub use crate::rcc::RccExt as _stm32_hal_rcc_RccExt; pub use crate::serial::SerialExt as _; pub use crate::spi::SpiExt as _; pub use crate::time::U32Ext as _stm32_hal_time_U32Ext; +pub use crate::timer::pwm_input::PwmInputExt as _; #[cfg(feature = "rtic")] pub use crate::timer::MonoTimerExt as _stm32f4xx_hal_timer_MonoTimerExt; pub use crate::timer::PwmExt as _stm32f4xx_hal_timer_PwmExt; diff --git a/src/qei.rs b/src/qei.rs index a79c75af..1f5fe404 100644 --- a/src/qei.rs +++ b/src/qei.rs @@ -4,16 +4,12 @@ NOTE: In some cases you need to specify remap you need, especially for TIM2 (see [Alternate function remapping](super::timer)): */ -use core::marker::PhantomData; - use crate::pac; use embedded_hal_02 as hal; pub use hal::Direction; -use crate::afio::MAPR; - -use crate::timer::pwm_input::Pins; -use crate::timer::{pins::sealed::Remap, Timer}; +use crate::rcc::Clocks; +use crate::timer::{InPins, InputPins, Timer}; /// SMS (Slave Mode Selection) register #[derive(Copy, Clone, Debug)] @@ -60,81 +56,107 @@ impl Default for QeiOptions { } } -pub struct Qei { +pub struct Qei { tim: TIM, - pins: PINS, - _remap: PhantomData, + pins: (TIM::InCh1, TIM::InCh2), +} + +pub trait QeiExt: Sized + InputPins { + fn qei( + self, + pins: impl Into>, + options: QeiOptions, + clocks: &Clocks, + ) -> Qei; } #[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity"))] -impl Timer { - pub fn qei( +impl QeiExt for pac::TIM1 { + fn qei( self, - pins: PINS, - mapr: &mut MAPR, + pins: impl Into>, options: QeiOptions, - ) -> Qei - where - REMAP: Remap, - PINS: Pins, - { - mapr.modify_mapr(|_, w| unsafe { w.tim1_remap().bits(REMAP::REMAP) }); + clocks: &Clocks, + ) -> Qei { + Timer::new(self, clocks).qei(pins, options) + } +} +#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity"))] +impl Timer { + pub fn qei( + self, + pins: impl Into::InCh1, ::InCh2>>, + options: QeiOptions, + ) -> Qei { let Self { tim, clk: _ } = self; Qei::_tim1(tim, pins, options) } } -impl Timer { - pub fn qei( +impl QeiExt for pac::TIM2 { + fn qei( self, - pins: PINS, - mapr: &mut MAPR, + pins: impl Into>, options: QeiOptions, - ) -> Qei - where - REMAP: Remap, - PINS: Pins, - { - mapr.modify_mapr(|_, w| unsafe { w.tim2_remap().bits(REMAP::REMAP) }); + clocks: &Clocks, + ) -> Qei { + Timer::new(self, clocks).qei(pins, options) + } +} +impl Timer { + pub fn qei( + self, + pins: impl Into::InCh1, ::InCh2>>, + options: QeiOptions, + ) -> Qei { let Self { tim, clk: _ } = self; Qei::_tim2(tim, pins, options) } } -impl Timer { - pub fn qei( +impl QeiExt for pac::TIM3 { + fn qei( self, - pins: PINS, - mapr: &mut MAPR, + pins: impl Into>, options: QeiOptions, - ) -> Qei - where - REMAP: Remap, - PINS: Pins, - { - mapr.modify_mapr(|_, w| unsafe { w.tim3_remap().bits(REMAP::REMAP) }); + clocks: &Clocks, + ) -> Qei { + Timer::new(self, clocks).qei(pins, options) + } +} +impl Timer { + pub fn qei( + self, + pins: impl Into::InCh1, ::InCh2>>, + options: QeiOptions, + ) -> Qei { let Self { tim, clk: _ } = self; Qei::_tim3(tim, pins, options) } } #[cfg(feature = "medium")] -impl Timer { - pub fn qei( +impl QeiExt for pac::TIM4 { + fn qei( self, - pins: PINS, - mapr: &mut MAPR, + pins: impl Into>, options: QeiOptions, - ) -> Qei - where - REMAP: Remap, - PINS: Pins, - { - mapr.modify_mapr(|_, w| w.tim4_remap().bit(REMAP::REMAP == 1)); + clocks: &Clocks, + ) -> Qei { + Timer::new(self, &clocks).qei(pins, options) + } +} +#[cfg(feature = "medium")] +impl Timer { + pub fn qei( + self, + pins: impl Into::InCh1, ::InCh2>>, + options: QeiOptions, + ) -> Qei { let Self { tim, clk: _ } = self; Qei::_tim4(tim, pins, options) } @@ -142,8 +164,14 @@ impl Timer { macro_rules! hal { ($TIMX:ty: $timX:ident, $timXen:ident, $timXrst:ident) => { - impl Qei<$TIMX, REMAP, PINS> { - fn $timX(tim: $TIMX, pins: PINS, options: QeiOptions) -> Self { + impl Qei<$TIMX> { + fn $timX( + tim: $TIMX, + pins: impl Into::InCh1, <$TIMX as InputPins>::InCh2>>, + options: QeiOptions, + ) -> Self { + let pins = pins.into(); + // Configure TxC1 and TxC2 as captures tim.ccmr1_input().write(|w| w.cc1s().ti1().cc2s().ti2()); @@ -163,17 +191,21 @@ macro_rules! hal { Qei { tim, - pins, - _remap: PhantomData, + pins: (pins.c1, pins.c2), } } - pub fn release(self) -> ($TIMX, PINS) { + pub fn release( + self, + ) -> ( + $TIMX, + (<$TIMX as InputPins>::InCh1, <$TIMX as InputPins>::InCh2), + ) { (self.tim, self.pins) } } - impl hal::Qei for Qei<$TIMX, REMAP, PINS> { + impl hal::Qei for Qei<$TIMX> { type Count = u16; fn count(&self) -> u16 { diff --git a/src/timer/hal_02.rs b/src/timer/hal_02.rs index 42c4d26d..3b734128 100644 --- a/src/timer/hal_02.rs +++ b/src/timer/hal_02.rs @@ -11,8 +11,8 @@ use fugit::{ExtU32, HertzU32 as Hertz, TimerDurationU32}; use void::Void; use super::{ - pins::sealed::Remap, pwm::Pins, Channel, Counter, CounterHz, Delay, Error, Instance, Pwm, - PwmChannel, PwmHz, SysCounter, SysCounterHz, SysDelay, WithPwm, + pwm::Pins, Channel, Counter, CounterHz, Delay, Error, Instance, Pwm, PwmChannel, PwmHz, + SysCounter, SysCounterHz, SysDelay, WithPwm, }; impl DelayUs for SysDelay { @@ -153,11 +153,10 @@ impl embedded_hal_02::PwmPin for PwmChanne } } -impl embedded_hal_02::Pwm for PwmHz +impl embedded_hal_02::Pwm for PwmHz where TIM: Instance + WithPwm, - REMAP: Remap, - PINS: Pins, + PINS: Pins, { type Channel = Channel; type Duty = u16; @@ -264,11 +263,10 @@ impl Cancel for Counter { } } -impl embedded_hal_02::Pwm for Pwm +impl embedded_hal_02::Pwm for Pwm where TIM: Instance + WithPwm, - REMAP: Remap, - PINS: Pins, + PINS: Pins, { type Channel = Channel; type Duty = u16; diff --git a/src/timer/pins.rs b/src/timer/pins.rs index e0e9c716..a244ee0e 100644 --- a/src/timer/pins.rs +++ b/src/timer/pins.rs @@ -1,61 +1,517 @@ +use crate::afio::{Remap, MAPR}; +use crate::gpio::{self, Alternate, Cr}; use crate::pac; -pub trait CPin {} -pub struct Ch; pub const C1: u8 = 0; pub const C2: u8 = 1; pub const C3: u8 = 2; pub const C4: u8 = 3; -pub(crate) mod sealed { - pub trait Remap { - type Periph; - const REMAP: u8; +pub struct InPins { + pub c1: CH1, + pub c2: CH2, +} + +impl From<(CH1, CH2)> for InPins { + fn from(value: (CH1, CH2)) -> Self { + Self { + c1: value.0, + c2: value.1, + } + } +} + +pinsx!(Pins2: (CH1, c1, C1), (CH2, c2, C2)); +pinsx!(Pins3: (CH1, c1, C1), (CH2, c2, C2), (CH3, c3, C3)); +pinsx!(Pins4: (CH1, c1, C1), (CH2, c2, C2), (CH3, c3, C3), (CH4, c4, C4)); + +macro_rules! pinsx { + ($name:ident: $(($CH:ident, $c:ident, $C:ident)),+) => { + pub struct $name<$($CH),+> { + $( + pub $c: $CH, + )+ + } + + impl<$($CH),+> From<($($CH),+)> for $name<$($CH),+> { + fn from(value: ($($CH),+)) -> Self { + let ($($c),+) = value; + Self { + $( + $c, + )+ + } + } + } + + impl Pins for $name<$($CH),+> + where + $( + $CH: Pins, + )+ + { + const C1: bool = false $(|| $CH::C1)+; + const C2: bool = false $(|| $CH::C2)+; + const C3: bool = false $(|| $CH::C3)+; + const C4: bool = false $(|| $CH::C4)+; + type Channels = ($($CH::Channels),+); + fn split() -> Self::Channels { + ($($CH::split()),+) + } + } + }; +} +use pinsx; + +#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity"))] +pub mod tim1 { + use super::*; + + remap4! { + pac::TIM1: [ + PA8, PA9, PA10, PA11 => MAPR: 0; + PE9, PE11, PE13, PE14 => MAPR: 3; + ] + } + remap12! { + pac::TIM1: [ + PA8, PA9 => MAPR: 0; + PE9, PE11 => MAPR: 3; + ] + } + remap_input! { + pac::TIM1: [ + PA8, PA9 => MAPR: 0; + PE9, PE11 => MAPR: 3; + ] + } + remap34! { + pac::TIM1: [ + PA10, PA11 => MAPR: 0; + PE13, PE14 => MAPR: 3; + ] + } + + out_enums! { + Ch1: PA8, PE9; + Ch2: PA9, PE11; + Ch3: PA10, PE13; + Ch4: PA11, PE14; + } + in_enums! { + InCh1: PA8, PE9; + InCh2: PA9, PE11; + } +} + +pub mod tim2 { + use super::*; + + remap4! { + pac::TIM2: [ + PA0, PA1, PA2, PA3 => MAPR: 0; + PA15, PB3, PA2, PA3 => MAPR: 1; + PA0, PA1, PB10, PB11 => MAPR: 2; + PA15, PB3, PB10, PB11 => MAPR: 3; + ] + } + remap12! { + pac::TIM2: [ + PA0, PA1 => MAPR: 0; + PA15, PB3 => MAPR: 1; + ] + } + remap_input! { + pac::TIM2: [ + PA0, PA1 => MAPR: 0; + PA15, PB3 => MAPR: 1; + ] + } + remap34! { + pac::TIM2: [ + PA2, PA3 => MAPR: 0; + PB10, PB11 => MAPR: 2; + ] + } + + out_enums! { + Ch1: PA0, PA15; + Ch2: PA1, PB3; + Ch3: PA2, PB10; + Ch4: PA3, PB11; + } + in_enums! { + InCh1: PA0, PA15; + InCh2: PA1, PB3; + } +} + +pub mod tim3 { + use super::*; + + remap4! { + pac::TIM3: [ + PA6, PA7, PB0, PB1 => MAPR: 0; + PB4, PB5, PB0, PB1 => MAPR: 2; + PC6, PC7, PC8, PC9 => MAPR: 3; + ] + } + remap12! { + pac::TIM3: [ + PA6, PA7 => MAPR: 0; + PB4, PB5 => MAPR: 2; + PC6, PC7 => MAPR: 3; + ] + } + remap_input! { + pac::TIM3: [ + PA6, PA7 => MAPR: 0; + PB4, PB5 => MAPR: 2; + PC6, PC7 => MAPR: 3; + ] + } + remap34! { + pac::TIM3: [ + PB0, PB1 => MAPR: 0; + PC8, PC9 => MAPR: 3; + ] + } + + out_enums! { + Ch1: PA6, PB4, PC6; + Ch2: PA7, PB5, PC7; + Ch3: PB0, PC8; + Ch4: PB1, PC9; + } + in_enums! { + InCh1: PA6, PB4, PC6; + InCh2: PA7, PB5, PC7; + } +} + +#[cfg(feature = "medium")] +pub mod tim4 { + use super::*; + + remap4! { + pac::TIM4: [ + PB6, PB7, PB8, PB9 => MAPR: 0; + PD12, PD13, PD14, PD15 => MAPR: 1; + ] + } + remap12! { + pac::TIM4: [ + PB6, PB7 => MAPR: 0; + PD12, PD13 => MAPR: 1; + ] + } + remap_input! { + pac::TIM4: [ + PB6, PB7 => MAPR: 0; + PD12, PD13 => MAPR: 1; + ] + } + remap34! { + pac::TIM4: [ + PB8, PB9 => MAPR: 0; + PD14, PD15 => MAPR: 1; + ] + } - fn remap(mapr: &mut crate::afio::MAPR); + out_enums! { + Ch1: PB6, PD12; + Ch2: PB7, PD13; + Ch3: PB8, PD14; + Ch4: PB9, PD15; + } + in_enums! { + InCh1: PB6, PD12; + InCh2: PB7, PD13; } } -macro_rules! remap { - ($($name:ident: ($TIMX:ty, $state:literal, $P1:ident, $P2:ident, $P3:ident, $P4:ident, { $remapex:expr }),)+) => { +macro_rules! out_enums { + ($($Ch: ident: $($P:ident),+;)+) => { $( - pub struct $name; - impl sealed::Remap for $name { - type Periph = $TIMX; - const REMAP: u8 = $state; + pub enum $Ch { + $( + $P(gpio::$P), + )+ + } + )+ + }; +} +use out_enums; +macro_rules! in_enums { + ($($Ch: ident: $($P:ident),+;)+) => { + $( + pub enum $Ch { + $( + $P(gpio::$P), + )+ + } + )+ + }; +} +use in_enums; + +macro_rules! remap4 { + ($TIM:ty: [ + $($P1:ident, $P2:ident, $P3:ident, $P4:ident $( => $MAPR:ident: $remap:literal)?;)+ + ]) => { + pub type Channels1234 = Pins4; + remap_combo! { + $TIM; C1, C2, C3, C4: [ + $($P1, $P2, $P3, $P4 $( => $MAPR: $remap)?;)+ + ] + } + pub type Channels123 = Pins3; + remap_combo! { + $TIM; (C1, Ch1), (C2, Ch2), (C3, Ch3): [ + $($P1, $P2, $P3 $( => $MAPR: $remap)?;)+ + ] + } + pub type Channels124 = Pins3; + remap_combo! { + $TIM; (C1, Ch1), (C2, Ch2), (C4, Ch4): [ + $($P1, $P2, $P4 $( => $MAPR: $remap)?;)+ + ] + } + pub type Channels134 = Pins3; + remap_combo! { + $TIM; (C1, Ch1), (C3, Ch3), (C4, Ch4): [ + $($P1, $P3, $P4 $( => $MAPR: $remap)?;)+ + ] + } + pub type Channels234 = Pins3; + remap_combo! { + $TIM; (C2, Ch2), (C3, Ch3), (C4, Ch4): [ + $($P2, $P3, $P4 $( => $MAPR: $remap)?;)+ + ] + } + pub type Channels13 = Pins2; + remap_combo! { + $TIM; (C1, Ch1), (C3, Ch3): [ + $($P1, $P3 $( => $MAPR: $remap)?;)+ + ] + } + pub type Channels14 = Pins2; + remap_combo! { + $TIM; (C1, Ch1), (C4, Ch4): [ + $($P1, $P4 $( => $MAPR: $remap)?;)+ + ] + } + pub type Channels23 = Pins2; + remap_combo! { + $TIM; (C2, Ch2), (C3, Ch3): [ + $($P2, $P3 $( => $MAPR: $remap)?;)+ + ] + } + pub type Channels24 = Pins2; + remap_combo! { + $TIM; (C2, Ch2), (C4, Ch4): [ + $($P2, $P4 $( => $MAPR: $remap)?;)+ + ] + } + } +} +use remap4; + +macro_rules! remap12 { + ($TIM:ty: [ + $($P1:ident, $P2:ident $( => $MAPR:ident: $remap:literal)?;)+ + ]) => { + pub type Channels12 = Pins2; + remap_combo! { + $TIM; (C1, Ch1), (C2, Ch2): [ + $($P1, $P2 $( => $MAPR: $remap)?;)+ + ] + } + remap_combo! { + $TIM; (C1, Ch1): [ + $($P1 $( => $MAPR: $remap)?;)+ + ] + } + remap_combo! { + $TIM; (C2, Ch2): [ + $($P2 $( => $MAPR: $remap)?;)+ + ] + } + } +} +use remap12; + +macro_rules! remap34 { + ($TIM:ty: [ + $($P1:ident, $P2:ident $( => $MAPR:ident: $remap:literal)?;)+ + ]) => { + pub type Channels34 = Pins2; + remap_combo! { + $TIM; (C3, Ch3), (C4, Ch4): [ + $($P1, $P2 $( => $MAPR: $remap)?;)+ + ] + } + remap_combo! { + $TIM; (C3, Ch3): [ + $($P1 $( => $MAPR: $remap)?;)+ + ] + } + remap_combo! { + $TIM; (C4, Ch4): [ + $($P2 $( => $MAPR: $remap)?;)+ + ] + } + } +} +use remap34; + +macro_rules! remap_combo { + ($TIM:ty; $C1:ident, $C2:ident, $C3:ident, $C4:ident: [ + $($P0:ident, $P1:ident, $P2:ident, $P3:ident $( => $MAPR:ident: $remap:literal)?;)+ + ]) => { + $( + impl From<(gpio::$P0, gpio::$P1, gpio::$P2, gpio::$P3 $(, &mut $MAPR)?)> for Pins4 { + fn from(p: (gpio::$P0, gpio::$P1, gpio::$P2, gpio::$P3 $(, &mut $MAPR)?)) -> Self { + $(<$TIM>::remap(p.4, $remap);)? + Self { c1: Ch1::$P0(p.0), c2: Ch2::$P1(p.1), c3: Ch3::$P2(p.2), c4: Ch4::$P3(p.3) } + } + } + + impl From<(gpio::$P0, gpio::$P1, gpio::$P2, gpio::$P3 $(, &mut $MAPR)?)> for Pins4 { + fn from(p: (gpio::$P0, gpio::$P1, gpio::$P2, gpio::$P3 $(, &mut $MAPR)?)) -> Self { + let p0 = p.0.into_mode(&mut Cr); + let p1 = p.1.into_mode(&mut Cr); + let p2 = p.2.into_mode(&mut Cr); + let p3 = p.3.into_mode(&mut Cr); + $(<$TIM>::remap(p.4, $remap);)? + Self { c1: Ch1::$P0(p0), c2: Ch2::$P1(p1), c3: Ch3::$P2(p2), c4: Ch4::$P3(p3) } + } + } + )+ + }; + + ($TIM:ty; ($C1:ident, $Ch1:ident), ($C2:ident, $Ch2:ident), ($C3:ident, $Ch3:ident): [ + $($P0:ident, $P1:ident, $P2:ident $( => $MAPR:ident: $remap:literal)?;)+ + ]) => { + $( + impl From<(gpio::$P0, gpio::$P1, gpio::$P2 $(, &mut $MAPR)?)> for Pins3<$Ch1, $Ch2, $Ch3> { + fn from(p: (gpio::$P0, gpio::$P1, gpio::$P2 $(, &mut $MAPR)?)) -> Self { + $(<$TIM>::remap(p.3, $remap);)? + Self { c1: $Ch1::$P0(p.0), c2: $Ch2::$P1(p.1), c3: $Ch3::$P2(p.2) } + } + } - fn remap(mapr: &mut crate::afio::MAPR) { - mapr.modify_mapr($remapex); + impl From<(gpio::$P0, gpio::$P1, gpio::$P2 $(, &mut $MAPR)?)> for Pins3<$Ch1, $Ch2, $Ch3> { + fn from(p: (gpio::$P0, gpio::$P1, gpio::$P2 $(, &mut $MAPR)?)) -> Self { + let p0 = p.0.into_mode(&mut Cr); + let p1 = p.1.into_mode(&mut Cr); + let p2 = p.2.into_mode(&mut Cr); + $(<$TIM>::remap(p.3, $remap);)? + Self { c1: $Ch1::$P0(p0), c2: $Ch2::$P1(p1), c3: $Ch3::$P2(p2) } } } - impl CPin<$name, 0> for crate::gpio::$P1 {} - impl CPin<$name, 1> for crate::gpio::$P2 {} - impl CPin<$name, 2> for crate::gpio::$P3 {} - impl CPin<$name, 3> for crate::gpio::$P4 {} )+ + }; + + ($TIM:ty; ($C1:ident, $Ch1:ident), ($C2:ident, $Ch2:ident): [ + $($P0:ident, $P1:ident $( => $MAPR:ident: $remap:literal)?;)+ + ]) => { + $( + impl From<(gpio::$P0, gpio::$P1 $(, &mut $MAPR)?)> for Pins2<$Ch1, $Ch2> { + fn from(p: (gpio::$P0, gpio::$P1 $(, &mut $MAPR)?)) -> Self { + $(<$TIM>::remap(p.2, $remap);)? + Self { c1: $Ch1::$P0(p.0), c2: $Ch2::$P1(p.1) } + } + } + + impl From<(gpio::$P0, gpio::$P1 $(, &mut $MAPR)?)> for Pins2<$Ch1, $Ch2> { + fn from(p: (gpio::$P0, gpio::$P1 $(, &mut $MAPR)?)) -> Self { + let p0 = p.0.into_mode(&mut Cr); + let p1 = p.1.into_mode(&mut Cr); + $(<$TIM>::remap(p.2, $remap);)? + Self { c1: $Ch1::$P0(p0), c2: $Ch2::$P1(p1) } + } + } + )+ + }; + + ($TIM:ty; ($C:ident, $Ch:ident): [ + $($P0:ident $( => $MAPR:ident: $remap:literal)?;)+ + ]) => { + impl Pins<$TIM> for $Ch { + const $C: bool = true; + type Channels = PwmChannel<$TIM, $C>; + fn split() -> Self::Channels { + PwmChannel::new() + } + } + + $( + impl From<(gpio::$P0 $(, &mut $MAPR)?)> for $Ch { + fn from(p: (gpio::$P0 $(, &mut $MAPR)?)) -> Self { + $(<$TIM>::remap(p.1, $remap);)? + $Ch::$P0(p.0) + } + } + + impl From<(gpio::$P0 $(, &mut $MAPR)?)> for $Ch { + fn from(p: (gpio::$P0 $(, &mut $MAPR)?)) -> Self { + let p0 = p.0.into_mode(&mut Cr); + $(<$TIM>::remap(p.1, $remap);)? + $Ch::$P0(p0) + } + } + )+ + }; +} +use remap_combo; + +use super::{Channel, PwmChannel}; + +pub trait Pins { + const C1: bool = false; + const C2: bool = false; + const C3: bool = false; + const C4: bool = false; + type Channels; + + fn check_used(c: Channel) -> Channel { + if (c == Channel::C1 && Self::C1) + || (c == Channel::C2 && Self::C2) + || (c == Channel::C3 && Self::C3) + || (c == Channel::C4 && Self::C4) + { + c + } else { + panic!("Unused channel") + } } + + fn split() -> Self::Channels; } -#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity"))] -remap!( - Tim1NoRemap: (pac::TIM1, 0b00, PA8, PA9, PA10, PA11, {|_, w| unsafe { w.tim1_remap().bits(Self::REMAP)}}), - //Tim1PartialRemap: (pac::TIM1, 0b01, PA8, PA9, PA10, PA11), - Tim1FullRemap: (pac::TIM1, 0b11, PE9, PE11, PE13, PE14, {|_, w| unsafe { w.tim1_remap().bits(Self::REMAP)}}), -); - -remap!( - Tim2NoRemap: (pac::TIM2, 0b00, PA0, PA1, PA2, PA3, {|_, w| unsafe { w.tim2_remap().bits(Self::REMAP)}}), - Tim2PartialRemap1: (pac::TIM2, 0b01, PA15, PB3, PA2, PA3, {|_, w| unsafe { w.tim2_remap().bits(Self::REMAP)}}), - Tim2PartialRemap2: (pac::TIM2, 0b10, PA0, PA1, PB10, PB11, {|_, w| unsafe { w.tim2_remap().bits(Self::REMAP)}}), - Tim2FullRemap: (pac::TIM2, 0b11, PA15, PB3, PB10, PB11, {|_, w| unsafe { w.tim2_remap().bits(Self::REMAP)}}), - - Tim3NoRemap: (pac::TIM3, 0b00, PA6, PA7, PB0, PB1, {|_, w| unsafe { w.tim3_remap().bits(Self::REMAP)}}), - Tim3PartialRemap: (pac::TIM3, 0b10, PB4, PB5, PB0, PB1, {|_, w| unsafe { w.tim3_remap().bits(Self::REMAP)}}), - Tim3FullRemap: (pac::TIM3, 0b11, PC6, PC7, PC8, PC9, {|_, w| unsafe { w.tim3_remap().bits(Self::REMAP)}}), -); +macro_rules! remap_input { + ($TIM:ty: [ + $($P0:ident, $P1:ident $( => $MAPR:ident: $remap:literal)?;)+ + ]) => { + impl InputPins for $TIM { + type InCh1 = InCh1; + type InCh2 = InCh2; + } -#[cfg(feature = "medium")] -remap!( - Tim4NoRemap: (pac::TIM4, 0b00, PB6, PB7, PB8, PB9, {|_, w| w.tim4_remap().bit(Self::REMAP == 1)}), - Tim4Remap: (pac::TIM4, 0b01, PD12, PD13, PD14, PD15, {|_, w| w.tim4_remap().bit(Self::REMAP == 1)}), -); + $( + impl From<(gpio::$P0, gpio::$P1 $(, &mut $MAPR)?)> for InPins { + fn from(p: (gpio::$P0, gpio::$P1 $(, &mut $MAPR)?)) -> Self { + $(<$TIM>::remap(p.2, $remap);)? + Self { c1: InCh1::$P0(p.0), c2: InCh2::$P1(p.1) } + } + } + )+ + }; +} +use remap_input; + +pub trait InputPins { + type InCh1; + type InCh2; +} diff --git a/src/timer/pwm.rs b/src/timer/pwm.rs index 01fe1e61..e4c5125f 100644 --- a/src/timer/pwm.rs +++ b/src/timer/pwm.rs @@ -52,120 +52,46 @@ c0.enable() ``` */ - -use crate::afio::MAPR; -use crate::gpio::{self, Alternate}; +pub use super::pins::Pins; use super::{compute_arr_presc, Channel, FTimer, Instance, Ocm, Timer, WithPwm}; +pub use super::{C1, C2, C3, C4}; use crate::rcc::Clocks; use core::marker::PhantomData; use core::ops::{Deref, DerefMut}; use fugit::{HertzU32 as Hertz, TimerDurationU32}; -pub trait Pins { - const C1: bool = false; - const C2: bool = false; - const C3: bool = false; - const C4: bool = false; - type Channels; - - fn check_used(c: Channel) -> Channel { - if (c == Channel::C1 && Self::C1) - || (c == Channel::C2 && Self::C2) - || (c == Channel::C3 && Self::C3) - || (c == Channel::C4 && Self::C4) - { - c - } else { - panic!("Unused channel") - } - } - - fn split() -> Self::Channels; -} - -pub use super::{pins::sealed::Remap, CPin, Ch, C1, C2, C3, C4}; - pub struct PwmChannel { pub(super) _tim: PhantomData, } -macro_rules! pins_impl { - ( $( ( $($PINX:ident),+ ), ( $($ENCHX:ident),+ ); )+ ) => { - $( - #[allow(unused_parens)] - impl Pins),+)> for ($($PINX),+) - where - TIM: Instance + WithPwm, - REMAP: Remap, - $($PINX: CPin + gpio::PinExt>,)+ - { - $(const $ENCHX: bool = true;)+ - type Channels = ($(PwmChannel),+); - fn split() -> Self::Channels { - ($(PwmChannel::::new()),+) - } - } - )+ - }; -} - -pins_impl!( - (P1, P2, P3, P4), (C1, C2, C3, C4); - (P2, P3, P4), (C2, C3, C4); - (P1, P3, P4), (C1, C3, C4); - (P1, P2, P4), (C1, C2, C4); - (P1, P2, P3), (C1, C2, C3); - (P3, P4), (C3, C4); - (P2, P4), (C2, C4); - (P2, P3), (C2, C3); - (P1, P4), (C1, C4); - (P1, P3), (C1, C3); - (P1, P2), (C1, C2); - (P1), (C1); - (P2), (C2); - (P3), (C3); - (P4), (C4); -); - pub trait PwmExt where Self: Sized + Instance + WithPwm, { - fn pwm( + fn pwm( self, - pins: PINS, - mapr: &mut MAPR, + pins: impl Into, time: TimerDurationU32, clocks: &Clocks, - ) -> Pwm + ) -> Pwm where - REMAP: Remap, - PINS: Pins; + PINS: Pins; - fn pwm_hz( - self, - pins: PINS, - mapr: &mut MAPR, - freq: Hertz, - clocks: &Clocks, - ) -> PwmHz + fn pwm_hz(self, pins: impl Into, freq: Hertz, clocks: &Clocks) -> PwmHz where - REMAP: Remap, - PINS: Pins; + PINS: Pins; - fn pwm_us( + fn pwm_us( self, - pins: PINS, - mapr: &mut MAPR, + pins: impl Into, time: TimerDurationU32<1_000_000>, clocks: &Clocks, - ) -> Pwm + ) -> Pwm where - REMAP: Remap, - PINS: Pins, + PINS: Pins, { - self.pwm::<_, _, _, 1_000_000>(pins, mapr, time, clocks) + self.pwm::<_, 1_000_000>(pins, time, clocks) } } @@ -173,32 +99,23 @@ impl PwmExt for TIM where Self: Sized + Instance + WithPwm, { - fn pwm( + fn pwm( self, - pins: PINS, - mapr: &mut MAPR, + pins: impl Into, time: TimerDurationU32, clocks: &Clocks, - ) -> Pwm + ) -> Pwm where - REMAP: Remap, - PINS: Pins, + PINS: Pins, { - FTimer::::new(self, clocks).pwm(pins, mapr, time) + FTimer::::new(self, clocks).pwm(pins, time) } - fn pwm_hz( - self, - pins: PINS, - mapr: &mut MAPR, - time: Hertz, - clocks: &Clocks, - ) -> PwmHz + fn pwm_hz(self, pins: impl Into, time: Hertz, clocks: &Clocks) -> PwmHz where - REMAP: Remap, - PINS: Pins, + PINS: Pins, { - Timer::new(self, clocks).pwm_hz(pins, mapr, time) + Timer::new(self, clocks).pwm_hz(pins, time) } } @@ -238,21 +155,19 @@ impl PwmChannel { } } -pub struct PwmHz +pub struct PwmHz where TIM: Instance + WithPwm, - REMAP: Remap, - PINS: Pins, + PINS: Pins, { timer: Timer, - _pins: PhantomData<(REMAP, P, PINS)>, + _pins: PhantomData, } -impl PwmHz +impl PwmHz where TIM: Instance + WithPwm, - REMAP: Remap, - PINS: Pins, + PINS: Pins, { pub fn release(mut self) -> Timer { // stop timer @@ -265,11 +180,10 @@ where } } -impl Deref for PwmHz +impl Deref for PwmHz where TIM: Instance + WithPwm, - REMAP: Remap, - PINS: Pins, + PINS: Pins, { type Target = Timer; fn deref(&self) -> &Self::Target { @@ -277,11 +191,10 @@ where } } -impl DerefMut for PwmHz +impl DerefMut for PwmHz where TIM: Instance + WithPwm, - REMAP: Remap, - PINS: Pins, + PINS: Pins, { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.timer @@ -289,17 +202,11 @@ where } impl Timer { - pub fn pwm_hz( - mut self, - _pins: PINS, - mapr: &mut MAPR, - freq: Hertz, - ) -> PwmHz + pub fn pwm_hz(mut self, pins: impl Into, freq: Hertz) -> PwmHz where - REMAP: Remap, - PINS: Pins, + PINS: Pins, { - REMAP::remap(mapr); + let _pins = pins.into(); if PINS::C1 { self.tim @@ -339,11 +246,10 @@ impl Timer { } } -impl PwmHz +impl PwmHz where TIM: Instance + WithPwm, - REMAP: Remap, - PINS: Pins, + PINS: Pins, { pub fn enable(&mut self, channel: Channel) { TIM::enable_channel(PINS::check_used(channel) as u8, true) @@ -384,21 +290,19 @@ where } } -pub struct Pwm +pub struct Pwm where TIM: Instance + WithPwm, - REMAP: Remap, - PINS: Pins, + PINS: Pins, { timer: FTimer, - _pins: PhantomData<(REMAP, P, PINS)>, + _pins: PhantomData, } -impl Pwm +impl Pwm where TIM: Instance + WithPwm, - REMAP: Remap, - PINS: Pins, + PINS: Pins, { pub fn split(self) -> PINS::Channels { PINS::split() @@ -411,11 +315,10 @@ where } } -impl Deref for Pwm +impl Deref for Pwm where TIM: Instance + WithPwm, - REMAP: Remap, - PINS: Pins, + PINS: Pins, { type Target = FTimer; fn deref(&self) -> &Self::Target { @@ -423,11 +326,10 @@ where } } -impl DerefMut for Pwm +impl DerefMut for Pwm where TIM: Instance + WithPwm, - REMAP: Remap, - PINS: Pins, + PINS: Pins, { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.timer @@ -435,17 +337,15 @@ where } impl FTimer { - pub fn pwm( + pub fn pwm( mut self, - _pins: PINS, - mapr: &mut MAPR, + pins: impl Into, time: TimerDurationU32, - ) -> Pwm + ) -> Pwm where - REMAP: Remap, - PINS: Pins, + PINS: Pins, { - REMAP::remap(mapr); + let _pins = pins.into(); if PINS::C1 { self.tim @@ -483,11 +383,10 @@ impl FTimer { } } -impl Pwm +impl Pwm where TIM: Instance + WithPwm, - REMAP: Remap, - PINS: Pins, + PINS: Pins, { pub fn enable(&mut self, channel: Channel) { TIM::enable_channel(PINS::check_used(channel) as u8, true) diff --git a/src/timer/pwm_input.rs b/src/timer/pwm_input.rs index 78bb7c42..72f2e89f 100644 --- a/src/timer/pwm_input.rs +++ b/src/timer/pwm_input.rs @@ -6,29 +6,13 @@ use core::mem; use crate::pac::{self, DBGMCU as DBG}; -use crate::afio::MAPR; -use crate::gpio::{self, Input}; use crate::rcc::{BusTimerClock, Clocks}; use crate::time::Hertz; -use crate::timer::Timer; - -pub trait Pins {} - -use super::pins::{sealed::Remap, CPin}; - -impl Pins for (P1, P2) -where - REMAP: Remap, - P1: CPin + gpio::PinExt>, - P2: CPin + gpio::PinExt>, -{ -} +use crate::timer::{InPins, InputPins, Timer}; /// PWM Input -pub struct PwmInput { +pub struct PwmInput { _timer: PhantomData, - _remap: PhantomData, - _pins: PhantomData, } /// How the data is read from the timer @@ -74,78 +58,114 @@ pub enum Configuration { RawValues { arr: u16, presc: u16 }, } +pub trait PwmInputExt: Sized + InputPins { + fn pwm_input( + self, + pins: impl Into>, + dbg: &mut DBG, + mode: Configuration, + clocks: &Clocks, + ) -> PwmInput; +} + +#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity"))] +impl PwmInputExt for pac::TIM1 { + fn pwm_input( + self, + pins: impl Into>, + dbg: &mut DBG, + mode: Configuration, + clocks: &Clocks, + ) -> PwmInput { + Timer::new(self, clocks).pwm_input(pins, dbg, mode) + } +} + #[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity"))] impl Timer { - pub fn pwm_input( + pub fn pwm_input( mut self, - pins: PINS, - mapr: &mut MAPR, + pins: impl Into::InCh1, ::InCh2>>, dbg: &mut DBG, mode: Configuration, - ) -> PwmInput - where - REMAP: Remap, - PINS: Pins, - { - REMAP::remap(mapr); + ) -> PwmInput { self.stop_in_debug(dbg, false); let Self { tim, clk } = self; tim1(tim, pins, clk, mode) } } +impl PwmInputExt for pac::TIM2 { + fn pwm_input( + self, + pins: impl Into>, + dbg: &mut DBG, + mode: Configuration, + clocks: &Clocks, + ) -> PwmInput { + Timer::new(self, clocks).pwm_input(pins, dbg, mode) + } +} + impl Timer { - pub fn pwm_input( + pub fn pwm_input( mut self, - pins: PINS, - mapr: &mut MAPR, + pins: impl Into::InCh1, ::InCh2>>, dbg: &mut DBG, mode: Configuration, - ) -> PwmInput - where - REMAP: Remap, - PINS: Pins, - { - REMAP::remap(mapr); + ) -> PwmInput { self.stop_in_debug(dbg, false); let Self { tim, clk } = self; tim2(tim, pins, clk, mode) } } +impl PwmInputExt for pac::TIM3 { + fn pwm_input( + self, + pins: impl Into>, + dbg: &mut DBG, + mode: Configuration, + clocks: &Clocks, + ) -> PwmInput { + Timer::new(self, clocks).pwm_input(pins, dbg, mode) + } +} + impl Timer { - pub fn pwm_input( + pub fn pwm_input( mut self, - pins: PINS, - mapr: &mut MAPR, + pins: impl Into::InCh1, ::InCh2>>, dbg: &mut DBG, mode: Configuration, - ) -> PwmInput - where - REMAP: Remap, - PINS: Pins, - { - REMAP::remap(mapr); + ) -> PwmInput { self.stop_in_debug(dbg, false); let Self { tim, clk } = self; tim3(tim, pins, clk, mode) } } +#[cfg(feature = "medium")] +impl PwmInputExt for pac::TIM4 { + fn pwm_input( + self, + pins: impl Into>, + dbg: &mut DBG, + mode: Configuration, + clocks: &Clocks, + ) -> PwmInput { + Timer::new(self, &clocks).pwm_input(pins, dbg, mode) + } +} + #[cfg(feature = "medium")] impl Timer { - pub fn pwm_input( + pub fn pwm_input( mut self, - pins: PINS, - mapr: &mut MAPR, + pins: impl Into::InCh1, ::InCh2>>, dbg: &mut DBG, mode: Configuration, - ) -> PwmInput - where - REMAP: Remap, - PINS: Pins, - { - REMAP::remap(mapr); + ) -> PwmInput { self.stop_in_debug(dbg, false); let Self { tim, clk } = self; tim4(tim, pins, clk, mode) @@ -163,16 +183,14 @@ fn compute_arr_presc(freq: u32, clock: u32) -> (u16, u16) { } macro_rules! hal { ($TIMX:ty: $timX:ident) => { - fn $timX( + fn $timX( tim: $TIMX, - _pins: PINS, + pins: impl Into::InCh1, <$TIMX as InputPins>::InCh2>>, clk: Hertz, mode: Configuration, - ) -> PwmInput<$TIMX, REMAP, PINS> - where - REMAP: Remap, - PINS: Pins, - { + ) -> PwmInput<$TIMX> { + let _pins = pins.into(); + use Configuration::*; // Disable capture on both channels during setting // (for Channel X bit is CCXE) @@ -238,11 +256,7 @@ macro_rules! hal { unsafe { mem::MaybeUninit::uninit().assume_init() } } - impl PwmInput<$TIMX, REMAP, PINS> - where - REMAP: Remap, - PINS: Pins, - { + impl PwmInput<$TIMX> { /// Return the frequency sampled by the timer pub fn read_frequency(&self, mode: ReadMode, clocks: &Clocks) -> Result { if let ReadMode::WaitForNextCapture = mode { From e5126b652849adfdd99eec3987240593c12dcd11 Mon Sep 17 00:00:00 2001 From: Andrey Zgarbul Date: Wed, 9 Oct 2024 23:05:45 +0300 Subject: [PATCH 3/3] beautify --- src/can.rs | 10 +-- src/i2c.rs | 8 +- src/serial.rs | 16 ++-- src/spi.rs | 14 ++-- src/timer/pins.rs | 192 ++++++++++++++++++++++++---------------------- 5 files changed, 124 insertions(+), 116 deletions(-) diff --git a/src/can.rs b/src/can.rs index 1ddd5d9e..2ae8556f 100644 --- a/src/can.rs +++ b/src/can.rs @@ -46,8 +46,8 @@ pub mod can1 { remap! { pac::CAN1: [ - PA12, PA11 => 0; - PB9, PB8 => 2; + Tx: PA12, Rx: PA11 => 0; + Tx: PB9, Rx: PB8 => 2; ] } } @@ -58,14 +58,14 @@ pub mod can2 { remap! { pac::CAN2: [ - PB6, PB5 => 0; - PB13, PB12 => 1; + Tx: PB6, Rx: PB5 => 0; + Tx: PB13, Rx: PB12 => 1; ] } } macro_rules! remap { - ($PER:ty: [$($TX:ident, $RX:ident => $remap:literal;)+]) => { + ($PER:ty: [$(Tx: $TX:ident, Rx: $RX:ident => $remap:literal;)+]) => { pub enum Tx { $( $TX(gpio::$TX), diff --git a/src/i2c.rs b/src/i2c.rs index 4ed73619..3602dab4 100644 --- a/src/i2c.rs +++ b/src/i2c.rs @@ -105,8 +105,8 @@ pub mod i2c1 { remap! { pac::I2C1: [ - PB6, PB7 => MAPR: 0; - PB8, PB9 => MAPR: 1; + Scl: PB6, Sda: PB7 => MAPR: 0; + Scl: PB8, Sda: PB9 => MAPR: 1; ] } } @@ -115,14 +115,14 @@ pub mod i2c2 { remap! { pac::I2C2: [ - PB10, PB11; + Scl: PB10, Sda: PB11; ] } } macro_rules! remap { ($PER:ty: [ - $($SCL:ident, $SDA:ident $( => $MAPR:ident: $remap:literal)?;)+ + $(Scl: $SCL:ident, Sda: $SDA:ident $( => $MAPR:ident: $remap:literal)?;)+ ]) => { pub enum Scl { $( diff --git a/src/serial.rs b/src/serial.rs index f1547787..21bdeb43 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -101,8 +101,8 @@ pub mod usart1 { remap! { pac::USART1: [ - PA9, PA10 => 0; - PB6, PB7 => 1; + Tx: PA9, Rx: PA10 => 0; + Tx: PB6, Rx: PB7 => 1; ] } } @@ -112,8 +112,8 @@ pub mod usart2 { remap! { pac::USART2: [ - PA2, PA3 => 0; - PD5, PD6 => 1; + Tx: PA2, Rx: PA3 => 0; + Tx: PD5, Rx: PD6 => 1; ] } } @@ -123,15 +123,15 @@ pub mod usart3 { remap! { pac::USART3: [ - PB10, PB11 => 0; - PC10, PC11 => 1; - PD8, PD9 => 3; + Tx: PB10, Rx: PB11 => 0; + Tx: PC10, Rx: PC11 => 1; + Tx: PD8, Rx: PD9 => 3; ] } } macro_rules! remap { - ($PER:ty: [$($TX:ident, $RX:ident => $remap:literal;)+]) => { + ($PER:ty: [$(Tx: $TX:ident, Rx: $RX:ident => $remap:literal;)+]) => { pub enum Tx { $( $TX(gpio::$TX>), diff --git a/src/spi.rs b/src/spi.rs index 67beaddc..b99e237a 100644 --- a/src/spi.rs +++ b/src/spi.rs @@ -124,8 +124,8 @@ pub mod spi1 { remap! { pac::SPI1: [ - PA5, PA6, PA7 => MAPR: 0; - PB3, PB4, PB5 => MAPR: 1; + Sck: PA5, Miso: PA6, Mosi: PA7 => MAPR: 0; + Sck: PB3, Miso: PB4, Mosi: PB5 => MAPR: 1; ] } } @@ -135,7 +135,7 @@ pub mod spi2 { remap! { pac::SPI2: [ - PB13, PB14, PB15; + Sck: PB13, Miso: PB14, Mosi: PB15; ] } } @@ -146,21 +146,21 @@ pub mod spi3 { #[cfg(not(feature = "connectivity"))] remap! { pac::SPI3: [ - PB3, PB4, PB5; + Sck: PB3, Miso: PB4, Mosi: PB5; ] } #[cfg(feature = "connectivity")] remap! { pac::SPI3: [ - PB3, PB4, PB5 => MAPR: 0; - PC10, PC11, PC12 => MAPR: 1; + Sck: PB3, Miso: PB4, Mosi: PB5 => MAPR: 0; + Sck: PC10, Miso: PC11, Mosi: PC12 => MAPR: 1; ] } } macro_rules! remap { ($PER:ty: [ - $($SCK:ident, $MISO:ident, $MOSI:ident $( => $MAPR:ident: $remap:literal)?;)+ + $(Sck: $SCK:ident, Miso: $MISO:ident, Mosi: $MOSI:ident $( => $MAPR:ident: $remap:literal)?;)+ ]) => { pub enum Sck { $( diff --git a/src/timer/pins.rs b/src/timer/pins.rs index a244ee0e..9d8df1fa 100644 --- a/src/timer/pins.rs +++ b/src/timer/pins.rs @@ -69,26 +69,26 @@ pub mod tim1 { remap4! { pac::TIM1: [ - PA8, PA9, PA10, PA11 => MAPR: 0; - PE9, PE11, PE13, PE14 => MAPR: 3; + C1: PA8, C2: PA9, C3: PA10, C4: PA11 => MAPR: 0; + C1: PE9, C2: PE11, C3: PE13, C4: PE14 => MAPR: 3; ] } remap12! { pac::TIM1: [ - PA8, PA9 => MAPR: 0; - PE9, PE11 => MAPR: 3; + C1: PA8, C2: PA9 => MAPR: 0; + C1: PE9, C2: PE11 => MAPR: 3; ] } remap_input! { pac::TIM1: [ - PA8, PA9 => MAPR: 0; - PE9, PE11 => MAPR: 3; + C1: PA8, C2: PA9 => MAPR: 0; + C1: PE9, C2: PE11 => MAPR: 3; ] } remap34! { pac::TIM1: [ - PA10, PA11 => MAPR: 0; - PE13, PE14 => MAPR: 3; + C3: PA10, C4: PA11 => MAPR: 0; + C3: PE13, C4: PE14 => MAPR: 3; ] } @@ -109,28 +109,28 @@ pub mod tim2 { remap4! { pac::TIM2: [ - PA0, PA1, PA2, PA3 => MAPR: 0; - PA15, PB3, PA2, PA3 => MAPR: 1; - PA0, PA1, PB10, PB11 => MAPR: 2; - PA15, PB3, PB10, PB11 => MAPR: 3; + C1: PA0, C2: PA1, C3: PA2, C4: PA3 => MAPR: 0; + C1: PA15, C2: PB3, C3: PA2, C4: PA3 => MAPR: 1; + C1: PA0, C2: PA1, C3: PB10, C4: PB11 => MAPR: 2; + C1: PA15, C2: PB3, C3: PB10, C4: PB11 => MAPR: 3; ] } remap12! { pac::TIM2: [ - PA0, PA1 => MAPR: 0; - PA15, PB3 => MAPR: 1; + C1: PA0, C2: PA1 => MAPR: 0; + C1: PA15, C2: PB3 => MAPR: 1; ] } remap_input! { pac::TIM2: [ - PA0, PA1 => MAPR: 0; - PA15, PB3 => MAPR: 1; + C1: PA0, C2: PA1 => MAPR: 0; + C1: PA15, C2: PB3 => MAPR: 1; ] } remap34! { pac::TIM2: [ - PA2, PA3 => MAPR: 0; - PB10, PB11 => MAPR: 2; + C3: PA2, C4: PA3 => MAPR: 0; + C3: PB10, C4: PB11 => MAPR: 2; ] } @@ -151,29 +151,29 @@ pub mod tim3 { remap4! { pac::TIM3: [ - PA6, PA7, PB0, PB1 => MAPR: 0; - PB4, PB5, PB0, PB1 => MAPR: 2; - PC6, PC7, PC8, PC9 => MAPR: 3; + C1: PA6, C2: PA7, C3: PB0, C4: PB1 => MAPR: 0; + C1: PB4, C2: PB5, C3: PB0, C4: PB1 => MAPR: 2; + C1: PC6, C2: PC7, C3: PC8, C4: PC9 => MAPR: 3; ] } remap12! { pac::TIM3: [ - PA6, PA7 => MAPR: 0; - PB4, PB5 => MAPR: 2; - PC6, PC7 => MAPR: 3; + C1: PA6, C2: PA7 => MAPR: 0; + C1: PB4, C2: PB5 => MAPR: 2; + C1: PC6, C2: PC7 => MAPR: 3; ] } remap_input! { pac::TIM3: [ - PA6, PA7 => MAPR: 0; - PB4, PB5 => MAPR: 2; - PC6, PC7 => MAPR: 3; + C1: PA6, C2: PA7 => MAPR: 0; + C1: PB4, C2: PB5 => MAPR: 2; + C1: PC6, C2: PC7 => MAPR: 3; ] } remap34! { pac::TIM3: [ - PB0, PB1 => MAPR: 0; - PC8, PC9 => MAPR: 3; + C3: PB0, C4: PB1 => MAPR: 0; + C3: PC8, C4: PC9 => MAPR: 3; ] } @@ -195,26 +195,26 @@ pub mod tim4 { remap4! { pac::TIM4: [ - PB6, PB7, PB8, PB9 => MAPR: 0; - PD12, PD13, PD14, PD15 => MAPR: 1; + C1: PB6, C2: PB7, C3: PB8, C4: PB9 => MAPR: 0; + C1: PD12, C2: PD13, C3: PD14, C4: PD15 => MAPR: 1; ] } remap12! { pac::TIM4: [ - PB6, PB7 => MAPR: 0; - PD12, PD13 => MAPR: 1; + C1: PB6, C2: PB7 => MAPR: 0; + C1: PD12, C2: PD13 => MAPR: 1; ] } remap_input! { pac::TIM4: [ - PB6, PB7 => MAPR: 0; - PD12, PD13 => MAPR: 1; + C1: PB6, C2: PB7 => MAPR: 0; + C1: PD12, C2: PD13 => MAPR: 1; ] } remap34! { pac::TIM4: [ - PB8, PB9 => MAPR: 0; - PD14, PD15 => MAPR: 1; + C3: PB8, C4: PB9 => MAPR: 0; + C3: PD14, C4: PD15 => MAPR: 1; ] } @@ -257,11 +257,11 @@ use in_enums; macro_rules! remap4 { ($TIM:ty: [ - $($P1:ident, $P2:ident, $P3:ident, $P4:ident $( => $MAPR:ident: $remap:literal)?;)+ + $(C1: $P1:ident, C2: $P2:ident, C3: $P3:ident, C4: $P4:ident $( => $MAPR:ident: $remap:literal)?;)+ ]) => { pub type Channels1234 = Pins4; remap_combo! { - $TIM; C1, C2, C3, C4: [ + $TIM; (C1, Ch1), (C2, Ch2), (C3, Ch3), (C4, Ch4): [ $($P1, $P2, $P3, $P4 $( => $MAPR: $remap)?;)+ ] } @@ -319,7 +319,7 @@ use remap4; macro_rules! remap12 { ($TIM:ty: [ - $($P1:ident, $P2:ident $( => $MAPR:ident: $remap:literal)?;)+ + $(C1: $P1:ident, C2: $P2:ident $( => $MAPR:ident: $remap:literal)?;)+ ]) => { pub type Channels12 = Pins2; remap_combo! { @@ -343,7 +343,7 @@ use remap12; macro_rules! remap34 { ($TIM:ty: [ - $($P1:ident, $P2:ident $( => $MAPR:ident: $remap:literal)?;)+ + $(C3: $P1:ident, C4: $P2:ident $( => $MAPR:ident: $remap:literal)?;)+ ]) => { pub type Channels34 = Pins2; remap_combo! { @@ -366,77 +366,83 @@ macro_rules! remap34 { use remap34; macro_rules! remap_combo { - ($TIM:ty; $C1:ident, $C2:ident, $C3:ident, $C4:ident: [ - $($P0:ident, $P1:ident, $P2:ident, $P3:ident $( => $MAPR:ident: $remap:literal)?;)+ + ($TIM:ty; ($C1:ident, $Ch1:ident), ($C2:ident, $Ch2:ident), ($C3:ident, $Ch3:ident), ($C4:ident, $Ch4:ident): [ + $($P1:ident, $P2:ident, $P3:ident, $P4:ident $( => $MAPR:ident: $remap:literal)?;)+ ]) => { $( - impl From<(gpio::$P0, gpio::$P1, gpio::$P2, gpio::$P3 $(, &mut $MAPR)?)> for Pins4 { - fn from(p: (gpio::$P0, gpio::$P1, gpio::$P2, gpio::$P3 $(, &mut $MAPR)?)) -> Self { - $(<$TIM>::remap(p.4, $remap);)? - Self { c1: Ch1::$P0(p.0), c2: Ch2::$P1(p.1), c3: Ch3::$P2(p.2), c4: Ch4::$P3(p.3) } + impl From<(gpio::$P1, gpio::$P2, gpio::$P3, gpio::$P4 $(, &mut $MAPR)?)> for Pins4<$Ch1, $Ch2, $Ch3, $Ch4> { + fn from(p: (gpio::$P1, gpio::$P2, gpio::$P3, gpio::$P4 $(, &mut $MAPR)?)) -> Self { + let (c1, c2, c3, c4, mapr) = p; + $(<$TIM>::remap(mapr, $remap);)? + Self { c1: $Ch1::$P1(c1), c2: $Ch2::$P2(c2), c3: $Ch3::$P3(c3), c4: $Ch4::$P4(c4) } } } - impl From<(gpio::$P0, gpio::$P1, gpio::$P2, gpio::$P3 $(, &mut $MAPR)?)> for Pins4 { - fn from(p: (gpio::$P0, gpio::$P1, gpio::$P2, gpio::$P3 $(, &mut $MAPR)?)) -> Self { - let p0 = p.0.into_mode(&mut Cr); - let p1 = p.1.into_mode(&mut Cr); - let p2 = p.2.into_mode(&mut Cr); - let p3 = p.3.into_mode(&mut Cr); - $(<$TIM>::remap(p.4, $remap);)? - Self { c1: Ch1::$P0(p0), c2: Ch2::$P1(p1), c3: Ch3::$P2(p2), c4: Ch4::$P3(p3) } + impl From<(gpio::$P1, gpio::$P2, gpio::$P3, gpio::$P4 $(, &mut $MAPR)?)> for Pins4 { + fn from(p: (gpio::$P1, gpio::$P2, gpio::$P3, gpio::$P4 $(, &mut $MAPR)?)) -> Self { + let (c1, c2, c3, c4, mapr) = p; + let c1 = c1.into_mode(&mut Cr); + let c2 = c2.into_mode(&mut Cr); + let c3 = c3.into_mode(&mut Cr); + let c4 = c4.into_mode(&mut Cr); + $(<$TIM>::remap(mapr, $remap);)? + Self { c1: Ch1::$P1(c1), c2: Ch2::$P2(c2), c3: Ch3::$P3(c3), c4: Ch4::$P4(c4) } } } )+ }; ($TIM:ty; ($C1:ident, $Ch1:ident), ($C2:ident, $Ch2:ident), ($C3:ident, $Ch3:ident): [ - $($P0:ident, $P1:ident, $P2:ident $( => $MAPR:ident: $remap:literal)?;)+ + $($P1:ident, $P2:ident, $P3:ident $( => $MAPR:ident: $remap:literal)?;)+ ]) => { $( - impl From<(gpio::$P0, gpio::$P1, gpio::$P2 $(, &mut $MAPR)?)> for Pins3<$Ch1, $Ch2, $Ch3> { - fn from(p: (gpio::$P0, gpio::$P1, gpio::$P2 $(, &mut $MAPR)?)) -> Self { - $(<$TIM>::remap(p.3, $remap);)? - Self { c1: $Ch1::$P0(p.0), c2: $Ch2::$P1(p.1), c3: $Ch3::$P2(p.2) } + impl From<(gpio::$P1, gpio::$P2, gpio::$P3 $(, &mut $MAPR)?)> for Pins3<$Ch1, $Ch2, $Ch3> { + fn from(p: (gpio::$P1, gpio::$P2, gpio::$P3 $(, &mut $MAPR)?)) -> Self { + let (c1, c2, c3, mapr) = p; + $(<$TIM>::remap(mapr, $remap);)? + Self { c1: $Ch1::$P1(c1), c2: $Ch2::$P2(c2), c3: $Ch3::$P3(c3) } } } - impl From<(gpio::$P0, gpio::$P1, gpio::$P2 $(, &mut $MAPR)?)> for Pins3<$Ch1, $Ch2, $Ch3> { - fn from(p: (gpio::$P0, gpio::$P1, gpio::$P2 $(, &mut $MAPR)?)) -> Self { - let p0 = p.0.into_mode(&mut Cr); - let p1 = p.1.into_mode(&mut Cr); - let p2 = p.2.into_mode(&mut Cr); - $(<$TIM>::remap(p.3, $remap);)? - Self { c1: $Ch1::$P0(p0), c2: $Ch2::$P1(p1), c3: $Ch3::$P2(p2) } + impl From<(gpio::$P1, gpio::$P2, gpio::$P3 $(, &mut $MAPR)?)> for Pins3<$Ch1, $Ch2, $Ch3> { + fn from(p: (gpio::$P1, gpio::$P2, gpio::$P3 $(, &mut $MAPR)?)) -> Self { + let (c1, c2, c3, mapr) = p; + let c1 = c1.into_mode(&mut Cr); + let c2 = c2.into_mode(&mut Cr); + let c3 = c3.into_mode(&mut Cr); + $(<$TIM>::remap(mapr, $remap);)? + Self { c1: $Ch1::$P1(c1), c2: $Ch2::$P2(c2), c3: $Ch3::$P3(c3) } } } )+ }; ($TIM:ty; ($C1:ident, $Ch1:ident), ($C2:ident, $Ch2:ident): [ - $($P0:ident, $P1:ident $( => $MAPR:ident: $remap:literal)?;)+ + $($P1:ident, $P2:ident $( => $MAPR:ident: $remap:literal)?;)+ ]) => { $( - impl From<(gpio::$P0, gpio::$P1 $(, &mut $MAPR)?)> for Pins2<$Ch1, $Ch2> { - fn from(p: (gpio::$P0, gpio::$P1 $(, &mut $MAPR)?)) -> Self { - $(<$TIM>::remap(p.2, $remap);)? - Self { c1: $Ch1::$P0(p.0), c2: $Ch2::$P1(p.1) } + impl From<(gpio::$P1, gpio::$P2 $(, &mut $MAPR)?)> for Pins2<$Ch1, $Ch2> { + fn from(p: (gpio::$P1, gpio::$P2 $(, &mut $MAPR)?)) -> Self { + let (c1, c2, mapr) = p; + $(<$TIM>::remap(mapr, $remap);)? + Self { c1: $Ch1::$P1(c1), c2: $Ch2::$P2(c2) } } } - impl From<(gpio::$P0, gpio::$P1 $(, &mut $MAPR)?)> for Pins2<$Ch1, $Ch2> { - fn from(p: (gpio::$P0, gpio::$P1 $(, &mut $MAPR)?)) -> Self { - let p0 = p.0.into_mode(&mut Cr); - let p1 = p.1.into_mode(&mut Cr); - $(<$TIM>::remap(p.2, $remap);)? - Self { c1: $Ch1::$P0(p0), c2: $Ch2::$P1(p1) } + impl From<(gpio::$P1, gpio::$P2 $(, &mut $MAPR)?)> for Pins2<$Ch1, $Ch2> { + fn from(p: (gpio::$P1, gpio::$P2 $(, &mut $MAPR)?)) -> Self { + let (c1, c2, mapr) = p; + let c1 = c1.into_mode(&mut Cr); + let c2 = c2.into_mode(&mut Cr); + $(<$TIM>::remap(mapr, $remap);)? + Self { c1: $Ch1::$P1(c1), c2: $Ch2::$P2(c2) } } } )+ }; ($TIM:ty; ($C:ident, $Ch:ident): [ - $($P0:ident $( => $MAPR:ident: $remap:literal)?;)+ + $($P:ident $( => $MAPR:ident: $remap:literal)?;)+ ]) => { impl Pins<$TIM> for $Ch { const $C: bool = true; @@ -447,18 +453,20 @@ macro_rules! remap_combo { } $( - impl From<(gpio::$P0 $(, &mut $MAPR)?)> for $Ch { - fn from(p: (gpio::$P0 $(, &mut $MAPR)?)) -> Self { - $(<$TIM>::remap(p.1, $remap);)? - $Ch::$P0(p.0) + impl From<(gpio::$P $(, &mut $MAPR)?)> for $Ch { + fn from(p: (gpio::$P $(, &mut $MAPR)?)) -> Self { + let (c, mapr) = p; + $(<$TIM>::remap(mapr, $remap);)? + $Ch::$P(c) } } - impl From<(gpio::$P0 $(, &mut $MAPR)?)> for $Ch { - fn from(p: (gpio::$P0 $(, &mut $MAPR)?)) -> Self { - let p0 = p.0.into_mode(&mut Cr); - $(<$TIM>::remap(p.1, $remap);)? - $Ch::$P0(p0) + impl From<(gpio::$P $(, &mut $MAPR)?)> for $Ch { + fn from(p: (gpio::$P $(, &mut $MAPR)?)) -> Self { + let (c, mapr) = p; + let c = c.into_mode(&mut Cr); + $(<$TIM>::remap(mapr, $remap);)? + $Ch::$P(c) } } )+ @@ -492,7 +500,7 @@ pub trait Pins { macro_rules! remap_input { ($TIM:ty: [ - $($P0:ident, $P1:ident $( => $MAPR:ident: $remap:literal)?;)+ + $(C1: $P1:ident, C2: $P2:ident $( => $MAPR:ident: $remap:literal)?;)+ ]) => { impl InputPins for $TIM { type InCh1 = InCh1; @@ -500,10 +508,10 @@ macro_rules! remap_input { } $( - impl From<(gpio::$P0, gpio::$P1 $(, &mut $MAPR)?)> for InPins { - fn from(p: (gpio::$P0, gpio::$P1 $(, &mut $MAPR)?)) -> Self { + impl From<(gpio::$P1, gpio::$P2 $(, &mut $MAPR)?)> for InPins { + fn from(p: (gpio::$P1, gpio::$P2 $(, &mut $MAPR)?)) -> Self { $(<$TIM>::remap(p.2, $remap);)? - Self { c1: InCh1::$P0(p.0), c2: InCh2::$P1(p.1) } + Self { c1: InCh1::$P1(p.0), c2: InCh2::$P2(p.1) } } } )+