From d6636ca11669c60925acb08c32d488c481ee1581 Mon Sep 17 00:00:00 2001 From: eZio Pan <eziopan@qq.com> Date: Tue, 30 Jan 2024 16:54:06 +0800 Subject: [PATCH 01/10] minor fix --- embassy-stm32/src/dma/ringbuffer.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/embassy-stm32/src/dma/ringbuffer.rs b/embassy-stm32/src/dma/ringbuffer.rs index c5b42060a..23f1d67d5 100644 --- a/embassy-stm32/src/dma/ringbuffer.rs +++ b/embassy-stm32/src/dma/ringbuffer.rs @@ -37,6 +37,7 @@ pub struct ReadableDmaRingBuffer<'a, W: Word> { } #[derive(Debug, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct OverrunError; pub trait DmaCtrl { From dc4898ca89d2130158acf1ced1f8cb3b25efe4b8 Mon Sep 17 00:00:00 2001 From: eZio Pan <eziopan@qq.com> Date: Tue, 30 Jan 2024 16:53:39 +0800 Subject: [PATCH 02/10] update timer mod after stm32-metapac timer_v2 --- embassy-stm32/Cargo.toml | 4 +- embassy-stm32/src/time_driver.rs | 8 +- embassy-stm32/src/timer/complementary_pwm.rs | 2 +- embassy-stm32/src/timer/mod.rs | 526 ++++++++++++++----- embassy-stm32/src/timer/qei.rs | 2 +- embassy-stm32/src/timer/simple_pwm.rs | 6 +- examples/stm32h7/src/bin/dac_dma.rs | 14 +- examples/stm32l4/src/bin/dac_dma.rs | 14 +- 8 files changed, 433 insertions(+), 143 deletions(-) diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 61d70b732..c6bc27f89 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -68,7 +68,7 @@ rand_core = "0.6.3" sdio-host = "0.5.0" critical-section = "1.1" #stm32-metapac = { version = "15" } -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-d7c933984fe0cbd120b6aaa7742bd585f89fa786" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", rev = "stm32-data-028efe4e6e0719b661cbdf8ffda3341e4d63d0df" } vcell = "0.1.3" bxcan = "0.7.0" nb = "1.0.0" @@ -89,7 +89,7 @@ critical-section = { version = "1.1", features = ["std"] } proc-macro2 = "1.0.36" quote = "1.0.15" #stm32-metapac = { version = "15", default-features = false, features = ["metadata"]} -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-d7c933984fe0cbd120b6aaa7742bd585f89fa786", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-028efe4e6e0719b661cbdf8ffda3341e4d63d0df", default-features = false, features = ["metadata"]} [features] diff --git a/embassy-stm32/src/time_driver.rs b/embassy-stm32/src/time_driver.rs index 320b29ddb..29ff4a736 100644 --- a/embassy-stm32/src/time_driver.rs +++ b/embassy-stm32/src/time_driver.rs @@ -14,7 +14,7 @@ use crate::pac::timer::vals; use crate::rcc::sealed::RccPeripheral; #[cfg(feature = "low-power")] use crate::rtc::Rtc; -use crate::timer::sealed::{Basic16bitInstance as BasicInstance, GeneralPurpose16bitInstance as Instance}; +use crate::timer::sealed::{CoreInstance, GeneralPurpose16bitInstance as Instance}; use crate::{interrupt, peripherals}; // NOTE regarding ALARM_COUNT: @@ -234,8 +234,8 @@ impl RtcDriver { w.set_ccie(0, true); }); - <T as BasicInstance>::Interrupt::unpend(); - unsafe { <T as BasicInstance>::Interrupt::enable() }; + <T as CoreInstance>::Interrupt::unpend(); + unsafe { <T as CoreInstance>::Interrupt::enable() }; r.cr1().modify(|w| w.set_cen(true)); } @@ -251,7 +251,7 @@ impl RtcDriver { // Clear all interrupt flags. Bits in SR are "write 0 to clear", so write the bitwise NOT. // Other approaches such as writing all zeros, or RMWing won't work, they can // miss interrupts. - r.sr().write_value(regs::SrGp(!sr.0)); + r.sr().write_value(regs::SrGp16(!sr.0)); // Overflow if sr.uif() { diff --git a/embassy-stm32/src/timer/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs index eddce0404..0470e3048 100644 --- a/embassy-stm32/src/timer/complementary_pwm.rs +++ b/embassy-stm32/src/timer/complementary_pwm.rs @@ -52,7 +52,7 @@ pub struct ComplementaryPwm<'d, T> { inner: PeripheralRef<'d, T>, } -impl<'d, T: ComplementaryCaptureCompare16bitInstance> ComplementaryPwm<'d, T> { +impl<'d, T: GeneralPurpose16bitInstance + ComplementaryCaptureCompare16bitInstance> ComplementaryPwm<'d, T> { /// Create a new complementary PWM driver. #[allow(clippy::too_many_arguments)] pub fn new( diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs index 210bf7153..f66b4d094 100644 --- a/embassy-stm32/src/timer/mod.rs +++ b/embassy-stm32/src/timer/mod.rs @@ -1,5 +1,19 @@ //! Timers, PWM, quadrature decoder. +// Timer inheritance +// +// CaptureCompare16bitInstance ComplementaryCaptureCompare16bitInstance +// v v +// Core -------------------------> 1CH -------------------------> 1CH_CMP +// | | ^ | +// +--> Basic_NoCr2 --> Basic +--> 2CH --> GP16 --> GP32 | +--> 2CH_CMP --> ADV +// | | | ^ | | ^ ^ +// | | +------|--|--------------|-----------+ | +// | +--------------------+ +--------------|-----------|---------+ +// | | | | +// | +--------------------------------------|-----------+ +// +----------------------------------------------------+ + pub mod complementary_pwm; pub mod qei; pub mod simple_pwm; @@ -19,32 +33,32 @@ pub mod low_level { pub(crate) mod sealed { use super::*; - /// Basic 16-bit timer instance. - pub trait Basic16bitInstance: RccPeripheral { + /// Virtual Core 16-bit timer instance. + pub trait CoreInstance: RccPeripheral { /// Interrupt for this timer. type Interrupt: interrupt::typelevel::Interrupt; - /// Get access to the basic 16bit timer registers. + /// Get access to the virutal core 16bit timer registers. /// /// Note: This works even if the timer is more capable, because registers /// for the less capable timers are a subset. This allows writing a driver /// for a given set of capabilities, and having it transparently work with /// more capable timers. - fn regs() -> crate::pac::timer::TimBasic; + fn regs_core() -> crate::pac::timer::TimCore; /// Start the timer. fn start(&mut self) { - Self::regs().cr1().modify(|r| r.set_cen(true)); + Self::regs_core().cr1().modify(|r| r.set_cen(true)); } /// Stop the timer. fn stop(&mut self) { - Self::regs().cr1().modify(|r| r.set_cen(false)); + Self::regs_core().cr1().modify(|r| r.set_cen(false)); } /// Reset the counter value to 0 fn reset(&mut self) { - Self::regs().cnt().write(|r| r.set_cnt(0)); + Self::regs_core().cnt().write(|r| r.set_cnt(0)); } /// Set the frequency of how many times per second the timer counts up to the max value or down to 0. @@ -64,7 +78,7 @@ pub(crate) mod sealed { // the timer counts `0..=arr`, we want it to count `0..divide_by` let arr = unwrap!(u16::try_from(divide_by - 1)); - let regs = Self::regs(); + let regs = Self::regs_core(); regs.psc().write(|r| r.set_psc(psc)); regs.arr().write(|r| r.set_arr(arr)); @@ -77,7 +91,7 @@ pub(crate) mod sealed { /// /// Returns whether the update interrupt flag was set. fn clear_update_interrupt(&mut self) -> bool { - let regs = Self::regs(); + let regs = Self::regs_core(); let sr = regs.sr().read(); if sr.uif() { regs.sr().modify(|r| { @@ -91,29 +105,19 @@ pub(crate) mod sealed { /// Enable/disable the update interrupt. fn enable_update_interrupt(&mut self, enable: bool) { - Self::regs().dier().modify(|r| r.set_uie(enable)); - } - - /// Enable/disable the update dma. - fn enable_update_dma(&mut self, enable: bool) { - Self::regs().dier().modify(|r| r.set_ude(enable)); - } - - /// Get the update dma enable/disable state. - fn get_update_dma_state(&self) -> bool { - Self::regs().dier().read().ude() + Self::regs_core().dier().modify(|r| r.set_uie(enable)); } /// Enable/disable autoreload preload. fn set_autoreload_preload(&mut self, enable: bool) { - Self::regs().cr1().modify(|r| r.set_arpe(enable)); + Self::regs_core().cr1().modify(|r| r.set_arpe(enable)); } /// Get the timer frequency. fn get_frequency(&self) -> Hertz { let timer_f = Self::frequency(); - let regs = Self::regs(); + let regs = Self::regs_core(); let arr = regs.arr().read().arr(); let psc = regs.psc().read().psc(); @@ -121,8 +125,67 @@ pub(crate) mod sealed { } } + /// Virtual Basic without CR2 16-bit timer instance. + pub trait BasicNoCr2Instance: CoreInstance { + /// Get access to the Baisc 16bit timer registers. + /// + /// Note: This works even if the timer is more capable, because registers + /// for the less capable timers are a subset. This allows writing a driver + /// for a given set of capabilities, and having it transparently work with + /// more capable timers. + fn regs_basic_no_cr2() -> crate::pac::timer::TimBasicNoCr2; + + /// Enable/disable the update dma. + fn enable_update_dma(&mut self, enable: bool) { + Self::regs_basic_no_cr2().dier().modify(|r| r.set_ude(enable)); + } + + /// Get the update dma enable/disable state. + fn get_update_dma_state(&self) -> bool { + Self::regs_basic_no_cr2().dier().read().ude() + } + } + + /// Basic 16-bit timer instance. + pub trait BasicInstance: BasicNoCr2Instance { + /// Get access to the Baisc 16bit timer registers. + /// + /// Note: This works even if the timer is more capable, because registers + /// for the less capable timers are a subset. This allows writing a driver + /// for a given set of capabilities, and having it transparently work with + /// more capable timers. + fn regs_basic() -> crate::pac::timer::TimBasic; + } + + /// Gneral-purpose 1 channel 16-bit timer instance. + pub trait GeneralPurpose1ChannelInstance: CoreInstance { + /// Get access to the general purpose 1 channel 16bit timer registers. + /// + /// Note: This works even if the timer is more capable, because registers + /// for the less capable timers are a subset. This allows writing a driver + /// for a given set of capabilities, and having it transparently work with + /// more capable timers. + fn regs_1ch() -> crate::pac::timer::Tim1ch; + + /// Set clock divider. + fn set_clock_division(&mut self, ckd: vals::Ckd) { + Self::regs_1ch().cr1().modify(|r| r.set_ckd(ckd)); + } + } + + /// Gneral-purpose 1 channel 16-bit timer instance. + pub trait GeneralPurpose2ChannelInstance: GeneralPurpose1ChannelInstance { + /// Get access to the general purpose 2 channel 16bit timer registers. + /// + /// Note: This works even if the timer is more capable, because registers + /// for the less capable timers are a subset. This allows writing a driver + /// for a given set of capabilities, and having it transparently work with + /// more capable timers. + fn regs_2ch() -> crate::pac::timer::Tim2ch; + } + /// Gneral-purpose 16-bit timer instance. - pub trait GeneralPurpose16bitInstance: Basic16bitInstance { + pub trait GeneralPurpose16bitInstance: BasicInstance + GeneralPurpose2ChannelInstance { /// Get access to the general purpose 16bit timer registers. /// /// Note: This works even if the timer is more capable, because registers @@ -135,7 +198,7 @@ pub(crate) mod sealed { fn set_counting_mode(&mut self, mode: CountingMode) { let (cms, dir) = mode.into(); - let timer_enabled = Self::regs().cr1().read().cen(); + let timer_enabled = Self::regs_core().cr1().read().cen(); // Changing from edge aligned to center aligned (and vice versa) is not allowed while the timer is running. // Changing direction is discouraged while the timer is running. assert!(!timer_enabled); @@ -149,11 +212,6 @@ pub(crate) mod sealed { let cr1 = Self::regs_gp16().cr1().read(); (cr1.cms(), cr1.dir()).into() } - - /// Set clock divider. - fn set_clock_division(&mut self, ckd: vals::Ckd) { - Self::regs_gp16().cr1().modify(|r| r.set_ckd(ckd)); - } } /// Gneral-purpose 32-bit timer instance. @@ -196,36 +254,67 @@ pub(crate) mod sealed { } } + /// 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. + /// + /// Note: This works even if the timer is more capable, because registers + /// for the less capable timers are a subset. This allows writing a driver + /// for a given set of capabilities, and having it transparently work with + /// more capable timers. + fn regs_1ch_cmp() -> crate::pac::timer::Tim1chCmp; + + /// Enable timer outputs. + fn enable_outputs(&mut self) { + Self::regs_1ch_cmp().bdtr().modify(|w| w.set_moe(true)); + } + } + + /// Gneral-purpose 2 channel with one complementary 16-bit timer instance. + pub trait GeneralPurpose2ChannelComplementaryInstance: + BasicInstance + GeneralPurpose1ChannelComplementaryInstance + { + /// Get access to the general purpose 2 channel with one complementary 16bit timer registers. + /// + /// Note: This works even if the timer is more capable, because registers + /// for the less capable timers are a subset. This allows writing a driver + /// for a given set of capabilities, and having it transparently work with + /// more capable timers. + fn regs_2ch_cmp() -> crate::pac::timer::Tim2chCmp; + } + /// Advanced control timer instance. - pub trait AdvancedControlInstance: GeneralPurpose16bitInstance { + pub trait AdvancedControlInstance: + GeneralPurpose2ChannelComplementaryInstance + GeneralPurpose16bitInstance + { /// Get access to the advanced timer registers. fn regs_advanced() -> crate::pac::timer::TimAdv; } /// Capture/Compare 16-bit timer instance. - pub trait CaptureCompare16bitInstance: GeneralPurpose16bitInstance { + pub trait CaptureCompare16bitInstance: GeneralPurpose1ChannelInstance { /// Set input capture filter. - fn set_input_capture_filter(&mut self, channel: Channel, icf: vals::Icf) { + fn set_input_capture_filter(&mut self, channel: Channel, icf: vals::FilterValue) { let raw_channel = channel.index(); - Self::regs_gp16() + Self::regs_1ch() .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)); + Self::regs_1ch().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)); + Self::regs_1ch().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() + Self::regs_1ch() .ccmr_input(raw_channel / 2) .modify(|r| r.set_icpsc(raw_channel % 2, factor)); } @@ -233,14 +322,14 @@ pub(crate) mod sealed { /// Set input TI selection. fn set_input_ti_selection(&mut self, channel: Channel, tisel: InputTISelection) { let raw_channel = channel.index(); - Self::regs_gp16() + Self::regs_1ch() .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 { + Self::regs_1ch().ccer().modify(|r| match mode { InputCaptureMode::Rising => { r.set_ccnp(channel.index(), false); r.set_ccp(channel.index(), false); @@ -256,12 +345,9 @@ pub(crate) mod sealed { }); } - /// Enable timer outputs. - fn enable_outputs(&mut self); - /// Set output compare mode. fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode) { - let r = Self::regs_gp16(); + let r = Self::regs_1ch(); let raw_channel: usize = channel.index(); r.ccmr_output(raw_channel / 2) .modify(|w| w.set_ocm(raw_channel % 2, mode.into())); @@ -269,45 +355,45 @@ pub(crate) mod sealed { /// Set output polarity. fn set_output_polarity(&mut self, channel: Channel, polarity: OutputPolarity) { - Self::regs_gp16() + Self::regs_1ch() .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)); + Self::regs_1ch().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()) + Self::regs_1ch().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)); + Self::regs_1ch().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() + Self::regs_1ch().ccr(channel.index()).read().ccr() } /// Get max compare value. This depends on the timer frequency and the clock frequency from RCC. fn get_max_compare_value(&self) -> u16 { - Self::regs_gp16().arr().read().arr() + Self::regs_1ch().arr().read().arr() } /// Get compare value for a channel. fn get_compare_value(&self, channel: Channel) -> u16 { - Self::regs_gp16().ccr(channel.index()).read().ccr() + Self::regs_1ch().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() + Self::regs_1ch() .ccmr_output(channel_index / 2) .modify(|w| w.set_ocpe(channel_index % 2, preload)); } @@ -334,27 +420,29 @@ pub(crate) mod sealed { } /// Capture/Compare 16-bit timer instance with complementary pin support. - pub trait ComplementaryCaptureCompare16bitInstance: CaptureCompare16bitInstance + AdvancedControlInstance { + pub trait ComplementaryCaptureCompare16bitInstance: + CaptureCompare16bitInstance + GeneralPurpose1ChannelComplementaryInstance + { /// Set complementary output polarity. fn set_complementary_output_polarity(&mut self, channel: Channel, polarity: OutputPolarity) { - Self::regs_advanced() + Self::regs_1ch_cmp() .ccer() .modify(|w| w.set_ccnp(channel.index(), polarity.into())); } /// Set clock divider for the dead time. fn set_dead_time_clock_division(&mut self, value: vals::Ckd) { - Self::regs_advanced().cr1().modify(|w| w.set_ckd(value)); + Self::regs_1ch_cmp().cr1().modify(|w| w.set_ckd(value)); } /// Set dead time, as a fraction of the max duty value. fn set_dead_time_value(&mut self, value: u8) { - Self::regs_advanced().bdtr().modify(|w| w.set_dtg(value)); + Self::regs_1ch_cmp().bdtr().modify(|w| w.set_dtg(value)); } /// Enable/disable a complementary channel. fn enable_complementary_channel(&mut self, channel: Channel, enable: bool) { - Self::regs_advanced() + Self::regs_1ch_cmp() .ccer() .modify(|w| w.set_ccne(channel.index(), enable)); } @@ -571,11 +659,29 @@ impl From<OutputPolarity> for bool { } } -/// Basic 16-bit timer instance. -pub trait Basic16bitInstance: sealed::Basic16bitInstance + 'static {} +/// Virtual Core 16-bit timer instance. +pub trait CoreInstance: sealed::CoreInstance + 'static {} -/// Gneral-purpose 16-bit timer instance. -pub trait GeneralPurpose16bitInstance: sealed::GeneralPurpose16bitInstance + Basic16bitInstance + '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 +{ +} + +/// General-purpose 16-bit timer instance. +pub trait GeneralPurpose16bitInstance: + sealed::GeneralPurpose16bitInstance + BasicInstance + GeneralPurpose2ChannelInstance + 'static +{ +} /// Gneral-purpose 32-bit timer instance. pub trait GeneralPurpose32bitInstance: @@ -583,18 +689,39 @@ pub trait GeneralPurpose32bitInstance: { } +/// General-purpose 1 channel with one complementary 16-bit timer instance. +pub trait GeneralPurpose1ChannelComplementaryInstance: + sealed::GeneralPurpose1ChannelComplementaryInstance + GeneralPurpose1ChannelInstance + 'static +{ +} + +/// General-purpose 2 channel with one complementary 16-bit timer instance. +pub trait GeneralPurpose2ChannelComplementaryInstance: + sealed::GeneralPurpose2ChannelComplementaryInstance + + BasicInstance + + GeneralPurpose1ChannelComplementaryInstance + + 'static +{ +} + /// Advanced control timer instance. -pub trait AdvancedControlInstance: sealed::AdvancedControlInstance + GeneralPurpose16bitInstance + 'static {} +pub trait AdvancedControlInstance: + sealed::AdvancedControlInstance + GeneralPurpose2ChannelComplementaryInstance + GeneralPurpose16bitInstance + 'static +{ +} /// Capture/Compare 16-bit timer instance. pub trait CaptureCompare16bitInstance: - sealed::CaptureCompare16bitInstance + GeneralPurpose16bitInstance + 'static + sealed::CaptureCompare16bitInstance + GeneralPurpose1ChannelInstance + 'static { } /// Capture/Compare 16-bit timer instance with complementary pin support. pub trait ComplementaryCaptureCompare16bitInstance: - sealed::ComplementaryCaptureCompare16bitInstance + CaptureCompare16bitInstance + AdvancedControlInstance + 'static + sealed::ComplementaryCaptureCompare16bitInstance + + CaptureCompare16bitInstance + + GeneralPurpose1ChannelComplementaryInstance + + 'static { } @@ -621,12 +748,34 @@ pin_trait!(BreakInput2Comparator1Pin, CaptureCompare16bitInstance); pin_trait!(BreakInput2Comparator2Pin, CaptureCompare16bitInstance); #[allow(unused)] -macro_rules! impl_basic_16bit_timer { +macro_rules! impl_core_timer { ($inst:ident, $irq:ident) => { - impl sealed::Basic16bitInstance for crate::peripherals::$inst { + impl sealed::CoreInstance for crate::peripherals::$inst { type Interrupt = crate::interrupt::typelevel::$irq; - fn regs() -> crate::pac::timer::TimBasic { + fn regs_core() -> crate::pac::timer::TimCore { + unsafe { crate::pac::timer::TimCore::from_ptr(crate::pac::$inst.as_ptr()) } + } + } + }; +} + +#[allow(unused)] +macro_rules! impl_basic_no_cr2_timer { + ($inst:ident) => { + impl sealed::BasicNoCr2Instance for crate::peripherals::$inst { + fn regs_basic_no_cr2() -> crate::pac::timer::TimBasicNoCr2 { + unsafe { crate::pac::timer::TimBasicNoCr2::from_ptr(crate::pac::$inst.as_ptr()) } + } + } + }; +} + +#[allow(unused)] +macro_rules! impl_basic_timer { + ($inst:ident) => { + impl sealed::BasicInstance for crate::peripherals::$inst { + fn regs_basic() -> crate::pac::timer::TimBasic { unsafe { crate::pac::timer::TimBasic::from_ptr(crate::pac::$inst.as_ptr()) } } } @@ -634,7 +783,40 @@ macro_rules! impl_basic_16bit_timer { } #[allow(unused)] -macro_rules! impl_32bit_timer { +macro_rules! impl_1ch_timer { + ($inst:ident) => { + impl sealed::GeneralPurpose1ChannelInstance for crate::peripherals::$inst { + fn regs_1ch() -> crate::pac::timer::Tim1ch { + unsafe { crate::pac::timer::Tim1ch::from_ptr(crate::pac::$inst.as_ptr()) } + } + } + }; +} + +#[allow(unused)] +macro_rules! impl_2ch_timer { + ($inst:ident) => { + impl sealed::GeneralPurpose2ChannelInstance for crate::peripherals::$inst { + fn regs_2ch() -> crate::pac::timer::Tim2ch { + unsafe { crate::pac::timer::Tim2ch::from_ptr(crate::pac::$inst.as_ptr()) } + } + } + }; +} + +#[allow(unused)] +macro_rules! impl_gp_16bit_timer { + ($inst:ident) => { + impl sealed::GeneralPurpose16bitInstance for crate::peripherals::$inst { + fn regs_gp16() -> crate::pac::timer::TimGp16 { + unsafe { crate::pac::timer::TimGp16::from_ptr(crate::pac::$inst.as_ptr()) } + } + } + }; +} + +#[allow(unused)] +macro_rules! impl_gp_32bit_timer { ($inst:ident) => { impl sealed::GeneralPurpose32bitInstance for crate::peripherals::$inst { fn regs_gp32() -> crate::pac::timer::TimGp32 { @@ -644,84 +826,194 @@ macro_rules! impl_32bit_timer { }; } +#[allow(unused)] +macro_rules! impl_1ch_cmp_timer { + ($inst:ident) => { + impl sealed::GeneralPurpose1ChannelComplementaryInstance for crate::peripherals::$inst { + fn regs_1ch_cmp() -> crate::pac::timer::Tim1chCmp { + unsafe { crate::pac::timer::Tim1chCmp::from_ptr(crate::pac::$inst.as_ptr()) } + } + } + }; +} + +#[allow(unused)] +macro_rules! impl_2ch_cmp_timer { + ($inst:ident) => { + impl sealed::GeneralPurpose2ChannelComplementaryInstance for crate::peripherals::$inst { + fn regs_2ch_cmp() -> crate::pac::timer::Tim2chCmp { + unsafe { crate::pac::timer::Tim2chCmp::from_ptr(crate::pac::$inst.as_ptr()) } + } + } + }; +} + +#[allow(unused)] +macro_rules! impl_adv_timer { + ($inst:ident) => { + impl sealed::AdvancedControlInstance for crate::peripherals::$inst { + fn regs_advanced() -> crate::pac::timer::TimAdv { + unsafe { crate::pac::timer::TimAdv::from_ptr(crate::pac::$inst.as_ptr()) } + } + } + }; +} + #[allow(unused)] macro_rules! impl_compare_capable_16bit { ($inst:ident) => { - impl sealed::CaptureCompare16bitInstance for crate::peripherals::$inst { - fn enable_outputs(&mut self) {} - } + impl sealed::CaptureCompare16bitInstance for crate::peripherals::$inst {} + }; +} + +#[allow(unused)] +macro_rules! impl_compare_capable_32bit { + ($inst:ident) => { + impl sealed::CaptureCompare32bitInstance for crate::peripherals::$inst {} + }; +} + +#[allow(unused)] +macro_rules! impl_compare_capable_complementary_16bit { + ($inst:ident) => { + impl sealed::ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {} }; } foreach_interrupt! { - ($inst:ident, timer, TIM_BASIC, UP, $irq:ident) => { - impl_basic_16bit_timer!($inst, $irq); - impl Basic16bitInstance for crate::peripherals::$inst {} - }; - ($inst:ident, timer, TIM_GP16, UP, $irq:ident) => { - impl_basic_16bit_timer!($inst, $irq); - impl_compare_capable_16bit!($inst); - impl Basic16bitInstance for crate::peripherals::$inst {} - impl GeneralPurpose16bitInstance for crate::peripherals::$inst {} - impl CaptureCompare16bitInstance for crate::peripherals::$inst {} - impl sealed::GeneralPurpose16bitInstance for crate::peripherals::$inst { - fn regs_gp16() -> crate::pac::timer::TimGp16 { - crate::pac::$inst - } - } + ($inst:ident, timer, TIM_BASIC, UP, $irq:ident) => { + 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_1ch_timer!($inst); + impl_compare_capable_16bit!($inst); + impl CoreInstance for crate::peripherals::$inst {} + impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {} + impl CaptureCompare16bitInstance for crate::peripherals::$inst {} + }; + + + ($inst:ident, timer, TIM_2CH, UP, $irq:ident) => { + impl_core_timer!($inst, $irq); + impl_1ch_timer!($inst); + impl_compare_capable_16bit!($inst); + impl_2ch_timer!($inst); + impl CoreInstance for crate::peripherals::$inst {} + impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {} + impl CaptureCompare16bitInstance for crate::peripherals::$inst {} + impl GeneralPurpose2ChannelInstance for crate::peripherals::$inst {} + }; + + ($inst:ident, timer, TIM_GP16, UP, $irq:ident) => { + impl_core_timer!($inst, $irq); + impl_basic_no_cr2_timer!($inst); + impl_basic_timer!($inst); + impl_1ch_timer!($inst); + impl_compare_capable_16bit!($inst); + impl_2ch_timer!($inst); + impl_gp_16bit_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 CaptureCompare16bitInstance for crate::peripherals::$inst {} + impl GeneralPurpose2ChannelInstance for crate::peripherals::$inst {} + impl GeneralPurpose16bitInstance for crate::peripherals::$inst {} }; ($inst:ident, timer, TIM_GP32, UP, $irq:ident) => { - impl_basic_16bit_timer!($inst, $irq); - impl_32bit_timer!($inst); + impl_core_timer!($inst, $irq); + impl_basic_no_cr2_timer!($inst); + impl_basic_timer!($inst); + impl_1ch_timer!($inst); impl_compare_capable_16bit!($inst); - impl Basic16bitInstance for crate::peripherals::$inst {} + impl_compare_capable_32bit!($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 BasicInstance for crate::peripherals::$inst {} + impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {} impl CaptureCompare16bitInstance for crate::peripherals::$inst {} impl CaptureCompare32bitInstance for crate::peripherals::$inst {} + impl GeneralPurpose2ChannelInstance for crate::peripherals::$inst {} impl GeneralPurpose16bitInstance for crate::peripherals::$inst {} impl GeneralPurpose32bitInstance for crate::peripherals::$inst {} - impl sealed::CaptureCompare32bitInstance for crate::peripherals::$inst {} - - impl sealed::GeneralPurpose16bitInstance for crate::peripherals::$inst { - fn regs_gp16() -> crate::pac::timer::TimGp16 { - unsafe { crate::pac::timer::TimGp16::from_ptr(crate::pac::$inst.as_ptr()) } - } - } }; - ($inst:ident, timer, TIM_ADV, UP, $irq:ident) => { - impl_basic_16bit_timer!($inst, $irq); + ($inst:ident, timer, TIM_1CH_CMP, UP, $irq:ident) => { + impl_core_timer!($inst, $irq); + impl_basic_no_cr2_timer!($inst); + impl_1ch_timer!($inst); + impl_compare_capable_16bit!($inst); + impl_1ch_cmp_timer!($inst); + impl_compare_capable_complementary_16bit!($inst); + impl CoreInstance for crate::peripherals::$inst {} + impl BasicNoCr2Instance for crate::peripherals::$inst{} + impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {} + impl CaptureCompare16bitInstance for crate::peripherals::$inst {} + impl GeneralPurpose1ChannelComplementaryInstance for crate::peripherals::$inst {} + impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {} + }; - impl Basic16bitInstance for crate::peripherals::$inst {} + + ($inst:ident, timer, TIM_2CH_CMP, UP, $irq:ident) => { + impl_core_timer!($inst, $irq); + impl_basic_no_cr2_timer!($inst); + impl_basic_timer!($inst); + impl_1ch_timer!($inst); + impl_compare_capable_16bit!($inst); + impl_1ch_cmp_timer!($inst); + impl_compare_capable_complementary_16bit!($inst); + impl_2ch_cmp_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 CaptureCompare16bitInstance for crate::peripherals::$inst {} + impl GeneralPurpose1ChannelComplementaryInstance for crate::peripherals::$inst {} + impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {} + impl GeneralPurpose2ChannelComplementaryInstance for crate::peripherals::$inst {} + }; + + + ($inst:ident, timer, TIM_ADV, 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_compare_capable_16bit!($inst); + impl_1ch_cmp_timer!($inst); + impl_gp_16bit_timer!($inst); + impl_compare_capable_complementary_16bit!($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 CaptureCompare16bitInstance for crate::peripherals::$inst {} + impl GeneralPurpose1ChannelComplementaryInstance for crate::peripherals::$inst {} impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {} + impl GeneralPurpose2ChannelComplementaryInstance for crate::peripherals::$inst {} impl AdvancedControlInstance for crate::peripherals::$inst {} - impl sealed::CaptureCompare16bitInstance for crate::peripherals::$inst { - fn enable_outputs(&mut self) { - use crate::timer::sealed::AdvancedControlInstance; - let r = Self::regs_advanced(); - r.bdtr().modify(|w| w.set_moe(true)); - } - } - impl sealed::ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {} - impl sealed::GeneralPurpose16bitInstance for crate::peripherals::$inst { - fn regs_gp16() -> crate::pac::timer::TimGp16 { - unsafe { crate::pac::timer::TimGp16::from_ptr(crate::pac::$inst.as_ptr()) } - } - } - - impl sealed::AdvancedControlInstance for crate::peripherals::$inst { - fn regs_advanced() -> crate::pac::timer::TimAdv { - crate::pac::$inst - } - } }; } // Update Event trigger DMA for every timer -dma_trait!(UpDma, Basic16bitInstance); +dma_trait!(UpDma, BasicNoCr2Instance); dma_trait!(Ch1Dma, CaptureCompare16bitInstance); dma_trait!(Ch2Dma, CaptureCompare16bitInstance); diff --git a/embassy-stm32/src/timer/qei.rs b/embassy-stm32/src/timer/qei.rs index 59efb72ba..75e5ab12a 100644 --- a/embassy-stm32/src/timer/qei.rs +++ b/embassy-stm32/src/timer/qei.rs @@ -57,7 +57,7 @@ pub struct Qei<'d, T> { _inner: PeripheralRef<'d, T>, } -impl<'d, T: CaptureCompare16bitInstance> Qei<'d, T> { +impl<'d, T: GeneralPurpose16bitInstance + CaptureCompare16bitInstance> Qei<'d, T> { /// Create a new quadrature decoder driver. pub fn new(tim: impl Peripheral<P = T> + '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 0b4c1225f..1c665d456 100644 --- a/embassy-stm32/src/timer/simple_pwm.rs +++ b/embassy-stm32/src/timer/simple_pwm.rs @@ -59,7 +59,7 @@ pub struct SimplePwm<'d, T> { inner: PeripheralRef<'d, T>, } -impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> { +impl<'d, T: GeneralPurpose16bitInstance + CaptureCompare16bitInstance> SimplePwm<'d, T> { /// Create a new simple PWM driver. pub fn new( tim: impl Peripheral<P = T> + 'd, @@ -84,8 +84,6 @@ impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> { this.set_frequency(freq); this.inner.start(); - this.inner.enable_outputs(); - [Channel::Ch1, Channel::Ch2, Channel::Ch3, Channel::Ch4] .iter() .for_each(|&channel| { @@ -202,7 +200,7 @@ impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> { &mut dma, req, duty, - T::regs_gp16().ccr(channel.index()).as_ptr() as *mut _, + T::regs_1ch().ccr(channel.index()).as_ptr() as *mut _, dma_transfer_option, ) .await diff --git a/examples/stm32h7/src/bin/dac_dma.rs b/examples/stm32h7/src/bin/dac_dma.rs index 8e5c41a43..d88bd838f 100644 --- a/examples/stm32h7/src/bin/dac_dma.rs +++ b/examples/stm32h7/src/bin/dac_dma.rs @@ -8,7 +8,7 @@ use embassy_stm32::pac::timer::vals::Mms; use embassy_stm32::peripherals::{DAC1, DMA1_CH3, DMA1_CH4, TIM6, TIM7}; use embassy_stm32::rcc::low_level::RccPeripheral; use embassy_stm32::time::Hertz; -use embassy_stm32::timer::low_level::Basic16bitInstance; +use embassy_stm32::timer::low_level::BasicInstance; use micromath::F32Ext; use {defmt_rtt as _, panic_probe as _}; @@ -75,9 +75,9 @@ async fn dac_task1(mut dac: DacCh1<'static, DAC1, DMA1_CH3>) { dac.enable(); TIM6::enable_and_reset(); - TIM6::regs().arr().modify(|w| w.set_arr(reload as u16 - 1)); - TIM6::regs().cr2().modify(|w| w.set_mms(Mms::UPDATE)); - TIM6::regs().cr1().modify(|w| { + TIM6::regs_basic().arr().modify(|w| w.set_arr(reload as u16 - 1)); + TIM6::regs_basic().cr2().modify(|w| w.set_mms(Mms::UPDATE)); + TIM6::regs_basic().cr1().modify(|w| { w.set_opm(false); w.set_cen(true); }); @@ -112,9 +112,9 @@ async fn dac_task2(mut dac: DacCh2<'static, DAC1, DMA1_CH4>) { } TIM7::enable_and_reset(); - TIM7::regs().arr().modify(|w| w.set_arr(reload as u16 - 1)); - TIM7::regs().cr2().modify(|w| w.set_mms(Mms::UPDATE)); - TIM7::regs().cr1().modify(|w| { + TIM7::regs_basic().arr().modify(|w| w.set_arr(reload as u16 - 1)); + TIM7::regs_basic().cr2().modify(|w| w.set_mms(Mms::UPDATE)); + TIM7::regs_basic().cr1().modify(|w| { w.set_opm(false); w.set_cen(true); }); diff --git a/examples/stm32l4/src/bin/dac_dma.rs b/examples/stm32l4/src/bin/dac_dma.rs index 8e5098557..f227812cd 100644 --- a/examples/stm32l4/src/bin/dac_dma.rs +++ b/examples/stm32l4/src/bin/dac_dma.rs @@ -8,7 +8,7 @@ use embassy_stm32::pac::timer::vals::Mms; use embassy_stm32::peripherals::{DAC1, DMA1_CH3, DMA1_CH4, TIM6, TIM7}; use embassy_stm32::rcc::low_level::RccPeripheral; use embassy_stm32::time::Hertz; -use embassy_stm32::timer::low_level::Basic16bitInstance; +use embassy_stm32::timer::low_level::BasicInstance; use micromath::F32Ext; use {defmt_rtt as _, panic_probe as _}; @@ -46,9 +46,9 @@ async fn dac_task1(mut dac: DacCh1<'static, DAC1, DMA1_CH3>) { dac.enable(); TIM6::enable_and_reset(); - TIM6::regs().arr().modify(|w| w.set_arr(reload as u16 - 1)); - TIM6::regs().cr2().modify(|w| w.set_mms(Mms::UPDATE)); - TIM6::regs().cr1().modify(|w| { + TIM6::regs_basic().arr().modify(|w| w.set_arr(reload as u16 - 1)); + TIM6::regs_basic().cr2().modify(|w| w.set_mms(Mms::UPDATE)); + TIM6::regs_basic().cr1().modify(|w| { w.set_opm(false); w.set_cen(true); }); @@ -83,9 +83,9 @@ async fn dac_task2(mut dac: DacCh2<'static, DAC1, DMA1_CH4>) { } TIM7::enable_and_reset(); - TIM7::regs().arr().modify(|w| w.set_arr(reload as u16 - 1)); - TIM7::regs().cr2().modify(|w| w.set_mms(Mms::UPDATE)); - TIM7::regs().cr1().modify(|w| { + TIM7::regs_basic().arr().modify(|w| w.set_arr(reload as u16 - 1)); + TIM7::regs_basic().cr2().modify(|w| w.set_mms(Mms::UPDATE)); + TIM7::regs_basic().cr1().modify(|w| { w.set_opm(false); w.set_cen(true); }); From 53bf0332e9e862fa5c09a1e9ab9a6d7116219ed7 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis <dirbaio@dirbaio.net> Date: Sat, 10 Feb 2024 00:00:26 +0100 Subject: [PATCH 03/10] asdkf --- embassy-stm32/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index c6bc27f89..eb67404d3 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -68,7 +68,7 @@ rand_core = "0.6.3" sdio-host = "0.5.0" critical-section = "1.1" #stm32-metapac = { version = "15" } -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", rev = "stm32-data-028efe4e6e0719b661cbdf8ffda3341e4d63d0df" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-028efe4e6e0719b661cbdf8ffda3341e4d63d0df" } vcell = "0.1.3" bxcan = "0.7.0" nb = "1.0.0" From d538829f2f3542c78ee9eb218c0b5c982acfb46b Mon Sep 17 00:00:00 2001 From: eZio Pan <eziopan@qq.com> Date: Thu, 1 Feb 2024 17:10:47 +0800 Subject: [PATCH 04/10] add methods with macro --- embassy-stm32/src/timer/complementary_pwm.rs | 52 +- embassy-stm32/src/timer/mod.rs | 522 ++++++++---------- embassy-stm32/src/timer/qei.rs | 4 +- embassy-stm32/src/timer/simple_pwm.rs | 40 +- .../stm32h7/src/bin/low_level_timer_api.rs | 4 +- 5 files changed, 298 insertions(+), 324 deletions(-) diff --git a/embassy-stm32/src/timer/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs index 0470e3048..b9cd044c9 100644 --- a/embassy-stm32/src/timer/complementary_pwm.rs +++ b/embassy-stm32/src/timer/complementary_pwm.rs @@ -1,6 +1,7 @@ //! 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; @@ -23,7 +24,7 @@ pub struct ComplementaryPwmPin<'d, T, C> { macro_rules! complementary_channel_impl { ($new_chx:ident, $channel:ident, $pin_trait:ident) => { - impl<'d, T: CaptureCompare16bitInstance> ComplementaryPwmPin<'d, T, $channel> { + impl<'d, T: AdvancedControlInstance> ComplementaryPwmPin<'d, T, $channel> { #[doc = concat!("Create a new ", stringify!($channel), " complementary PWM pin instance.")] pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd, output_type: OutputType) -> Self { into_ref!(pin); @@ -52,7 +53,7 @@ pub struct ComplementaryPwm<'d, T> { inner: PeripheralRef<'d, T>, } -impl<'d, T: GeneralPurpose16bitInstance + ComplementaryCaptureCompare16bitInstance> ComplementaryPwm<'d, T> { +impl<'d, T: AdvancedControlInstance> ComplementaryPwm<'d, T> { /// Create a new complementary PWM driver. #[allow(clippy::too_many_arguments)] pub fn new( @@ -84,27 +85,30 @@ impl<'d, T: GeneralPurpose16bitInstance + ComplementaryCaptureCompare16bitInstan this.inner.enable_outputs(); - this.inner - .set_output_compare_mode(Channel::Ch1, OutputCompareMode::PwmMode1); - this.inner - .set_output_compare_mode(Channel::Ch2, OutputCompareMode::PwmMode1); - this.inner - .set_output_compare_mode(Channel::Ch3, OutputCompareMode::PwmMode1); - this.inner - .set_output_compare_mode(Channel::Ch4, OutputCompareMode::PwmMode1); + [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 } /// Enable the given channel. pub fn enable(&mut self, channel: Channel) { - self.inner.enable_channel(channel, true); - self.inner.enable_complementary_channel(channel, true); + sealed::GeneralPurpose16bitInstance::enable_channel(self.inner.deref_mut(), channel, true); + sealed::AdvancedControlInstance::enable_complementary_channel(self.inner.deref_mut(), channel, true); } /// Disable the given channel. pub fn disable(&mut self, channel: Channel) { - self.inner.enable_complementary_channel(channel, false); - self.inner.enable_channel(channel, false); + sealed::AdvancedControlInstance::enable_complementary_channel(self.inner.deref_mut(), channel, false); + sealed::GeneralPurpose16bitInstance::enable_channel(self.inner.deref_mut(), channel, false); } /// Set PWM frequency. @@ -132,13 +136,13 @@ impl<'d, T: GeneralPurpose16bitInstance + ComplementaryCaptureCompare16bitInstan /// 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()); - self.inner.set_compare_value(channel, duty) + sealed::GeneralPurpose16bitInstance::set_compare_value(self.inner.deref_mut(), channel, duty) } /// Set the output polarity for a given channel. pub fn set_polarity(&mut self, channel: Channel, polarity: OutputPolarity) { - self.inner.set_output_polarity(channel, polarity); - self.inner.set_complementary_output_polarity(channel, polarity); + sealed::GeneralPurpose16bitInstance::set_output_polarity(self.inner.deref_mut(), channel, polarity); + sealed::AdvancedControlInstance::set_complementary_output_polarity(self.inner.deref_mut(), channel, polarity); } /// Set the dead time as a proportion of max_duty @@ -150,19 +154,19 @@ impl<'d, T: GeneralPurpose16bitInstance + ComplementaryCaptureCompare16bitInstan } } -impl<'d, T: ComplementaryCaptureCompare16bitInstance> embedded_hal_02::Pwm for ComplementaryPwm<'d, T> { +impl<'d, T: AdvancedControlInstance> embedded_hal_02::Pwm for ComplementaryPwm<'d, T> { type Channel = Channel; type Time = Hertz; type Duty = u16; fn disable(&mut self, channel: Self::Channel) { - self.inner.enable_complementary_channel(channel, false); - self.inner.enable_channel(channel, false); + sealed::AdvancedControlInstance::enable_complementary_channel(self.inner.deref_mut(), channel, false); + sealed::GeneralPurpose16bitInstance::enable_channel(self.inner.deref_mut(), channel, false); } fn enable(&mut self, channel: Self::Channel) { - self.inner.enable_channel(channel, true); - self.inner.enable_complementary_channel(channel, true); + sealed::GeneralPurpose16bitInstance::enable_channel(self.inner.deref_mut(), channel, true); + sealed::AdvancedControlInstance::enable_complementary_channel(self.inner.deref_mut(), channel, true); } fn get_period(&self) -> Self::Time { @@ -170,7 +174,7 @@ impl<'d, T: ComplementaryCaptureCompare16bitInstance> embedded_hal_02::Pwm for C } fn get_duty(&self, channel: Self::Channel) -> Self::Duty { - self.inner.get_compare_value(channel) + sealed::GeneralPurpose16bitInstance::get_compare_value(self.inner.deref(), channel) } fn get_max_duty(&self) -> Self::Duty { @@ -179,7 +183,7 @@ impl<'d, T: ComplementaryCaptureCompare16bitInstance> embedded_hal_02::Pwm for C fn set_duty(&mut self, channel: Self::Channel, duty: Self::Duty) { assert!(duty <= self.get_max_duty()); - self.inner.set_compare_value(channel, duty) + sealed::GeneralPurpose16bitInstance::set_compare_value(self.inner.deref_mut(), channel, duty) } fn set_period<P>(&mut self, period: P) diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs index f66b4d094..2f5d5770a 100644 --- a/embassy-stm32/src/timer/mod.rs +++ b/embassy-stm32/src/timer/mod.rs @@ -2,8 +2,6 @@ // Timer inheritance // -// CaptureCompare16bitInstance ComplementaryCaptureCompare16bitInstance -// v v // Core -------------------------> 1CH -------------------------> 1CH_CMP // | | ^ | // +--> Basic_NoCr2 --> Basic +--> 2CH --> GP16 --> GP32 | +--> 2CH_CMP --> ADV @@ -33,6 +31,156 @@ 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 r = Self::$regs(); + let raw_channel: usize = channel.index(); + r.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_1ch() + .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)) + } + }; + } + + 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. @@ -171,6 +319,13 @@ pub(crate) mod sealed { fn set_clock_division(&mut self, ckd: vals::Ckd) { Self::regs_1ch().cr1().modify(|r| r.set_ckd(ckd)); } + + /// Get max compare value. This depends on the timer frequency and the clock frequency from RCC. + 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. @@ -182,6 +337,8 @@ 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. @@ -212,6 +369,9 @@ pub(crate) mod sealed { let cr1 = Self::regs_gp16().cr1().read(); (cr1.cms(), cr1.dir()).into() } + + add_capture_compare_common_methods!(regs_gp16); + add_capture_compare_dma_methods!(regs_gp16); } /// Gneral-purpose 32-bit timer instance. @@ -252,204 +412,7 @@ pub(crate) mod sealed { timer_f / arr / (psc + 1) } - } - /// 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. - /// - /// Note: This works even if the timer is more capable, because registers - /// for the less capable timers are a subset. This allows writing a driver - /// for a given set of capabilities, and having it transparently work with - /// more capable timers. - fn regs_1ch_cmp() -> crate::pac::timer::Tim1chCmp; - - /// Enable timer outputs. - fn enable_outputs(&mut self) { - Self::regs_1ch_cmp().bdtr().modify(|w| w.set_moe(true)); - } - } - - /// Gneral-purpose 2 channel with one complementary 16-bit timer instance. - pub trait GeneralPurpose2ChannelComplementaryInstance: - BasicInstance + GeneralPurpose1ChannelComplementaryInstance - { - /// Get access to the general purpose 2 channel with one complementary 16bit timer registers. - /// - /// Note: This works even if the timer is more capable, because registers - /// for the less capable timers are a subset. This allows writing a driver - /// for a given set of capabilities, and having it transparently work with - /// more capable timers. - fn regs_2ch_cmp() -> crate::pac::timer::Tim2chCmp; - } - - /// Advanced control timer instance. - pub trait AdvancedControlInstance: - GeneralPurpose2ChannelComplementaryInstance + GeneralPurpose16bitInstance - { - /// Get access to the advanced timer registers. - fn regs_advanced() -> crate::pac::timer::TimAdv; - } - - /// Capture/Compare 16-bit timer instance. - pub trait CaptureCompare16bitInstance: GeneralPurpose1ChannelInstance { - /// Set input capture filter. - fn set_input_capture_filter(&mut self, channel: Channel, icf: vals::FilterValue) { - let raw_channel = channel.index(); - Self::regs_1ch() - .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_1ch().sr().modify(|r| r.set_ccif(channel.index(), false)); - } - - /// Enable input interrupt. - fn enable_input_interrupt(&mut self, channel: Channel, enable: bool) { - Self::regs_1ch().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_1ch() - .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_1ch() - .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_1ch().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 r = Self::regs_1ch(); - let raw_channel: usize = channel.index(); - r.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_1ch() - .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_1ch().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_1ch().ccer().read().cce(channel.index()) - } - - /// Set compare value for a channel. - fn set_compare_value(&mut self, channel: Channel, value: u16) { - Self::regs_1ch().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_1ch().ccr(channel.index()).read().ccr() - } - - /// Get max compare value. This depends on the timer frequency and the clock frequency from RCC. - fn get_max_compare_value(&self) -> u16 { - Self::regs_1ch().arr().read().arr() - } - - /// Get compare value for a channel. - fn get_compare_value(&self, channel: Channel) -> u16 { - Self::regs_1ch().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_1ch() - .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)) - } - } - - /// Capture/Compare 16-bit timer instance with complementary pin support. - pub trait ComplementaryCaptureCompare16bitInstance: - CaptureCompare16bitInstance + GeneralPurpose1ChannelComplementaryInstance - { - /// Set complementary output polarity. - fn set_complementary_output_polarity(&mut self, channel: Channel, polarity: OutputPolarity) { - Self::regs_1ch_cmp() - .ccer() - .modify(|w| w.set_ccnp(channel.index(), polarity.into())); - } - - /// Set clock divider for the dead time. - fn set_dead_time_clock_division(&mut self, value: vals::Ckd) { - Self::regs_1ch_cmp().cr1().modify(|w| w.set_ckd(value)); - } - - /// Set dead time, as a fraction of the max duty value. - fn set_dead_time_value(&mut self, value: u8) { - Self::regs_1ch_cmp().bdtr().modify(|w| w.set_dtg(value)); - } - - /// Enable/disable a complementary channel. - fn enable_complementary_channel(&mut self, channel: Channel, enable: bool) { - Self::regs_1ch_cmp() - .ccer() - .modify(|w| w.set_ccne(channel.index(), enable)); - } - } - - /// Capture/Compare 32-bit timer instance. - pub trait CaptureCompare32bitInstance: GeneralPurpose32bitInstance + CaptureCompare16bitInstance { /// Set comapre value for a channel. fn set_compare_value(&mut self, channel: Channel, value: u32) { Self::regs_gp32().ccr(channel.index()).modify(|w| w.set_ccr(value)); @@ -470,6 +433,59 @@ pub(crate) mod sealed { Self::regs_gp32().ccr(channel.index()).read().ccr() } } + + /// 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. + /// + /// Note: This works even if the timer is more capable, because registers + /// for the less capable timers are a subset. This allows writing a driver + /// for a given set of capabilities, and having it transparently work with + /// more capable timers. + fn regs_1ch_cmp() -> crate::pac::timer::Tim1chCmp; + + /// Set clock divider for the dead time. + fn set_dead_time_clock_division(&mut self, value: vals::Ckd) { + Self::regs_1ch_cmp().cr1().modify(|w| w.set_ckd(value)); + } + + /// Set dead time, as a fraction of the max duty value. + fn set_dead_time_value(&mut self, value: u8) { + Self::regs_1ch_cmp().bdtr().modify(|w| w.set_dtg(value)); + } + + /// Enable timer outputs. + fn enable_outputs(&mut self) { + Self::regs_1ch_cmp().bdtr().modify(|w| w.set_moe(true)); + } + + add_complementary_capture_compare_methods!(regs_1ch_cmp); + } + + /// Gneral-purpose 2 channel with one complementary 16-bit timer instance. + pub trait GeneralPurpose2ChannelComplementaryInstance: + BasicInstance + GeneralPurpose2ChannelInstance + GeneralPurpose1ChannelComplementaryInstance + { + /// Get access to the general purpose 2 channel with one complementary 16bit timer registers. + /// + /// Note: This works even if the timer is more capable, because registers + /// for the less capable timers are a subset. This allows writing a driver + /// 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); + } + + /// Advanced control timer instance. + pub trait AdvancedControlInstance: + GeneralPurpose2ChannelComplementaryInstance + GeneralPurpose16bitInstance + { + /// Get access to the advanced timer registers. + fn regs_advanced() -> crate::pac::timer::TimAdv; + + add_complementary_capture_compare_methods!(regs_advanced); + } } /// Timer channel. @@ -699,6 +715,7 @@ pub trait GeneralPurpose1ChannelComplementaryInstance: pub trait GeneralPurpose2ChannelComplementaryInstance: sealed::GeneralPurpose2ChannelComplementaryInstance + BasicInstance + + GeneralPurpose2ChannelInstance + GeneralPurpose1ChannelComplementaryInstance + 'static { @@ -710,42 +727,30 @@ pub trait AdvancedControlInstance: { } -/// Capture/Compare 16-bit timer instance. -pub trait CaptureCompare16bitInstance: - sealed::CaptureCompare16bitInstance + GeneralPurpose1ChannelInstance + 'static -{ -} +pin_trait!(Channel1Pin, GeneralPurpose1ChannelInstance); +pin_trait!(Channel2Pin, GeneralPurpose2ChannelInstance); +pin_trait!(Channel3Pin, GeneralPurpose16bitInstance); +pin_trait!(Channel4Pin, GeneralPurpose16bitInstance); -/// Capture/Compare 16-bit timer instance with complementary pin support. -pub trait ComplementaryCaptureCompare16bitInstance: - sealed::ComplementaryCaptureCompare16bitInstance - + CaptureCompare16bitInstance - + GeneralPurpose1ChannelComplementaryInstance - + 'static -{ -} +#[cfg(not(stm32l0))] +pin_trait!(ExternalTriggerPin, GeneralPurpose16bitInstance); -/// Capture/Compare 32-bit timer instance. -pub trait CaptureCompare32bitInstance: - sealed::CaptureCompare32bitInstance + CaptureCompare16bitInstance + GeneralPurpose32bitInstance + 'static -{ -} +#[cfg(stm32l0)] +pin_trait!(ExternalTriggerPin, GeneralPurpose2ChannelInstance); -pin_trait!(Channel1Pin, CaptureCompare16bitInstance); -pin_trait!(Channel1ComplementaryPin, CaptureCompare16bitInstance); -pin_trait!(Channel2Pin, CaptureCompare16bitInstance); -pin_trait!(Channel2ComplementaryPin, CaptureCompare16bitInstance); -pin_trait!(Channel3Pin, CaptureCompare16bitInstance); -pin_trait!(Channel3ComplementaryPin, CaptureCompare16bitInstance); -pin_trait!(Channel4Pin, CaptureCompare16bitInstance); -pin_trait!(Channel4ComplementaryPin, CaptureCompare16bitInstance); -pin_trait!(ExternalTriggerPin, CaptureCompare16bitInstance); -pin_trait!(BreakInputPin, CaptureCompare16bitInstance); -pin_trait!(BreakInputComparator1Pin, CaptureCompare16bitInstance); -pin_trait!(BreakInputComparator2Pin, CaptureCompare16bitInstance); -pin_trait!(BreakInput2Pin, CaptureCompare16bitInstance); -pin_trait!(BreakInput2Comparator1Pin, CaptureCompare16bitInstance); -pin_trait!(BreakInput2Comparator2Pin, CaptureCompare16bitInstance); +pin_trait!(Channel1ComplementaryPin, GeneralPurpose1ChannelComplementaryInstance); +pin_trait!(Channel2ComplementaryPin, GeneralPurpose2ChannelComplementaryInstance); +pin_trait!(Channel3ComplementaryPin, AdvancedControlInstance); +pin_trait!(Channel4ComplementaryPin, AdvancedControlInstance); + +pin_trait!(BreakInputPin, GeneralPurpose1ChannelComplementaryInstance); +pin_trait!(BreakInput2Pin, GeneralPurpose2ChannelComplementaryInstance); + +pin_trait!(BreakInputComparator1Pin, GeneralPurpose1ChannelComplementaryInstance); +pin_trait!(BreakInputComparator2Pin, AdvancedControlInstance); + +pin_trait!(BreakInput2Comparator1Pin, AdvancedControlInstance); +pin_trait!(BreakInput2Comparator2Pin, AdvancedControlInstance); #[allow(unused)] macro_rules! impl_core_timer { @@ -859,27 +864,6 @@ macro_rules! impl_adv_timer { }; } -#[allow(unused)] -macro_rules! impl_compare_capable_16bit { - ($inst:ident) => { - impl sealed::CaptureCompare16bitInstance for crate::peripherals::$inst {} - }; -} - -#[allow(unused)] -macro_rules! impl_compare_capable_32bit { - ($inst:ident) => { - impl sealed::CaptureCompare32bitInstance for crate::peripherals::$inst {} - }; -} - -#[allow(unused)] -macro_rules! impl_compare_capable_complementary_16bit { - ($inst:ident) => { - impl sealed::ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {} - }; -} - foreach_interrupt! { ($inst:ident, timer, TIM_BASIC, UP, $irq:ident) => { @@ -894,21 +878,17 @@ foreach_interrupt! { ($inst:ident, timer, TIM_1CH, UP, $irq:ident) => { impl_core_timer!($inst, $irq); impl_1ch_timer!($inst); - impl_compare_capable_16bit!($inst); impl CoreInstance for crate::peripherals::$inst {} impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {} - impl CaptureCompare16bitInstance for crate::peripherals::$inst {} }; ($inst:ident, timer, TIM_2CH, UP, $irq:ident) => { impl_core_timer!($inst, $irq); impl_1ch_timer!($inst); - impl_compare_capable_16bit!($inst); impl_2ch_timer!($inst); impl CoreInstance for crate::peripherals::$inst {} impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {} - impl CaptureCompare16bitInstance for crate::peripherals::$inst {} impl GeneralPurpose2ChannelInstance for crate::peripherals::$inst {} }; @@ -917,14 +897,12 @@ foreach_interrupt! { impl_basic_no_cr2_timer!($inst); impl_basic_timer!($inst); impl_1ch_timer!($inst); - impl_compare_capable_16bit!($inst); impl_2ch_timer!($inst); impl_gp_16bit_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 CaptureCompare16bitInstance for crate::peripherals::$inst {} impl GeneralPurpose2ChannelInstance for crate::peripherals::$inst {} impl GeneralPurpose16bitInstance for crate::peripherals::$inst {} }; @@ -934,8 +912,6 @@ foreach_interrupt! { impl_basic_no_cr2_timer!($inst); impl_basic_timer!($inst); impl_1ch_timer!($inst); - impl_compare_capable_16bit!($inst); - impl_compare_capable_32bit!($inst); impl_2ch_timer!($inst); impl_gp_16bit_timer!($inst); impl_gp_32bit_timer!($inst); @@ -943,8 +919,6 @@ foreach_interrupt! { impl BasicNoCr2Instance for crate::peripherals::$inst{} impl BasicInstance for crate::peripherals::$inst {} impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {} - impl CaptureCompare16bitInstance for crate::peripherals::$inst {} - impl CaptureCompare32bitInstance for crate::peripherals::$inst {} impl GeneralPurpose2ChannelInstance for crate::peripherals::$inst {} impl GeneralPurpose16bitInstance for crate::peripherals::$inst {} impl GeneralPurpose32bitInstance for crate::peripherals::$inst {} @@ -954,15 +928,11 @@ foreach_interrupt! { impl_core_timer!($inst, $irq); impl_basic_no_cr2_timer!($inst); impl_1ch_timer!($inst); - impl_compare_capable_16bit!($inst); impl_1ch_cmp_timer!($inst); - impl_compare_capable_complementary_16bit!($inst); impl CoreInstance for crate::peripherals::$inst {} impl BasicNoCr2Instance for crate::peripherals::$inst{} impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {} - impl CaptureCompare16bitInstance for crate::peripherals::$inst {} impl GeneralPurpose1ChannelComplementaryInstance for crate::peripherals::$inst {} - impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {} }; @@ -971,17 +941,15 @@ foreach_interrupt! { impl_basic_no_cr2_timer!($inst); impl_basic_timer!($inst); impl_1ch_timer!($inst); - impl_compare_capable_16bit!($inst); + impl_2ch_timer!($inst); impl_1ch_cmp_timer!($inst); - impl_compare_capable_complementary_16bit!($inst); impl_2ch_cmp_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 CaptureCompare16bitInstance for crate::peripherals::$inst {} + impl GeneralPurpose2ChannelInstance for crate::peripherals::$inst {} impl GeneralPurpose1ChannelComplementaryInstance for crate::peripherals::$inst {} - impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {} impl GeneralPurpose2ChannelComplementaryInstance for crate::peripherals::$inst {} }; @@ -992,10 +960,8 @@ foreach_interrupt! { impl_basic_timer!($inst); impl_1ch_timer!($inst); impl_2ch_timer!($inst); - impl_compare_capable_16bit!($inst); impl_1ch_cmp_timer!($inst); impl_gp_16bit_timer!($inst); - impl_compare_capable_complementary_16bit!($inst); impl_2ch_cmp_timer!($inst); impl_adv_timer!($inst); impl CoreInstance for crate::peripherals::$inst {} @@ -1004,9 +970,7 @@ foreach_interrupt! { impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {} impl GeneralPurpose2ChannelInstance for crate::peripherals::$inst {} impl GeneralPurpose16bitInstance for crate::peripherals::$inst {} - impl CaptureCompare16bitInstance for crate::peripherals::$inst {} impl GeneralPurpose1ChannelComplementaryInstance for crate::peripherals::$inst {} - impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {} impl GeneralPurpose2ChannelComplementaryInstance for crate::peripherals::$inst {} impl AdvancedControlInstance for crate::peripherals::$inst {} }; @@ -1015,7 +979,7 @@ foreach_interrupt! { // Update Event trigger DMA for every timer dma_trait!(UpDma, BasicNoCr2Instance); -dma_trait!(Ch1Dma, CaptureCompare16bitInstance); -dma_trait!(Ch2Dma, CaptureCompare16bitInstance); -dma_trait!(Ch3Dma, CaptureCompare16bitInstance); -dma_trait!(Ch4Dma, CaptureCompare16bitInstance); +dma_trait!(Ch1Dma, GeneralPurpose1ChannelInstance); +dma_trait!(Ch2Dma, GeneralPurpose2ChannelInstance); +dma_trait!(Ch3Dma, GeneralPurpose16bitInstance); +dma_trait!(Ch4Dma, GeneralPurpose16bitInstance); diff --git a/embassy-stm32/src/timer/qei.rs b/embassy-stm32/src/timer/qei.rs index 75e5ab12a..7e56312bb 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: CaptureCompare16bitInstance> QeiPin<'d, T, $channel> { + impl<'d, T: GeneralPurpose16bitInstance> QeiPin<'d, T, $channel> { #[doc = concat!("Create a new ", stringify!($channel), " QEI pin instance.")] pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd) -> Self { into_ref!(pin); @@ -57,7 +57,7 @@ pub struct Qei<'d, T> { _inner: PeripheralRef<'d, T>, } -impl<'d, T: GeneralPurpose16bitInstance + CaptureCompare16bitInstance> Qei<'d, T> { +impl<'d, T: GeneralPurpose16bitInstance> Qei<'d, T> { /// Create a new quadrature decoder driver. pub fn new(tim: impl Peripheral<P = T> + '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 1c665d456..088d02c97 100644 --- a/embassy-stm32/src/timer/simple_pwm.rs +++ b/embassy-stm32/src/timer/simple_pwm.rs @@ -1,6 +1,7 @@ //! Simple PWM driver. use core::marker::PhantomData; +use core::ops::{Deref, DerefMut}; use embassy_hal_internal::{into_ref, PeripheralRef}; @@ -30,7 +31,7 @@ pub struct PwmPin<'d, T, C> { macro_rules! channel_impl { ($new_chx:ident, $channel:ident, $pin_trait:ident) => { - impl<'d, T: CaptureCompare16bitInstance> PwmPin<'d, T, $channel> { + impl<'d, T: GeneralPurpose16bitInstance> PwmPin<'d, T, $channel> { #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance.")] pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd, output_type: OutputType) -> Self { into_ref!(pin); @@ -59,7 +60,7 @@ pub struct SimplePwm<'d, T> { inner: PeripheralRef<'d, T>, } -impl<'d, T: GeneralPurpose16bitInstance + CaptureCompare16bitInstance> SimplePwm<'d, T> { +impl<'d, T: GeneralPurpose16bitInstance> SimplePwm<'d, T> { /// Create a new simple PWM driver. pub fn new( tim: impl Peripheral<P = T> + 'd, @@ -87,8 +88,13 @@ impl<'d, T: GeneralPurpose16bitInstance + CaptureCompare16bitInstance> SimplePwm [Channel::Ch1, Channel::Ch2, Channel::Ch3, Channel::Ch4] .iter() .for_each(|&channel| { - this.inner.set_output_compare_mode(channel, OutputCompareMode::PwmMode1); - this.inner.set_output_compare_preload(channel, true) + 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 @@ -96,17 +102,17 @@ impl<'d, T: GeneralPurpose16bitInstance + CaptureCompare16bitInstance> SimplePwm /// Enable the given channel. pub fn enable(&mut self, channel: Channel) { - self.inner.enable_channel(channel, true); + sealed::GeneralPurpose16bitInstance::enable_channel(self.inner.deref_mut(), channel, true); } /// Disable the given channel. pub fn disable(&mut self, channel: Channel) { - self.inner.enable_channel(channel, false); + sealed::GeneralPurpose16bitInstance::enable_channel(self.inner.deref_mut(), channel, false); } /// Check whether given channel is enabled pub fn is_enabled(&self, channel: Channel) -> bool { - self.inner.get_channel_enable_state(channel) + sealed::GeneralPurpose16bitInstance::get_channel_enable_state(self.inner.deref(), channel) } /// Set PWM frequency. @@ -134,24 +140,24 @@ impl<'d, T: GeneralPurpose16bitInstance + CaptureCompare16bitInstance> SimplePwm /// 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()); - self.inner.set_compare_value(channel, duty) + sealed::GeneralPurpose16bitInstance::set_compare_value(self.inner.deref_mut(), 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 { - self.inner.get_compare_value(channel) + sealed::GeneralPurpose16bitInstance::get_compare_value(self.inner.deref(), channel) } /// Set the output polarity for a given channel. pub fn set_polarity(&mut self, channel: Channel, polarity: OutputPolarity) { - self.inner.set_output_polarity(channel, polarity); + sealed::GeneralPurpose16bitInstance::set_output_polarity(self.inner.deref_mut(), channel, polarity); } /// Set the output compare mode for a given channel. pub fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode) { - self.inner.set_output_compare_mode(channel, mode); + sealed::GeneralPurpose16bitInstance::set_output_compare_mode(self.inner.deref_mut(), channel, mode); } /// Generate a sequence of PWM waveform @@ -226,7 +232,7 @@ impl<'d, T: GeneralPurpose16bitInstance + CaptureCompare16bitInstance> SimplePwm macro_rules! impl_waveform_chx { ($fn_name:ident, $dma_ch:ident, $cc_ch:ident) => { - impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> { + impl<'d, T: GeneralPurpose16bitInstance> SimplePwm<'d, T> { /// Generate a sequence of PWM waveform /// /// Note: @@ -313,17 +319,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: CaptureCompare16bitInstance> embedded_hal_02::Pwm for SimplePwm<'d, T> { +impl<'d, T: GeneralPurpose16bitInstance> embedded_hal_02::Pwm for SimplePwm<'d, T> { type Channel = Channel; type Time = Hertz; type Duty = u16; fn disable(&mut self, channel: Self::Channel) { - self.inner.enable_channel(channel, false); + sealed::GeneralPurpose16bitInstance::enable_channel(self.inner.deref_mut(), channel, false); } fn enable(&mut self, channel: Self::Channel) { - self.inner.enable_channel(channel, true); + sealed::GeneralPurpose16bitInstance::enable_channel(self.inner.deref_mut(), channel, true); } fn get_period(&self) -> Self::Time { @@ -331,7 +337,7 @@ impl<'d, T: CaptureCompare16bitInstance> embedded_hal_02::Pwm for SimplePwm<'d, } fn get_duty(&self, channel: Self::Channel) -> Self::Duty { - self.inner.get_compare_value(channel) + sealed::GeneralPurpose16bitInstance::get_compare_value(self.inner.deref(), channel) } fn get_max_duty(&self) -> Self::Duty { @@ -340,7 +346,7 @@ impl<'d, T: CaptureCompare16bitInstance> embedded_hal_02::Pwm for SimplePwm<'d, fn set_duty(&mut self, channel: Self::Channel, duty: Self::Duty) { assert!(duty <= self.get_max_duty()); - self.inner.set_compare_value(channel, duty) + sealed::GeneralPurpose16bitInstance::set_compare_value(self.inner.deref_mut(), channel, duty) } fn set_period<P>(&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 cc508c3cf..0be3eccb7 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: CaptureCompare32bitInstance> { +pub struct SimplePwm32<'d, T: GeneralPurpose32bitInstance> { inner: PeripheralRef<'d, T>, } -impl<'d, T: CaptureCompare32bitInstance> SimplePwm32<'d, T> { +impl<'d, T: GeneralPurpose32bitInstance> SimplePwm32<'d, T> { pub fn new( tim: impl Peripheral<P = T> + 'd, ch1: impl Peripheral<P = impl Channel1Pin<T>> + 'd, From 5b646bc3bd0c4a2cd9acf6a59b3a76f2bbcb0bfb Mon Sep 17 00:00:00 2001 From: eZio Pan <eziopan@qq.com> Date: Thu, 1 Feb 2024 23:04:39 +0800 Subject: [PATCH 05/10] stm32-timer: L0 is special --- embassy-stm32/src/timer/mod.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs index 2f5d5770a..8be96b414 100644 --- a/embassy-stm32/src/timer/mod.rs +++ b/embassy-stm32/src/timer/mod.rs @@ -12,6 +12,7 @@ // | +--------------------------------------|-----------+ // +----------------------------------------------------+ +#[cfg(not(any(stm32l0, stm32l1)))] pub mod complementary_pwm; pub mod qei; pub mod simple_pwm; @@ -163,6 +164,7 @@ pub(crate) mod sealed { }; } + #[cfg(not(any(stm32l0, stm32l1)))] macro_rules! add_complementary_capture_compare_methods { ($regs:ident) => { /// Set complementary output polarity. @@ -374,6 +376,7 @@ pub(crate) mod sealed { add_capture_compare_dma_methods!(regs_gp16); } + #[cfg(not(any(stm32l0)))] /// Gneral-purpose 32-bit timer instance. pub trait GeneralPurpose32bitInstance: GeneralPurpose16bitInstance { /// Get access to the general purpose 32bit timer registers. @@ -434,6 +437,7 @@ pub(crate) mod sealed { } } + #[cfg(not(any(stm32l0, stm32l1)))] /// 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,6 +466,7 @@ pub(crate) mod sealed { add_complementary_capture_compare_methods!(regs_1ch_cmp); } + #[cfg(not(any(stm32l0, stm32l1)))] /// Gneral-purpose 2 channel with one complementary 16-bit timer instance. pub trait GeneralPurpose2ChannelComplementaryInstance: BasicInstance + GeneralPurpose2ChannelInstance + GeneralPurpose1ChannelComplementaryInstance @@ -477,6 +482,7 @@ pub(crate) mod sealed { add_complementary_capture_compare_methods!(regs_2ch_cmp); } + #[cfg(not(any(stm32l0, stm32l1)))] /// Advanced control timer instance. pub trait AdvancedControlInstance: GeneralPurpose2ChannelComplementaryInstance + GeneralPurpose16bitInstance @@ -699,18 +705,21 @@ pub trait GeneralPurpose16bitInstance: { } +#[cfg(not(stm32l0))] /// 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 @@ -721,6 +730,7 @@ pub trait GeneralPurpose2ChannelComplementaryInstance: { } +#[cfg(not(any(stm32l0, stm32l1)))] /// Advanced control timer instance. pub trait AdvancedControlInstance: sealed::AdvancedControlInstance + GeneralPurpose2ChannelComplementaryInstance + GeneralPurpose16bitInstance + 'static @@ -738,18 +748,28 @@ pin_trait!(ExternalTriggerPin, GeneralPurpose16bitInstance); #[cfg(stm32l0)] pin_trait!(ExternalTriggerPin, GeneralPurpose2ChannelInstance); +#[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(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); #[allow(unused)] From 319f10da5daff415ad2dac17f4eed43313455167 Mon Sep 17 00:00:00 2001 From: eZio Pan <eziopan@qq.com> Date: Thu, 1 Feb 2024 23:41:32 +0800 Subject: [PATCH 06/10] stm32-timer: filter out c0, f1 and f37x --- embassy-stm32/src/timer/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs index 8be96b414..be5c6cf29 100644 --- a/embassy-stm32/src/timer/mod.rs +++ b/embassy-stm32/src/timer/mod.rs @@ -376,7 +376,7 @@ pub(crate) mod sealed { add_capture_compare_dma_methods!(regs_gp16); } - #[cfg(not(any(stm32l0)))] + #[cfg(not(any(stm32f1, stm32l0, stm32c0)))] /// Gneral-purpose 32-bit timer instance. pub trait GeneralPurpose32bitInstance: GeneralPurpose16bitInstance { /// Get access to the general purpose 32bit timer registers. @@ -705,7 +705,7 @@ pub trait GeneralPurpose16bitInstance: { } -#[cfg(not(stm32l0))] +#[cfg(not(any(stm32f1, stm32l0, stm32c0)))] /// Gneral-purpose 32-bit timer instance. pub trait GeneralPurpose32bitInstance: sealed::GeneralPurpose32bitInstance + GeneralPurpose16bitInstance + 'static @@ -730,7 +730,7 @@ pub trait GeneralPurpose2ChannelComplementaryInstance: { } -#[cfg(not(any(stm32l0, stm32l1)))] +#[cfg(not(any(stm32f37, stm32l0, stm32l1)))] /// Advanced control timer instance. pub trait AdvancedControlInstance: sealed::AdvancedControlInstance + GeneralPurpose2ChannelComplementaryInstance + GeneralPurpose16bitInstance + 'static From b3cdf3a040ae97923e84eca525505f7eff55e870 Mon Sep 17 00:00:00 2001 From: eZio Pan <eziopan@qq.com> Date: Fri, 2 Feb 2024 14:52:54 +0800 Subject: [PATCH 07/10] bug fix --- embassy-stm32/src/timer/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs index be5c6cf29..3e303a6cf 100644 --- a/embassy-stm32/src/timer/mod.rs +++ b/embassy-stm32/src/timer/mod.rs @@ -90,9 +90,9 @@ pub(crate) mod sealed { /// Set output compare mode. fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode) { - let r = Self::$regs(); let raw_channel: usize = channel.index(); - r.ccmr_output(raw_channel / 2) + Self::$regs() + .ccmr_output(raw_channel / 2) .modify(|w| w.set_ocm(raw_channel % 2, mode.into())); } @@ -133,7 +133,7 @@ pub(crate) mod sealed { /// Set output compare preload. fn set_output_compare_preload(&mut self, channel: Channel, preload: bool) { let channel_index = channel.index(); - Self::regs_1ch() + Self::$regs() .ccmr_output(channel_index / 2) .modify(|w| w.set_ocpe(channel_index % 2, preload)); } From 6c690ab259ed15eece329a53a7147e7780f53cf3 Mon Sep 17 00:00:00 2001 From: eZio Pan <eziopan@qq.com> Date: Fri, 2 Feb 2024 17:45:51 +0800 Subject: [PATCH 08/10] 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<P = impl $pin_trait<T>> + '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<P>(&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<OutputPolarity> 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<P = impl $pin_trait<T>> + '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<P = T> + '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<P = impl $pin_trait<T>> + '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<P = T> + '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<P>(&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<P = T> + 'd, ch1: impl Peripheral<P = impl Channel1Pin<T>> + 'd, From 0f94006be3aa099d0a6039d51834562e51f91580 Mon Sep 17 00:00:00 2001 From: eZio Pan <eziopan@qq.com> Date: Sat, 3 Feb 2024 17:30:00 +0800 Subject: [PATCH 09/10] doc fix --- embassy-stm32/src/timer/mod.rs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs index 5f40be957..9780c005c 100644 --- a/embassy-stm32/src/timer/mod.rs +++ b/embassy-stm32/src/timer/mod.rs @@ -20,10 +20,10 @@ //! //! 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 +//! BasicInstance --> Basic Timer +//! CaptureCompare16bitInstance --> 1-channel Timer, 2-channel Timer, General Purpose 16-bit Timer +//! CaptureCompare32bitInstance --> General Purpose 32-bit Timer +//! ComplementaryCaptureCompare16bitInstance --> 1-channel with one complentary Timer, 2-channel with one complentary Timer, Advance Control Timer #[cfg(not(stm32l0))] pub mod complementary_pwm; @@ -667,7 +667,8 @@ impl From<OutputPolarity> for bool { /// Basic 16-bit timer instance. pub trait BasicInstance: sealed::BasicInstance + sealed::BasicNoCr2Instance + sealed::CoreInstance + 'static {} -/// General-purpose 16-bit timer instance. +// It's just a General-purpose 16-bit timer instance. +/// Capture Compare timer instance. pub trait CaptureCompare16bitInstance: BasicInstance + sealed::GeneralPurpose2ChannelInstance @@ -678,14 +679,16 @@ pub trait CaptureCompare16bitInstance: } #[cfg(not(stm32l0))] -/// Gneral-purpose 32-bit timer instance. +// It's just a General-purpose 32-bit timer instance. +/// Capture Compare 32-bit timer instance. pub trait CaptureCompare32bitInstance: - sealed::GeneralPurpose32bitInstance + CaptureCompare16bitInstance + 'static + CaptureCompare16bitInstance + sealed::GeneralPurpose32bitInstance + 'static { } #[cfg(not(stm32l0))] -/// Advanced control timer instance. +// It's just a Advanced Control timer instance. +/// Complementary Capture Compare 32-bit timer instance. pub trait ComplementaryCaptureCompare16bitInstance: CaptureCompare16bitInstance + sealed::GeneralPurpose1ChannelComplementaryInstance From 8fd803a5fe0af8cc9d648ba2efba755b502f08e9 Mon Sep 17 00:00:00 2001 From: eZio Pan <eziopan@qq.com> Date: Sun, 4 Feb 2024 15:14:02 +0800 Subject: [PATCH 10/10] use cfg_if to reduce macro condition --- embassy-stm32/src/timer/mod.rs | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs index 9780c005c..0118395a7 100644 --- a/embassy-stm32/src/timer/mod.rs +++ b/embassy-stm32/src/timer/mod.rs @@ -704,29 +704,23 @@ pin_trait!(Channel3Pin, CaptureCompare16bitInstance); pin_trait!(Channel4Pin, CaptureCompare16bitInstance); pin_trait!(ExternalTriggerPin, CaptureCompare16bitInstance); -#[cfg(not(stm32l0))] -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_if::cfg_if! { + if #[cfg(not(stm32l0))] { + pin_trait!(Channel1ComplementaryPin, ComplementaryCaptureCompare16bitInstance); + pin_trait!(Channel2ComplementaryPin, ComplementaryCaptureCompare16bitInstance); + pin_trait!(Channel3ComplementaryPin, ComplementaryCaptureCompare16bitInstance); + pin_trait!(Channel4ComplementaryPin, ComplementaryCaptureCompare16bitInstance); -#[cfg(not(stm32l0))] -pin_trait!(BreakInputPin, ComplementaryCaptureCompare16bitInstance); -#[cfg(not(stm32l0))] -pin_trait!(BreakInput2Pin, ComplementaryCaptureCompare16bitInstance); + pin_trait!(BreakInputPin, ComplementaryCaptureCompare16bitInstance); + pin_trait!(BreakInput2Pin, ComplementaryCaptureCompare16bitInstance); -#[cfg(not(stm32l0))] -pin_trait!(BreakInputComparator1Pin, ComplementaryCaptureCompare16bitInstance); -#[cfg(not(stm32l0))] -pin_trait!(BreakInputComparator2Pin, ComplementaryCaptureCompare16bitInstance); + pin_trait!(BreakInputComparator1Pin, ComplementaryCaptureCompare16bitInstance); + pin_trait!(BreakInputComparator2Pin, ComplementaryCaptureCompare16bitInstance); -#[cfg(not(stm32l0))] -pin_trait!(BreakInput2Comparator1Pin, ComplementaryCaptureCompare16bitInstance); -#[cfg(not(stm32l0))] -pin_trait!(BreakInput2Comparator2Pin, ComplementaryCaptureCompare16bitInstance); + pin_trait!(BreakInput2Comparator1Pin, ComplementaryCaptureCompare16bitInstance); + pin_trait!(BreakInput2Comparator2Pin, ComplementaryCaptureCompare16bitInstance); + } +} #[allow(unused)] macro_rules! impl_core_timer {