From 3e78f8a108c031f992116808b66c5e6c760c2c9e Mon Sep 17 00:00:00 2001 From: melvdl Date: Thu, 26 Jun 2025 19:35:19 +0200 Subject: stm32: generify timer channels --- embassy-stm32/build.rs | 36 ++++----- embassy-stm32/src/timer/complementary_pwm.rs | 72 ++++++++--------- embassy-stm32/src/timer/input_capture.rs | 67 ++++++++-------- embassy-stm32/src/timer/low_level.rs | 38 ++++----- embassy-stm32/src/timer/mod.rs | 111 +++++++++++++++++++++------ embassy-stm32/src/timer/one_pulse.rs | 88 ++++++++++++--------- embassy-stm32/src/timer/pwm_input.rs | 32 ++++---- embassy-stm32/src/timer/qei.rs | 10 ++- embassy-stm32/src/timer/simple_pwm.rs | 80 +++++++++---------- 9 files changed, 297 insertions(+), 237 deletions(-) diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 8143c9a23..192688149 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -1090,21 +1090,21 @@ fn main() { (("fmc", "CLK"), quote!(crate::fmc::ClkPin)), (("fmc", "BA0"), quote!(crate::fmc::BA0Pin)), (("fmc", "BA1"), quote!(crate::fmc::BA1Pin)), - (("timer", "CH1"), quote!(crate::timer::Channel1Pin)), - (("timer", "CH1N"), quote!(crate::timer::Channel1ComplementaryPin)), - (("timer", "CH2"), quote!(crate::timer::Channel2Pin)), - (("timer", "CH2N"), quote!(crate::timer::Channel2ComplementaryPin)), - (("timer", "CH3"), quote!(crate::timer::Channel3Pin)), - (("timer", "CH3N"), quote!(crate::timer::Channel3ComplementaryPin)), - (("timer", "CH4"), quote!(crate::timer::Channel4Pin)), - (("timer", "CH4N"), quote!(crate::timer::Channel4ComplementaryPin)), + (("timer", "CH1"), quote!(crate::timer::TimerPin)), + (("timer", "CH1N"), quote!(crate::timer::TimerComplementaryPin)), + (("timer", "CH2"), quote!(crate::timer::TimerPin)), + (("timer", "CH2N"), quote!(crate::timer::TimerComplementaryPin)), + (("timer", "CH3"), quote!(crate::timer::TimerPin)), + (("timer", "CH3N"), quote!(crate::timer::TimerComplementaryPin)), + (("timer", "CH4"), quote!(crate::timer::TimerPin)), + (("timer", "CH4N"), quote!(crate::timer::TimerComplementaryPin)), (("timer", "ETR"), quote!(crate::timer::ExternalTriggerPin)), - (("timer", "BKIN"), quote!(crate::timer::BreakInputPin)), - (("timer", "BKIN_COMP1"), quote!(crate::timer::BreakInputComparator1Pin)), - (("timer", "BKIN_COMP2"), quote!(crate::timer::BreakInputComparator2Pin)), - (("timer", "BKIN2"), quote!(crate::timer::BreakInput2Pin)), - (("timer", "BKIN2_COMP1"), quote!(crate::timer::BreakInput2Comparator1Pin)), - (("timer", "BKIN2_COMP2"), quote!(crate::timer::BreakInput2Comparator2Pin)), + (("timer", "BKIN"), quote!(crate::timer::BreakInputPin)), + (("timer", "BKIN_COMP1"), quote!(crate::timer::BreakInputComparator1Pin)), + (("timer", "BKIN_COMP2"), quote!(crate::timer::BreakInputComparator2Pin)), + (("timer", "BKIN2"), quote!(crate::timer::BreakInputPin)), + (("timer", "BKIN2_COMP1"), quote!(crate::timer::BreakInput2Comparator1Pin)), + (("timer", "BKIN2_COMP2"), quote!(crate::timer::BreakInput2Comparator2Pin)), (("hrtim", "CHA1"), quote!(crate::hrtim::ChannelAPin)), (("hrtim", "CHA2"), quote!(crate::hrtim::ChannelAComplementaryPin)), (("hrtim", "CHB1"), quote!(crate::hrtim::ChannelBPin)), @@ -1475,10 +1475,10 @@ fn main() { (("hash", "IN"), quote!(crate::hash::Dma)), (("cryp", "IN"), quote!(crate::cryp::DmaIn)), (("cryp", "OUT"), quote!(crate::cryp::DmaOut)), - (("timer", "CH1"), quote!(crate::timer::Ch1Dma)), - (("timer", "CH2"), quote!(crate::timer::Ch2Dma)), - (("timer", "CH3"), quote!(crate::timer::Ch3Dma)), - (("timer", "CH4"), quote!(crate::timer::Ch4Dma)), + (("timer", "CH1"), quote!(crate::timer::Dma)), + (("timer", "CH2"), quote!(crate::timer::Dma)), + (("timer", "CH3"), quote!(crate::timer::Dma)), + (("timer", "CH4"), quote!(crate::timer::Dma)), (("cordic", "WRITE"), quote!(crate::cordic::WriteDma)), // FIXME: stm32u5a crash on Cordic driver (("cordic", "READ"), quote!(crate::cordic::ReadDma)), // FIXME: stm32u5a crash on Cordic driver ] diff --git a/embassy-stm32/src/timer/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs index 8eec6c0c7..4600dd1a3 100644 --- a/embassy-stm32/src/timer/complementary_pwm.rs +++ b/embassy-stm32/src/timer/complementary_pwm.rs @@ -5,14 +5,12 @@ use core::marker::PhantomData; use stm32_metapac::timer::vals::Ckd; use super::low_level::{CountingMode, OutputPolarity, Timer}; -use super::simple_pwm::{Ch1, Ch2, Ch3, Ch4, PwmPin}; -use super::{ - AdvancedInstance4Channel, Channel, Channel1ComplementaryPin, Channel2ComplementaryPin, Channel3ComplementaryPin, - Channel4ComplementaryPin, -}; +use super::simple_pwm::PwmPin; +use super::{AdvancedInstance4Channel, Ch1, Ch2, Ch3, Ch4, TimerChannel, TimerComplementaryPin}; use crate::gpio::{AnyPin, OutputType}; use crate::time::Hertz; use crate::timer::low_level::OutputCompareMode; +use crate::timer::Channel; use crate::Peri; /// Complementary PWM pin wrapper. @@ -23,32 +21,23 @@ pub struct ComplementaryPwmPin<'d, T, C> { phantom: PhantomData<(T, C)>, } -macro_rules! complementary_channel_impl { - ($new_chx:ident, $channel:ident, $pin_trait:ident) => { - impl<'d, T: AdvancedInstance4Channel> ComplementaryPwmPin<'d, T, $channel> { - #[doc = concat!("Create a new ", stringify!($channel), " complementary PWM pin instance.")] - pub fn $new_chx(pin: Peri<'d, impl $pin_trait>, output_type: OutputType) -> Self { - critical_section::with(|_| { - pin.set_low(); - pin.set_as_af( - pin.af_num(), - crate::gpio::AfType::output(output_type, crate::gpio::Speed::VeryHigh), - ); - }); - ComplementaryPwmPin { - _pin: pin.into(), - phantom: PhantomData, - } - } +impl<'d, T: AdvancedInstance4Channel, C: Channel> ComplementaryPwmPin<'d, T, C> { + /// Create a new complementary PWM pin instance. + pub fn new(pin: Peri<'d, impl TimerComplementaryPin>, output_type: OutputType) -> Self { + critical_section::with(|_| { + pin.set_low(); + pin.set_as_af( + pin.af_num(), + crate::gpio::AfType::output(output_type, crate::gpio::Speed::VeryHigh), + ); + }); + ComplementaryPwmPin { + _pin: pin.into(), + phantom: PhantomData, } - }; + } } -complementary_channel_impl!(new_ch1, Ch1, Channel1ComplementaryPin); -complementary_channel_impl!(new_ch2, Ch2, Channel2ComplementaryPin); -complementary_channel_impl!(new_ch3, Ch3, Channel3ComplementaryPin); -complementary_channel_impl!(new_ch4, Ch4, Channel4ComplementaryPin); - /// PWM driver with support for standard and complementary outputs. pub struct ComplementaryPwm<'d, T: AdvancedInstance4Channel> { inner: Timer<'d, T>, @@ -82,24 +71,29 @@ impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> { this.inner.enable_outputs(); - [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); - }); + [ + TimerChannel::Ch1, + TimerChannel::Ch2, + TimerChannel::Ch3, + TimerChannel::Ch4, + ] + .iter() + .for_each(|&channel| { + this.inner.set_output_compare_mode(channel, OutputCompareMode::PwmMode1); + this.inner.set_output_compare_preload(channel, true); + }); this } /// Enable the given channel. - pub fn enable(&mut self, channel: Channel) { + pub fn enable(&mut self, channel: TimerChannel) { self.inner.enable_channel(channel, true); self.inner.enable_complementary_channel(channel, true); } /// Disable the given channel. - pub fn disable(&mut self, channel: Channel) { + pub fn disable(&mut self, channel: TimerChannel) { self.inner.enable_complementary_channel(channel, false); self.inner.enable_channel(channel, false); } @@ -127,13 +121,13 @@ impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> { /// Set 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 set_duty(&mut self, channel: Channel, duty: u16) { + pub fn set_duty(&mut self, channel: TimerChannel, duty: u16) { assert!(duty <= self.get_max_duty()); self.inner.set_compare_value(channel, duty as _) } /// Set the output polarity for a given channel. - pub fn set_polarity(&mut self, channel: Channel, polarity: OutputPolarity) { + pub fn set_polarity(&mut self, channel: TimerChannel, polarity: OutputPolarity) { self.inner.set_output_polarity(channel, polarity); self.inner.set_complementary_output_polarity(channel, polarity); } @@ -148,7 +142,7 @@ impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> { } impl<'d, T: AdvancedInstance4Channel> embedded_hal_02::Pwm for ComplementaryPwm<'d, T> { - type Channel = Channel; + type Channel = TimerChannel; type Time = Hertz; type Duty = u16; diff --git a/embassy-stm32/src/timer/input_capture.rs b/embassy-stm32/src/timer/input_capture.rs index ec8b1ddf1..da567d504 100644 --- a/embassy-stm32/src/timer/input_capture.rs +++ b/embassy-stm32/src/timer/input_capture.rs @@ -6,14 +6,12 @@ use core::pin::Pin; use core::task::{Context, Poll}; use super::low_level::{CountingMode, FilterValue, InputCaptureMode, InputTISelection, Timer}; -use super::{ - CaptureCompareInterruptHandler, Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, - GeneralInstance4Channel, -}; +use super::{CaptureCompareInterruptHandler, GeneralInstance4Channel, TimerChannel, TimerPin}; pub use super::{Ch1, Ch2, Ch3, Ch4}; use crate::gpio::{AfType, AnyPin, Pull}; use crate::interrupt::typelevel::{Binding, Interrupt}; use crate::time::Hertz; +use crate::timer::Channel; use crate::Peri; /// Capture pin wrapper. @@ -23,27 +21,17 @@ pub struct CapturePin<'d, T, C> { _pin: Peri<'d, AnyPin>, phantom: PhantomData<(T, C)>, } - -macro_rules! channel_impl { - ($new_chx:ident, $channel:ident, $pin_trait:ident) => { - impl<'d, T: GeneralInstance4Channel> CapturePin<'d, T, $channel> { - #[doc = concat!("Create a new ", stringify!($channel), " capture pin instance.")] - pub fn $new_chx(pin: Peri<'d, impl $pin_trait>, pull: Pull) -> Self { - pin.set_as_af(pin.af_num(), AfType::input(pull)); - CapturePin { - _pin: pin.into(), - phantom: PhantomData, - } - } +impl<'d, T: GeneralInstance4Channel, C: Channel> CapturePin<'d, T, C> { + /// Create a new capture pin instance. + pub fn new(pin: Peri<'d, impl TimerPin>, pull: Pull) -> Self { + pin.set_as_af(pin.af_num(), AfType::input(pull)); + CapturePin { + _pin: pin.into(), + phantom: PhantomData, } - }; + } } -channel_impl!(new_ch1, Ch1, Channel1Pin); -channel_impl!(new_ch2, Ch2, Channel2Pin); -channel_impl!(new_ch3, Ch3, Channel3Pin); -channel_impl!(new_ch4, Ch4, Channel4Pin); - /// Input capture driver. pub struct InputCapture<'d, T: GeneralInstance4Channel> { inner: Timer<'d, T>, @@ -80,41 +68,46 @@ impl<'d, T: GeneralInstance4Channel> InputCapture<'d, T> { } /// Enable the given channel. - pub fn enable(&mut self, channel: Channel) { + pub fn enable(&mut self, channel: TimerChannel) { self.inner.enable_channel(channel, true); } /// Disable the given channel. - pub fn disable(&mut self, channel: Channel) { + pub fn disable(&mut self, channel: TimerChannel) { self.inner.enable_channel(channel, false); } /// Check whether given channel is enabled - pub fn is_enabled(&self, channel: Channel) -> bool { + pub fn is_enabled(&self, channel: TimerChannel) -> bool { self.inner.get_channel_enable_state(channel) } /// Set the input capture mode for a given channel. - pub fn set_input_capture_mode(&mut self, channel: Channel, mode: InputCaptureMode) { + pub fn set_input_capture_mode(&mut self, channel: TimerChannel, mode: InputCaptureMode) { self.inner.set_input_capture_mode(channel, mode); } /// Set input TI selection. - pub fn set_input_ti_selection(&mut self, channel: Channel, tisel: InputTISelection) { + pub fn set_input_ti_selection(&mut self, channel: TimerChannel, tisel: InputTISelection) { self.inner.set_input_ti_selection(channel, tisel) } /// Get capture value for a channel. - pub fn get_capture_value(&self, channel: Channel) -> u32 { + pub fn get_capture_value(&self, channel: TimerChannel) -> u32 { self.inner.get_capture_value(channel) } /// Get input interrupt. - pub fn get_input_interrupt(&self, channel: Channel) -> bool { + pub fn get_input_interrupt(&self, channel: TimerChannel) -> bool { self.inner.get_input_interrupt(channel) } - fn new_future(&self, channel: Channel, mode: InputCaptureMode, tisel: InputTISelection) -> InputCaptureFuture { + fn new_future( + &self, + channel: TimerChannel, + mode: InputCaptureMode, + tisel: InputTISelection, + ) -> InputCaptureFuture { // Configuration steps from ST RM0390 (STM32F446) chapter 17.3.5 // or ST RM0008 (STM32F103) chapter 15.3.5 Input capture mode self.inner.set_input_ti_selection(channel, tisel); @@ -131,37 +124,37 @@ impl<'d, T: GeneralInstance4Channel> InputCapture<'d, T> { } /// Asynchronously wait until the pin sees a rising edge. - pub async fn wait_for_rising_edge(&mut self, channel: Channel) -> u32 { + pub async fn wait_for_rising_edge(&mut self, channel: TimerChannel) -> u32 { self.new_future(channel, InputCaptureMode::Rising, InputTISelection::Normal) .await } /// Asynchronously wait until the pin sees a falling edge. - pub async fn wait_for_falling_edge(&mut self, channel: Channel) -> u32 { + pub async fn wait_for_falling_edge(&mut self, channel: TimerChannel) -> u32 { self.new_future(channel, InputCaptureMode::Falling, InputTISelection::Normal) .await } /// Asynchronously wait until the pin sees any edge. - pub async fn wait_for_any_edge(&mut self, channel: Channel) -> u32 { + pub async fn wait_for_any_edge(&mut self, channel: TimerChannel) -> u32 { self.new_future(channel, InputCaptureMode::BothEdges, InputTISelection::Normal) .await } /// Asynchronously wait until the (alternate) pin sees a rising edge. - pub async fn wait_for_rising_edge_alternate(&mut self, channel: Channel) -> u32 { + pub async fn wait_for_rising_edge_alternate(&mut self, channel: TimerChannel) -> u32 { self.new_future(channel, InputCaptureMode::Rising, InputTISelection::Alternate) .await } /// Asynchronously wait until the (alternate) pin sees a falling edge. - pub async fn wait_for_falling_edge_alternate(&mut self, channel: Channel) -> u32 { + pub async fn wait_for_falling_edge_alternate(&mut self, channel: TimerChannel) -> u32 { self.new_future(channel, InputCaptureMode::Falling, InputTISelection::Alternate) .await } /// Asynchronously wait until the (alternate) pin sees any edge. - pub async fn wait_for_any_edge_alternate(&mut self, channel: Channel) -> u32 { + pub async fn wait_for_any_edge_alternate(&mut self, channel: TimerChannel) -> u32 { self.new_future(channel, InputCaptureMode::BothEdges, InputTISelection::Alternate) .await } @@ -169,7 +162,7 @@ impl<'d, T: GeneralInstance4Channel> InputCapture<'d, T> { #[must_use = "futures do nothing unless you `.await` or poll them"] struct InputCaptureFuture { - channel: Channel, + channel: TimerChannel, phantom: PhantomData, } diff --git a/embassy-stm32/src/timer/low_level.rs b/embassy-stm32/src/timer/low_level.rs index dc8ceb725..bfdbcf968 100644 --- a/embassy-stm32/src/timer/low_level.rs +++ b/embassy-stm32/src/timer/low_level.rs @@ -503,7 +503,7 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> { } /// Set input capture filter. - pub fn set_input_capture_filter(&self, channel: Channel, icf: vals::FilterValue) { + pub fn set_input_capture_filter(&self, channel: TimerChannel, icf: vals::FilterValue) { let raw_channel = channel.index(); self.regs_gp16() .ccmr_input(raw_channel / 2) @@ -511,22 +511,22 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> { } /// Clear input interrupt. - pub fn clear_input_interrupt(&self, channel: Channel) { + pub fn clear_input_interrupt(&self, channel: TimerChannel) { self.regs_gp16().sr().modify(|r| r.set_ccif(channel.index(), false)); } /// Get input interrupt. - pub fn get_input_interrupt(&self, channel: Channel) -> bool { + pub fn get_input_interrupt(&self, channel: TimerChannel) -> bool { self.regs_gp16().sr().read().ccif(channel.index()) } /// Enable input interrupt. - pub fn enable_input_interrupt(&self, channel: Channel, enable: bool) { + pub fn enable_input_interrupt(&self, channel: TimerChannel, enable: bool) { self.regs_gp16().dier().modify(|r| r.set_ccie(channel.index(), enable)); } /// Set input capture prescaler. - pub fn set_input_capture_prescaler(&self, channel: Channel, factor: u8) { + pub fn set_input_capture_prescaler(&self, channel: TimerChannel, factor: u8) { let raw_channel = channel.index(); self.regs_gp16() .ccmr_input(raw_channel / 2) @@ -534,7 +534,7 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> { } /// Set input TI selection. - pub fn set_input_ti_selection(&self, channel: Channel, tisel: InputTISelection) { + pub fn set_input_ti_selection(&self, channel: TimerChannel, tisel: InputTISelection) { let raw_channel = channel.index(); self.regs_gp16() .ccmr_input(raw_channel / 2) @@ -542,7 +542,7 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> { } /// Set input capture mode. - pub fn set_input_capture_mode(&self, channel: Channel, mode: InputCaptureMode) { + pub fn set_input_capture_mode(&self, channel: TimerChannel, mode: InputCaptureMode) { self.regs_gp16().ccer().modify(|r| match mode { InputCaptureMode::Rising => { r.set_ccnp(channel.index(), false); @@ -560,7 +560,7 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> { } /// Set output compare mode. - pub fn set_output_compare_mode(&self, channel: Channel, mode: OutputCompareMode) { + pub fn set_output_compare_mode(&self, channel: TimerChannel, mode: OutputCompareMode) { let raw_channel: usize = channel.index(); self.regs_gp16() .ccmr_output(raw_channel / 2) @@ -568,24 +568,24 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> { } /// Set output polarity. - pub fn set_output_polarity(&self, channel: Channel, polarity: OutputPolarity) { + pub fn set_output_polarity(&self, channel: TimerChannel, polarity: OutputPolarity) { self.regs_gp16() .ccer() .modify(|w| w.set_ccp(channel.index(), polarity.into())); } /// Enable/disable a channel. - pub fn enable_channel(&self, channel: Channel, enable: bool) { + pub fn enable_channel(&self, channel: TimerChannel, enable: bool) { self.regs_gp16().ccer().modify(|w| w.set_cce(channel.index(), enable)); } /// Get enable/disable state of a channel - pub fn get_channel_enable_state(&self, channel: Channel) -> bool { + pub fn get_channel_enable_state(&self, channel: TimerChannel) -> bool { self.regs_gp16().ccer().read().cce(channel.index()) } /// Set compare value for a channel. - pub fn set_compare_value(&self, channel: Channel, value: u32) { + pub fn set_compare_value(&self, channel: TimerChannel, value: u32) { match T::BITS { TimerBits::Bits16 => { let value = unwrap!(u16::try_from(value)); @@ -599,7 +599,7 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> { } /// Get compare value for a channel. - pub fn get_compare_value(&self, channel: Channel) -> u32 { + pub fn get_compare_value(&self, channel: TimerChannel) -> u32 { match T::BITS { TimerBits::Bits16 => self.regs_gp16().ccr(channel.index()).read().ccr() as u32, #[cfg(not(stm32l0))] @@ -608,12 +608,12 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> { } /// Get capture value for a channel. - pub fn get_capture_value(&self, channel: Channel) -> u32 { + pub fn get_capture_value(&self, channel: TimerChannel) -> u32 { self.get_compare_value(channel) } /// Set output compare preload. - pub fn set_output_compare_preload(&self, channel: Channel, preload: bool) { + pub fn set_output_compare_preload(&self, channel: TimerChannel, preload: bool) { let channel_index = channel.index(); self.regs_gp16() .ccmr_output(channel_index / 2) @@ -631,12 +631,12 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> { } /// Get capture compare DMA enable state - pub fn get_cc_dma_enable_state(&self, channel: Channel) -> bool { + pub fn get_cc_dma_enable_state(&self, channel: TimerChannel) -> bool { self.regs_gp16().dier().read().ccde(channel.index()) } /// Set capture compare DMA enable state - pub fn set_cc_dma_enable_state(&self, channel: Channel, ccde: bool) { + pub fn set_cc_dma_enable_state(&self, channel: TimerChannel, ccde: bool) { self.regs_gp16().dier().modify(|w| w.set_ccde(channel.index(), ccde)) } @@ -713,14 +713,14 @@ impl<'d, T: AdvancedInstance4Channel> Timer<'d, T> { } /// Set complementary output polarity. - pub fn set_complementary_output_polarity(&self, channel: Channel, polarity: OutputPolarity) { + pub fn set_complementary_output_polarity(&self, channel: TimerChannel, polarity: OutputPolarity) { self.regs_advanced() .ccer() .modify(|w| w.set_ccnp(channel.index(), polarity.into())); } /// Enable/disable a complementary channel. - pub fn enable_complementary_channel(&self, channel: Channel, enable: bool) { + pub fn enable_complementary_channel(&self, channel: TimerChannel, enable: bool) { self.regs_advanced() .ccer() .modify(|w| w.set_ccne(channel.index(), enable)); diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs index b29382fc8..362d95e25 100644 --- a/embassy-stm32/src/timer/mod.rs +++ b/embassy-stm32/src/timer/mod.rs @@ -19,7 +19,7 @@ use crate::rcc::RccPeripheral; /// Timer channel. #[derive(Clone, Copy)] -pub enum Channel { +pub enum TimerChannel { /// Channel 1. Ch1, /// Channel 2. @@ -30,14 +30,14 @@ pub enum Channel { Ch4, } -impl Channel { +impl TimerChannel { /// Get the channel index (0..3) pub fn index(&self) -> usize { match self { - Channel::Ch1 => 0, - Channel::Ch2 => 1, - Channel::Ch3 => 2, - Channel::Ch4 => 3, + TimerChannel::Ch1 => 0, + TimerChannel::Ch2 => 1, + TimerChannel::Ch3 => 2, + TimerChannel::Ch4 => 3, } } } @@ -51,6 +51,80 @@ pub enum Ch3 {} /// Channel 4 marker type. pub enum Ch4 {} +/// Timer channel trait. +#[allow(private_bounds)] +pub trait Channel: SealedChannel { + /// The runtime channel. + const CHANNEL: TimerChannel; +} + +trait SealedChannel {} + +impl Channel for Ch1 { + const CHANNEL: TimerChannel = TimerChannel::Ch1; +} + +impl Channel for Ch2 { + const CHANNEL: TimerChannel = TimerChannel::Ch2; +} + +impl Channel for Ch3 { + const CHANNEL: TimerChannel = TimerChannel::Ch3; +} + +impl Channel for Ch4 { + const CHANNEL: TimerChannel = TimerChannel::Ch4; +} + +impl SealedChannel for Ch1 {} +impl SealedChannel for Ch2 {} +impl SealedChannel for Ch3 {} +impl SealedChannel for Ch4 {} + +/// Timer break input. +#[derive(Clone, Copy)] +pub enum BkIn { + /// Break input 1. + BkIn1, + /// Break input 2. + BkIn2, +} + +impl BkIn { + /// Get the channel index (0..3) + pub fn index(&self) -> usize { + match self { + BkIn::BkIn1 => 0, + BkIn::BkIn2 => 1, + } + } +} + +/// Break input 1 marker type. +pub enum BkIn1 {} +/// Break input 2 marker type. +pub enum BkIn2 {} + +/// Timer channel trait. +#[allow(private_bounds)] +pub trait BreakInput: SealedBreakInput { + /// The runtim timer channel. + const INPUT: BkIn; +} + +trait SealedBreakInput {} + +impl BreakInput for BkIn1 { + const INPUT: BkIn = BkIn::BkIn1; +} + +impl BreakInput for BkIn2 { + const INPUT: BkIn = BkIn::BkIn2; +} + +impl SealedBreakInput for BkIn1 {} +impl SealedBreakInput for BkIn2 {} + /// Amount of bits of a timer. #[derive(Clone, Copy, PartialEq, Eq, Debug)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] @@ -149,33 +223,20 @@ pub trait AdvancedInstance2Channel: BasicInstance + GeneralInstance2Channel + Ad /// Advanced 16-bit timer with 4 channels instance. pub trait AdvancedInstance4Channel: AdvancedInstance2Channel + GeneralInstance4Channel {} -pin_trait!(Channel1Pin, GeneralInstance4Channel); -pin_trait!(Channel2Pin, GeneralInstance4Channel); -pin_trait!(Channel3Pin, GeneralInstance4Channel); -pin_trait!(Channel4Pin, GeneralInstance4Channel); +pin_trait!(TimerPin, GeneralInstance4Channel, Channel); pin_trait!(ExternalTriggerPin, GeneralInstance4Channel); -pin_trait!(Channel1ComplementaryPin, AdvancedInstance4Channel); -pin_trait!(Channel2ComplementaryPin, AdvancedInstance4Channel); -pin_trait!(Channel3ComplementaryPin, AdvancedInstance4Channel); -pin_trait!(Channel4ComplementaryPin, AdvancedInstance4Channel); - -pin_trait!(BreakInputPin, AdvancedInstance4Channel); -pin_trait!(BreakInput2Pin, AdvancedInstance4Channel); +pin_trait!(TimerComplementaryPin, AdvancedInstance4Channel, Channel); -pin_trait!(BreakInputComparator1Pin, AdvancedInstance4Channel); -pin_trait!(BreakInputComparator2Pin, AdvancedInstance4Channel); +pin_trait!(BreakInputPin, AdvancedInstance4Channel, BreakInput); -pin_trait!(BreakInput2Comparator1Pin, AdvancedInstance4Channel); -pin_trait!(BreakInput2Comparator2Pin, AdvancedInstance4Channel); +pin_trait!(BreakInputComparator1Pin, AdvancedInstance4Channel, BreakInput); +pin_trait!(BreakInputComparator2Pin, AdvancedInstance4Channel, BreakInput); // Update Event trigger DMA for every timer dma_trait!(UpDma, BasicInstance); -dma_trait!(Ch1Dma, GeneralInstance4Channel); -dma_trait!(Ch2Dma, GeneralInstance4Channel); -dma_trait!(Ch3Dma, GeneralInstance4Channel); -dma_trait!(Ch4Dma, GeneralInstance4Channel); +dma_trait!(Dma, GeneralInstance4Channel, Channel); #[allow(unused)] macro_rules! impl_core_timer { diff --git a/embassy-stm32/src/timer/one_pulse.rs b/embassy-stm32/src/timer/one_pulse.rs index 933165ef9..47c1d7f49 100644 --- a/embassy-stm32/src/timer/one_pulse.rs +++ b/embassy-stm32/src/timer/one_pulse.rs @@ -9,9 +9,7 @@ use core::task::{Context, Poll}; use super::low_level::{ CountingMode, FilterValue, InputCaptureMode, InputTISelection, SlaveMode, Timer, TriggerSource, }; -use super::{ - CaptureCompareInterruptHandler, Channel, Channel1Pin, Channel2Pin, ExternalTriggerPin, GeneralInstance4Channel, -}; +use super::{CaptureCompareInterruptHandler, ExternalTriggerPin, GeneralInstance4Channel, TimerChannel, TimerPin}; pub use super::{Ch1, Ch2}; use crate::gpio::{AfType, AnyPin, Pull}; use crate::interrupt::typelevel::{Binding, Interrupt}; @@ -48,24 +46,40 @@ pub struct TriggerPin<'d, T, C> { phantom: PhantomData<(T, C)>, } -macro_rules! channel_impl { - ($new_chx:ident, $channel:ident, $pin_trait:ident) => { - impl<'d, T: GeneralInstance4Channel> TriggerPin<'d, T, $channel> { - #[doc = concat!("Create a new ", stringify!($channel), " trigger pin instance.")] - pub fn $new_chx(pin: Peri<'d, impl $pin_trait>, pull: Pull) -> Self { - pin.set_as_af(pin.af_num(), AfType::input(pull)); - TriggerPin { - _pin: pin.into(), - phantom: PhantomData, - } - } +// TODO: Generify trigger inputs + +impl<'d, T: GeneralInstance4Channel> TriggerPin<'d, T, Ch1> { + /// "Create a new Ch1 trigger pin instance. + pub fn new_ch1(pin: Peri<'d, impl TimerPin>, pull: Pull) -> Self { + pin.set_as_af(pin.af_num(), AfType::input(pull)); + TriggerPin { + _pin: pin.into(), + phantom: PhantomData, } - }; + } } -channel_impl!(new_ch1, Ch1, Channel1Pin); -channel_impl!(new_ch2, Ch2, Channel2Pin); -channel_impl!(new_ext, Ext, ExternalTriggerPin); +impl<'d, T: GeneralInstance4Channel> TriggerPin<'d, T, Ch2> { + /// "Create a new Ch2 trigger pin instance. + pub fn new_ch2(pin: Peri<'d, impl TimerPin>, pull: Pull) -> Self { + pin.set_as_af(pin.af_num(), AfType::input(pull)); + TriggerPin { + _pin: pin.into(), + phantom: PhantomData, + } + } +} + +impl<'d, T: GeneralInstance4Channel> TriggerPin<'d, T, Ext> { + /// "Create a new EXT trigger pin instance. + pub fn new_ext(pin: Peri<'d, impl ExternalTriggerPin>, pull: Pull) -> Self { + pin.set_as_af(pin.af_num(), AfType::input(pull)); + TriggerPin { + _pin: pin.into(), + phantom: PhantomData, + } + } +} /// One pulse driver. /// @@ -91,9 +105,9 @@ impl<'d, T: GeneralInstance4Channel> OnePulse<'d, T> { this.inner.set_trigger_source(TriggerSource::TI1F_ED); this.inner - .set_input_ti_selection(Channel::Ch1, InputTISelection::Normal); + .set_input_ti_selection(TimerChannel::Ch1, InputTISelection::Normal); this.inner - .set_input_capture_filter(Channel::Ch1, FilterValue::NO_FILTER); + .set_input_capture_filter(TimerChannel::Ch1, FilterValue::NO_FILTER); this.new_inner(freq, pulse_end, counting_mode); this @@ -116,10 +130,10 @@ impl<'d, T: GeneralInstance4Channel> OnePulse<'d, T> { this.inner.set_trigger_source(TriggerSource::TI1FP1); this.inner - .set_input_ti_selection(Channel::Ch1, InputTISelection::Normal); + .set_input_ti_selection(TimerChannel::Ch1, InputTISelection::Normal); this.inner - .set_input_capture_filter(Channel::Ch1, FilterValue::NO_FILTER); - this.inner.set_input_capture_mode(Channel::Ch1, capture_mode); + .set_input_capture_filter(TimerChannel::Ch1, FilterValue::NO_FILTER); + this.inner.set_input_capture_mode(TimerChannel::Ch1, capture_mode); this.new_inner(freq, pulse_end, counting_mode); this @@ -142,10 +156,10 @@ impl<'d, T: GeneralInstance4Channel> OnePulse<'d, T> { this.inner.set_trigger_source(TriggerSource::TI2FP2); this.inner - .set_input_ti_selection(Channel::Ch2, InputTISelection::Normal); + .set_input_ti_selection(TimerChannel::Ch2, InputTISelection::Normal); this.inner - .set_input_capture_filter(Channel::Ch2, FilterValue::NO_FILTER); - this.inner.set_input_capture_mode(Channel::Ch2, capture_mode); + .set_input_capture_filter(TimerChannel::Ch2, FilterValue::NO_FILTER); + this.inner.set_input_capture_mode(TimerChannel::Ch2, capture_mode); this.new_inner(freq, pulse_end, counting_mode); this @@ -217,7 +231,7 @@ impl<'d, T: GeneralInstance4Channel> OnePulse<'d, T> { /// Get a single channel /// /// If you need to use multiple channels, use [`Self::split`]. - pub fn channel(&mut self, channel: Channel) -> OnePulseChannel<'_, T> { + pub fn channel(&mut self, channel: TimerChannel) -> OnePulseChannel<'_, T> { OnePulseChannel { inner: unsafe { self.inner.clone_unchecked() }, channel, @@ -230,7 +244,7 @@ impl<'d, T: GeneralInstance4Channel> OnePulse<'d, T> { /// /// If you need to use multiple channels, use [`Self::split`]. pub fn ch1(&mut self) -> OnePulseChannel<'_, T> { - self.channel(Channel::Ch1) + self.channel(TimerChannel::Ch1) } /// Channel 2 @@ -239,7 +253,7 @@ impl<'d, T: GeneralInstance4Channel> OnePulse<'d, T> { /// /// If you need to use multiple channels, use [`Self::split`]. pub fn ch2(&mut self) -> OnePulseChannel<'_, T> { - self.channel(Channel::Ch2) + self.channel(TimerChannel::Ch2) } /// Channel 3 @@ -248,7 +262,7 @@ impl<'d, T: GeneralInstance4Channel> OnePulse<'d, T> { /// /// If you need to use multiple channels, use [`Self::split`]. pub fn ch3(&mut self) -> OnePulseChannel<'_, T> { - self.channel(Channel::Ch3) + self.channel(TimerChannel::Ch3) } /// Channel 4 @@ -257,7 +271,7 @@ impl<'d, T: GeneralInstance4Channel> OnePulse<'d, T> { /// /// If you need to use multiple channels, use [`Self::split`]. pub fn ch4(&mut self) -> OnePulseChannel<'_, T> { - self.channel(Channel::Ch4) + self.channel(TimerChannel::Ch4) } /// Splits a [`OnePulse`] into four output channels. @@ -276,10 +290,10 @@ impl<'d, T: GeneralInstance4Channel> OnePulse<'d, T> { }; OnePulseChannels { - ch1: ch(Channel::Ch1), - ch2: ch(Channel::Ch2), - ch3: ch(Channel::Ch3), - ch4: ch(Channel::Ch4), + ch1: ch(TimerChannel::Ch1), + ch2: ch(TimerChannel::Ch2), + ch3: ch(TimerChannel::Ch3), + ch4: ch(TimerChannel::Ch4), } } } @@ -303,7 +317,7 @@ pub struct OnePulseChannels<'d, T: GeneralInstance4Channel> { /// configuration is shared with all four channels. pub struct OnePulseChannel<'d, T: GeneralInstance4Channel> { inner: ManuallyDrop>, - channel: Channel, + channel: TimerChannel, } impl<'d, T: GeneralInstance4Channel> OnePulseChannel<'d, T> { @@ -350,7 +364,7 @@ impl<'d, T: GeneralInstance4Channel> OnePulseChannel<'d, T> { #[must_use = "futures do nothing unless you `.await` or poll them"] struct OnePulseFuture { - channel: Channel, + channel: TimerChannel, phantom: PhantomData, } diff --git a/embassy-stm32/src/timer/pwm_input.rs b/embassy-stm32/src/timer/pwm_input.rs index 98b798634..3f9e5f651 100644 --- a/embassy-stm32/src/timer/pwm_input.rs +++ b/embassy-stm32/src/timer/pwm_input.rs @@ -1,33 +1,33 @@ //! PWM Input driver. use super::low_level::{CountingMode, InputCaptureMode, InputTISelection, SlaveMode, Timer, TriggerSource}; -use super::{Channel, Channel1Pin, Channel2Pin, GeneralInstance4Channel}; +use super::{Ch1, Ch2, GeneralInstance4Channel, TimerChannel, TimerPin}; use crate::gpio::{AfType, Pull}; use crate::time::Hertz; use crate::Peri; /// PWM Input driver. pub struct PwmInput<'d, T: GeneralInstance4Channel> { - channel: Channel, + channel: TimerChannel, inner: Timer<'d, T>, } impl<'d, T: GeneralInstance4Channel> PwmInput<'d, T> { /// Create a new PWM input driver. - pub fn new(tim: Peri<'d, T>, pin: Peri<'d, impl Channel1Pin>, pull: Pull, freq: Hertz) -> Self { + pub fn new(tim: Peri<'d, T>, pin: Peri<'d, impl TimerPin>, pull: Pull, freq: Hertz) -> Self { pin.set_as_af(pin.af_num(), AfType::input(pull)); - Self::new_inner(tim, freq, Channel::Ch1, Channel::Ch2) + Self::new_inner(tim, freq, TimerChannel::Ch1, TimerChannel::Ch2) } /// Create a new PWM input driver. - pub fn new_alt(tim: Peri<'d, T>, pin: Peri<'d, impl Channel2Pin>, pull: Pull, freq: Hertz) -> Self { + pub fn new_alt(tim: Peri<'d, T>, pin: Peri<'d, impl TimerPin>, pull: Pull, freq: Hertz) -> Self { pin.set_as_af(pin.af_num(), AfType::input(pull)); - Self::new_inner(tim, freq, Channel::Ch2, Channel::Ch1) + Self::new_inner(tim, freq, TimerChannel::Ch2, TimerChannel::Ch1) } - fn new_inner(tim: Peri<'d, T>, freq: Hertz, ch1: Channel, ch2: Channel) -> Self { + fn new_inner(tim: Peri<'d, T>, freq: Hertz, ch1: TimerChannel, ch2: TimerChannel) -> Self { let mut inner = Timer::new(tim); inner.set_counting_mode(CountingMode::EdgeAlignedUp); @@ -44,8 +44,8 @@ impl<'d, T: GeneralInstance4Channel> PwmInput<'d, T> { inner.set_input_capture_mode(ch2, InputCaptureMode::Falling); inner.set_trigger_source(match ch1 { - Channel::Ch1 => TriggerSource::TI1FP1, - Channel::Ch2 => TriggerSource::TI2FP2, + TimerChannel::Ch1 => TriggerSource::TI1FP1, + TimerChannel::Ch2 => TriggerSource::TI2FP2, _ => panic!("Invalid channel for PWM input"), }); @@ -58,19 +58,19 @@ impl<'d, T: GeneralInstance4Channel> PwmInput<'d, T> { /// Enable the given channel. pub fn enable(&mut self) { - self.inner.enable_channel(Channel::Ch1, true); - self.inner.enable_channel(Channel::Ch2, true); + self.inner.enable_channel(TimerChannel::Ch1, true); + self.inner.enable_channel(TimerChannel::Ch2, true); } /// Disable the given channel. pub fn disable(&mut self) { - self.inner.enable_channel(Channel::Ch1, false); - self.inner.enable_channel(Channel::Ch2, false); + self.inner.enable_channel(TimerChannel::Ch1, false); + self.inner.enable_channel(TimerChannel::Ch2, false); } /// Check whether given channel is enabled pub fn is_enabled(&self) -> bool { - self.inner.get_channel_enable_state(Channel::Ch1) + self.inner.get_channel_enable_state(TimerChannel::Ch1) } /// Get the period tick count @@ -81,8 +81,8 @@ impl<'d, T: GeneralInstance4Channel> PwmInput<'d, T> { /// Get the pulse width tick count pub fn get_width_ticks(&self) -> u32 { self.inner.get_capture_value(match self.channel { - Channel::Ch1 => Channel::Ch2, - Channel::Ch2 => Channel::Ch1, + TimerChannel::Ch1 => TimerChannel::Ch2, + TimerChannel::Ch2 => TimerChannel::Ch1, _ => panic!("Invalid channel for PWM input"), }) } diff --git a/embassy-stm32/src/timer/qei.rs b/embassy-stm32/src/timer/qei.rs index f3c81667c..bc7e71290 100644 --- a/embassy-stm32/src/timer/qei.rs +++ b/embassy-stm32/src/timer/qei.rs @@ -6,7 +6,7 @@ use stm32_metapac::timer::vals; use super::low_level::Timer; pub use super::{Ch1, Ch2}; -use super::{Channel1Pin, Channel2Pin, GeneralInstance4Channel}; +use super::{GeneralInstance4Channel, TimerPin}; use crate::gpio::{AfType, AnyPin, Pull}; use crate::Peri; @@ -24,11 +24,13 @@ pub struct QeiPin<'d, T, Channel> { phantom: PhantomData<(T, Channel)>, } +// TODO: generify QEI channels + macro_rules! channel_impl { ($new_chx:ident, $channel:ident, $pin_trait:ident) => { impl<'d, T: GeneralInstance4Channel> QeiPin<'d, T, $channel> { #[doc = concat!("Create a new ", stringify!($channel), " QEI pin instance.")] - pub fn $new_chx(pin: Peri<'d, impl $pin_trait>) -> Self { + pub fn $new_chx(pin: Peri<'d, impl $pin_trait>) -> Self { critical_section::with(|_| { pin.set_low(); pin.set_as_af(pin.af_num(), AfType::input(Pull::None)); @@ -42,8 +44,8 @@ macro_rules! channel_impl { }; } -channel_impl!(new_ch1, Ch1, Channel1Pin); -channel_impl!(new_ch2, Ch2, Channel2Pin); +channel_impl!(new_ch1, Ch1, TimerPin); +channel_impl!(new_ch2, Ch2, TimerPin); /// Quadrature decoder driver. pub struct Qei<'d, T: GeneralInstance4Channel> { diff --git a/embassy-stm32/src/timer/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs index f7f433154..02835c379 100644 --- a/embassy-stm32/src/timer/simple_pwm.rs +++ b/embassy-stm32/src/timer/simple_pwm.rs @@ -4,22 +4,13 @@ use core::marker::PhantomData; use core::mem::ManuallyDrop; use super::low_level::{CountingMode, OutputCompareMode, OutputPolarity, Timer}; -use super::{Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, GeneralInstance4Channel, TimerBits}; +use super::{Ch1, Ch2, Ch3, Ch4, GeneralInstance4Channel, TimerBits, TimerChannel, TimerPin}; #[cfg(gpio_v2)] use crate::gpio::Pull; use crate::gpio::{AfType, AnyPin, OutputType, Speed}; use crate::time::Hertz; use crate::Peri; -/// Channel 1 marker type. -pub enum Ch1 {} -/// Channel 2 marker type. -pub enum Ch2 {} -/// Channel 3 marker type. -pub enum Ch3 {} -/// Channel 4 marker type. -pub enum Ch4 {} - /// PWM pin wrapper. /// /// This wraps a pin to make it usable with PWM. @@ -47,7 +38,7 @@ macro_rules! channel_impl { ($new_chx:ident, $new_chx_with_config:ident, $channel:ident, $pin_trait:ident) => { impl<'d, T: GeneralInstance4Channel> PwmPin<'d, T, $channel> { #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance.")] - pub fn $new_chx(pin: Peri<'d, impl $pin_trait>, output_type: OutputType) -> Self { + pub fn $new_chx(pin: Peri<'d, impl $pin_trait>, output_type: OutputType) -> Self { critical_section::with(|_| { pin.set_low(); pin.set_as_af(pin.af_num(), AfType::output(output_type, Speed::VeryHigh)); @@ -59,7 +50,7 @@ macro_rules! channel_impl { } #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance with config.")] - pub fn $new_chx_with_config(pin: Peri<'d, impl $pin_trait>, pin_config: PwmPinConfig) -> Self { + pub fn $new_chx_with_config(pin: Peri<'d, impl $pin_trait>, pin_config: PwmPinConfig) -> Self { critical_section::with(|_| { pin.set_low(); pin.set_as_af( @@ -79,10 +70,10 @@ macro_rules! channel_impl { }; } -channel_impl!(new_ch1, new_ch1_with_config, Ch1, Channel1Pin); -channel_impl!(new_ch2, new_ch2_with_config, Ch2, Channel2Pin); -channel_impl!(new_ch3, new_ch3_with_config, Ch3, Channel3Pin); -channel_impl!(new_ch4, new_ch4_with_config, Ch4, Channel4Pin); +channel_impl!(new_ch1, new_ch1_with_config, Ch1, TimerPin); +channel_impl!(new_ch2, new_ch2_with_config, Ch2, TimerPin); +channel_impl!(new_ch3, new_ch3_with_config, Ch3, TimerPin); +channel_impl!(new_ch4, new_ch4_with_config, Ch4, TimerPin); /// A single channel of a pwm, obtained from [`SimplePwm::split`], /// [`SimplePwm::channel`], [`SimplePwm::ch1`], etc. @@ -91,7 +82,7 @@ channel_impl!(new_ch4, new_ch4_with_config, Ch4, Channel4Pin); /// the frequency configuration is shared with all four channels. pub struct SimplePwmChannel<'d, T: GeneralInstance4Channel> { timer: ManuallyDrop>, - channel: Channel, + channel: TimerChannel, } // TODO: check for RMW races @@ -216,13 +207,18 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { this.inner.enable_outputs(); // Required for advanced timers, see GeneralInstance4Channel for details this.inner.start(); - [Channel::Ch1, Channel::Ch2, Channel::Ch3, Channel::Ch4] - .iter() - .for_each(|&channel| { - this.inner.set_output_compare_mode(channel, OutputCompareMode::PwmMode1); + [ + TimerChannel::Ch1, + TimerChannel::Ch2, + TimerChannel::Ch3, + TimerChannel::Ch4, + ] + .iter() + .for_each(|&channel| { + this.inner.set_output_compare_mode(channel, OutputCompareMode::PwmMode1); - this.inner.set_output_compare_preload(channel, true); - }); + this.inner.set_output_compare_preload(channel, true); + }); this } @@ -230,7 +226,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { /// Get a single channel /// /// If you need to use multiple channels, use [`Self::split`]. - pub fn channel(&mut self, channel: Channel) -> SimplePwmChannel<'_, T> { + pub fn channel(&mut self, channel: TimerChannel) -> SimplePwmChannel<'_, T> { SimplePwmChannel { timer: unsafe { self.inner.clone_unchecked() }, channel, @@ -243,7 +239,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { /// /// If you need to use multiple channels, use [`Self::split`]. pub fn ch1(&mut self) -> SimplePwmChannel<'_, T> { - self.channel(Channel::Ch1) + self.channel(TimerChannel::Ch1) } /// Channel 2 @@ -252,7 +248,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { /// /// If you need to use multiple channels, use [`Self::split`]. pub fn ch2(&mut self) -> SimplePwmChannel<'_, T> { - self.channel(Channel::Ch2) + self.channel(TimerChannel::Ch2) } /// Channel 3 @@ -261,7 +257,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { /// /// If you need to use multiple channels, use [`Self::split`]. pub fn ch3(&mut self) -> SimplePwmChannel<'_, T> { - self.channel(Channel::Ch3) + self.channel(TimerChannel::Ch3) } /// Channel 4 @@ -270,7 +266,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { /// /// If you need to use multiple channels, use [`Self::split`]. pub fn ch4(&mut self) -> SimplePwmChannel<'_, T> { - self.channel(Channel::Ch4) + self.channel(TimerChannel::Ch4) } /// Splits a [`SimplePwm`] into four pwm channels. @@ -292,10 +288,10 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { }; SimplePwmChannels { - ch1: ch(Channel::Ch1), - ch2: ch(Channel::Ch2), - ch3: ch(Channel::Ch3), - ch4: ch(Channel::Ch4), + ch1: ch(TimerChannel::Ch1), + ch2: ch(TimerChannel::Ch2), + ch3: ch(TimerChannel::Ch3), + ch4: ch(TimerChannel::Ch4), } } @@ -326,7 +322,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { /// /// Note: /// you will need to provide corresponding TIMx_UP DMA channel to use this method. - pub async fn waveform_up(&mut self, dma: Peri<'_, impl super::UpDma>, channel: Channel, duty: &[u16]) { + pub async fn waveform_up(&mut self, dma: Peri<'_, impl super::UpDma>, channel: TimerChannel, duty: &[u16]) { #[allow(clippy::let_unit_value)] // eg. stm32f334 let req = dma.request(); @@ -409,8 +405,8 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { pub async fn waveform_up_multi_channel( &mut self, dma: Peri<'_, impl super::UpDma>, - starting_channel: Channel, - ending_channel: Channel, + starting_channel: TimerChannel, + ending_channel: TimerChannel, duty: &[u16], ) { let cr1_addr = self.inner.regs_gp16().cr1().as_ptr() as u32; @@ -470,13 +466,13 @@ macro_rules! impl_waveform_chx { ($fn_name:ident, $dma_ch:ident, $cc_ch:ident) => { impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { /// Generate a sequence of PWM waveform - pub async fn $fn_name(&mut self, dma: Peri<'_, impl super::$dma_ch>, duty: &[u16]) { + pub async fn $fn_name(&mut self, dma: Peri<'_, impl super::$dma_ch>, duty: &[u16]) { use crate::pac::timer::vals::Ccds; #[allow(clippy::let_unit_value)] // eg. stm32f334 let req = dma.request(); - let cc_channel = Channel::$cc_ch; + let cc_channel = TimerChannel::$cc_ch; let original_duty_state = self.channel(cc_channel).current_duty_cycle(); let original_enable_state = self.channel(cc_channel).is_enabled(); @@ -562,10 +558,10 @@ macro_rules! impl_waveform_chx { }; } -impl_waveform_chx!(waveform_ch1, Ch1Dma, Ch1); -impl_waveform_chx!(waveform_ch2, Ch2Dma, Ch2); -impl_waveform_chx!(waveform_ch3, Ch3Dma, Ch3); -impl_waveform_chx!(waveform_ch4, Ch4Dma, Ch4); +impl_waveform_chx!(waveform_ch1, Dma, Ch1); +impl_waveform_chx!(waveform_ch2, Dma, Ch2); +impl_waveform_chx!(waveform_ch3, Dma, Ch3); +impl_waveform_chx!(waveform_ch4, Dma, Ch4); impl<'d, T: GeneralInstance4Channel> embedded_hal_1::pwm::ErrorType for SimplePwmChannel<'d, T> { type Error = core::convert::Infallible; @@ -603,7 +599,7 @@ impl<'d, T: GeneralInstance4Channel> embedded_hal_1::pwm::SetDutyCycle for Simpl } impl<'d, T: GeneralInstance4Channel> embedded_hal_02::Pwm for SimplePwm<'d, T> { - type Channel = Channel; + type Channel = TimerChannel; type Time = Hertz; type Duty = u32; -- cgit From 1623d4e639a54f21678381b54fd6d444309dab0a Mon Sep 17 00:00:00 2001 From: melvdl Date: Thu, 26 Jun 2025 22:55:12 +0200 Subject: stm32: generify timer::one_pulse and timer::qei pin constructors --- embassy-stm32/src/timer/one_pulse.rs | 88 ++++++++++++++++++++++++++---------- embassy-stm32/src/timer/qei.rs | 42 +++++++++-------- 2 files changed, 86 insertions(+), 44 deletions(-) diff --git a/embassy-stm32/src/timer/one_pulse.rs b/embassy-stm32/src/timer/one_pulse.rs index 47c1d7f49..e89ad8390 100644 --- a/embassy-stm32/src/timer/one_pulse.rs +++ b/embassy-stm32/src/timer/one_pulse.rs @@ -7,7 +7,7 @@ use core::pin::Pin; use core::task::{Context, Poll}; use super::low_level::{ - CountingMode, FilterValue, InputCaptureMode, InputTISelection, SlaveMode, Timer, TriggerSource, + CountingMode, FilterValue, InputCaptureMode, InputTISelection, SlaveMode, Timer, TriggerSource as Ts, }; use super::{CaptureCompareInterruptHandler, ExternalTriggerPin, GeneralInstance4Channel, TimerChannel, TimerPin}; pub use super::{Ch1, Ch2}; @@ -46,33 +46,71 @@ pub struct TriggerPin<'d, T, C> { phantom: PhantomData<(T, C)>, } -// TODO: Generify trigger inputs +trait SealedTriggerSource {} -impl<'d, T: GeneralInstance4Channel> TriggerPin<'d, T, Ch1> { - /// "Create a new Ch1 trigger pin instance. - pub fn new_ch1(pin: Peri<'d, impl TimerPin>, pull: Pull) -> Self { - pin.set_as_af(pin.af_num(), AfType::input(pull)); - TriggerPin { - _pin: pin.into(), - phantom: PhantomData, - } +/// Marker trait for a trigger source. +#[expect(private_bounds)] +pub trait TriggerSource: SealedTriggerSource {} + +impl TriggerSource for Ch1 {} +impl TriggerSource for Ch2 {} +impl TriggerSource for Ext {} + +impl SealedTriggerSource for Ch1 {} +impl SealedTriggerSource for Ch2 {} +impl SealedTriggerSource for Ext {} + +trait SealedTimerTriggerPin: crate::gpio::Pin {} + +/// Marker trait for a trigger pin. +#[expect(private_bounds)] +// TODO: find better naming scheme than prefixing all pin traits with "Timer". +// The trait name cannot conflict with the corresponding type's name. +// Applies to other timer submodules as well. +pub trait TimerTriggerPin: SealedTimerTriggerPin { + /// Get the AF number needed to use this pin as a trigger source. + fn af_num(&self) -> u8; +} + +impl TimerTriggerPin for P +where + T: GeneralInstance4Channel, + P: TimerPin, + C: super::Channel + TriggerSource, +{ + fn af_num(&self) -> u8 { + TimerPin::af_num(self) } } -impl<'d, T: GeneralInstance4Channel> TriggerPin<'d, T, Ch2> { - /// "Create a new Ch2 trigger pin instance. - pub fn new_ch2(pin: Peri<'d, impl TimerPin>, pull: Pull) -> Self { - pin.set_as_af(pin.af_num(), AfType::input(pull)); - TriggerPin { - _pin: pin.into(), - phantom: PhantomData, - } +impl TimerTriggerPin for P +where + T: GeneralInstance4Channel, + P: ExternalTriggerPin, +{ + fn af_num(&self) -> u8 { + ExternalTriggerPin::af_num(self) } } -impl<'d, T: GeneralInstance4Channel> TriggerPin<'d, T, Ext> { - /// "Create a new EXT trigger pin instance. - pub fn new_ext(pin: Peri<'d, impl ExternalTriggerPin>, pull: Pull) -> Self { +impl SealedTimerTriggerPin for P +where + T: GeneralInstance4Channel, + P: TimerPin, + C: super::Channel + TriggerSource, +{ +} + +impl SealedTimerTriggerPin for P +where + T: GeneralInstance4Channel, + P: ExternalTriggerPin, +{ +} + +impl<'d, T: GeneralInstance4Channel, C: TriggerSource> TriggerPin<'d, T, C> { + /// "Create a new Ch1 trigger pin instance. + pub fn new(pin: Peri<'d, impl TimerTriggerPin>, pull: Pull) -> Self { pin.set_as_af(pin.af_num(), AfType::input(pull)); TriggerPin { _pin: pin.into(), @@ -103,7 +141,7 @@ impl<'d, T: GeneralInstance4Channel> OnePulse<'d, T> { ) -> Self { let mut this = Self { inner: Timer::new(tim) }; - this.inner.set_trigger_source(TriggerSource::TI1F_ED); + this.inner.set_trigger_source(Ts::TI1F_ED); this.inner .set_input_ti_selection(TimerChannel::Ch1, InputTISelection::Normal); this.inner @@ -128,7 +166,7 @@ impl<'d, T: GeneralInstance4Channel> OnePulse<'d, T> { ) -> Self { let mut this = Self { inner: Timer::new(tim) }; - this.inner.set_trigger_source(TriggerSource::TI1FP1); + this.inner.set_trigger_source(Ts::TI1FP1); this.inner .set_input_ti_selection(TimerChannel::Ch1, InputTISelection::Normal); this.inner @@ -154,7 +192,7 @@ impl<'d, T: GeneralInstance4Channel> OnePulse<'d, T> { ) -> Self { let mut this = Self { inner: Timer::new(tim) }; - this.inner.set_trigger_source(TriggerSource::TI2FP2); + this.inner.set_trigger_source(Ts::TI2FP2); this.inner .set_input_ti_selection(TimerChannel::Ch2, InputTISelection::Normal); this.inner @@ -186,7 +224,7 @@ impl<'d, T: GeneralInstance4Channel> OnePulse<'d, T> { // No filtering r.set_etf(FilterValue::NO_FILTER); }); - this.inner.set_trigger_source(TriggerSource::ETRF); + this.inner.set_trigger_source(Ts::ETRF); this.new_inner(freq, pulse_end, counting_mode); this diff --git a/embassy-stm32/src/timer/qei.rs b/embassy-stm32/src/timer/qei.rs index bc7e71290..657052cfa 100644 --- a/embassy-stm32/src/timer/qei.rs +++ b/embassy-stm32/src/timer/qei.rs @@ -8,6 +8,7 @@ use super::low_level::Timer; pub use super::{Ch1, Ch2}; use super::{GeneralInstance4Channel, TimerPin}; use crate::gpio::{AfType, AnyPin, Pull}; +use crate::timer::Channel; use crate::Peri; /// Counting direction @@ -24,28 +25,31 @@ pub struct QeiPin<'d, T, Channel> { phantom: PhantomData<(T, Channel)>, } -// TODO: generify QEI channels - -macro_rules! channel_impl { - ($new_chx:ident, $channel:ident, $pin_trait:ident) => { - impl<'d, T: GeneralInstance4Channel> QeiPin<'d, T, $channel> { - #[doc = concat!("Create a new ", stringify!($channel), " QEI pin instance.")] - pub fn $new_chx(pin: Peri<'d, impl $pin_trait>) -> Self { - critical_section::with(|_| { - pin.set_low(); - pin.set_as_af(pin.af_num(), AfType::input(Pull::None)); - }); - QeiPin { - _pin: pin.into(), - phantom: PhantomData, - } - } +impl<'d, T: GeneralInstance4Channel, C: QeiChannel> QeiPin<'d, T, C> { + /// Create a new QEI pin instance. + pub fn new(pin: Peri<'d, impl TimerPin>) -> Self { + critical_section::with(|_| { + pin.set_low(); + pin.set_as_af(pin.af_num(), AfType::input(Pull::None)); + }); + QeiPin { + _pin: pin.into(), + phantom: PhantomData, } - }; + } } -channel_impl!(new_ch1, Ch1, TimerPin); -channel_impl!(new_ch2, Ch2, TimerPin); +trait SealedQeiChannel: Channel {} + +/// Marker trait for a timer channel eligible for use with QEI. +#[expect(private_bounds)] +pub trait QeiChannel: SealedQeiChannel {} + +impl QeiChannel for Ch1 {} +impl QeiChannel for Ch2 {} + +impl SealedQeiChannel for Ch1 {} +impl SealedQeiChannel for Ch2 {} /// Quadrature decoder driver. pub struct Qei<'d, T: GeneralInstance4Channel> { -- cgit From cbd24bf2eece65a787fc085c255e9b2932ea73e3 Mon Sep 17 00:00:00 2001 From: melvdl Date: Fri, 27 Jun 2025 01:04:47 +0200 Subject: stm32: fix timer break input 2 trait name in build script --- embassy-stm32/build.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 192688149..13fc23e54 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -1103,8 +1103,8 @@ fn main() { (("timer", "BKIN_COMP1"), quote!(crate::timer::BreakInputComparator1Pin)), (("timer", "BKIN_COMP2"), quote!(crate::timer::BreakInputComparator2Pin)), (("timer", "BKIN2"), quote!(crate::timer::BreakInputPin)), - (("timer", "BKIN2_COMP1"), quote!(crate::timer::BreakInput2Comparator1Pin)), - (("timer", "BKIN2_COMP2"), quote!(crate::timer::BreakInput2Comparator2Pin)), + (("timer", "BKIN2_COMP1"), quote!(crate::timer::BreakInputComparator1Pin)), + (("timer", "BKIN2_COMP2"), quote!(crate::timer::BreakInputComparator2Pin)), (("hrtim", "CHA1"), quote!(crate::hrtim::ChannelAPin)), (("hrtim", "CHA2"), quote!(crate::hrtim::ChannelAComplementaryPin)), (("hrtim", "CHB1"), quote!(crate::hrtim::ChannelBPin)), -- cgit From 6f88c2c73caa63a6e534130f4a064cb95d3e9d7d Mon Sep 17 00:00:00 2001 From: melvdl Date: Fri, 27 Jun 2025 01:08:28 +0200 Subject: stm32: rename timer channel trait; replace impls via macro with impls generic over timer channels --- embassy-stm32/src/timer/complementary_pwm.rs | 33 ++-- embassy-stm32/src/timer/input_capture.rs | 41 ++-- embassy-stm32/src/timer/low_level.rs | 38 ++-- embassy-stm32/src/timer/mod.rs | 48 ++--- embassy-stm32/src/timer/one_pulse.rs | 44 ++--- embassy-stm32/src/timer/pwm_input.rs | 28 +-- embassy-stm32/src/timer/qei.rs | 4 +- embassy-stm32/src/timer/simple_pwm.rs | 279 ++++++++++++--------------- 8 files changed, 241 insertions(+), 274 deletions(-) diff --git a/embassy-stm32/src/timer/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs index 4600dd1a3..a450705a2 100644 --- a/embassy-stm32/src/timer/complementary_pwm.rs +++ b/embassy-stm32/src/timer/complementary_pwm.rs @@ -6,11 +6,11 @@ use stm32_metapac::timer::vals::Ckd; use super::low_level::{CountingMode, OutputPolarity, Timer}; use super::simple_pwm::PwmPin; -use super::{AdvancedInstance4Channel, Ch1, Ch2, Ch3, Ch4, TimerChannel, TimerComplementaryPin}; +use super::{AdvancedInstance4Channel, Ch1, Ch2, Ch3, Ch4, Channel, TimerComplementaryPin}; use crate::gpio::{AnyPin, OutputType}; use crate::time::Hertz; use crate::timer::low_level::OutputCompareMode; -use crate::timer::Channel; +use crate::timer::TimerChannel; use crate::Peri; /// Complementary PWM pin wrapper. @@ -21,7 +21,7 @@ pub struct ComplementaryPwmPin<'d, T, C> { phantom: PhantomData<(T, C)>, } -impl<'d, T: AdvancedInstance4Channel, C: Channel> ComplementaryPwmPin<'d, T, C> { +impl<'d, T: AdvancedInstance4Channel, C: TimerChannel> ComplementaryPwmPin<'d, T, C> { /// Create a new complementary PWM pin instance. pub fn new(pin: Peri<'d, impl TimerComplementaryPin>, output_type: OutputType) -> Self { critical_section::with(|_| { @@ -71,29 +71,24 @@ impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> { this.inner.enable_outputs(); - [ - TimerChannel::Ch1, - TimerChannel::Ch2, - TimerChannel::Ch3, - TimerChannel::Ch4, - ] - .iter() - .for_each(|&channel| { - this.inner.set_output_compare_mode(channel, OutputCompareMode::PwmMode1); - this.inner.set_output_compare_preload(channel, true); - }); + [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); + }); this } /// Enable the given channel. - pub fn enable(&mut self, channel: TimerChannel) { + pub fn enable(&mut self, channel: Channel) { self.inner.enable_channel(channel, true); self.inner.enable_complementary_channel(channel, true); } /// Disable the given channel. - pub fn disable(&mut self, channel: TimerChannel) { + pub fn disable(&mut self, channel: Channel) { self.inner.enable_complementary_channel(channel, false); self.inner.enable_channel(channel, false); } @@ -121,13 +116,13 @@ impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> { /// Set 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 set_duty(&mut self, channel: TimerChannel, duty: u16) { + pub fn set_duty(&mut self, channel: Channel, duty: u16) { assert!(duty <= self.get_max_duty()); self.inner.set_compare_value(channel, duty as _) } /// Set the output polarity for a given channel. - pub fn set_polarity(&mut self, channel: TimerChannel, polarity: OutputPolarity) { + 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); } @@ -142,7 +137,7 @@ impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> { } impl<'d, T: AdvancedInstance4Channel> embedded_hal_02::Pwm for ComplementaryPwm<'d, T> { - type Channel = TimerChannel; + type Channel = Channel; type Time = Hertz; type Duty = u16; diff --git a/embassy-stm32/src/timer/input_capture.rs b/embassy-stm32/src/timer/input_capture.rs index da567d504..49e22b10f 100644 --- a/embassy-stm32/src/timer/input_capture.rs +++ b/embassy-stm32/src/timer/input_capture.rs @@ -6,12 +6,12 @@ use core::pin::Pin; use core::task::{Context, Poll}; use super::low_level::{CountingMode, FilterValue, InputCaptureMode, InputTISelection, Timer}; -use super::{CaptureCompareInterruptHandler, GeneralInstance4Channel, TimerChannel, TimerPin}; +use super::{CaptureCompareInterruptHandler, GeneralInstance4Channel, Channel, TimerPin}; pub use super::{Ch1, Ch2, Ch3, Ch4}; use crate::gpio::{AfType, AnyPin, Pull}; use crate::interrupt::typelevel::{Binding, Interrupt}; use crate::time::Hertz; -use crate::timer::Channel; +use crate::timer::TimerChannel; use crate::Peri; /// Capture pin wrapper. @@ -21,7 +21,7 @@ pub struct CapturePin<'d, T, C> { _pin: Peri<'d, AnyPin>, phantom: PhantomData<(T, C)>, } -impl<'d, T: GeneralInstance4Channel, C: Channel> CapturePin<'d, T, C> { +impl<'d, T: GeneralInstance4Channel, C: TimerChannel> CapturePin<'d, T, C> { /// Create a new capture pin instance. pub fn new(pin: Peri<'d, impl TimerPin>, pull: Pull) -> Self { pin.set_as_af(pin.af_num(), AfType::input(pull)); @@ -68,46 +68,41 @@ impl<'d, T: GeneralInstance4Channel> InputCapture<'d, T> { } /// Enable the given channel. - pub fn enable(&mut self, channel: TimerChannel) { + pub fn enable(&mut self, channel: Channel) { self.inner.enable_channel(channel, true); } /// Disable the given channel. - pub fn disable(&mut self, channel: TimerChannel) { + pub fn disable(&mut self, channel: Channel) { self.inner.enable_channel(channel, false); } /// Check whether given channel is enabled - pub fn is_enabled(&self, channel: TimerChannel) -> bool { + pub fn is_enabled(&self, channel: Channel) -> bool { self.inner.get_channel_enable_state(channel) } /// Set the input capture mode for a given channel. - pub fn set_input_capture_mode(&mut self, channel: TimerChannel, mode: InputCaptureMode) { + pub fn set_input_capture_mode(&mut self, channel: Channel, mode: InputCaptureMode) { self.inner.set_input_capture_mode(channel, mode); } /// Set input TI selection. - pub fn set_input_ti_selection(&mut self, channel: TimerChannel, tisel: InputTISelection) { + pub fn set_input_ti_selection(&mut self, channel: Channel, tisel: InputTISelection) { self.inner.set_input_ti_selection(channel, tisel) } /// Get capture value for a channel. - pub fn get_capture_value(&self, channel: TimerChannel) -> u32 { + pub fn get_capture_value(&self, channel: Channel) -> u32 { self.inner.get_capture_value(channel) } /// Get input interrupt. - pub fn get_input_interrupt(&self, channel: TimerChannel) -> bool { + pub fn get_input_interrupt(&self, channel: Channel) -> bool { self.inner.get_input_interrupt(channel) } - fn new_future( - &self, - channel: TimerChannel, - mode: InputCaptureMode, - tisel: InputTISelection, - ) -> InputCaptureFuture { + fn new_future(&self, channel: Channel, mode: InputCaptureMode, tisel: InputTISelection) -> InputCaptureFuture { // Configuration steps from ST RM0390 (STM32F446) chapter 17.3.5 // or ST RM0008 (STM32F103) chapter 15.3.5 Input capture mode self.inner.set_input_ti_selection(channel, tisel); @@ -124,37 +119,37 @@ impl<'d, T: GeneralInstance4Channel> InputCapture<'d, T> { } /// Asynchronously wait until the pin sees a rising edge. - pub async fn wait_for_rising_edge(&mut self, channel: TimerChannel) -> u32 { + pub async fn wait_for_rising_edge(&mut self, channel: Channel) -> u32 { self.new_future(channel, InputCaptureMode::Rising, InputTISelection::Normal) .await } /// Asynchronously wait until the pin sees a falling edge. - pub async fn wait_for_falling_edge(&mut self, channel: TimerChannel) -> u32 { + pub async fn wait_for_falling_edge(&mut self, channel: Channel) -> u32 { self.new_future(channel, InputCaptureMode::Falling, InputTISelection::Normal) .await } /// Asynchronously wait until the pin sees any edge. - pub async fn wait_for_any_edge(&mut self, channel: TimerChannel) -> u32 { + pub async fn wait_for_any_edge(&mut self, channel: Channel) -> u32 { self.new_future(channel, InputCaptureMode::BothEdges, InputTISelection::Normal) .await } /// Asynchronously wait until the (alternate) pin sees a rising edge. - pub async fn wait_for_rising_edge_alternate(&mut self, channel: TimerChannel) -> u32 { + pub async fn wait_for_rising_edge_alternate(&mut self, channel: Channel) -> u32 { self.new_future(channel, InputCaptureMode::Rising, InputTISelection::Alternate) .await } /// Asynchronously wait until the (alternate) pin sees a falling edge. - pub async fn wait_for_falling_edge_alternate(&mut self, channel: TimerChannel) -> u32 { + pub async fn wait_for_falling_edge_alternate(&mut self, channel: Channel) -> u32 { self.new_future(channel, InputCaptureMode::Falling, InputTISelection::Alternate) .await } /// Asynchronously wait until the (alternate) pin sees any edge. - pub async fn wait_for_any_edge_alternate(&mut self, channel: TimerChannel) -> u32 { + pub async fn wait_for_any_edge_alternate(&mut self, channel: Channel) -> u32 { self.new_future(channel, InputCaptureMode::BothEdges, InputTISelection::Alternate) .await } @@ -162,7 +157,7 @@ impl<'d, T: GeneralInstance4Channel> InputCapture<'d, T> { #[must_use = "futures do nothing unless you `.await` or poll them"] struct InputCaptureFuture { - channel: TimerChannel, + channel: Channel, phantom: PhantomData, } diff --git a/embassy-stm32/src/timer/low_level.rs b/embassy-stm32/src/timer/low_level.rs index bfdbcf968..dc8ceb725 100644 --- a/embassy-stm32/src/timer/low_level.rs +++ b/embassy-stm32/src/timer/low_level.rs @@ -503,7 +503,7 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> { } /// Set input capture filter. - pub fn set_input_capture_filter(&self, channel: TimerChannel, icf: vals::FilterValue) { + pub fn set_input_capture_filter(&self, channel: Channel, icf: vals::FilterValue) { let raw_channel = channel.index(); self.regs_gp16() .ccmr_input(raw_channel / 2) @@ -511,22 +511,22 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> { } /// Clear input interrupt. - pub fn clear_input_interrupt(&self, channel: TimerChannel) { + pub fn clear_input_interrupt(&self, channel: Channel) { self.regs_gp16().sr().modify(|r| r.set_ccif(channel.index(), false)); } /// Get input interrupt. - pub fn get_input_interrupt(&self, channel: TimerChannel) -> bool { + pub fn get_input_interrupt(&self, channel: Channel) -> bool { self.regs_gp16().sr().read().ccif(channel.index()) } /// Enable input interrupt. - pub fn enable_input_interrupt(&self, channel: TimerChannel, enable: bool) { + pub fn enable_input_interrupt(&self, channel: Channel, enable: bool) { self.regs_gp16().dier().modify(|r| r.set_ccie(channel.index(), enable)); } /// Set input capture prescaler. - pub fn set_input_capture_prescaler(&self, channel: TimerChannel, factor: u8) { + pub fn set_input_capture_prescaler(&self, channel: Channel, factor: u8) { let raw_channel = channel.index(); self.regs_gp16() .ccmr_input(raw_channel / 2) @@ -534,7 +534,7 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> { } /// Set input TI selection. - pub fn set_input_ti_selection(&self, channel: TimerChannel, tisel: InputTISelection) { + pub fn set_input_ti_selection(&self, channel: Channel, tisel: InputTISelection) { let raw_channel = channel.index(); self.regs_gp16() .ccmr_input(raw_channel / 2) @@ -542,7 +542,7 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> { } /// Set input capture mode. - pub fn set_input_capture_mode(&self, channel: TimerChannel, mode: InputCaptureMode) { + pub fn set_input_capture_mode(&self, channel: Channel, mode: InputCaptureMode) { self.regs_gp16().ccer().modify(|r| match mode { InputCaptureMode::Rising => { r.set_ccnp(channel.index(), false); @@ -560,7 +560,7 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> { } /// Set output compare mode. - pub fn set_output_compare_mode(&self, channel: TimerChannel, mode: OutputCompareMode) { + pub fn set_output_compare_mode(&self, channel: Channel, mode: OutputCompareMode) { let raw_channel: usize = channel.index(); self.regs_gp16() .ccmr_output(raw_channel / 2) @@ -568,24 +568,24 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> { } /// Set output polarity. - pub fn set_output_polarity(&self, channel: TimerChannel, polarity: OutputPolarity) { + pub fn set_output_polarity(&self, channel: Channel, polarity: OutputPolarity) { self.regs_gp16() .ccer() .modify(|w| w.set_ccp(channel.index(), polarity.into())); } /// Enable/disable a channel. - pub fn enable_channel(&self, channel: TimerChannel, enable: bool) { + pub fn enable_channel(&self, channel: Channel, enable: bool) { self.regs_gp16().ccer().modify(|w| w.set_cce(channel.index(), enable)); } /// Get enable/disable state of a channel - pub fn get_channel_enable_state(&self, channel: TimerChannel) -> bool { + pub fn get_channel_enable_state(&self, channel: Channel) -> bool { self.regs_gp16().ccer().read().cce(channel.index()) } /// Set compare value for a channel. - pub fn set_compare_value(&self, channel: TimerChannel, value: u32) { + pub fn set_compare_value(&self, channel: Channel, value: u32) { match T::BITS { TimerBits::Bits16 => { let value = unwrap!(u16::try_from(value)); @@ -599,7 +599,7 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> { } /// Get compare value for a channel. - pub fn get_compare_value(&self, channel: TimerChannel) -> u32 { + pub fn get_compare_value(&self, channel: Channel) -> u32 { match T::BITS { TimerBits::Bits16 => self.regs_gp16().ccr(channel.index()).read().ccr() as u32, #[cfg(not(stm32l0))] @@ -608,12 +608,12 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> { } /// Get capture value for a channel. - pub fn get_capture_value(&self, channel: TimerChannel) -> u32 { + pub fn get_capture_value(&self, channel: Channel) -> u32 { self.get_compare_value(channel) } /// Set output compare preload. - pub fn set_output_compare_preload(&self, channel: TimerChannel, preload: bool) { + pub fn set_output_compare_preload(&self, channel: Channel, preload: bool) { let channel_index = channel.index(); self.regs_gp16() .ccmr_output(channel_index / 2) @@ -631,12 +631,12 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> { } /// Get capture compare DMA enable state - pub fn get_cc_dma_enable_state(&self, channel: TimerChannel) -> bool { + pub fn get_cc_dma_enable_state(&self, channel: Channel) -> bool { self.regs_gp16().dier().read().ccde(channel.index()) } /// Set capture compare DMA enable state - pub fn set_cc_dma_enable_state(&self, channel: TimerChannel, ccde: bool) { + pub fn set_cc_dma_enable_state(&self, channel: Channel, ccde: bool) { self.regs_gp16().dier().modify(|w| w.set_ccde(channel.index(), ccde)) } @@ -713,14 +713,14 @@ impl<'d, T: AdvancedInstance4Channel> Timer<'d, T> { } /// Set complementary output polarity. - pub fn set_complementary_output_polarity(&self, channel: TimerChannel, polarity: OutputPolarity) { + pub fn set_complementary_output_polarity(&self, channel: Channel, polarity: OutputPolarity) { self.regs_advanced() .ccer() .modify(|w| w.set_ccnp(channel.index(), polarity.into())); } /// Enable/disable a complementary channel. - pub fn enable_complementary_channel(&self, channel: TimerChannel, enable: bool) { + pub fn enable_complementary_channel(&self, channel: Channel, enable: bool) { self.regs_advanced() .ccer() .modify(|w| w.set_ccne(channel.index(), enable)); diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs index 362d95e25..7062f5f4c 100644 --- a/embassy-stm32/src/timer/mod.rs +++ b/embassy-stm32/src/timer/mod.rs @@ -19,7 +19,7 @@ use crate::rcc::RccPeripheral; /// Timer channel. #[derive(Clone, Copy)] -pub enum TimerChannel { +pub enum Channel { /// Channel 1. Ch1, /// Channel 2. @@ -30,14 +30,14 @@ pub enum TimerChannel { Ch4, } -impl TimerChannel { +impl Channel { /// Get the channel index (0..3) pub fn index(&self) -> usize { match self { - TimerChannel::Ch1 => 0, - TimerChannel::Ch2 => 1, - TimerChannel::Ch3 => 2, - TimerChannel::Ch4 => 3, + Channel::Ch1 => 0, + Channel::Ch2 => 1, + Channel::Ch3 => 2, + Channel::Ch4 => 3, } } } @@ -53,33 +53,33 @@ pub enum Ch4 {} /// Timer channel trait. #[allow(private_bounds)] -pub trait Channel: SealedChannel { +pub trait TimerChannel: SealedTimerChannel { /// The runtime channel. - const CHANNEL: TimerChannel; + const CHANNEL: Channel; } -trait SealedChannel {} +trait SealedTimerChannel {} -impl Channel for Ch1 { - const CHANNEL: TimerChannel = TimerChannel::Ch1; +impl TimerChannel for Ch1 { + const CHANNEL: Channel = Channel::Ch1; } -impl Channel for Ch2 { - const CHANNEL: TimerChannel = TimerChannel::Ch2; +impl TimerChannel for Ch2 { + const CHANNEL: Channel = Channel::Ch2; } -impl Channel for Ch3 { - const CHANNEL: TimerChannel = TimerChannel::Ch3; +impl TimerChannel for Ch3 { + const CHANNEL: Channel = Channel::Ch3; } -impl Channel for Ch4 { - const CHANNEL: TimerChannel = TimerChannel::Ch4; +impl TimerChannel for Ch4 { + const CHANNEL: Channel = Channel::Ch4; } -impl SealedChannel for Ch1 {} -impl SealedChannel for Ch2 {} -impl SealedChannel for Ch3 {} -impl SealedChannel for Ch4 {} +impl SealedTimerChannel for Ch1 {} +impl SealedTimerChannel for Ch2 {} +impl SealedTimerChannel for Ch3 {} +impl SealedTimerChannel for Ch4 {} /// Timer break input. #[derive(Clone, Copy)] @@ -223,10 +223,10 @@ pub trait AdvancedInstance2Channel: BasicInstance + GeneralInstance2Channel + Ad /// Advanced 16-bit timer with 4 channels instance. pub trait AdvancedInstance4Channel: AdvancedInstance2Channel + GeneralInstance4Channel {} -pin_trait!(TimerPin, GeneralInstance4Channel, Channel); +pin_trait!(TimerPin, GeneralInstance4Channel, TimerChannel); pin_trait!(ExternalTriggerPin, GeneralInstance4Channel); -pin_trait!(TimerComplementaryPin, AdvancedInstance4Channel, Channel); +pin_trait!(TimerComplementaryPin, AdvancedInstance4Channel, TimerChannel); pin_trait!(BreakInputPin, AdvancedInstance4Channel, BreakInput); @@ -236,7 +236,7 @@ pin_trait!(BreakInputComparator2Pin, AdvancedInstance4Channel, BreakInput); // Update Event trigger DMA for every timer dma_trait!(UpDma, BasicInstance); -dma_trait!(Dma, GeneralInstance4Channel, Channel); +dma_trait!(Dma, GeneralInstance4Channel, TimerChannel); #[allow(unused)] macro_rules! impl_core_timer { diff --git a/embassy-stm32/src/timer/one_pulse.rs b/embassy-stm32/src/timer/one_pulse.rs index e89ad8390..c8f0cafe7 100644 --- a/embassy-stm32/src/timer/one_pulse.rs +++ b/embassy-stm32/src/timer/one_pulse.rs @@ -9,7 +9,7 @@ use core::task::{Context, Poll}; use super::low_level::{ CountingMode, FilterValue, InputCaptureMode, InputTISelection, SlaveMode, Timer, TriggerSource as Ts, }; -use super::{CaptureCompareInterruptHandler, ExternalTriggerPin, GeneralInstance4Channel, TimerChannel, TimerPin}; +use super::{CaptureCompareInterruptHandler, Channel, ExternalTriggerPin, GeneralInstance4Channel, TimerPin}; pub use super::{Ch1, Ch2}; use crate::gpio::{AfType, AnyPin, Pull}; use crate::interrupt::typelevel::{Binding, Interrupt}; @@ -76,7 +76,7 @@ impl TimerTriggerPin for P where T: GeneralInstance4Channel, P: TimerPin, - C: super::Channel + TriggerSource, + C: super::TimerChannel + TriggerSource, { fn af_num(&self) -> u8 { TimerPin::af_num(self) @@ -97,7 +97,7 @@ impl SealedTimerTriggerPin for P where T: GeneralInstance4Channel, P: TimerPin, - C: super::Channel + TriggerSource, + C: super::TimerChannel + TriggerSource, { } @@ -143,9 +143,9 @@ impl<'d, T: GeneralInstance4Channel> OnePulse<'d, T> { this.inner.set_trigger_source(Ts::TI1F_ED); this.inner - .set_input_ti_selection(TimerChannel::Ch1, InputTISelection::Normal); + .set_input_ti_selection(Channel::Ch1, InputTISelection::Normal); this.inner - .set_input_capture_filter(TimerChannel::Ch1, FilterValue::NO_FILTER); + .set_input_capture_filter(Channel::Ch1, FilterValue::NO_FILTER); this.new_inner(freq, pulse_end, counting_mode); this @@ -168,10 +168,10 @@ impl<'d, T: GeneralInstance4Channel> OnePulse<'d, T> { this.inner.set_trigger_source(Ts::TI1FP1); this.inner - .set_input_ti_selection(TimerChannel::Ch1, InputTISelection::Normal); + .set_input_ti_selection(Channel::Ch1, InputTISelection::Normal); this.inner - .set_input_capture_filter(TimerChannel::Ch1, FilterValue::NO_FILTER); - this.inner.set_input_capture_mode(TimerChannel::Ch1, capture_mode); + .set_input_capture_filter(Channel::Ch1, FilterValue::NO_FILTER); + this.inner.set_input_capture_mode(Channel::Ch1, capture_mode); this.new_inner(freq, pulse_end, counting_mode); this @@ -194,10 +194,10 @@ impl<'d, T: GeneralInstance4Channel> OnePulse<'d, T> { this.inner.set_trigger_source(Ts::TI2FP2); this.inner - .set_input_ti_selection(TimerChannel::Ch2, InputTISelection::Normal); + .set_input_ti_selection(Channel::Ch2, InputTISelection::Normal); this.inner - .set_input_capture_filter(TimerChannel::Ch2, FilterValue::NO_FILTER); - this.inner.set_input_capture_mode(TimerChannel::Ch2, capture_mode); + .set_input_capture_filter(Channel::Ch2, FilterValue::NO_FILTER); + this.inner.set_input_capture_mode(Channel::Ch2, capture_mode); this.new_inner(freq, pulse_end, counting_mode); this @@ -269,7 +269,7 @@ impl<'d, T: GeneralInstance4Channel> OnePulse<'d, T> { /// Get a single channel /// /// If you need to use multiple channels, use [`Self::split`]. - pub fn channel(&mut self, channel: TimerChannel) -> OnePulseChannel<'_, T> { + pub fn channel(&mut self, channel: Channel) -> OnePulseChannel<'_, T> { OnePulseChannel { inner: unsafe { self.inner.clone_unchecked() }, channel, @@ -282,7 +282,7 @@ impl<'d, T: GeneralInstance4Channel> OnePulse<'d, T> { /// /// If you need to use multiple channels, use [`Self::split`]. pub fn ch1(&mut self) -> OnePulseChannel<'_, T> { - self.channel(TimerChannel::Ch1) + self.channel(Channel::Ch1) } /// Channel 2 @@ -291,7 +291,7 @@ impl<'d, T: GeneralInstance4Channel> OnePulse<'d, T> { /// /// If you need to use multiple channels, use [`Self::split`]. pub fn ch2(&mut self) -> OnePulseChannel<'_, T> { - self.channel(TimerChannel::Ch2) + self.channel(Channel::Ch2) } /// Channel 3 @@ -300,7 +300,7 @@ impl<'d, T: GeneralInstance4Channel> OnePulse<'d, T> { /// /// If you need to use multiple channels, use [`Self::split`]. pub fn ch3(&mut self) -> OnePulseChannel<'_, T> { - self.channel(TimerChannel::Ch3) + self.channel(Channel::Ch3) } /// Channel 4 @@ -309,7 +309,7 @@ impl<'d, T: GeneralInstance4Channel> OnePulse<'d, T> { /// /// If you need to use multiple channels, use [`Self::split`]. pub fn ch4(&mut self) -> OnePulseChannel<'_, T> { - self.channel(TimerChannel::Ch4) + self.channel(Channel::Ch4) } /// Splits a [`OnePulse`] into four output channels. @@ -328,10 +328,10 @@ impl<'d, T: GeneralInstance4Channel> OnePulse<'d, T> { }; OnePulseChannels { - ch1: ch(TimerChannel::Ch1), - ch2: ch(TimerChannel::Ch2), - ch3: ch(TimerChannel::Ch3), - ch4: ch(TimerChannel::Ch4), + ch1: ch(Channel::Ch1), + ch2: ch(Channel::Ch2), + ch3: ch(Channel::Ch3), + ch4: ch(Channel::Ch4), } } } @@ -355,7 +355,7 @@ pub struct OnePulseChannels<'d, T: GeneralInstance4Channel> { /// configuration is shared with all four channels. pub struct OnePulseChannel<'d, T: GeneralInstance4Channel> { inner: ManuallyDrop>, - channel: TimerChannel, + channel: Channel, } impl<'d, T: GeneralInstance4Channel> OnePulseChannel<'d, T> { @@ -402,7 +402,7 @@ impl<'d, T: GeneralInstance4Channel> OnePulseChannel<'d, T> { #[must_use = "futures do nothing unless you `.await` or poll them"] struct OnePulseFuture { - channel: TimerChannel, + channel: Channel, phantom: PhantomData, } diff --git a/embassy-stm32/src/timer/pwm_input.rs b/embassy-stm32/src/timer/pwm_input.rs index 3f9e5f651..2e05a0593 100644 --- a/embassy-stm32/src/timer/pwm_input.rs +++ b/embassy-stm32/src/timer/pwm_input.rs @@ -1,14 +1,14 @@ //! PWM Input driver. use super::low_level::{CountingMode, InputCaptureMode, InputTISelection, SlaveMode, Timer, TriggerSource}; -use super::{Ch1, Ch2, GeneralInstance4Channel, TimerChannel, TimerPin}; +use super::{Ch1, Ch2, GeneralInstance4Channel, Channel, TimerPin}; use crate::gpio::{AfType, Pull}; use crate::time::Hertz; use crate::Peri; /// PWM Input driver. pub struct PwmInput<'d, T: GeneralInstance4Channel> { - channel: TimerChannel, + channel: Channel, inner: Timer<'d, T>, } @@ -17,17 +17,17 @@ impl<'d, T: GeneralInstance4Channel> PwmInput<'d, T> { pub fn new(tim: Peri<'d, T>, pin: Peri<'d, impl TimerPin>, pull: Pull, freq: Hertz) -> Self { pin.set_as_af(pin.af_num(), AfType::input(pull)); - Self::new_inner(tim, freq, TimerChannel::Ch1, TimerChannel::Ch2) + Self::new_inner(tim, freq, Channel::Ch1, Channel::Ch2) } /// Create a new PWM input driver. pub fn new_alt(tim: Peri<'d, T>, pin: Peri<'d, impl TimerPin>, pull: Pull, freq: Hertz) -> Self { pin.set_as_af(pin.af_num(), AfType::input(pull)); - Self::new_inner(tim, freq, TimerChannel::Ch2, TimerChannel::Ch1) + Self::new_inner(tim, freq, Channel::Ch2, Channel::Ch1) } - fn new_inner(tim: Peri<'d, T>, freq: Hertz, ch1: TimerChannel, ch2: TimerChannel) -> Self { + fn new_inner(tim: Peri<'d, T>, freq: Hertz, ch1: Channel, ch2: Channel) -> Self { let mut inner = Timer::new(tim); inner.set_counting_mode(CountingMode::EdgeAlignedUp); @@ -44,8 +44,8 @@ impl<'d, T: GeneralInstance4Channel> PwmInput<'d, T> { inner.set_input_capture_mode(ch2, InputCaptureMode::Falling); inner.set_trigger_source(match ch1 { - TimerChannel::Ch1 => TriggerSource::TI1FP1, - TimerChannel::Ch2 => TriggerSource::TI2FP2, + Channel::Ch1 => TriggerSource::TI1FP1, + Channel::Ch2 => TriggerSource::TI2FP2, _ => panic!("Invalid channel for PWM input"), }); @@ -58,19 +58,19 @@ impl<'d, T: GeneralInstance4Channel> PwmInput<'d, T> { /// Enable the given channel. pub fn enable(&mut self) { - self.inner.enable_channel(TimerChannel::Ch1, true); - self.inner.enable_channel(TimerChannel::Ch2, true); + self.inner.enable_channel(Channel::Ch1, true); + self.inner.enable_channel(Channel::Ch2, true); } /// Disable the given channel. pub fn disable(&mut self) { - self.inner.enable_channel(TimerChannel::Ch1, false); - self.inner.enable_channel(TimerChannel::Ch2, false); + self.inner.enable_channel(Channel::Ch1, false); + self.inner.enable_channel(Channel::Ch2, false); } /// Check whether given channel is enabled pub fn is_enabled(&self) -> bool { - self.inner.get_channel_enable_state(TimerChannel::Ch1) + self.inner.get_channel_enable_state(Channel::Ch1) } /// Get the period tick count @@ -81,8 +81,8 @@ impl<'d, T: GeneralInstance4Channel> PwmInput<'d, T> { /// Get the pulse width tick count pub fn get_width_ticks(&self) -> u32 { self.inner.get_capture_value(match self.channel { - TimerChannel::Ch1 => TimerChannel::Ch2, - TimerChannel::Ch2 => TimerChannel::Ch1, + Channel::Ch1 => Channel::Ch2, + Channel::Ch2 => Channel::Ch1, _ => panic!("Invalid channel for PWM input"), }) } diff --git a/embassy-stm32/src/timer/qei.rs b/embassy-stm32/src/timer/qei.rs index 657052cfa..eabe1b22a 100644 --- a/embassy-stm32/src/timer/qei.rs +++ b/embassy-stm32/src/timer/qei.rs @@ -8,7 +8,7 @@ use super::low_level::Timer; pub use super::{Ch1, Ch2}; use super::{GeneralInstance4Channel, TimerPin}; use crate::gpio::{AfType, AnyPin, Pull}; -use crate::timer::Channel; +use crate::timer::TimerChannel; use crate::Peri; /// Counting direction @@ -39,7 +39,7 @@ impl<'d, T: GeneralInstance4Channel, C: QeiChannel> QeiPin<'d, T, C> { } } -trait SealedQeiChannel: Channel {} +trait SealedQeiChannel: TimerChannel {} /// Marker trait for a timer channel eligible for use with QEI. #[expect(private_bounds)] diff --git a/embassy-stm32/src/timer/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs index 02835c379..c04b1ab97 100644 --- a/embassy-stm32/src/timer/simple_pwm.rs +++ b/embassy-stm32/src/timer/simple_pwm.rs @@ -4,7 +4,7 @@ use core::marker::PhantomData; use core::mem::ManuallyDrop; use super::low_level::{CountingMode, OutputCompareMode, OutputPolarity, Timer}; -use super::{Ch1, Ch2, Ch3, Ch4, GeneralInstance4Channel, TimerBits, TimerChannel, TimerPin}; +use super::{Ch1, Ch2, Ch3, Ch4, Channel, GeneralInstance4Channel, TimerBits, TimerChannel, TimerPin}; #[cfg(gpio_v2)] use crate::gpio::Pull; use crate::gpio::{AfType, AnyPin, OutputType, Speed}; @@ -34,46 +34,37 @@ pub struct PwmPinConfig { pub pull: Pull, } -macro_rules! channel_impl { - ($new_chx:ident, $new_chx_with_config:ident, $channel:ident, $pin_trait:ident) => { - impl<'d, T: GeneralInstance4Channel> PwmPin<'d, T, $channel> { - #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance.")] - pub fn $new_chx(pin: Peri<'d, impl $pin_trait>, output_type: OutputType) -> Self { - critical_section::with(|_| { - pin.set_low(); - pin.set_as_af(pin.af_num(), AfType::output(output_type, Speed::VeryHigh)); - }); - PwmPin { - _pin: pin.into(), - phantom: PhantomData, - } - } - - #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance with config.")] - pub fn $new_chx_with_config(pin: Peri<'d, impl $pin_trait>, pin_config: PwmPinConfig) -> Self { - critical_section::with(|_| { - pin.set_low(); - pin.set_as_af( - pin.af_num(), - #[cfg(gpio_v1)] - AfType::output(pin_config.output_type, pin_config.speed), - #[cfg(gpio_v2)] - AfType::output_pull(pin_config.output_type, pin_config.speed, pin_config.pull), - ); - }); - PwmPin { - _pin: pin.into(), - phantom: PhantomData, - } - } +impl<'d, T: GeneralInstance4Channel, C: TimerChannel> PwmPin<'d, T, C> { + /// Create a new PWM pin instance. + pub fn new(pin: Peri<'d, impl TimerPin>, output_type: OutputType) -> Self { + critical_section::with(|_| { + pin.set_low(); + pin.set_as_af(pin.af_num(), AfType::output(output_type, Speed::VeryHigh)); + }); + PwmPin { + _pin: pin.into(), + phantom: PhantomData, } - }; -} + } -channel_impl!(new_ch1, new_ch1_with_config, Ch1, TimerPin); -channel_impl!(new_ch2, new_ch2_with_config, Ch2, TimerPin); -channel_impl!(new_ch3, new_ch3_with_config, Ch3, TimerPin); -channel_impl!(new_ch4, new_ch4_with_config, Ch4, TimerPin); + /// Create a new PWM pin instance with config. + pub fn new_with_config(pin: Peri<'d, impl TimerPin>, pin_config: PwmPinConfig) -> Self { + critical_section::with(|_| { + pin.set_low(); + pin.set_as_af( + pin.af_num(), + #[cfg(gpio_v1)] + AfType::output(pin_config.output_type, pin_config.speed), + #[cfg(gpio_v2)] + AfType::output_pull(pin_config.output_type, pin_config.speed, pin_config.pull), + ); + }); + PwmPin { + _pin: pin.into(), + phantom: PhantomData, + } + } +} /// A single channel of a pwm, obtained from [`SimplePwm::split`], /// [`SimplePwm::channel`], [`SimplePwm::ch1`], etc. @@ -82,7 +73,7 @@ channel_impl!(new_ch4, new_ch4_with_config, Ch4, TimerPin); /// the frequency configuration is shared with all four channels. pub struct SimplePwmChannel<'d, T: GeneralInstance4Channel> { timer: ManuallyDrop>, - channel: TimerChannel, + channel: Channel, } // TODO: check for RMW races @@ -207,18 +198,13 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { this.inner.enable_outputs(); // Required for advanced timers, see GeneralInstance4Channel for details this.inner.start(); - [ - TimerChannel::Ch1, - TimerChannel::Ch2, - TimerChannel::Ch3, - TimerChannel::Ch4, - ] - .iter() - .for_each(|&channel| { - this.inner.set_output_compare_mode(channel, OutputCompareMode::PwmMode1); - - this.inner.set_output_compare_preload(channel, true); - }); + [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); + }); this } @@ -226,7 +212,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { /// Get a single channel /// /// If you need to use multiple channels, use [`Self::split`]. - pub fn channel(&mut self, channel: TimerChannel) -> SimplePwmChannel<'_, T> { + pub fn channel(&mut self, channel: Channel) -> SimplePwmChannel<'_, T> { SimplePwmChannel { timer: unsafe { self.inner.clone_unchecked() }, channel, @@ -239,7 +225,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { /// /// If you need to use multiple channels, use [`Self::split`]. pub fn ch1(&mut self) -> SimplePwmChannel<'_, T> { - self.channel(TimerChannel::Ch1) + self.channel(Channel::Ch1) } /// Channel 2 @@ -248,7 +234,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { /// /// If you need to use multiple channels, use [`Self::split`]. pub fn ch2(&mut self) -> SimplePwmChannel<'_, T> { - self.channel(TimerChannel::Ch2) + self.channel(Channel::Ch2) } /// Channel 3 @@ -257,7 +243,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { /// /// If you need to use multiple channels, use [`Self::split`]. pub fn ch3(&mut self) -> SimplePwmChannel<'_, T> { - self.channel(TimerChannel::Ch3) + self.channel(Channel::Ch3) } /// Channel 4 @@ -266,7 +252,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { /// /// If you need to use multiple channels, use [`Self::split`]. pub fn ch4(&mut self) -> SimplePwmChannel<'_, T> { - self.channel(TimerChannel::Ch4) + self.channel(Channel::Ch4) } /// Splits a [`SimplePwm`] into four pwm channels. @@ -288,10 +274,10 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { }; SimplePwmChannels { - ch1: ch(TimerChannel::Ch1), - ch2: ch(TimerChannel::Ch2), - ch3: ch(TimerChannel::Ch3), - ch4: ch(TimerChannel::Ch4), + ch1: ch(Channel::Ch1), + ch2: ch(Channel::Ch2), + ch3: ch(Channel::Ch3), + ch4: ch(Channel::Ch4), } } @@ -322,7 +308,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { /// /// Note: /// you will need to provide corresponding TIMx_UP DMA channel to use this method. - pub async fn waveform_up(&mut self, dma: Peri<'_, impl super::UpDma>, channel: TimerChannel, duty: &[u16]) { + pub async fn waveform_up(&mut self, dma: Peri<'_, impl super::UpDma>, channel: Channel, duty: &[u16]) { #[allow(clippy::let_unit_value)] // eg. stm32f334 let req = dma.request(); @@ -405,8 +391,8 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { pub async fn waveform_up_multi_channel( &mut self, dma: Peri<'_, impl super::UpDma>, - starting_channel: TimerChannel, - ending_channel: TimerChannel, + starting_channel: Channel, + ending_channel: Channel, duty: &[u16], ) { let cr1_addr = self.inner.regs_gp16().cr1().as_ptr() as u32; @@ -462,106 +448,97 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { } } -macro_rules! impl_waveform_chx { - ($fn_name:ident, $dma_ch:ident, $cc_ch:ident) => { - impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { - /// Generate a sequence of PWM waveform - pub async fn $fn_name(&mut self, dma: Peri<'_, impl super::$dma_ch>, duty: &[u16]) { - use crate::pac::timer::vals::Ccds; +impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { + /// Generate a sequence of PWM waveform + pub async fn waveform(&mut self, dma: Peri<'_, impl super::Dma>, duty: &[u16]) { + use crate::pac::timer::vals::Ccds; - #[allow(clippy::let_unit_value)] // eg. stm32f334 - let req = dma.request(); + #[allow(clippy::let_unit_value)] // eg. stm32f334 + let req = dma.request(); - let cc_channel = TimerChannel::$cc_ch; + let cc_channel = C::CHANNEL; - let original_duty_state = self.channel(cc_channel).current_duty_cycle(); - let original_enable_state = self.channel(cc_channel).is_enabled(); - let original_cc_dma_on_update = self.inner.get_cc_dma_selection() == Ccds::ON_UPDATE; - let original_cc_dma_enabled = self.inner.get_cc_dma_enable_state(cc_channel); + let original_duty_state = self.channel(cc_channel).current_duty_cycle(); + let original_enable_state = self.channel(cc_channel).is_enabled(); + let original_cc_dma_on_update = self.inner.get_cc_dma_selection() == Ccds::ON_UPDATE; + let original_cc_dma_enabled = self.inner.get_cc_dma_enable_state(cc_channel); - // redirect CC DMA request onto Update Event - if !original_cc_dma_on_update { - self.inner.set_cc_dma_selection(Ccds::ON_UPDATE) - } + // redirect CC DMA request onto Update Event + if !original_cc_dma_on_update { + self.inner.set_cc_dma_selection(Ccds::ON_UPDATE) + } - if !original_cc_dma_enabled { - self.inner.set_cc_dma_enable_state(cc_channel, true); - } + if !original_cc_dma_enabled { + self.inner.set_cc_dma_enable_state(cc_channel, true); + } - if !original_enable_state { - self.channel(cc_channel).enable(); - } + if !original_enable_state { + self.channel(cc_channel).enable(); + } - unsafe { + unsafe { + #[cfg(not(any(bdma, gpdma)))] + use crate::dma::{Burst, FifoThreshold}; + use crate::dma::{Transfer, TransferOptions}; + + let dma_transfer_option = TransferOptions { + #[cfg(not(any(bdma, gpdma)))] + fifo_threshold: Some(FifoThreshold::Full), + #[cfg(not(any(bdma, gpdma)))] + mburst: Burst::Incr8, + ..Default::default() + }; + + match self.inner.bits() { + TimerBits::Bits16 => { + Transfer::new_write( + dma, + req, + duty, + self.inner.regs_gp16().ccr(cc_channel.index()).as_ptr() as *mut u16, + dma_transfer_option, + ) + .await + } + #[cfg(not(any(stm32l0)))] + TimerBits::Bits32 => { #[cfg(not(any(bdma, gpdma)))] - use crate::dma::{Burst, FifoThreshold}; - use crate::dma::{Transfer, TransferOptions}; - - let dma_transfer_option = TransferOptions { - #[cfg(not(any(bdma, gpdma)))] - fifo_threshold: Some(FifoThreshold::Full), - #[cfg(not(any(bdma, gpdma)))] - mburst: Burst::Incr8, - ..Default::default() - }; - - match self.inner.bits() { - TimerBits::Bits16 => { - Transfer::new_write( - dma, - req, - duty, - self.inner.regs_gp16().ccr(cc_channel.index()).as_ptr() as *mut u16, - dma_transfer_option, - ) - .await - } - #[cfg(not(any(stm32l0)))] - TimerBits::Bits32 => { - #[cfg(not(any(bdma, gpdma)))] - panic!("unsupported timer bits"); - - #[cfg(any(bdma, gpdma))] - Transfer::new_write( - dma, - req, - duty, - self.inner.regs_gp16().ccr(cc_channel.index()).as_ptr() as *mut u32, - dma_transfer_option, - ) - .await - } - }; - }; - - // restore output compare state - if !original_enable_state { - self.channel(cc_channel).disable(); + panic!("unsupported timer bits"); + + #[cfg(any(bdma, gpdma))] + Transfer::new_write( + dma, + req, + duty, + self.inner.regs_gp16().ccr(cc_channel.index()).as_ptr() as *mut u32, + dma_transfer_option, + ) + .await } + }; + }; - self.channel(cc_channel).set_duty_cycle(original_duty_state); + // restore output compare state + if !original_enable_state { + self.channel(cc_channel).disable(); + } - // Since DMA is closed before timer Capture Compare Event trigger DMA is turn off, - // this can almost always trigger a DMA FIFO error. - // - // optional TODO: - // clean FEIF after disable UDE - if !original_cc_dma_enabled { - self.inner.set_cc_dma_enable_state(cc_channel, false); - } + self.channel(cc_channel).set_duty_cycle(original_duty_state); - if !original_cc_dma_on_update { - self.inner.set_cc_dma_selection(Ccds::ON_COMPARE) - } - } + // Since DMA is closed before timer Capture Compare Event trigger DMA is turn off, + // this can almost always trigger a DMA FIFO error. + // + // optional TODO: + // clean FEIF after disable UDE + if !original_cc_dma_enabled { + self.inner.set_cc_dma_enable_state(cc_channel, false); } - }; -} -impl_waveform_chx!(waveform_ch1, Dma, Ch1); -impl_waveform_chx!(waveform_ch2, Dma, Ch2); -impl_waveform_chx!(waveform_ch3, Dma, Ch3); -impl_waveform_chx!(waveform_ch4, Dma, Ch4); + if !original_cc_dma_on_update { + self.inner.set_cc_dma_selection(Ccds::ON_COMPARE) + } + } +} impl<'d, T: GeneralInstance4Channel> embedded_hal_1::pwm::ErrorType for SimplePwmChannel<'d, T> { type Error = core::convert::Infallible; @@ -599,7 +576,7 @@ impl<'d, T: GeneralInstance4Channel> embedded_hal_1::pwm::SetDutyCycle for Simpl } impl<'d, T: GeneralInstance4Channel> embedded_hal_02::Pwm for SimplePwm<'d, T> { - type Channel = TimerChannel; + type Channel = Channel; type Time = Hertz; type Duty = u32; -- cgit From 41327c1325367177548dabc644636617274de7f4 Mon Sep 17 00:00:00 2001 From: melvdl Date: Fri, 27 Jun 2025 01:08:45 +0200 Subject: stm32: adapt examples to timer API changes --- examples/stm32f1/src/bin/input_capture.rs | 2 +- examples/stm32f4/src/bin/input_capture.rs | 2 +- examples/stm32f4/src/bin/pwm.rs | 2 +- examples/stm32f4/src/bin/pwm_complementary.rs | 4 ++-- examples/stm32f4/src/bin/ws2812_pwm.rs | 2 +- examples/stm32g0/src/bin/hf_timer.rs | 4 ++-- examples/stm32g0/src/bin/input_capture.rs | 4 ++-- examples/stm32g0/src/bin/pwm_complementary.rs | 8 ++++---- examples/stm32g0/src/bin/pwm_input.rs | 2 +- examples/stm32g4/src/bin/pwm.rs | 2 +- examples/stm32h7/src/bin/low_level_timer_api.rs | 10 +++++----- examples/stm32h7/src/bin/pwm.rs | 2 +- examples/stm32l0/src/bin/dds.rs | 4 ++-- 13 files changed, 24 insertions(+), 24 deletions(-) diff --git a/examples/stm32f1/src/bin/input_capture.rs b/examples/stm32f1/src/bin/input_capture.rs index 6fe8e0b50..84811fb95 100644 --- a/examples/stm32f1/src/bin/input_capture.rs +++ b/examples/stm32f1/src/bin/input_capture.rs @@ -39,7 +39,7 @@ async fn main(spawner: Spawner) { unwrap!(spawner.spawn(blinky(p.PC13))); - let ch3 = CapturePin::new_ch3(p.PA2, Pull::None); + let ch3 = CapturePin::new(p.PA2, Pull::None); let mut ic = InputCapture::new(p.TIM2, None, None, Some(ch3), None, Irqs, khz(1000), Default::default()); loop { diff --git a/examples/stm32f4/src/bin/input_capture.rs b/examples/stm32f4/src/bin/input_capture.rs index fe5e2bdfc..e15b4d26e 100644 --- a/examples/stm32f4/src/bin/input_capture.rs +++ b/examples/stm32f4/src/bin/input_capture.rs @@ -39,7 +39,7 @@ async fn main(spawner: Spawner) { unwrap!(spawner.spawn(blinky(p.PB2))); - let ch3 = CapturePin::new_ch3(p.PB10, Pull::None); + let ch3 = CapturePin::new(p.PB10, Pull::None); let mut ic = InputCapture::new(p.TIM2, None, None, Some(ch3), None, Irqs, khz(1000), Default::default()); loop { diff --git a/examples/stm32f4/src/bin/pwm.rs b/examples/stm32f4/src/bin/pwm.rs index 04811162b..e385842f0 100644 --- a/examples/stm32f4/src/bin/pwm.rs +++ b/examples/stm32f4/src/bin/pwm.rs @@ -14,7 +14,7 @@ async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let ch1_pin = PwmPin::new_ch1(p.PE9, OutputType::PushPull); + let ch1_pin = PwmPin::new(p.PE9, OutputType::PushPull); let mut pwm = SimplePwm::new(p.TIM1, Some(ch1_pin), None, None, None, khz(10), Default::default()); let mut ch1 = pwm.ch1(); ch1.enable(); diff --git a/examples/stm32f4/src/bin/pwm_complementary.rs b/examples/stm32f4/src/bin/pwm_complementary.rs index 161f43c48..c981f1a76 100644 --- a/examples/stm32f4/src/bin/pwm_complementary.rs +++ b/examples/stm32f4/src/bin/pwm_complementary.rs @@ -16,8 +16,8 @@ async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let ch1 = PwmPin::new_ch1(p.PE9, OutputType::PushPull); - let ch1n = ComplementaryPwmPin::new_ch1(p.PA7, OutputType::PushPull); + let ch1 = PwmPin::new(p.PE9, OutputType::PushPull); + let ch1n = ComplementaryPwmPin::new(p.PA7, OutputType::PushPull); let mut pwm = ComplementaryPwm::new( p.TIM1, Some(ch1), diff --git a/examples/stm32f4/src/bin/ws2812_pwm.rs b/examples/stm32f4/src/bin/ws2812_pwm.rs index ca924e181..5153e1cfd 100644 --- a/examples/stm32f4/src/bin/ws2812_pwm.rs +++ b/examples/stm32f4/src/bin/ws2812_pwm.rs @@ -50,7 +50,7 @@ async fn main(_spawner: Spawner) { let mut ws2812_pwm = SimplePwm::new( dp.TIM3, - Some(PwmPin::new_ch1(dp.PB4, OutputType::PushPull)), + Some(PwmPin::new(dp.PB4, OutputType::PushPull)), None, None, None, diff --git a/examples/stm32g0/src/bin/hf_timer.rs b/examples/stm32g0/src/bin/hf_timer.rs index dfb6e0edc..705905f01 100644 --- a/examples/stm32g0/src/bin/hf_timer.rs +++ b/examples/stm32g0/src/bin/hf_timer.rs @@ -37,8 +37,8 @@ async fn main(_spawner: Spawner) { } let p = embassy_stm32::init(config); - let ch1 = PwmPin::new_ch1(p.PA8, OutputType::PushPull); - let ch1n = ComplementaryPwmPin::new_ch1(p.PA7, OutputType::PushPull); + let ch1 = PwmPin::new(p.PA8, OutputType::PushPull); + let ch1n = ComplementaryPwmPin::new(p.PA7, OutputType::PushPull); let mut pwm = ComplementaryPwm::new( p.TIM1, diff --git a/examples/stm32g0/src/bin/input_capture.rs b/examples/stm32g0/src/bin/input_capture.rs index 08df4e043..df339d541 100644 --- a/examples/stm32g0/src/bin/input_capture.rs +++ b/examples/stm32g0/src/bin/input_capture.rs @@ -47,12 +47,12 @@ async fn main(spawner: Spawner) { unwrap!(spawner.spawn(blinky(p.PB1))); // Connect PB1 and PA8 with a 1k Ohm resistor - let ch1_pin = PwmPin::new_ch1(p.PA8, OutputType::PushPull); + let ch1_pin = PwmPin::new(p.PA8, OutputType::PushPull); let mut pwm = SimplePwm::new(p.TIM1, Some(ch1_pin), None, None, None, khz(1), Default::default()); pwm.ch1().enable(); pwm.ch1().set_duty_cycle(50); - let ch1 = CapturePin::new_ch1(p.PA0, Pull::None); + let ch1 = CapturePin::new(p.PA0, Pull::None); let mut ic = InputCapture::new(p.TIM2, Some(ch1), None, None, None, Irqs, khz(1000), Default::default()); let mut old_capture = 0; diff --git a/examples/stm32g0/src/bin/pwm_complementary.rs b/examples/stm32g0/src/bin/pwm_complementary.rs index 97b163c40..dbd9194c9 100644 --- a/examples/stm32g0/src/bin/pwm_complementary.rs +++ b/examples/stm32g0/src/bin/pwm_complementary.rs @@ -26,10 +26,10 @@ use {defmt_rtt as _, panic_probe as _}; async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); - let ch1 = PwmPin::new_ch1(p.PA8, OutputType::PushPull); - let ch1n = ComplementaryPwmPin::new_ch1(p.PA7, OutputType::PushPull); - let ch2 = PwmPin::new_ch2(p.PB3, OutputType::PushPull); - let ch2n = ComplementaryPwmPin::new_ch2(p.PB0, OutputType::PushPull); + let ch1 = PwmPin::new(p.PA8, OutputType::PushPull); + let ch1n = ComplementaryPwmPin::new(p.PA7, OutputType::PushPull); + let ch2 = PwmPin::new(p.PB3, OutputType::PushPull); + let ch2n = ComplementaryPwmPin::new(p.PB0, OutputType::PushPull); let mut pwm = ComplementaryPwm::new( p.TIM1, diff --git a/examples/stm32g0/src/bin/pwm_input.rs b/examples/stm32g0/src/bin/pwm_input.rs index 9d6b5fe97..dc2428607 100644 --- a/examples/stm32g0/src/bin/pwm_input.rs +++ b/examples/stm32g0/src/bin/pwm_input.rs @@ -42,7 +42,7 @@ async fn main(spawner: Spawner) { unwrap!(spawner.spawn(blinky(p.PB1))); // Connect PA8 and PA6 with a 1k Ohm resistor - let ch1_pin = PwmPin::new_ch1(p.PA8, OutputType::PushPull); + let ch1_pin = PwmPin::new(p.PA8, OutputType::PushPull); let mut pwm = SimplePwm::new(p.TIM1, Some(ch1_pin), None, None, None, khz(1), Default::default()); pwm.ch1().set_duty_cycle_fraction(1, 4); pwm.ch1().enable(); diff --git a/examples/stm32g4/src/bin/pwm.rs b/examples/stm32g4/src/bin/pwm.rs index 6c965012c..5b4194927 100644 --- a/examples/stm32g4/src/bin/pwm.rs +++ b/examples/stm32g4/src/bin/pwm.rs @@ -14,7 +14,7 @@ async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let ch1_pin = PwmPin::new_ch1(p.PC0, OutputType::PushPull); + let ch1_pin = PwmPin::new(p.PC0, OutputType::PushPull); let mut pwm = SimplePwm::new(p.TIM1, Some(ch1_pin), None, None, None, khz(10), Default::default()); let mut ch1 = pwm.ch1(); ch1.enable(); diff --git a/examples/stm32h7/src/bin/low_level_timer_api.rs b/examples/stm32h7/src/bin/low_level_timer_api.rs index 8de31ea5b..12abb8693 100644 --- a/examples/stm32h7/src/bin/low_level_timer_api.rs +++ b/examples/stm32h7/src/bin/low_level_timer_api.rs @@ -6,7 +6,7 @@ use embassy_executor::Spawner; use embassy_stm32::gpio::{AfType, Flex, OutputType, Speed}; use embassy_stm32::time::{khz, Hertz}; use embassy_stm32::timer::low_level::{OutputCompareMode, Timer as LLTimer}; -use embassy_stm32::timer::{Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, GeneralInstance32bit4Channel}; +use embassy_stm32::timer::{Ch1, Ch2, Ch3, Ch4, Channel, GeneralInstance32bit4Channel, TimerPin}; use embassy_stm32::{Config, Peri}; use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; @@ -67,10 +67,10 @@ pub struct SimplePwm32<'d, T: GeneralInstance32bit4Channel> { impl<'d, T: GeneralInstance32bit4Channel> SimplePwm32<'d, T> { pub fn new( tim: Peri<'d, T>, - ch1: Peri<'d, impl Channel1Pin>, - ch2: Peri<'d, impl Channel2Pin>, - ch3: Peri<'d, impl Channel3Pin>, - ch4: Peri<'d, impl Channel4Pin>, + ch1: Peri<'d, impl TimerPin>, + ch2: Peri<'d, impl TimerPin>, + ch3: Peri<'d, impl TimerPin>, + ch4: Peri<'d, impl TimerPin>, freq: Hertz, ) -> Self { let af1 = ch1.af_num(); diff --git a/examples/stm32h7/src/bin/pwm.rs b/examples/stm32h7/src/bin/pwm.rs index a1c53fc3f..73b43be69 100644 --- a/examples/stm32h7/src/bin/pwm.rs +++ b/examples/stm32h7/src/bin/pwm.rs @@ -36,7 +36,7 @@ async fn main(_spawner: Spawner) { let p = embassy_stm32::init(config); info!("Hello World!"); - let ch1_pin = PwmPin::new_ch1(p.PA6, OutputType::PushPull); + let ch1_pin = PwmPin::new(p.PA6, OutputType::PushPull); let mut pwm = SimplePwm::new(p.TIM3, Some(ch1_pin), None, None, None, khz(10), Default::default()); let mut ch1 = pwm.ch1(); ch1.enable(); diff --git a/examples/stm32l0/src/bin/dds.rs b/examples/stm32l0/src/bin/dds.rs index a54b28a93..eaa7a61a8 100644 --- a/examples/stm32l0/src/bin/dds.rs +++ b/examples/stm32l0/src/bin/dds.rs @@ -11,7 +11,7 @@ use embassy_stm32::rcc::*; use embassy_stm32::time::hz; use embassy_stm32::timer::low_level::{Timer as LLTimer, *}; use embassy_stm32::timer::simple_pwm::PwmPin; -use embassy_stm32::timer::Channel; +use embassy_stm32::timer::{Ch3, Channel}; use embassy_stm32::{interrupt, pac, Config}; use panic_probe as _; @@ -70,7 +70,7 @@ async fn main(_spawner: Spawner) { let p = embassy_stm32::init(config); // setup PWM pin in AF mode - let _ch3 = PwmPin::new_ch3(p.PA2, OutputType::PushPull); + let _ch3 = PwmPin::<_, Ch3>::new(p.PA2, OutputType::PushPull); // initialize timer // we cannot use SimplePWM here because the Time is privately encapsulated -- cgit From 2727fb266fa7d87b4fa23f7278e5255ca260fd14 Mon Sep 17 00:00:00 2001 From: melvdl Date: Fri, 27 Jun 2025 01:28:47 +0200 Subject: run cargo fmt --- embassy-stm32/src/timer/input_capture.rs | 2 +- embassy-stm32/src/timer/pwm_input.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/embassy-stm32/src/timer/input_capture.rs b/embassy-stm32/src/timer/input_capture.rs index 49e22b10f..dda33e7f1 100644 --- a/embassy-stm32/src/timer/input_capture.rs +++ b/embassy-stm32/src/timer/input_capture.rs @@ -6,7 +6,7 @@ use core::pin::Pin; use core::task::{Context, Poll}; use super::low_level::{CountingMode, FilterValue, InputCaptureMode, InputTISelection, Timer}; -use super::{CaptureCompareInterruptHandler, GeneralInstance4Channel, Channel, TimerPin}; +use super::{CaptureCompareInterruptHandler, Channel, GeneralInstance4Channel, TimerPin}; pub use super::{Ch1, Ch2, Ch3, Ch4}; use crate::gpio::{AfType, AnyPin, Pull}; use crate::interrupt::typelevel::{Binding, Interrupt}; diff --git a/embassy-stm32/src/timer/pwm_input.rs b/embassy-stm32/src/timer/pwm_input.rs index 2e05a0593..99afb5582 100644 --- a/embassy-stm32/src/timer/pwm_input.rs +++ b/embassy-stm32/src/timer/pwm_input.rs @@ -1,7 +1,7 @@ //! PWM Input driver. use super::low_level::{CountingMode, InputCaptureMode, InputTISelection, SlaveMode, Timer, TriggerSource}; -use super::{Ch1, Ch2, GeneralInstance4Channel, Channel, TimerPin}; +use super::{Ch1, Ch2, Channel, GeneralInstance4Channel, TimerPin}; use crate::gpio::{AfType, Pull}; use crate::time::Hertz; use crate::Peri; -- cgit