diff options
| author | Dario Nieuwenhuis <[email protected]> | 2025-09-05 23:00:31 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2025-09-05 23:00:31 +0200 |
| commit | 7419b398bf7cc5c1ff164c504f4a4027cd6bcd3b (patch) | |
| tree | 9ea26e1059b70502d0e5929a72a9f50c8c43838b /embassy-stm32/src/timer | |
| parent | a6562c4f033432e40970aafe82f33c5138adf84e (diff) | |
stm32/afio: use type inference for timer remaps as well.
Diffstat (limited to 'embassy-stm32/src/timer')
| -rw-r--r-- | embassy-stm32/src/timer/complementary_pwm.rs | 39 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/input_capture.rs | 25 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/mod.rs | 43 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/one_pulse.rs | 66 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/pwm_input.rs | 8 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/qei.rs | 14 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/simple_pwm.rs | 31 |
7 files changed, 72 insertions, 154 deletions
diff --git a/embassy-stm32/src/timer/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs index 08404cdd6..d3b84ed16 100644 --- a/embassy-stm32/src/timer/complementary_pwm.rs +++ b/embassy-stm32/src/timer/complementary_pwm.rs | |||
| @@ -16,21 +16,23 @@ use crate::Peri; | |||
| 16 | /// Complementary PWM pin wrapper. | 16 | /// Complementary PWM pin wrapper. |
| 17 | /// | 17 | /// |
| 18 | /// This wraps a pin to make it usable with PWM. | 18 | /// This wraps a pin to make it usable with PWM. |
| 19 | pub struct ComplementaryPwmPin<'d, T, C> { | 19 | pub struct ComplementaryPwmPin<'d, T, C, A> { |
| 20 | #[allow(unused)] | 20 | #[allow(unused)] |
| 21 | pin: Peri<'d, AnyPin>, | 21 | pin: Peri<'d, AnyPin>, |
| 22 | phantom: PhantomData<(T, C)>, | 22 | phantom: PhantomData<(T, C, A)>, |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | impl<'d, T: AdvancedInstance4Channel, C: TimerChannel> ComplementaryPwmPin<'d, T, C> { | 25 | impl<'d, T: AdvancedInstance4Channel, C: TimerChannel, A> ComplementaryPwmPin<'d, T, C, A> { |
| 26 | /// Create a new complementary PWM pin instance. | 26 | /// Create a new complementary PWM pin instance. |
| 27 | pub fn new(pin: Peri<'d, impl TimerComplementaryPin<T, C>>, output_type: OutputType) -> Self { | 27 | pub fn new(pin: Peri<'d, impl TimerComplementaryPin<T, C, A>>, output_type: OutputType) -> Self { |
| 28 | critical_section::with(|_| { | 28 | critical_section::with(|_| { |
| 29 | pin.set_low(); | 29 | pin.set_low(); |
| 30 | pin.set_as_af( | 30 | pin.set_as_af( |
| 31 | pin.af_num(), | 31 | pin.af_num(), |
| 32 | crate::gpio::AfType::output(output_type, crate::gpio::Speed::VeryHigh), | 32 | crate::gpio::AfType::output(output_type, crate::gpio::Speed::VeryHigh), |
| 33 | ); | 33 | ); |
| 34 | #[cfg(afio)] | ||
| 35 | pin.afio_remap(); | ||
| 34 | }); | 36 | }); |
| 35 | ComplementaryPwmPin { | 37 | ComplementaryPwmPin { |
| 36 | pin: pin.into(), | 38 | pin: pin.into(), |
| @@ -56,30 +58,19 @@ pub enum IdlePolarity { | |||
| 56 | impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> { | 58 | impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> { |
| 57 | /// Create a new complementary PWM driver. | 59 | /// Create a new complementary PWM driver. |
| 58 | #[allow(clippy::too_many_arguments, unused)] | 60 | #[allow(clippy::too_many_arguments, unused)] |
| 59 | pub fn new( | 61 | pub fn new<A>( |
| 60 | tim: Peri<'d, T>, | 62 | tim: Peri<'d, T>, |
| 61 | ch1: Option<PwmPin<'d, T, Ch1>>, | 63 | ch1: Option<PwmPin<'d, T, Ch1, A>>, |
| 62 | ch1n: Option<ComplementaryPwmPin<'d, T, Ch1>>, | 64 | ch1n: Option<ComplementaryPwmPin<'d, T, Ch1, A>>, |
| 63 | ch2: Option<PwmPin<'d, T, Ch2>>, | 65 | ch2: Option<PwmPin<'d, T, Ch2, A>>, |
| 64 | ch2n: Option<ComplementaryPwmPin<'d, T, Ch2>>, | 66 | ch2n: Option<ComplementaryPwmPin<'d, T, Ch2, A>>, |
| 65 | ch3: Option<PwmPin<'d, T, Ch3>>, | 67 | ch3: Option<PwmPin<'d, T, Ch3, A>>, |
| 66 | ch3n: Option<ComplementaryPwmPin<'d, T, Ch3>>, | 68 | ch3n: Option<ComplementaryPwmPin<'d, T, Ch3, A>>, |
| 67 | ch4: Option<PwmPin<'d, T, Ch4>>, | 69 | ch4: Option<PwmPin<'d, T, Ch4, A>>, |
| 68 | ch4n: Option<ComplementaryPwmPin<'d, T, Ch4>>, | 70 | ch4n: Option<ComplementaryPwmPin<'d, T, Ch4, A>>, |
| 69 | freq: Hertz, | 71 | freq: Hertz, |
| 70 | counting_mode: CountingMode, | 72 | counting_mode: CountingMode, |
| 71 | ) -> Self { | 73 | ) -> Self { |
| 72 | #[cfg(afio)] | ||
| 73 | super::set_afio::<T>(&[ | ||
| 74 | ch1.map(|p| p.pin), | ||
| 75 | ch1n.map(|p| p.pin), | ||
| 76 | ch2.map(|p| p.pin), | ||
| 77 | ch2n.map(|p| p.pin), | ||
| 78 | ch3.map(|p| p.pin), | ||
| 79 | ch3n.map(|p| p.pin), | ||
| 80 | ch4.map(|p| p.pin), | ||
| 81 | ch4n.map(|p| p.pin), | ||
| 82 | ]); | ||
| 83 | Self::new_inner(tim, freq, counting_mode) | 74 | Self::new_inner(tim, freq, counting_mode) |
| 84 | } | 75 | } |
| 85 | 76 | ||
diff --git a/embassy-stm32/src/timer/input_capture.rs b/embassy-stm32/src/timer/input_capture.rs index b717e6eac..262f9d067 100644 --- a/embassy-stm32/src/timer/input_capture.rs +++ b/embassy-stm32/src/timer/input_capture.rs | |||
| @@ -17,14 +17,14 @@ use crate::Peri; | |||
| 17 | /// Capture pin wrapper. | 17 | /// Capture pin wrapper. |
| 18 | /// | 18 | /// |
| 19 | /// This wraps a pin to make it usable with capture. | 19 | /// This wraps a pin to make it usable with capture. |
| 20 | pub struct CapturePin<'d, T, C> { | 20 | pub struct CapturePin<'d, T, C, A> { |
| 21 | #[allow(unused)] | 21 | #[allow(unused)] |
| 22 | pin: Peri<'d, AnyPin>, | 22 | pin: Peri<'d, AnyPin>, |
| 23 | phantom: PhantomData<(T, C)>, | 23 | phantom: PhantomData<(T, C, A)>, |
| 24 | } | 24 | } |
| 25 | impl<'d, T: GeneralInstance4Channel, C: TimerChannel> CapturePin<'d, T, C> { | 25 | impl<'d, T: GeneralInstance4Channel, C: TimerChannel, A> CapturePin<'d, T, C, A> { |
| 26 | /// Create a new capture pin instance. | 26 | /// Create a new capture pin instance. |
| 27 | pub fn new(pin: Peri<'d, impl TimerPin<T, C>>, pull: Pull) -> Self { | 27 | pub fn new(pin: Peri<'d, impl TimerPin<T, C, A>>, pull: Pull) -> Self { |
| 28 | pin.set_as_af(pin.af_num(), AfType::input(pull)); | 28 | pin.set_as_af(pin.af_num(), AfType::input(pull)); |
| 29 | CapturePin { | 29 | CapturePin { |
| 30 | pin: pin.into(), | 30 | pin: pin.into(), |
| @@ -41,23 +41,16 @@ pub struct InputCapture<'d, T: GeneralInstance4Channel> { | |||
| 41 | impl<'d, T: GeneralInstance4Channel> InputCapture<'d, T> { | 41 | impl<'d, T: GeneralInstance4Channel> InputCapture<'d, T> { |
| 42 | /// Create a new input capture driver. | 42 | /// Create a new input capture driver. |
| 43 | #[allow(unused)] | 43 | #[allow(unused)] |
| 44 | pub fn new( | 44 | pub fn new<A>( |
| 45 | tim: Peri<'d, T>, | 45 | tim: Peri<'d, T>, |
| 46 | ch1: Option<CapturePin<'d, T, Ch1>>, | 46 | ch1: Option<CapturePin<'d, T, Ch1, A>>, |
| 47 | ch2: Option<CapturePin<'d, T, Ch2>>, | 47 | ch2: Option<CapturePin<'d, T, Ch2, A>>, |
| 48 | ch3: Option<CapturePin<'d, T, Ch3>>, | 48 | ch3: Option<CapturePin<'d, T, Ch3, A>>, |
| 49 | ch4: Option<CapturePin<'d, T, Ch4>>, | 49 | ch4: Option<CapturePin<'d, T, Ch4, A>>, |
| 50 | _irq: impl Binding<T::CaptureCompareInterrupt, CaptureCompareInterruptHandler<T>> + 'd, | 50 | _irq: impl Binding<T::CaptureCompareInterrupt, CaptureCompareInterruptHandler<T>> + 'd, |
| 51 | freq: Hertz, | 51 | freq: Hertz, |
| 52 | counting_mode: CountingMode, | 52 | counting_mode: CountingMode, |
| 53 | ) -> Self { | 53 | ) -> Self { |
| 54 | #[cfg(afio)] | ||
| 55 | super::set_afio::<T>(&[ | ||
| 56 | ch1.map(|p| p.pin), | ||
| 57 | ch2.map(|p| p.pin), | ||
| 58 | ch3.map(|p| p.pin), | ||
| 59 | ch4.map(|p| p.pin), | ||
| 60 | ]); | ||
| 61 | Self::new_inner(tim, freq, counting_mode) | 54 | Self::new_inner(tim, freq, counting_mode) |
| 62 | } | 55 | } |
| 63 | 56 | ||
diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs index 38f4a1a51..b09bc7166 100644 --- a/embassy-stm32/src/timer/mod.rs +++ b/embassy-stm32/src/timer/mod.rs | |||
| @@ -14,8 +14,6 @@ pub mod pwm_input; | |||
| 14 | pub mod qei; | 14 | pub mod qei; |
| 15 | pub mod simple_pwm; | 15 | pub mod simple_pwm; |
| 16 | 16 | ||
| 17 | #[cfg(afio)] | ||
| 18 | use crate::gpio::SealedPin; | ||
| 19 | use crate::interrupt; | 17 | use crate::interrupt; |
| 20 | use crate::rcc::RccPeripheral; | 18 | use crate::rcc::RccPeripheral; |
| 21 | 19 | ||
| @@ -157,15 +155,9 @@ trait SealedInstance: RccPeripheral + PeripheralType { | |||
| 157 | fn state() -> &'static State; | 155 | fn state() -> &'static State; |
| 158 | } | 156 | } |
| 159 | 157 | ||
| 160 | #[allow(unused)] | ||
| 161 | pub(crate) trait Afio { | ||
| 162 | fn afio_mappings() -> &'static [AfioMapping]; | ||
| 163 | fn set_afio(value: u8); | ||
| 164 | } | ||
| 165 | |||
| 166 | /// Core timer instance. | 158 | /// Core timer instance. |
| 167 | #[allow(private_bounds)] | 159 | #[allow(private_bounds)] |
| 168 | pub trait CoreInstance: SealedInstance + Afio + 'static { | 160 | pub trait CoreInstance: SealedInstance + 'static { |
| 169 | /// Update Interrupt for this timer. | 161 | /// Update Interrupt for this timer. |
| 170 | type UpdateInterrupt: interrupt::typelevel::Interrupt; | 162 | type UpdateInterrupt: interrupt::typelevel::Interrupt; |
| 171 | 163 | ||
| @@ -231,15 +223,15 @@ pub trait AdvancedInstance2Channel: BasicInstance + GeneralInstance2Channel + Ad | |||
| 231 | /// Advanced 16-bit timer with 4 channels instance. | 223 | /// Advanced 16-bit timer with 4 channels instance. |
| 232 | pub trait AdvancedInstance4Channel: AdvancedInstance2Channel + GeneralInstance4Channel {} | 224 | pub trait AdvancedInstance4Channel: AdvancedInstance2Channel + GeneralInstance4Channel {} |
| 233 | 225 | ||
| 234 | pin_trait!(TimerPin, GeneralInstance4Channel, TimerChannel); | 226 | pin_trait!(TimerPin, GeneralInstance4Channel, TimerChannel, @A); |
| 235 | pin_trait!(ExternalTriggerPin, GeneralInstance4Channel); | 227 | pin_trait!(ExternalTriggerPin, GeneralInstance4Channel, @A); |
| 236 | 228 | ||
| 237 | pin_trait!(TimerComplementaryPin, AdvancedInstance4Channel, TimerChannel); | 229 | pin_trait!(TimerComplementaryPin, AdvancedInstance4Channel, TimerChannel, @A); |
| 238 | 230 | ||
| 239 | pin_trait!(BreakInputPin, AdvancedInstance4Channel, BreakInput); | 231 | pin_trait!(BreakInputPin, AdvancedInstance4Channel, BreakInput, @A); |
| 240 | 232 | ||
| 241 | pin_trait!(BreakInputComparator1Pin, AdvancedInstance4Channel, BreakInput); | 233 | pin_trait!(BreakInputComparator1Pin, AdvancedInstance4Channel, BreakInput, @A); |
| 242 | pin_trait!(BreakInputComparator2Pin, AdvancedInstance4Channel, BreakInput); | 234 | pin_trait!(BreakInputComparator2Pin, AdvancedInstance4Channel, BreakInput, @A); |
| 243 | 235 | ||
| 244 | // Update Event trigger DMA for every timer | 236 | // Update Event trigger DMA for every timer |
| 245 | dma_trait!(UpDma, BasicInstance); | 237 | dma_trait!(UpDma, BasicInstance); |
| @@ -458,24 +450,3 @@ impl<T: GeneralInstance1Channel> interrupt::typelevel::Handler<T::CaptureCompare | |||
| 458 | } | 450 | } |
| 459 | } | 451 | } |
| 460 | } | 452 | } |
| 461 | |||
| 462 | #[allow(unused)] | ||
| 463 | pub(crate) struct AfioMapping { | ||
| 464 | pub(crate) value: u8, | ||
| 465 | pub(crate) pins: &'static [u8], | ||
| 466 | } | ||
| 467 | |||
| 468 | #[cfg(afio)] | ||
| 469 | fn set_afio<'d, T: Afio>(pins: &[Option<embassy_hal_internal::Peri<'d, crate::gpio::AnyPin>>]) { | ||
| 470 | let mapping = T::afio_mappings() | ||
| 471 | .iter() | ||
| 472 | .find(|m| { | ||
| 473 | pins.iter() | ||
| 474 | .flatten() | ||
| 475 | .map(|p| (*p).pin_port()) | ||
| 476 | .all(|p| m.pins.contains(&p)) | ||
| 477 | }) | ||
| 478 | .expect("Should be called with a combination of timer pins supported by the hardware"); | ||
| 479 | |||
| 480 | T::set_afio(mapping.value); | ||
| 481 | } | ||
diff --git a/embassy-stm32/src/timer/one_pulse.rs b/embassy-stm32/src/timer/one_pulse.rs index 0267749e1..b15cea679 100644 --- a/embassy-stm32/src/timer/one_pulse.rs +++ b/embassy-stm32/src/timer/one_pulse.rs | |||
| @@ -15,6 +15,7 @@ use crate::gpio::{AfType, AnyPin, Pull}; | |||
| 15 | use crate::interrupt::typelevel::{Binding, Interrupt}; | 15 | use crate::interrupt::typelevel::{Binding, Interrupt}; |
| 16 | use crate::pac::timer::vals::Etp; | 16 | use crate::pac::timer::vals::Etp; |
| 17 | use crate::time::Hertz; | 17 | use crate::time::Hertz; |
| 18 | use crate::timer::TimerChannel; | ||
| 18 | use crate::Peri; | 19 | use crate::Peri; |
| 19 | 20 | ||
| 20 | /// External input marker type. | 21 | /// External input marker type. |
| @@ -61,58 +62,25 @@ impl SealedTriggerSource for Ch1 {} | |||
| 61 | impl SealedTriggerSource for Ch2 {} | 62 | impl SealedTriggerSource for Ch2 {} |
| 62 | impl SealedTriggerSource for Ext {} | 63 | impl SealedTriggerSource for Ext {} |
| 63 | 64 | ||
| 64 | trait SealedTimerTriggerPin<T, S>: crate::gpio::Pin {} | 65 | impl<'d, T: GeneralInstance4Channel, C: TriggerSource + TimerChannel> TriggerPin<'d, T, C> { |
| 65 | 66 | /// Create a new Channel trigger pin instance. | |
| 66 | /// Marker trait for a trigger pin. | 67 | pub fn new<A>(pin: Peri<'d, impl TimerPin<T, C, A>>, pull: Pull) -> Self { |
| 67 | #[expect(private_bounds)] | 68 | pin.set_as_af(pin.af_num(), AfType::input(pull)); |
| 68 | // TODO: find better naming scheme than prefixing all pin traits with "Timer". | 69 | #[cfg(afio)] |
| 69 | // The trait name cannot conflict with the corresponding type's name. | 70 | pin.afio_remap(); |
| 70 | // Applies to other timer submodules as well. | 71 | TriggerPin { |
| 71 | pub trait TimerTriggerPin<T, S>: SealedTimerTriggerPin<T, S> { | 72 | pin: pin.into(), |
| 72 | /// Get the AF number needed to use this pin as a trigger source. | 73 | phantom: PhantomData, |
| 73 | fn af_num(&self) -> u8; | 74 | } |
| 74 | } | ||
| 75 | |||
| 76 | impl<T, P, C> TimerTriggerPin<T, C> for P | ||
| 77 | where | ||
| 78 | T: GeneralInstance4Channel, | ||
| 79 | P: TimerPin<T, C>, | ||
| 80 | C: super::TimerChannel + TriggerSource, | ||
| 81 | { | ||
| 82 | fn af_num(&self) -> u8 { | ||
| 83 | TimerPin::af_num(self) | ||
| 84 | } | ||
| 85 | } | ||
| 86 | |||
| 87 | impl<T, P> TimerTriggerPin<T, Ext> for P | ||
| 88 | where | ||
| 89 | T: GeneralInstance4Channel, | ||
| 90 | P: ExternalTriggerPin<T>, | ||
| 91 | { | ||
| 92 | fn af_num(&self) -> u8 { | ||
| 93 | ExternalTriggerPin::af_num(self) | ||
| 94 | } | 75 | } |
| 95 | } | 76 | } |
| 96 | 77 | ||
| 97 | impl<T, P, C> SealedTimerTriggerPin<T, C> for P | 78 | impl<'d, T: GeneralInstance4Channel> TriggerPin<'d, T, Ext> { |
| 98 | where | 79 | /// Create a new external trigger pin instance. |
| 99 | T: GeneralInstance4Channel, | 80 | pub fn new_external<A>(pin: Peri<'d, impl ExternalTriggerPin<T, A>>, pull: Pull) -> Self { |
| 100 | P: TimerPin<T, C>, | ||
| 101 | C: super::TimerChannel + TriggerSource, | ||
| 102 | { | ||
| 103 | } | ||
| 104 | |||
| 105 | impl<T, P> SealedTimerTriggerPin<T, Ext> for P | ||
| 106 | where | ||
| 107 | T: GeneralInstance4Channel, | ||
| 108 | P: ExternalTriggerPin<T>, | ||
| 109 | { | ||
| 110 | } | ||
| 111 | |||
| 112 | impl<'d, T: GeneralInstance4Channel, C: TriggerSource> TriggerPin<'d, T, C> { | ||
| 113 | /// "Create a new Ch1 trigger pin instance. | ||
| 114 | pub fn new(pin: Peri<'d, impl TimerTriggerPin<T, C>>, pull: Pull) -> Self { | ||
| 115 | pin.set_as_af(pin.af_num(), AfType::input(pull)); | 81 | pin.set_as_af(pin.af_num(), AfType::input(pull)); |
| 82 | #[cfg(afio)] | ||
| 83 | pin.afio_remap(); | ||
| 116 | TriggerPin { | 84 | TriggerPin { |
| 117 | pin: pin.into(), | 85 | pin: pin.into(), |
| 118 | phantom: PhantomData, | 86 | phantom: PhantomData, |
| @@ -141,8 +109,6 @@ impl<'d, T: GeneralInstance4Channel> OnePulse<'d, T> { | |||
| 141 | pulse_end: u32, | 109 | pulse_end: u32, |
| 142 | counting_mode: CountingMode, | 110 | counting_mode: CountingMode, |
| 143 | ) -> Self { | 111 | ) -> Self { |
| 144 | #[cfg(afio)] | ||
| 145 | super::set_afio::<T>(&[Some(pin.pin)]); | ||
| 146 | let mut this = Self { inner: Timer::new(tim) }; | 112 | let mut this = Self { inner: Timer::new(tim) }; |
| 147 | 113 | ||
| 148 | this.inner.set_trigger_source(Ts::TI1F_ED); | 114 | this.inner.set_trigger_source(Ts::TI1F_ED); |
diff --git a/embassy-stm32/src/timer/pwm_input.rs b/embassy-stm32/src/timer/pwm_input.rs index c537e5268..62d7a8550 100644 --- a/embassy-stm32/src/timer/pwm_input.rs +++ b/embassy-stm32/src/timer/pwm_input.rs | |||
| @@ -18,19 +18,19 @@ pub struct PwmInput<'d, T: GeneralInstance4Channel> { | |||
| 18 | 18 | ||
| 19 | impl<'d, T: GeneralInstance4Channel> PwmInput<'d, T> { | 19 | impl<'d, T: GeneralInstance4Channel> PwmInput<'d, T> { |
| 20 | /// Create a new PWM input driver. | 20 | /// Create a new PWM input driver. |
| 21 | pub fn new_ch1(tim: Peri<'d, T>, pin: Peri<'d, impl TimerPin<T, Ch1>>, pull: Pull, freq: Hertz) -> Self { | 21 | pub fn new_ch1<A>(tim: Peri<'d, T>, pin: Peri<'d, impl TimerPin<T, Ch1, A>>, pull: Pull, freq: Hertz) -> Self { |
| 22 | pin.set_as_af(pin.af_num(), AfType::input(pull)); | 22 | pin.set_as_af(pin.af_num(), AfType::input(pull)); |
| 23 | #[cfg(afio)] | 23 | #[cfg(afio)] |
| 24 | super::set_afio::<T>(&[Some(pin.into())]); | 24 | pin.afio_remap(); |
| 25 | 25 | ||
| 26 | Self::new_inner(tim, freq, Channel::Ch1, Channel::Ch2) | 26 | Self::new_inner(tim, freq, Channel::Ch1, Channel::Ch2) |
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | /// Create a new PWM input driver. | 29 | /// Create a new PWM input driver. |
| 30 | pub fn new_ch2(tim: Peri<'d, T>, pin: Peri<'d, impl TimerPin<T, Ch2>>, pull: Pull, freq: Hertz) -> Self { | 30 | pub fn new_ch2<A>(tim: Peri<'d, T>, pin: Peri<'d, impl TimerPin<T, Ch2, A>>, pull: Pull, freq: Hertz) -> Self { |
| 31 | pin.set_as_af(pin.af_num(), AfType::input(pull)); | 31 | pin.set_as_af(pin.af_num(), AfType::input(pull)); |
| 32 | #[cfg(afio)] | 32 | #[cfg(afio)] |
| 33 | super::set_afio::<T>(&[Some(pin.into())]); | 33 | pin.afio_remap(); |
| 34 | 34 | ||
| 35 | Self::new_inner(tim, freq, Channel::Ch2, Channel::Ch1) | 35 | Self::new_inner(tim, freq, Channel::Ch2, Channel::Ch1) |
| 36 | } | 36 | } |
diff --git a/embassy-stm32/src/timer/qei.rs b/embassy-stm32/src/timer/qei.rs index 4e5a309ac..39d051294 100644 --- a/embassy-stm32/src/timer/qei.rs +++ b/embassy-stm32/src/timer/qei.rs | |||
| @@ -20,18 +20,20 @@ pub enum Direction { | |||
| 20 | } | 20 | } |
| 21 | 21 | ||
| 22 | /// Wrapper for using a pin with QEI. | 22 | /// Wrapper for using a pin with QEI. |
| 23 | pub struct QeiPin<'d, T, Channel> { | 23 | pub struct QeiPin<'d, T, Channel, A> { |
| 24 | #[allow(unused)] | 24 | #[allow(unused)] |
| 25 | pin: Peri<'d, AnyPin>, | 25 | pin: Peri<'d, AnyPin>, |
| 26 | phantom: PhantomData<(T, Channel)>, | 26 | phantom: PhantomData<(T, Channel, A)>, |
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | impl<'d, T: GeneralInstance4Channel, C: QeiChannel> QeiPin<'d, T, C> { | 29 | impl<'d, T: GeneralInstance4Channel, C: QeiChannel, A> QeiPin<'d, T, C, A> { |
| 30 | /// Create a new QEI pin instance. | 30 | /// Create a new QEI pin instance. |
| 31 | pub fn new(pin: Peri<'d, impl TimerPin<T, C>>) -> Self { | 31 | pub fn new(pin: Peri<'d, impl TimerPin<T, C, A>>) -> Self { |
| 32 | critical_section::with(|_| { | 32 | critical_section::with(|_| { |
| 33 | pin.set_low(); | 33 | pin.set_low(); |
| 34 | pin.set_as_af(pin.af_num(), AfType::input(Pull::None)); | 34 | pin.set_as_af(pin.af_num(), AfType::input(Pull::None)); |
| 35 | #[cfg(afio)] | ||
| 36 | pin.afio_remap(); | ||
| 35 | }); | 37 | }); |
| 36 | QeiPin { | 38 | QeiPin { |
| 37 | pin: pin.into(), | 39 | pin: pin.into(), |
| @@ -60,9 +62,7 @@ pub struct Qei<'d, T: GeneralInstance4Channel> { | |||
| 60 | impl<'d, T: GeneralInstance4Channel> Qei<'d, T> { | 62 | impl<'d, T: GeneralInstance4Channel> Qei<'d, T> { |
| 61 | /// Create a new quadrature decoder driver. | 63 | /// Create a new quadrature decoder driver. |
| 62 | #[allow(unused)] | 64 | #[allow(unused)] |
| 63 | pub fn new(tim: Peri<'d, T>, ch1: QeiPin<'d, T, Ch1>, ch2: QeiPin<'d, T, Ch2>) -> Self { | 65 | pub fn new<A>(tim: Peri<'d, T>, ch1: QeiPin<'d, T, Ch1, A>, ch2: QeiPin<'d, T, Ch2, A>) -> Self { |
| 64 | #[cfg(afio)] | ||
| 65 | super::set_afio::<T>(&[Some(ch1.pin), Some(ch2.pin)]); | ||
| 66 | Self::new_inner(tim) | 66 | Self::new_inner(tim) |
| 67 | } | 67 | } |
| 68 | 68 | ||
diff --git a/embassy-stm32/src/timer/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs index df86859fe..53f7cdd22 100644 --- a/embassy-stm32/src/timer/simple_pwm.rs +++ b/embassy-stm32/src/timer/simple_pwm.rs | |||
| @@ -14,10 +14,10 @@ use crate::Peri; | |||
| 14 | /// PWM pin wrapper. | 14 | /// PWM pin wrapper. |
| 15 | /// | 15 | /// |
| 16 | /// This wraps a pin to make it usable with PWM. | 16 | /// This wraps a pin to make it usable with PWM. |
| 17 | pub struct PwmPin<'d, T, C> { | 17 | pub struct PwmPin<'d, T, C, A> { |
| 18 | #[allow(unused)] | 18 | #[allow(unused)] |
| 19 | pub(crate) pin: Peri<'d, AnyPin>, | 19 | pub(crate) pin: Peri<'d, AnyPin>, |
| 20 | phantom: PhantomData<(T, C)>, | 20 | phantom: PhantomData<(T, C, A)>, |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | /// PWM pin config | 23 | /// PWM pin config |
| @@ -35,12 +35,14 @@ pub struct PwmPinConfig { | |||
| 35 | pub pull: Pull, | 35 | pub pull: Pull, |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | impl<'d, T: GeneralInstance4Channel, C: TimerChannel> PwmPin<'d, T, C> { | 38 | impl<'d, T: GeneralInstance4Channel, C: TimerChannel, A> PwmPin<'d, T, C, A> { |
| 39 | /// Create a new PWM pin instance. | 39 | /// Create a new PWM pin instance. |
| 40 | pub fn new(pin: Peri<'d, impl TimerPin<T, C>>, output_type: OutputType) -> Self { | 40 | pub fn new(pin: Peri<'d, impl TimerPin<T, C, A>>, output_type: OutputType) -> Self { |
| 41 | critical_section::with(|_| { | 41 | critical_section::with(|_| { |
| 42 | pin.set_low(); | 42 | pin.set_low(); |
| 43 | pin.set_as_af(pin.af_num(), AfType::output(output_type, Speed::VeryHigh)); | 43 | pin.set_as_af(pin.af_num(), AfType::output(output_type, Speed::VeryHigh)); |
| 44 | #[cfg(afio)] | ||
| 45 | pin.afio_remap(); | ||
| 44 | }); | 46 | }); |
| 45 | PwmPin { | 47 | PwmPin { |
| 46 | pin: pin.into(), | 48 | pin: pin.into(), |
| @@ -49,7 +51,7 @@ impl<'d, T: GeneralInstance4Channel, C: TimerChannel> PwmPin<'d, T, C> { | |||
| 49 | } | 51 | } |
| 50 | 52 | ||
| 51 | /// Create a new PWM pin instance with config. | 53 | /// Create a new PWM pin instance with config. |
| 52 | pub fn new_with_config(pin: Peri<'d, impl TimerPin<T, C>>, pin_config: PwmPinConfig) -> Self { | 54 | pub fn new_with_config(pin: Peri<'d, impl TimerPin<T, C, A>>, pin_config: PwmPinConfig) -> Self { |
| 53 | critical_section::with(|_| { | 55 | critical_section::with(|_| { |
| 54 | pin.set_low(); | 56 | pin.set_low(); |
| 55 | pin.set_as_af( | 57 | pin.set_as_af( |
| @@ -59,6 +61,8 @@ impl<'d, T: GeneralInstance4Channel, C: TimerChannel> PwmPin<'d, T, C> { | |||
| 59 | #[cfg(gpio_v2)] | 61 | #[cfg(gpio_v2)] |
| 60 | AfType::output_pull(pin_config.output_type, pin_config.speed, pin_config.pull), | 62 | AfType::output_pull(pin_config.output_type, pin_config.speed, pin_config.pull), |
| 61 | ); | 63 | ); |
| 64 | #[cfg(afio)] | ||
| 65 | pin.afio_remap(); | ||
| 62 | }); | 66 | }); |
| 63 | PwmPin { | 67 | PwmPin { |
| 64 | pin: pin.into(), | 68 | pin: pin.into(), |
| @@ -180,22 +184,15 @@ pub struct SimplePwm<'d, T: GeneralInstance4Channel> { | |||
| 180 | impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { | 184 | impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { |
| 181 | /// Create a new simple PWM driver. | 185 | /// Create a new simple PWM driver. |
| 182 | #[allow(unused)] | 186 | #[allow(unused)] |
| 183 | pub fn new( | 187 | pub fn new<A>( |
| 184 | tim: Peri<'d, T>, | 188 | tim: Peri<'d, T>, |
| 185 | ch1: Option<PwmPin<'d, T, Ch1>>, | 189 | ch1: Option<PwmPin<'d, T, Ch1, A>>, |
| 186 | ch2: Option<PwmPin<'d, T, Ch2>>, | 190 | ch2: Option<PwmPin<'d, T, Ch2, A>>, |
| 187 | ch3: Option<PwmPin<'d, T, Ch3>>, | 191 | ch3: Option<PwmPin<'d, T, Ch3, A>>, |
| 188 | ch4: Option<PwmPin<'d, T, Ch4>>, | 192 | ch4: Option<PwmPin<'d, T, Ch4, A>>, |
| 189 | freq: Hertz, | 193 | freq: Hertz, |
| 190 | counting_mode: CountingMode, | 194 | counting_mode: CountingMode, |
| 191 | ) -> Self { | 195 | ) -> Self { |
| 192 | #[cfg(afio)] | ||
| 193 | super::set_afio::<T>(&[ | ||
| 194 | ch1.map(|p| p.pin), | ||
| 195 | ch2.map(|p| p.pin), | ||
| 196 | ch3.map(|p| p.pin), | ||
| 197 | ch4.map(|p| p.pin), | ||
| 198 | ]); | ||
| 199 | Self::new_inner(tim, freq, counting_mode) | 196 | Self::new_inner(tim, freq, counting_mode) |
| 200 | } | 197 | } |
| 201 | 198 | ||
