From 6c690ab259ed15eece329a53a7147e7780f53cf3 Mon Sep 17 00:00:00 2001 From: eZio Pan Date: Fri, 2 Feb 2024 17:45:51 +0800 Subject: [PATCH] restore original public API of timer, but keep new PAC --- embassy-stm32/src/timer/complementary_pwm.rs | 41 +- embassy-stm32/src/timer/mod.rs | 525 ++++++++---------- embassy-stm32/src/timer/qei.rs | 4 +- embassy-stm32/src/timer/simple_pwm.rs | 39 +- .../stm32h7/src/bin/low_level_timer_api.rs | 4 +- 5 files changed, 274 insertions(+), 339 deletions(-) diff --git a/embassy-stm32/src/timer/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs index b9cd044c9..72f1ec864 100644 --- a/embassy-stm32/src/timer/complementary_pwm.rs +++ b/embassy-stm32/src/timer/complementary_pwm.rs @@ -1,7 +1,6 @@ //! PWM driver with complementary output support. use core::marker::PhantomData; -use core::ops::{Deref, DerefMut}; use embassy_hal_internal::{into_ref, PeripheralRef}; use stm32_metapac::timer::vals::Ckd; @@ -24,7 +23,7 @@ pub struct ComplementaryPwmPin<'d, T, C> { macro_rules! complementary_channel_impl { ($new_chx:ident, $channel:ident, $pin_trait:ident) => { - impl<'d, T: AdvancedControlInstance> ComplementaryPwmPin<'d, T, $channel> { + impl<'d, T: ComplementaryCaptureCompare16bitInstance> ComplementaryPwmPin<'d, T, $channel> { #[doc = concat!("Create a new ", stringify!($channel), " complementary PWM pin instance.")] pub fn $new_chx(pin: impl Peripheral

> + 'd, output_type: OutputType) -> Self { into_ref!(pin); @@ -53,7 +52,7 @@ pub struct ComplementaryPwm<'d, T> { inner: PeripheralRef<'d, T>, } -impl<'d, T: AdvancedControlInstance> ComplementaryPwm<'d, T> { +impl<'d, T: ComplementaryCaptureCompare16bitInstance> ComplementaryPwm<'d, T> { /// Create a new complementary PWM driver. #[allow(clippy::too_many_arguments)] pub fn new( @@ -88,12 +87,8 @@ impl<'d, T: AdvancedControlInstance> ComplementaryPwm<'d, T> { [Channel::Ch1, Channel::Ch2, Channel::Ch3, Channel::Ch4] .iter() .for_each(|&channel| { - sealed::GeneralPurpose16bitInstance::set_output_compare_mode( - this.inner.deref_mut(), - channel, - OutputCompareMode::PwmMode1, - ); - sealed::GeneralPurpose16bitInstance::set_output_compare_preload(this.inner.deref_mut(), channel, true); + this.inner.set_output_compare_mode(channel, OutputCompareMode::PwmMode1); + this.inner.set_output_compare_preload(channel, true); }); this @@ -101,14 +96,14 @@ impl<'d, T: AdvancedControlInstance> ComplementaryPwm<'d, T> { /// Enable the given channel. pub fn enable(&mut self, channel: Channel) { - sealed::GeneralPurpose16bitInstance::enable_channel(self.inner.deref_mut(), channel, true); - sealed::AdvancedControlInstance::enable_complementary_channel(self.inner.deref_mut(), channel, true); + self.inner.enable_channel(channel, true); + self.inner.enable_complementary_channel(channel, true); } /// Disable the given channel. pub fn disable(&mut self, channel: Channel) { - sealed::AdvancedControlInstance::enable_complementary_channel(self.inner.deref_mut(), channel, false); - sealed::GeneralPurpose16bitInstance::enable_channel(self.inner.deref_mut(), channel, false); + self.inner.enable_complementary_channel(channel, false); + self.inner.enable_channel(channel, false); } /// Set PWM frequency. @@ -136,13 +131,13 @@ impl<'d, T: AdvancedControlInstance> ComplementaryPwm<'d, T> { /// The value ranges from 0 for 0% duty, to [`get_max_duty`](Self::get_max_duty) for 100% duty, both included. pub fn set_duty(&mut self, channel: Channel, duty: u16) { assert!(duty <= self.get_max_duty()); - sealed::GeneralPurpose16bitInstance::set_compare_value(self.inner.deref_mut(), channel, duty) + self.inner.set_compare_value(channel, duty) } /// Set the output polarity for a given channel. pub fn set_polarity(&mut self, channel: Channel, polarity: OutputPolarity) { - sealed::GeneralPurpose16bitInstance::set_output_polarity(self.inner.deref_mut(), channel, polarity); - sealed::AdvancedControlInstance::set_complementary_output_polarity(self.inner.deref_mut(), channel, polarity); + self.inner.set_output_polarity(channel, polarity); + self.inner.set_complementary_output_polarity(channel, polarity); } /// Set the dead time as a proportion of max_duty @@ -154,19 +149,19 @@ impl<'d, T: AdvancedControlInstance> ComplementaryPwm<'d, T> { } } -impl<'d, T: AdvancedControlInstance> embedded_hal_02::Pwm for ComplementaryPwm<'d, T> { +impl<'d, T: ComplementaryCaptureCompare16bitInstance> embedded_hal_02::Pwm for ComplementaryPwm<'d, T> { type Channel = Channel; type Time = Hertz; type Duty = u16; fn disable(&mut self, channel: Self::Channel) { - sealed::AdvancedControlInstance::enable_complementary_channel(self.inner.deref_mut(), channel, false); - sealed::GeneralPurpose16bitInstance::enable_channel(self.inner.deref_mut(), channel, false); + self.inner.enable_complementary_channel(channel, false); + self.inner.enable_channel(channel, false); } fn enable(&mut self, channel: Self::Channel) { - sealed::GeneralPurpose16bitInstance::enable_channel(self.inner.deref_mut(), channel, true); - sealed::AdvancedControlInstance::enable_complementary_channel(self.inner.deref_mut(), channel, true); + self.inner.enable_channel(channel, true); + self.inner.enable_complementary_channel(channel, true); } fn get_period(&self) -> Self::Time { @@ -174,7 +169,7 @@ impl<'d, T: AdvancedControlInstance> embedded_hal_02::Pwm for ComplementaryPwm<' } fn get_duty(&self, channel: Self::Channel) -> Self::Duty { - sealed::GeneralPurpose16bitInstance::get_compare_value(self.inner.deref(), channel) + self.inner.get_compare_value(channel) } fn get_max_duty(&self) -> Self::Duty { @@ -183,7 +178,7 @@ impl<'d, T: AdvancedControlInstance> embedded_hal_02::Pwm for ComplementaryPwm<' fn set_duty(&mut self, channel: Self::Channel, duty: Self::Duty) { assert!(duty <= self.get_max_duty()); - sealed::GeneralPurpose16bitInstance::set_compare_value(self.inner.deref_mut(), channel, duty) + self.inner.set_compare_value(channel, duty) } fn set_period

(&mut self, period: P) diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs index 3e303a6cf..5f40be957 100644 --- a/embassy-stm32/src/timer/mod.rs +++ b/embassy-stm32/src/timer/mod.rs @@ -1,6 +1,8 @@ //! Timers, PWM, quadrature decoder. -// Timer inheritance +//! Timer inheritance + +// sealed: // // Core -------------------------> 1CH -------------------------> 1CH_CMP // | | ^ | @@ -12,7 +14,18 @@ // | +--------------------------------------|-----------+ // +----------------------------------------------------+ -#[cfg(not(any(stm32l0, stm32l1)))] +//! BasicInstance --> CaptureCompare16bitInstance --+--> ComplementaryCaptureCompare16bitInstance +//! | +//! +--> CaptureCompare32bitInstance +//! +//! mapping: +//! +//! Basic Timer --> BasicInstance +//! 1-channel Timer, 2-channel Timer, General Purpose 16-bit Timer --> CaptureCompare16bitInstance +//! General Purpose 32-bit Timer --> CaptureCompare32bitInstance +//! 1-channel with one complentary Timer, 2-channel with one complentary Timer, Advance Control Timer --> ComplementaryCaptureCompare16bitInstance + +#[cfg(not(stm32l0))] pub mod complementary_pwm; pub mod qei; pub mod simple_pwm; @@ -32,157 +45,6 @@ pub mod low_level { pub(crate) mod sealed { use super::*; - macro_rules! add_capture_compare_common_methods { - ($regs:ident) => { - /// Set input capture filter. - fn set_input_capture_filter(&mut self, channel: Channel, icf: vals::FilterValue) { - let raw_channel = channel.index(); - Self::$regs() - .ccmr_input(raw_channel / 2) - .modify(|r| r.set_icf(raw_channel % 2, icf)); - } - - /// Clear input interrupt. - fn clear_input_interrupt(&mut self, channel: Channel) { - Self::$regs().sr().modify(|r| r.set_ccif(channel.index(), false)); - } - - /// Enable input interrupt. - fn enable_input_interrupt(&mut self, channel: Channel, enable: bool) { - Self::$regs() - .dier() - .modify(|r| r.set_ccie(channel.index(), enable)); - } - - /// Set input capture prescaler. - fn set_input_capture_prescaler(&mut self, channel: Channel, factor: u8) { - let raw_channel = channel.index(); - Self::$regs() - .ccmr_input(raw_channel / 2) - .modify(|r| r.set_icpsc(raw_channel % 2, factor)); - } - - /// Set input TI selection. - fn set_input_ti_selection(&mut self, channel: Channel, tisel: InputTISelection) { - let raw_channel = channel.index(); - Self::$regs() - .ccmr_input(raw_channel / 2) - .modify(|r| r.set_ccs(raw_channel % 2, tisel.into())); - } - - /// Set input capture mode. - fn set_input_capture_mode(&mut self, channel: Channel, mode: InputCaptureMode) { - Self::$regs().ccer().modify(|r| match mode { - InputCaptureMode::Rising => { - r.set_ccnp(channel.index(), false); - r.set_ccp(channel.index(), false); - } - InputCaptureMode::Falling => { - r.set_ccnp(channel.index(), false); - r.set_ccp(channel.index(), true); - } - InputCaptureMode::BothEdges => { - r.set_ccnp(channel.index(), true); - r.set_ccp(channel.index(), true); - } - }); - } - - /// Set output compare mode. - fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode) { - let raw_channel: usize = channel.index(); - Self::$regs() - .ccmr_output(raw_channel / 2) - .modify(|w| w.set_ocm(raw_channel % 2, mode.into())); - } - - /// Set output polarity. - fn set_output_polarity(&mut self, channel: Channel, polarity: OutputPolarity) { - Self::$regs() - .ccer() - .modify(|w| w.set_ccp(channel.index(), polarity.into())); - } - - /// Enable/disable a channel. - fn enable_channel(&mut self, channel: Channel, enable: bool) { - Self::$regs() - .ccer() - .modify(|w| w.set_cce(channel.index(), enable)); - } - - /// Get enable/disable state of a channel - fn get_channel_enable_state(&self, channel: Channel) -> bool { - Self::$regs().ccer().read().cce(channel.index()) - } - - /// Set compare value for a channel. - fn set_compare_value(&mut self, channel: Channel, value: u16) { - Self::$regs().ccr(channel.index()).modify(|w| w.set_ccr(value)); - } - - /// Get capture value for a channel. - fn get_capture_value(&mut self, channel: Channel) -> u16 { - Self::$regs().ccr(channel.index()).read().ccr() - } - - /// Get compare value for a channel. - fn get_compare_value(&self, channel: Channel) -> u16 { - Self::$regs().ccr(channel.index()).read().ccr() - } - - /// Set output compare preload. - fn set_output_compare_preload(&mut self, channel: Channel, preload: bool) { - let channel_index = channel.index(); - Self::$regs() - .ccmr_output(channel_index / 2) - .modify(|w| w.set_ocpe(channel_index % 2, preload)); - } - }; - } - - macro_rules! add_capture_compare_dma_methods { - ($regs:ident) => { - /// Get capture compare DMA selection - fn get_cc_dma_selection(&self) -> super::vals::Ccds { - Self::$regs().cr2().read().ccds() - } - - /// Set capture compare DMA selection - fn set_cc_dma_selection(&mut self, ccds: super::vals::Ccds) { - Self::$regs().cr2().modify(|w| w.set_ccds(ccds)) - } - - /// Get capture compare DMA enable state - fn get_cc_dma_enable_state(&self, channel: Channel) -> bool { - Self::$regs().dier().read().ccde(channel.index()) - } - - /// Set capture compare DMA enable state - fn set_cc_dma_enable_state(&mut self, channel: Channel, ccde: bool) { - Self::$regs().dier().modify(|w| w.set_ccde(channel.index(), ccde)) - } - }; - } - - #[cfg(not(any(stm32l0, stm32l1)))] - macro_rules! add_complementary_capture_compare_methods { - ($regs:ident) => { - /// Set complementary output polarity. - fn set_complementary_output_polarity(&mut self, channel: Channel, polarity: OutputPolarity) { - Self::$regs() - .ccer() - .modify(|w| w.set_ccnp(channel.index(), polarity.into())); - } - - /// Enable/disable a complementary channel. - fn enable_complementary_channel(&mut self, channel: Channel, enable: bool) { - Self::$regs() - .ccer() - .modify(|w| w.set_ccne(channel.index(), enable)); - } - }; - } - /// Virtual Core 16-bit timer instance. pub trait CoreInstance: RccPeripheral { /// Interrupt for this timer. @@ -326,8 +188,6 @@ pub(crate) mod sealed { fn get_max_compare_value(&self) -> u16 { Self::regs_1ch().arr().read().arr() } - - add_capture_compare_common_methods!(regs_1ch); } /// Gneral-purpose 1 channel 16-bit timer instance. @@ -339,8 +199,6 @@ pub(crate) mod sealed { /// for a given set of capabilities, and having it transparently work with /// more capable timers. fn regs_2ch() -> crate::pac::timer::Tim2ch; - - add_capture_compare_common_methods!(regs_2ch); } /// Gneral-purpose 16-bit timer instance. @@ -372,11 +230,128 @@ pub(crate) mod sealed { (cr1.cms(), cr1.dir()).into() } - add_capture_compare_common_methods!(regs_gp16); - add_capture_compare_dma_methods!(regs_gp16); + /// Set input capture filter. + fn set_input_capture_filter(&mut self, channel: Channel, icf: vals::FilterValue) { + let raw_channel = channel.index(); + Self::regs_gp16() + .ccmr_input(raw_channel / 2) + .modify(|r| r.set_icf(raw_channel % 2, icf)); + } + + /// Clear input interrupt. + fn clear_input_interrupt(&mut self, channel: Channel) { + Self::regs_gp16().sr().modify(|r| r.set_ccif(channel.index(), false)); + } + + /// Enable input interrupt. + fn enable_input_interrupt(&mut self, channel: Channel, enable: bool) { + Self::regs_gp16().dier().modify(|r| r.set_ccie(channel.index(), enable)); + } + + /// Set input capture prescaler. + fn set_input_capture_prescaler(&mut self, channel: Channel, factor: u8) { + let raw_channel = channel.index(); + Self::regs_gp16() + .ccmr_input(raw_channel / 2) + .modify(|r| r.set_icpsc(raw_channel % 2, factor)); + } + + /// Set input TI selection. + fn set_input_ti_selection(&mut self, channel: Channel, tisel: InputTISelection) { + let raw_channel = channel.index(); + Self::regs_gp16() + .ccmr_input(raw_channel / 2) + .modify(|r| r.set_ccs(raw_channel % 2, tisel.into())); + } + + /// Set input capture mode. + fn set_input_capture_mode(&mut self, channel: Channel, mode: InputCaptureMode) { + Self::regs_gp16().ccer().modify(|r| match mode { + InputCaptureMode::Rising => { + r.set_ccnp(channel.index(), false); + r.set_ccp(channel.index(), false); + } + InputCaptureMode::Falling => { + r.set_ccnp(channel.index(), false); + r.set_ccp(channel.index(), true); + } + InputCaptureMode::BothEdges => { + r.set_ccnp(channel.index(), true); + r.set_ccp(channel.index(), true); + } + }); + } + + /// Set output compare mode. + fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode) { + let raw_channel: usize = channel.index(); + Self::regs_gp16() + .ccmr_output(raw_channel / 2) + .modify(|w| w.set_ocm(raw_channel % 2, mode.into())); + } + + /// Set output polarity. + fn set_output_polarity(&mut self, channel: Channel, polarity: OutputPolarity) { + Self::regs_gp16() + .ccer() + .modify(|w| w.set_ccp(channel.index(), polarity.into())); + } + + /// Enable/disable a channel. + fn enable_channel(&mut self, channel: Channel, enable: bool) { + Self::regs_gp16().ccer().modify(|w| w.set_cce(channel.index(), enable)); + } + + /// Get enable/disable state of a channel + fn get_channel_enable_state(&self, channel: Channel) -> bool { + Self::regs_gp16().ccer().read().cce(channel.index()) + } + + /// Set compare value for a channel. + fn set_compare_value(&mut self, channel: Channel, value: u16) { + Self::regs_gp16().ccr(channel.index()).modify(|w| w.set_ccr(value)); + } + + /// Get capture value for a channel. + fn get_capture_value(&mut self, channel: Channel) -> u16 { + Self::regs_gp16().ccr(channel.index()).read().ccr() + } + + /// Get compare value for a channel. + fn get_compare_value(&self, channel: Channel) -> u16 { + Self::regs_gp16().ccr(channel.index()).read().ccr() + } + + /// Set output compare preload. + fn set_output_compare_preload(&mut self, channel: Channel, preload: bool) { + let channel_index = channel.index(); + Self::regs_gp16() + .ccmr_output(channel_index / 2) + .modify(|w| w.set_ocpe(channel_index % 2, preload)); + } + + /// Get capture compare DMA selection + fn get_cc_dma_selection(&self) -> super::vals::Ccds { + Self::regs_gp16().cr2().read().ccds() + } + + /// Set capture compare DMA selection + fn set_cc_dma_selection(&mut self, ccds: super::vals::Ccds) { + Self::regs_gp16().cr2().modify(|w| w.set_ccds(ccds)) + } + + /// Get capture compare DMA enable state + fn get_cc_dma_enable_state(&self, channel: Channel) -> bool { + Self::regs_gp16().dier().read().ccde(channel.index()) + } + + /// Set capture compare DMA enable state + fn set_cc_dma_enable_state(&mut self, channel: Channel, ccde: bool) { + Self::regs_gp16().dier().modify(|w| w.set_ccde(channel.index(), ccde)) + } } - #[cfg(not(any(stm32f1, stm32l0, stm32c0)))] + #[cfg(not(stm32l0))] /// Gneral-purpose 32-bit timer instance. pub trait GeneralPurpose32bitInstance: GeneralPurpose16bitInstance { /// Get access to the general purpose 32bit timer registers. @@ -437,7 +412,7 @@ pub(crate) mod sealed { } } - #[cfg(not(any(stm32l0, stm32l1)))] + #[cfg(not(stm32l0))] /// Gneral-purpose 1 channel with one complementary 16-bit timer instance. pub trait GeneralPurpose1ChannelComplementaryInstance: BasicNoCr2Instance + GeneralPurpose1ChannelInstance { /// Get access to the general purpose 1 channel with one complementary 16bit timer registers. @@ -462,11 +437,9 @@ pub(crate) mod sealed { fn enable_outputs(&mut self) { Self::regs_1ch_cmp().bdtr().modify(|w| w.set_moe(true)); } - - add_complementary_capture_compare_methods!(regs_1ch_cmp); } - #[cfg(not(any(stm32l0, stm32l1)))] + #[cfg(not(stm32l0))] /// Gneral-purpose 2 channel with one complementary 16-bit timer instance. pub trait GeneralPurpose2ChannelComplementaryInstance: BasicInstance + GeneralPurpose2ChannelInstance + GeneralPurpose1ChannelComplementaryInstance @@ -478,11 +451,9 @@ pub(crate) mod sealed { /// for a given set of capabilities, and having it transparently work with /// more capable timers. fn regs_2ch_cmp() -> crate::pac::timer::Tim2chCmp; - - add_complementary_capture_compare_methods!(regs_2ch_cmp); } - #[cfg(not(any(stm32l0, stm32l1)))] + #[cfg(not(stm32l0))] /// Advanced control timer instance. pub trait AdvancedControlInstance: GeneralPurpose2ChannelComplementaryInstance + GeneralPurpose16bitInstance @@ -490,7 +461,19 @@ pub(crate) mod sealed { /// Get access to the advanced timer registers. fn regs_advanced() -> crate::pac::timer::TimAdv; - add_complementary_capture_compare_methods!(regs_advanced); + /// Set complementary output polarity. + fn set_complementary_output_polarity(&mut self, channel: Channel, polarity: OutputPolarity) { + Self::regs_advanced() + .ccer() + .modify(|w| w.set_ccnp(channel.index(), polarity.into())); + } + + /// Enable/disable a complementary channel. + fn enable_complementary_channel(&mut self, channel: Channel, enable: bool) { + Self::regs_advanced() + .ccer() + .modify(|w| w.set_ccne(channel.index(), enable)); + } } } @@ -681,96 +664,66 @@ impl From for bool { } } -/// Virtual Core 16-bit timer instance. -pub trait CoreInstance: sealed::CoreInstance + 'static {} - -/// Virtual Basic 16-bit timer without CR2 register instance. -pub trait BasicNoCr2Instance: sealed::BasicNoCr2Instance + CoreInstance + 'static {} - /// Basic 16-bit timer instance. -pub trait BasicInstance: sealed::BasicInstance + BasicNoCr2Instance + 'static {} - -/// 1 channel 16-bit instance. -pub trait GeneralPurpose1ChannelInstance: sealed::GeneralPurpose1ChannelInstance + CoreInstance + 'static {} - -/// 2 channel 16-bit instance. -pub trait GeneralPurpose2ChannelInstance: - sealed::GeneralPurpose2ChannelInstance + GeneralPurpose1ChannelInstance + 'static -{ -} +pub trait BasicInstance: sealed::BasicInstance + sealed::BasicNoCr2Instance + sealed::CoreInstance + 'static {} /// General-purpose 16-bit timer instance. -pub trait GeneralPurpose16bitInstance: - sealed::GeneralPurpose16bitInstance + BasicInstance + GeneralPurpose2ChannelInstance + 'static -{ -} - -#[cfg(not(any(stm32f1, stm32l0, stm32c0)))] -/// Gneral-purpose 32-bit timer instance. -pub trait GeneralPurpose32bitInstance: - sealed::GeneralPurpose32bitInstance + GeneralPurpose16bitInstance + 'static -{ -} - -#[cfg(not(any(stm32l0, stm32l1)))] -/// General-purpose 1 channel with one complementary 16-bit timer instance. -pub trait GeneralPurpose1ChannelComplementaryInstance: - sealed::GeneralPurpose1ChannelComplementaryInstance + GeneralPurpose1ChannelInstance + 'static -{ -} - -#[cfg(not(any(stm32l0, stm32l1)))] -/// General-purpose 2 channel with one complementary 16-bit timer instance. -pub trait GeneralPurpose2ChannelComplementaryInstance: - sealed::GeneralPurpose2ChannelComplementaryInstance - + BasicInstance - + GeneralPurpose2ChannelInstance - + GeneralPurpose1ChannelComplementaryInstance +pub trait CaptureCompare16bitInstance: + BasicInstance + + sealed::GeneralPurpose2ChannelInstance + + sealed::GeneralPurpose1ChannelInstance + + sealed::GeneralPurpose16bitInstance + 'static { } -#[cfg(not(any(stm32f37, stm32l0, stm32l1)))] -/// Advanced control timer instance. -pub trait AdvancedControlInstance: - sealed::AdvancedControlInstance + GeneralPurpose2ChannelComplementaryInstance + GeneralPurpose16bitInstance + 'static +#[cfg(not(stm32l0))] +/// Gneral-purpose 32-bit timer instance. +pub trait CaptureCompare32bitInstance: + sealed::GeneralPurpose32bitInstance + CaptureCompare16bitInstance + 'static { } -pin_trait!(Channel1Pin, GeneralPurpose1ChannelInstance); -pin_trait!(Channel2Pin, GeneralPurpose2ChannelInstance); -pin_trait!(Channel3Pin, GeneralPurpose16bitInstance); -pin_trait!(Channel4Pin, GeneralPurpose16bitInstance); +#[cfg(not(stm32l0))] +/// Advanced control timer instance. +pub trait ComplementaryCaptureCompare16bitInstance: + CaptureCompare16bitInstance + + sealed::GeneralPurpose1ChannelComplementaryInstance + + sealed::GeneralPurpose2ChannelComplementaryInstance + + sealed::AdvancedControlInstance + + 'static +{ +} + +pin_trait!(Channel1Pin, CaptureCompare16bitInstance); +pin_trait!(Channel2Pin, CaptureCompare16bitInstance); +pin_trait!(Channel3Pin, CaptureCompare16bitInstance); +pin_trait!(Channel4Pin, CaptureCompare16bitInstance); +pin_trait!(ExternalTriggerPin, CaptureCompare16bitInstance); #[cfg(not(stm32l0))] -pin_trait!(ExternalTriggerPin, GeneralPurpose16bitInstance); +pin_trait!(Channel1ComplementaryPin, ComplementaryCaptureCompare16bitInstance); +#[cfg(not(stm32l0))] +pin_trait!(Channel2ComplementaryPin, ComplementaryCaptureCompare16bitInstance); +#[cfg(not(stm32l0))] +pin_trait!(Channel3ComplementaryPin, ComplementaryCaptureCompare16bitInstance); +#[cfg(not(stm32l0))] +pin_trait!(Channel4ComplementaryPin, ComplementaryCaptureCompare16bitInstance); -#[cfg(stm32l0)] -pin_trait!(ExternalTriggerPin, GeneralPurpose2ChannelInstance); +#[cfg(not(stm32l0))] +pin_trait!(BreakInputPin, ComplementaryCaptureCompare16bitInstance); +#[cfg(not(stm32l0))] +pin_trait!(BreakInput2Pin, ComplementaryCaptureCompare16bitInstance); -#[cfg(not(any(stm32l0, stm32l1)))] -pin_trait!(Channel1ComplementaryPin, GeneralPurpose1ChannelComplementaryInstance); -#[cfg(not(any(stm32l0, stm32l1)))] -pin_trait!(Channel2ComplementaryPin, GeneralPurpose2ChannelComplementaryInstance); -#[cfg(not(any(stm32l0, stm32l1)))] -pin_trait!(Channel3ComplementaryPin, AdvancedControlInstance); -#[cfg(not(any(stm32l0, stm32l1)))] -pin_trait!(Channel4ComplementaryPin, AdvancedControlInstance); +#[cfg(not(stm32l0))] +pin_trait!(BreakInputComparator1Pin, ComplementaryCaptureCompare16bitInstance); +#[cfg(not(stm32l0))] +pin_trait!(BreakInputComparator2Pin, ComplementaryCaptureCompare16bitInstance); -#[cfg(not(any(stm32l0, stm32l1)))] -pin_trait!(BreakInputPin, GeneralPurpose1ChannelComplementaryInstance); -#[cfg(not(any(stm32l0, stm32l1)))] -pin_trait!(BreakInput2Pin, GeneralPurpose2ChannelComplementaryInstance); - -#[cfg(not(any(stm32l0, stm32l1)))] -pin_trait!(BreakInputComparator1Pin, GeneralPurpose1ChannelComplementaryInstance); -#[cfg(not(any(stm32l0, stm32l1)))] -pin_trait!(BreakInputComparator2Pin, AdvancedControlInstance); - -#[cfg(not(any(stm32l0, stm32l1)))] -pin_trait!(BreakInput2Comparator1Pin, AdvancedControlInstance); -#[cfg(not(any(stm32l0, stm32l1)))] -pin_trait!(BreakInput2Comparator2Pin, AdvancedControlInstance); +#[cfg(not(stm32l0))] +pin_trait!(BreakInput2Comparator1Pin, ComplementaryCaptureCompare16bitInstance); +#[cfg(not(stm32l0))] +pin_trait!(BreakInput2Comparator2Pin, ComplementaryCaptureCompare16bitInstance); #[allow(unused)] macro_rules! impl_core_timer { @@ -830,7 +783,7 @@ macro_rules! impl_2ch_timer { } #[allow(unused)] -macro_rules! impl_gp_16bit_timer { +macro_rules! impl_gp16_timer { ($inst:ident) => { impl sealed::GeneralPurpose16bitInstance for crate::peripherals::$inst { fn regs_gp16() -> crate::pac::timer::TimGp16 { @@ -841,7 +794,7 @@ macro_rules! impl_gp_16bit_timer { } #[allow(unused)] -macro_rules! impl_gp_32bit_timer { +macro_rules! impl_gp32_timer { ($inst:ident) => { impl sealed::GeneralPurpose32bitInstance for crate::peripherals::$inst { fn regs_gp32() -> crate::pac::timer::TimGp32 { @@ -890,26 +843,30 @@ foreach_interrupt! { impl_core_timer!($inst, $irq); impl_basic_no_cr2_timer!($inst); impl_basic_timer!($inst); - impl CoreInstance for crate::peripherals::$inst {} - impl BasicNoCr2Instance for crate::peripherals::$inst{} impl BasicInstance for crate::peripherals::$inst {} }; ($inst:ident, timer, TIM_1CH, UP, $irq:ident) => { impl_core_timer!($inst, $irq); + impl_basic_no_cr2_timer!($inst); + impl_basic_timer!($inst); impl_1ch_timer!($inst); - impl CoreInstance for crate::peripherals::$inst {} - impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {} + impl_2ch_timer!($inst); + impl_gp16_timer!($inst); + impl BasicInstance for crate::peripherals::$inst {} + impl CaptureCompare16bitInstance for crate::peripherals::$inst {} }; ($inst:ident, timer, TIM_2CH, UP, $irq:ident) => { impl_core_timer!($inst, $irq); + impl_basic_no_cr2_timer!($inst); + impl_basic_timer!($inst); impl_1ch_timer!($inst); impl_2ch_timer!($inst); - impl CoreInstance for crate::peripherals::$inst {} - impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {} - impl GeneralPurpose2ChannelInstance for crate::peripherals::$inst {} + impl_gp16_timer!($inst); + impl BasicInstance for crate::peripherals::$inst {} + impl CaptureCompare16bitInstance for crate::peripherals::$inst {} }; ($inst:ident, timer, TIM_GP16, UP, $irq:ident) => { @@ -918,13 +875,9 @@ foreach_interrupt! { impl_basic_timer!($inst); impl_1ch_timer!($inst); impl_2ch_timer!($inst); - impl_gp_16bit_timer!($inst); - impl CoreInstance for crate::peripherals::$inst {} - impl BasicNoCr2Instance for crate::peripherals::$inst{} + impl_gp16_timer!($inst); impl BasicInstance for crate::peripherals::$inst {} - impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {} - impl GeneralPurpose2ChannelInstance for crate::peripherals::$inst {} - impl GeneralPurpose16bitInstance for crate::peripherals::$inst {} + impl CaptureCompare16bitInstance for crate::peripherals::$inst {} }; ($inst:ident, timer, TIM_GP32, UP, $irq:ident) => { @@ -933,26 +886,26 @@ foreach_interrupt! { impl_basic_timer!($inst); impl_1ch_timer!($inst); impl_2ch_timer!($inst); - impl_gp_16bit_timer!($inst); - impl_gp_32bit_timer!($inst); - impl CoreInstance for crate::peripherals::$inst {} - impl BasicNoCr2Instance for crate::peripherals::$inst{} + impl_gp16_timer!($inst); + impl_gp32_timer!($inst); impl BasicInstance for crate::peripherals::$inst {} - impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {} - impl GeneralPurpose2ChannelInstance for crate::peripherals::$inst {} - impl GeneralPurpose16bitInstance for crate::peripherals::$inst {} - impl GeneralPurpose32bitInstance for crate::peripherals::$inst {} + impl CaptureCompare16bitInstance for crate::peripherals::$inst {} + impl CaptureCompare32bitInstance for crate::peripherals::$inst {} }; ($inst:ident, timer, TIM_1CH_CMP, UP, $irq:ident) => { impl_core_timer!($inst, $irq); impl_basic_no_cr2_timer!($inst); + impl_basic_timer!($inst); impl_1ch_timer!($inst); + impl_2ch_timer!($inst); + impl_gp16_timer!($inst); impl_1ch_cmp_timer!($inst); - impl CoreInstance for crate::peripherals::$inst {} - impl BasicNoCr2Instance for crate::peripherals::$inst{} - impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {} - impl GeneralPurpose1ChannelComplementaryInstance for crate::peripherals::$inst {} + impl_2ch_cmp_timer!($inst); + impl_adv_timer!($inst); + impl BasicInstance for crate::peripherals::$inst {} + impl CaptureCompare16bitInstance for crate::peripherals::$inst {} + impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {} }; @@ -962,15 +915,13 @@ foreach_interrupt! { impl_basic_timer!($inst); impl_1ch_timer!($inst); impl_2ch_timer!($inst); + impl_gp16_timer!($inst); impl_1ch_cmp_timer!($inst); impl_2ch_cmp_timer!($inst); - impl CoreInstance for crate::peripherals::$inst {} - impl BasicNoCr2Instance for crate::peripherals::$inst{} + impl_adv_timer!($inst); impl BasicInstance for crate::peripherals::$inst {} - impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {} - impl GeneralPurpose2ChannelInstance for crate::peripherals::$inst {} - impl GeneralPurpose1ChannelComplementaryInstance for crate::peripherals::$inst {} - impl GeneralPurpose2ChannelComplementaryInstance for crate::peripherals::$inst {} + impl CaptureCompare16bitInstance for crate::peripherals::$inst {} + impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {} }; @@ -980,26 +931,20 @@ foreach_interrupt! { impl_basic_timer!($inst); impl_1ch_timer!($inst); impl_2ch_timer!($inst); + impl_gp16_timer!($inst); impl_1ch_cmp_timer!($inst); - impl_gp_16bit_timer!($inst); impl_2ch_cmp_timer!($inst); impl_adv_timer!($inst); - impl CoreInstance for crate::peripherals::$inst {} - impl BasicNoCr2Instance for crate::peripherals::$inst{} impl BasicInstance for crate::peripherals::$inst {} - impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {} - impl GeneralPurpose2ChannelInstance for crate::peripherals::$inst {} - impl GeneralPurpose16bitInstance for crate::peripherals::$inst {} - impl GeneralPurpose1ChannelComplementaryInstance for crate::peripherals::$inst {} - impl GeneralPurpose2ChannelComplementaryInstance for crate::peripherals::$inst {} - impl AdvancedControlInstance for crate::peripherals::$inst {} + impl CaptureCompare16bitInstance for crate::peripherals::$inst {} + impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {} }; } // Update Event trigger DMA for every timer -dma_trait!(UpDma, BasicNoCr2Instance); +dma_trait!(UpDma, BasicInstance); -dma_trait!(Ch1Dma, GeneralPurpose1ChannelInstance); -dma_trait!(Ch2Dma, GeneralPurpose2ChannelInstance); -dma_trait!(Ch3Dma, GeneralPurpose16bitInstance); -dma_trait!(Ch4Dma, GeneralPurpose16bitInstance); +dma_trait!(Ch1Dma, CaptureCompare16bitInstance); +dma_trait!(Ch2Dma, CaptureCompare16bitInstance); +dma_trait!(Ch3Dma, CaptureCompare16bitInstance); +dma_trait!(Ch4Dma, CaptureCompare16bitInstance); diff --git a/embassy-stm32/src/timer/qei.rs b/embassy-stm32/src/timer/qei.rs index 7e56312bb..59efb72ba 100644 --- a/embassy-stm32/src/timer/qei.rs +++ b/embassy-stm32/src/timer/qei.rs @@ -30,7 +30,7 @@ pub struct QeiPin<'d, T, Channel> { macro_rules! channel_impl { ($new_chx:ident, $channel:ident, $pin_trait:ident) => { - impl<'d, T: GeneralPurpose16bitInstance> QeiPin<'d, T, $channel> { + impl<'d, T: CaptureCompare16bitInstance> QeiPin<'d, T, $channel> { #[doc = concat!("Create a new ", stringify!($channel), " QEI pin instance.")] pub fn $new_chx(pin: impl Peripheral

> + 'd) -> Self { into_ref!(pin); @@ -57,7 +57,7 @@ pub struct Qei<'d, T> { _inner: PeripheralRef<'d, T>, } -impl<'d, T: GeneralPurpose16bitInstance> Qei<'d, T> { +impl<'d, T: CaptureCompare16bitInstance> Qei<'d, T> { /// Create a new quadrature decoder driver. pub fn new(tim: impl Peripheral

+ 'd, _ch1: QeiPin<'d, T, Ch1>, _ch2: QeiPin<'d, T, Ch2>) -> Self { Self::new_inner(tim) diff --git a/embassy-stm32/src/timer/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs index 088d02c97..1acba504e 100644 --- a/embassy-stm32/src/timer/simple_pwm.rs +++ b/embassy-stm32/src/timer/simple_pwm.rs @@ -1,7 +1,6 @@ //! Simple PWM driver. use core::marker::PhantomData; -use core::ops::{Deref, DerefMut}; use embassy_hal_internal::{into_ref, PeripheralRef}; @@ -31,7 +30,7 @@ pub struct PwmPin<'d, T, C> { macro_rules! channel_impl { ($new_chx:ident, $channel:ident, $pin_trait:ident) => { - impl<'d, T: GeneralPurpose16bitInstance> PwmPin<'d, T, $channel> { + impl<'d, T: CaptureCompare16bitInstance> PwmPin<'d, T, $channel> { #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance.")] pub fn $new_chx(pin: impl Peripheral

> + 'd, output_type: OutputType) -> Self { into_ref!(pin); @@ -60,7 +59,7 @@ pub struct SimplePwm<'d, T> { inner: PeripheralRef<'d, T>, } -impl<'d, T: GeneralPurpose16bitInstance> SimplePwm<'d, T> { +impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> { /// Create a new simple PWM driver. pub fn new( tim: impl Peripheral

+ 'd, @@ -88,13 +87,9 @@ impl<'d, T: GeneralPurpose16bitInstance> SimplePwm<'d, T> { [Channel::Ch1, Channel::Ch2, Channel::Ch3, Channel::Ch4] .iter() .for_each(|&channel| { - sealed::GeneralPurpose16bitInstance::set_output_compare_mode( - this.inner.deref_mut(), - channel, - OutputCompareMode::PwmMode1, - ); + this.inner.set_output_compare_mode(channel, OutputCompareMode::PwmMode1); - sealed::GeneralPurpose16bitInstance::set_output_compare_preload(this.inner.deref_mut(), channel, true); + this.inner.set_output_compare_preload(channel, true); }); this @@ -102,17 +97,17 @@ impl<'d, T: GeneralPurpose16bitInstance> SimplePwm<'d, T> { /// Enable the given channel. pub fn enable(&mut self, channel: Channel) { - sealed::GeneralPurpose16bitInstance::enable_channel(self.inner.deref_mut(), channel, true); + self.inner.enable_channel(channel, true); } /// Disable the given channel. pub fn disable(&mut self, channel: Channel) { - sealed::GeneralPurpose16bitInstance::enable_channel(self.inner.deref_mut(), channel, false); + self.inner.enable_channel(channel, false); } /// Check whether given channel is enabled pub fn is_enabled(&self, channel: Channel) -> bool { - sealed::GeneralPurpose16bitInstance::get_channel_enable_state(self.inner.deref(), channel) + self.inner.get_channel_enable_state(channel) } /// Set PWM frequency. @@ -140,24 +135,24 @@ impl<'d, T: GeneralPurpose16bitInstance> SimplePwm<'d, T> { /// The value ranges from 0 for 0% duty, to [`get_max_duty`](Self::get_max_duty) for 100% duty, both included. pub fn set_duty(&mut self, channel: Channel, duty: u16) { assert!(duty <= self.get_max_duty()); - sealed::GeneralPurpose16bitInstance::set_compare_value(self.inner.deref_mut(), channel, duty) + self.inner.set_compare_value(channel, duty) } /// Get the duty for a given channel. /// /// The value ranges from 0 for 0% duty, to [`get_max_duty`](Self::get_max_duty) for 100% duty, both included. pub fn get_duty(&self, channel: Channel) -> u16 { - sealed::GeneralPurpose16bitInstance::get_compare_value(self.inner.deref(), channel) + self.inner.get_compare_value(channel) } /// Set the output polarity for a given channel. pub fn set_polarity(&mut self, channel: Channel, polarity: OutputPolarity) { - sealed::GeneralPurpose16bitInstance::set_output_polarity(self.inner.deref_mut(), channel, polarity); + self.inner.set_output_polarity(channel, polarity); } /// Set the output compare mode for a given channel. pub fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode) { - sealed::GeneralPurpose16bitInstance::set_output_compare_mode(self.inner.deref_mut(), channel, mode); + self.inner.set_output_compare_mode(channel, mode); } /// Generate a sequence of PWM waveform @@ -232,7 +227,7 @@ impl<'d, T: GeneralPurpose16bitInstance> SimplePwm<'d, T> { macro_rules! impl_waveform_chx { ($fn_name:ident, $dma_ch:ident, $cc_ch:ident) => { - impl<'d, T: GeneralPurpose16bitInstance> SimplePwm<'d, T> { + impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> { /// Generate a sequence of PWM waveform /// /// Note: @@ -319,17 +314,17 @@ impl_waveform_chx!(waveform_ch2, Ch2Dma, Ch2); impl_waveform_chx!(waveform_ch3, Ch3Dma, Ch3); impl_waveform_chx!(waveform_ch4, Ch4Dma, Ch4); -impl<'d, T: GeneralPurpose16bitInstance> embedded_hal_02::Pwm for SimplePwm<'d, T> { +impl<'d, T: CaptureCompare16bitInstance> embedded_hal_02::Pwm for SimplePwm<'d, T> { type Channel = Channel; type Time = Hertz; type Duty = u16; fn disable(&mut self, channel: Self::Channel) { - sealed::GeneralPurpose16bitInstance::enable_channel(self.inner.deref_mut(), channel, false); + self.inner.enable_channel(channel, false); } fn enable(&mut self, channel: Self::Channel) { - sealed::GeneralPurpose16bitInstance::enable_channel(self.inner.deref_mut(), channel, true); + self.inner.enable_channel(channel, true); } fn get_period(&self) -> Self::Time { @@ -337,7 +332,7 @@ impl<'d, T: GeneralPurpose16bitInstance> embedded_hal_02::Pwm for SimplePwm<'d, } fn get_duty(&self, channel: Self::Channel) -> Self::Duty { - sealed::GeneralPurpose16bitInstance::get_compare_value(self.inner.deref(), channel) + self.inner.get_compare_value(channel) } fn get_max_duty(&self) -> Self::Duty { @@ -346,7 +341,7 @@ impl<'d, T: GeneralPurpose16bitInstance> embedded_hal_02::Pwm for SimplePwm<'d, fn set_duty(&mut self, channel: Self::Channel, duty: Self::Duty) { assert!(duty <= self.get_max_duty()); - sealed::GeneralPurpose16bitInstance::set_compare_value(self.inner.deref_mut(), channel, duty) + self.inner.set_compare_value(channel, duty) } fn set_period

(&mut self, period: P) diff --git a/examples/stm32h7/src/bin/low_level_timer_api.rs b/examples/stm32h7/src/bin/low_level_timer_api.rs index 0be3eccb7..cc508c3cf 100644 --- a/examples/stm32h7/src/bin/low_level_timer_api.rs +++ b/examples/stm32h7/src/bin/low_level_timer_api.rs @@ -56,11 +56,11 @@ async fn main(_spawner: Spawner) { Timer::after_millis(300).await; } } -pub struct SimplePwm32<'d, T: GeneralPurpose32bitInstance> { +pub struct SimplePwm32<'d, T: CaptureCompare32bitInstance> { inner: PeripheralRef<'d, T>, } -impl<'d, T: GeneralPurpose32bitInstance> SimplePwm32<'d, T> { +impl<'d, T: CaptureCompare32bitInstance> SimplePwm32<'d, T> { pub fn new( tim: impl Peripheral

+ 'd, ch1: impl Peripheral

> + 'd,