aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormelvdl <[email protected]>2025-06-26 19:35:19 +0200
committermelvdl <[email protected]>2025-06-26 19:35:19 +0200
commit3e78f8a108c031f992116808b66c5e6c760c2c9e (patch)
treef31b228bc4528aea224bc49565a859abffc93fcf
parent06b160ac83b70b292ea92446a1eb69096b1c86ea (diff)
stm32: generify timer channels
-rw-r--r--embassy-stm32/build.rs36
-rw-r--r--embassy-stm32/src/timer/complementary_pwm.rs72
-rw-r--r--embassy-stm32/src/timer/input_capture.rs67
-rw-r--r--embassy-stm32/src/timer/low_level.rs38
-rw-r--r--embassy-stm32/src/timer/mod.rs111
-rw-r--r--embassy-stm32/src/timer/one_pulse.rs88
-rw-r--r--embassy-stm32/src/timer/pwm_input.rs32
-rw-r--r--embassy-stm32/src/timer/qei.rs10
-rw-r--r--embassy-stm32/src/timer/simple_pwm.rs80
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() {
1090 (("fmc", "CLK"), quote!(crate::fmc::ClkPin)), 1090 (("fmc", "CLK"), quote!(crate::fmc::ClkPin)),
1091 (("fmc", "BA0"), quote!(crate::fmc::BA0Pin)), 1091 (("fmc", "BA0"), quote!(crate::fmc::BA0Pin)),
1092 (("fmc", "BA1"), quote!(crate::fmc::BA1Pin)), 1092 (("fmc", "BA1"), quote!(crate::fmc::BA1Pin)),
1093 (("timer", "CH1"), quote!(crate::timer::Channel1Pin)), 1093 (("timer", "CH1"), quote!(crate::timer::TimerPin<Ch1>)),
1094 (("timer", "CH1N"), quote!(crate::timer::Channel1ComplementaryPin)), 1094 (("timer", "CH1N"), quote!(crate::timer::TimerComplementaryPin<Ch1>)),
1095 (("timer", "CH2"), quote!(crate::timer::Channel2Pin)), 1095 (("timer", "CH2"), quote!(crate::timer::TimerPin<Ch2>)),
1096 (("timer", "CH2N"), quote!(crate::timer::Channel2ComplementaryPin)), 1096 (("timer", "CH2N"), quote!(crate::timer::TimerComplementaryPin<Ch2>)),
1097 (("timer", "CH3"), quote!(crate::timer::Channel3Pin)), 1097 (("timer", "CH3"), quote!(crate::timer::TimerPin<Ch3>)),
1098 (("timer", "CH3N"), quote!(crate::timer::Channel3ComplementaryPin)), 1098 (("timer", "CH3N"), quote!(crate::timer::TimerComplementaryPin<Ch3>)),
1099 (("timer", "CH4"), quote!(crate::timer::Channel4Pin)), 1099 (("timer", "CH4"), quote!(crate::timer::TimerPin<Ch4>)),
1100 (("timer", "CH4N"), quote!(crate::timer::Channel4ComplementaryPin)), 1100 (("timer", "CH4N"), quote!(crate::timer::TimerComplementaryPin<Ch4>)),
1101 (("timer", "ETR"), quote!(crate::timer::ExternalTriggerPin)), 1101 (("timer", "ETR"), quote!(crate::timer::ExternalTriggerPin)),
1102 (("timer", "BKIN"), quote!(crate::timer::BreakInputPin)), 1102 (("timer", "BKIN"), quote!(crate::timer::BreakInputPin<BkIn1>)),
1103 (("timer", "BKIN_COMP1"), quote!(crate::timer::BreakInputComparator1Pin)), 1103 (("timer", "BKIN_COMP1"), quote!(crate::timer::BreakInputComparator1Pin<BkIn1>)),
1104 (("timer", "BKIN_COMP2"), quote!(crate::timer::BreakInputComparator2Pin)), 1104 (("timer", "BKIN_COMP2"), quote!(crate::timer::BreakInputComparator2Pin<BkIn1>)),
1105 (("timer", "BKIN2"), quote!(crate::timer::BreakInput2Pin)), 1105 (("timer", "BKIN2"), quote!(crate::timer::BreakInputPin<BkIn2>)),
1106 (("timer", "BKIN2_COMP1"), quote!(crate::timer::BreakInput2Comparator1Pin)), 1106 (("timer", "BKIN2_COMP1"), quote!(crate::timer::BreakInput2Comparator1Pin<BkIn2>)),
1107 (("timer", "BKIN2_COMP2"), quote!(crate::timer::BreakInput2Comparator2Pin)), 1107 (("timer", "BKIN2_COMP2"), quote!(crate::timer::BreakInput2Comparator2Pin<BkIn2>)),
1108 (("hrtim", "CHA1"), quote!(crate::hrtim::ChannelAPin)), 1108 (("hrtim", "CHA1"), quote!(crate::hrtim::ChannelAPin)),
1109 (("hrtim", "CHA2"), quote!(crate::hrtim::ChannelAComplementaryPin)), 1109 (("hrtim", "CHA2"), quote!(crate::hrtim::ChannelAComplementaryPin)),
1110 (("hrtim", "CHB1"), quote!(crate::hrtim::ChannelBPin)), 1110 (("hrtim", "CHB1"), quote!(crate::hrtim::ChannelBPin)),
@@ -1475,10 +1475,10 @@ fn main() {
1475 (("hash", "IN"), quote!(crate::hash::Dma)), 1475 (("hash", "IN"), quote!(crate::hash::Dma)),
1476 (("cryp", "IN"), quote!(crate::cryp::DmaIn)), 1476 (("cryp", "IN"), quote!(crate::cryp::DmaIn)),
1477 (("cryp", "OUT"), quote!(crate::cryp::DmaOut)), 1477 (("cryp", "OUT"), quote!(crate::cryp::DmaOut)),
1478 (("timer", "CH1"), quote!(crate::timer::Ch1Dma)), 1478 (("timer", "CH1"), quote!(crate::timer::Dma<Ch1>)),
1479 (("timer", "CH2"), quote!(crate::timer::Ch2Dma)), 1479 (("timer", "CH2"), quote!(crate::timer::Dma<Ch2>)),
1480 (("timer", "CH3"), quote!(crate::timer::Ch3Dma)), 1480 (("timer", "CH3"), quote!(crate::timer::Dma<Ch3>)),
1481 (("timer", "CH4"), quote!(crate::timer::Ch4Dma)), 1481 (("timer", "CH4"), quote!(crate::timer::Dma<Ch4>)),
1482 (("cordic", "WRITE"), quote!(crate::cordic::WriteDma)), // FIXME: stm32u5a crash on Cordic driver 1482 (("cordic", "WRITE"), quote!(crate::cordic::WriteDma)), // FIXME: stm32u5a crash on Cordic driver
1483 (("cordic", "READ"), quote!(crate::cordic::ReadDma)), // FIXME: stm32u5a crash on Cordic driver 1483 (("cordic", "READ"), quote!(crate::cordic::ReadDma)), // FIXME: stm32u5a crash on Cordic driver
1484 ] 1484 ]
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;
5use stm32_metapac::timer::vals::Ckd; 5use stm32_metapac::timer::vals::Ckd;
6 6
7use super::low_level::{CountingMode, OutputPolarity, Timer}; 7use super::low_level::{CountingMode, OutputPolarity, Timer};
8use super::simple_pwm::{Ch1, Ch2, Ch3, Ch4, PwmPin}; 8use super::simple_pwm::PwmPin;
9use super::{ 9use super::{AdvancedInstance4Channel, Ch1, Ch2, Ch3, Ch4, TimerChannel, TimerComplementaryPin};
10 AdvancedInstance4Channel, Channel, Channel1ComplementaryPin, Channel2ComplementaryPin, Channel3ComplementaryPin,
11 Channel4ComplementaryPin,
12};
13use crate::gpio::{AnyPin, OutputType}; 10use crate::gpio::{AnyPin, OutputType};
14use crate::time::Hertz; 11use crate::time::Hertz;
15use crate::timer::low_level::OutputCompareMode; 12use crate::timer::low_level::OutputCompareMode;
13use crate::timer::Channel;
16use crate::Peri; 14use crate::Peri;
17 15
18/// Complementary PWM pin wrapper. 16/// Complementary PWM pin wrapper.
@@ -23,32 +21,23 @@ pub struct ComplementaryPwmPin<'d, T, C> {
23 phantom: PhantomData<(T, C)>, 21 phantom: PhantomData<(T, C)>,
24} 22}
25 23
26macro_rules! complementary_channel_impl { 24impl<'d, T: AdvancedInstance4Channel, C: Channel> ComplementaryPwmPin<'d, T, C> {
27 ($new_chx:ident, $channel:ident, $pin_trait:ident) => { 25 /// Create a new complementary PWM pin instance.
28 impl<'d, T: AdvancedInstance4Channel> ComplementaryPwmPin<'d, T, $channel> { 26 pub fn new(pin: Peri<'d, impl TimerComplementaryPin<T, C>>, output_type: OutputType) -> Self {
29 #[doc = concat!("Create a new ", stringify!($channel), " complementary PWM pin instance.")] 27 critical_section::with(|_| {
30 pub fn $new_chx(pin: Peri<'d, impl $pin_trait<T>>, output_type: OutputType) -> Self { 28 pin.set_low();
31 critical_section::with(|_| { 29 pin.set_as_af(
32 pin.set_low(); 30 pin.af_num(),
33 pin.set_as_af( 31 crate::gpio::AfType::output(output_type, crate::gpio::Speed::VeryHigh),
34 pin.af_num(), 32 );
35 crate::gpio::AfType::output(output_type, crate::gpio::Speed::VeryHigh), 33 });
36 ); 34 ComplementaryPwmPin {
37 }); 35 _pin: pin.into(),
38 ComplementaryPwmPin { 36 phantom: PhantomData,
39 _pin: pin.into(),
40 phantom: PhantomData,
41 }
42 }
43 } 37 }
44 }; 38 }
45} 39}
46 40
47complementary_channel_impl!(new_ch1, Ch1, Channel1ComplementaryPin);
48complementary_channel_impl!(new_ch2, Ch2, Channel2ComplementaryPin);
49complementary_channel_impl!(new_ch3, Ch3, Channel3ComplementaryPin);
50complementary_channel_impl!(new_ch4, Ch4, Channel4ComplementaryPin);
51
52/// PWM driver with support for standard and complementary outputs. 41/// PWM driver with support for standard and complementary outputs.
53pub struct ComplementaryPwm<'d, T: AdvancedInstance4Channel> { 42pub struct ComplementaryPwm<'d, T: AdvancedInstance4Channel> {
54 inner: Timer<'d, T>, 43 inner: Timer<'d, T>,
@@ -82,24 +71,29 @@ impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> {
82 71
83 this.inner.enable_outputs(); 72 this.inner.enable_outputs();
84 73
85 [Channel::Ch1, Channel::Ch2, Channel::Ch3, Channel::Ch4] 74 [
86 .iter() 75 TimerChannel::Ch1,
87 .for_each(|&channel| { 76 TimerChannel::Ch2,
88 this.inner.set_output_compare_mode(channel, OutputCompareMode::PwmMode1); 77 TimerChannel::Ch3,
89 this.inner.set_output_compare_preload(channel, true); 78 TimerChannel::Ch4,
90 }); 79 ]
80 .iter()
81 .for_each(|&channel| {
82 this.inner.set_output_compare_mode(channel, OutputCompareMode::PwmMode1);
83 this.inner.set_output_compare_preload(channel, true);
84 });
91 85
92 this 86 this
93 } 87 }
94 88
95 /// Enable the given channel. 89 /// Enable the given channel.
96 pub fn enable(&mut self, channel: Channel) { 90 pub fn enable(&mut self, channel: TimerChannel) {
97 self.inner.enable_channel(channel, true); 91 self.inner.enable_channel(channel, true);
98 self.inner.enable_complementary_channel(channel, true); 92 self.inner.enable_complementary_channel(channel, true);
99 } 93 }
100 94
101 /// Disable the given channel. 95 /// Disable the given channel.
102 pub fn disable(&mut self, channel: Channel) { 96 pub fn disable(&mut self, channel: TimerChannel) {
103 self.inner.enable_complementary_channel(channel, false); 97 self.inner.enable_complementary_channel(channel, false);
104 self.inner.enable_channel(channel, false); 98 self.inner.enable_channel(channel, false);
105 } 99 }
@@ -127,13 +121,13 @@ impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> {
127 /// Set the duty for a given channel. 121 /// Set the duty for a given channel.
128 /// 122 ///
129 /// The value ranges from 0 for 0% duty, to [`get_max_duty`](Self::get_max_duty) for 100% duty, both included. 123 /// The value ranges from 0 for 0% duty, to [`get_max_duty`](Self::get_max_duty) for 100% duty, both included.
130 pub fn set_duty(&mut self, channel: Channel, duty: u16) { 124 pub fn set_duty(&mut self, channel: TimerChannel, duty: u16) {
131 assert!(duty <= self.get_max_duty()); 125 assert!(duty <= self.get_max_duty());
132 self.inner.set_compare_value(channel, duty as _) 126 self.inner.set_compare_value(channel, duty as _)
133 } 127 }
134 128
135 /// Set the output polarity for a given channel. 129 /// Set the output polarity for a given channel.
136 pub fn set_polarity(&mut self, channel: Channel, polarity: OutputPolarity) { 130 pub fn set_polarity(&mut self, channel: TimerChannel, polarity: OutputPolarity) {
137 self.inner.set_output_polarity(channel, polarity); 131 self.inner.set_output_polarity(channel, polarity);
138 self.inner.set_complementary_output_polarity(channel, polarity); 132 self.inner.set_complementary_output_polarity(channel, polarity);
139 } 133 }
@@ -148,7 +142,7 @@ impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> {
148} 142}
149 143
150impl<'d, T: AdvancedInstance4Channel> embedded_hal_02::Pwm for ComplementaryPwm<'d, T> { 144impl<'d, T: AdvancedInstance4Channel> embedded_hal_02::Pwm for ComplementaryPwm<'d, T> {
151 type Channel = Channel; 145 type Channel = TimerChannel;
152 type Time = Hertz; 146 type Time = Hertz;
153 type Duty = u16; 147 type Duty = u16;
154 148
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;
6use core::task::{Context, Poll}; 6use core::task::{Context, Poll};
7 7
8use super::low_level::{CountingMode, FilterValue, InputCaptureMode, InputTISelection, Timer}; 8use super::low_level::{CountingMode, FilterValue, InputCaptureMode, InputTISelection, Timer};
9use super::{ 9use super::{CaptureCompareInterruptHandler, GeneralInstance4Channel, TimerChannel, TimerPin};
10 CaptureCompareInterruptHandler, Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin,
11 GeneralInstance4Channel,
12};
13pub use super::{Ch1, Ch2, Ch3, Ch4}; 10pub use super::{Ch1, Ch2, Ch3, Ch4};
14use crate::gpio::{AfType, AnyPin, Pull}; 11use crate::gpio::{AfType, AnyPin, Pull};
15use crate::interrupt::typelevel::{Binding, Interrupt}; 12use crate::interrupt::typelevel::{Binding, Interrupt};
16use crate::time::Hertz; 13use crate::time::Hertz;
14use crate::timer::Channel;
17use crate::Peri; 15use crate::Peri;
18 16
19/// Capture pin wrapper. 17/// Capture pin wrapper.
@@ -23,27 +21,17 @@ pub struct CapturePin<'d, T, C> {
23 _pin: Peri<'d, AnyPin>, 21 _pin: Peri<'d, AnyPin>,
24 phantom: PhantomData<(T, C)>, 22 phantom: PhantomData<(T, C)>,
25} 23}
26 24impl<'d, T: GeneralInstance4Channel, C: Channel> CapturePin<'d, T, C> {
27macro_rules! channel_impl { 25 /// Create a new capture pin instance.
28 ($new_chx:ident, $channel:ident, $pin_trait:ident) => { 26 pub fn new(pin: Peri<'d, impl TimerPin<T, C>>, pull: Pull) -> Self {
29 impl<'d, T: GeneralInstance4Channel> CapturePin<'d, T, $channel> { 27 pin.set_as_af(pin.af_num(), AfType::input(pull));
30 #[doc = concat!("Create a new ", stringify!($channel), " capture pin instance.")] 28 CapturePin {
31 pub fn $new_chx(pin: Peri<'d, impl $pin_trait<T>>, pull: Pull) -> Self { 29 _pin: pin.into(),
32 pin.set_as_af(pin.af_num(), AfType::input(pull)); 30 phantom: PhantomData,
33 CapturePin {
34 _pin: pin.into(),
35 phantom: PhantomData,
36 }
37 }
38 } 31 }
39 }; 32 }
40} 33}
41 34
42channel_impl!(new_ch1, Ch1, Channel1Pin);
43channel_impl!(new_ch2, Ch2, Channel2Pin);
44channel_impl!(new_ch3, Ch3, Channel3Pin);
45channel_impl!(new_ch4, Ch4, Channel4Pin);
46
47/// Input capture driver. 35/// Input capture driver.
48pub struct InputCapture<'d, T: GeneralInstance4Channel> { 36pub struct InputCapture<'d, T: GeneralInstance4Channel> {
49 inner: Timer<'d, T>, 37 inner: Timer<'d, T>,
@@ -80,41 +68,46 @@ impl<'d, T: GeneralInstance4Channel> InputCapture<'d, T> {
80 } 68 }
81 69
82 /// Enable the given channel. 70 /// Enable the given channel.
83 pub fn enable(&mut self, channel: Channel) { 71 pub fn enable(&mut self, channel: TimerChannel) {
84 self.inner.enable_channel(channel, true); 72 self.inner.enable_channel(channel, true);
85 } 73 }
86 74
87 /// Disable the given channel. 75 /// Disable the given channel.
88 pub fn disable(&mut self, channel: Channel) { 76 pub fn disable(&mut self, channel: TimerChannel) {
89 self.inner.enable_channel(channel, false); 77 self.inner.enable_channel(channel, false);
90 } 78 }
91 79
92 /// Check whether given channel is enabled 80 /// Check whether given channel is enabled
93 pub fn is_enabled(&self, channel: Channel) -> bool { 81 pub fn is_enabled(&self, channel: TimerChannel) -> bool {
94 self.inner.get_channel_enable_state(channel) 82 self.inner.get_channel_enable_state(channel)
95 } 83 }
96 84
97 /// Set the input capture mode for a given channel. 85 /// Set the input capture mode for a given channel.
98 pub fn set_input_capture_mode(&mut self, channel: Channel, mode: InputCaptureMode) { 86 pub fn set_input_capture_mode(&mut self, channel: TimerChannel, mode: InputCaptureMode) {
99 self.inner.set_input_capture_mode(channel, mode); 87 self.inner.set_input_capture_mode(channel, mode);
100 } 88 }
101 89
102 /// Set input TI selection. 90 /// Set input TI selection.
103 pub fn set_input_ti_selection(&mut self, channel: Channel, tisel: InputTISelection) { 91 pub fn set_input_ti_selection(&mut self, channel: TimerChannel, tisel: InputTISelection) {
104 self.inner.set_input_ti_selection(channel, tisel) 92 self.inner.set_input_ti_selection(channel, tisel)
105 } 93 }
106 94
107 /// Get capture value for a channel. 95 /// Get capture value for a channel.
108 pub fn get_capture_value(&self, channel: Channel) -> u32 { 96 pub fn get_capture_value(&self, channel: TimerChannel) -> u32 {
109 self.inner.get_capture_value(channel) 97 self.inner.get_capture_value(channel)
110 } 98 }
111 99
112 /// Get input interrupt. 100 /// Get input interrupt.
113 pub fn get_input_interrupt(&self, channel: Channel) -> bool { 101 pub fn get_input_interrupt(&self, channel: TimerChannel) -> bool {
114 self.inner.get_input_interrupt(channel) 102 self.inner.get_input_interrupt(channel)
115 } 103 }
116 104
117 fn new_future(&self, channel: Channel, mode: InputCaptureMode, tisel: InputTISelection) -> InputCaptureFuture<T> { 105 fn new_future(
106 &self,
107 channel: TimerChannel,
108 mode: InputCaptureMode,
109 tisel: InputTISelection,
110 ) -> InputCaptureFuture<T> {
118 // Configuration steps from ST RM0390 (STM32F446) chapter 17.3.5 111 // Configuration steps from ST RM0390 (STM32F446) chapter 17.3.5
119 // or ST RM0008 (STM32F103) chapter 15.3.5 Input capture mode 112 // or ST RM0008 (STM32F103) chapter 15.3.5 Input capture mode
120 self.inner.set_input_ti_selection(channel, tisel); 113 self.inner.set_input_ti_selection(channel, tisel);
@@ -131,37 +124,37 @@ impl<'d, T: GeneralInstance4Channel> InputCapture<'d, T> {
131 } 124 }
132 125
133 /// Asynchronously wait until the pin sees a rising edge. 126 /// Asynchronously wait until the pin sees a rising edge.
134 pub async fn wait_for_rising_edge(&mut self, channel: Channel) -> u32 { 127 pub async fn wait_for_rising_edge(&mut self, channel: TimerChannel) -> u32 {
135 self.new_future(channel, InputCaptureMode::Rising, InputTISelection::Normal) 128 self.new_future(channel, InputCaptureMode::Rising, InputTISelection::Normal)
136 .await 129 .await
137 } 130 }
138 131
139 /// Asynchronously wait until the pin sees a falling edge. 132 /// Asynchronously wait until the pin sees a falling edge.
140 pub async fn wait_for_falling_edge(&mut self, channel: Channel) -> u32 { 133 pub async fn wait_for_falling_edge(&mut self, channel: TimerChannel) -> u32 {
141 self.new_future(channel, InputCaptureMode::Falling, InputTISelection::Normal) 134 self.new_future(channel, InputCaptureMode::Falling, InputTISelection::Normal)
142 .await 135 .await
143 } 136 }
144 137
145 /// Asynchronously wait until the pin sees any edge. 138 /// Asynchronously wait until the pin sees any edge.
146 pub async fn wait_for_any_edge(&mut self, channel: Channel) -> u32 { 139 pub async fn wait_for_any_edge(&mut self, channel: TimerChannel) -> u32 {
147 self.new_future(channel, InputCaptureMode::BothEdges, InputTISelection::Normal) 140 self.new_future(channel, InputCaptureMode::BothEdges, InputTISelection::Normal)
148 .await 141 .await
149 } 142 }
150 143
151 /// Asynchronously wait until the (alternate) pin sees a rising edge. 144 /// Asynchronously wait until the (alternate) pin sees a rising edge.
152 pub async fn wait_for_rising_edge_alternate(&mut self, channel: Channel) -> u32 { 145 pub async fn wait_for_rising_edge_alternate(&mut self, channel: TimerChannel) -> u32 {
153 self.new_future(channel, InputCaptureMode::Rising, InputTISelection::Alternate) 146 self.new_future(channel, InputCaptureMode::Rising, InputTISelection::Alternate)
154 .await 147 .await
155 } 148 }
156 149
157 /// Asynchronously wait until the (alternate) pin sees a falling edge. 150 /// Asynchronously wait until the (alternate) pin sees a falling edge.
158 pub async fn wait_for_falling_edge_alternate(&mut self, channel: Channel) -> u32 { 151 pub async fn wait_for_falling_edge_alternate(&mut self, channel: TimerChannel) -> u32 {
159 self.new_future(channel, InputCaptureMode::Falling, InputTISelection::Alternate) 152 self.new_future(channel, InputCaptureMode::Falling, InputTISelection::Alternate)
160 .await 153 .await
161 } 154 }
162 155
163 /// Asynchronously wait until the (alternate) pin sees any edge. 156 /// Asynchronously wait until the (alternate) pin sees any edge.
164 pub async fn wait_for_any_edge_alternate(&mut self, channel: Channel) -> u32 { 157 pub async fn wait_for_any_edge_alternate(&mut self, channel: TimerChannel) -> u32 {
165 self.new_future(channel, InputCaptureMode::BothEdges, InputTISelection::Alternate) 158 self.new_future(channel, InputCaptureMode::BothEdges, InputTISelection::Alternate)
166 .await 159 .await
167 } 160 }
@@ -169,7 +162,7 @@ impl<'d, T: GeneralInstance4Channel> InputCapture<'d, T> {
169 162
170#[must_use = "futures do nothing unless you `.await` or poll them"] 163#[must_use = "futures do nothing unless you `.await` or poll them"]
171struct InputCaptureFuture<T: GeneralInstance4Channel> { 164struct InputCaptureFuture<T: GeneralInstance4Channel> {
172 channel: Channel, 165 channel: TimerChannel,
173 phantom: PhantomData<T>, 166 phantom: PhantomData<T>,
174} 167}
175 168
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> {
503 } 503 }
504 504
505 /// Set input capture filter. 505 /// Set input capture filter.
506 pub fn set_input_capture_filter(&self, channel: Channel, icf: vals::FilterValue) { 506 pub fn set_input_capture_filter(&self, channel: TimerChannel, icf: vals::FilterValue) {
507 let raw_channel = channel.index(); 507 let raw_channel = channel.index();
508 self.regs_gp16() 508 self.regs_gp16()
509 .ccmr_input(raw_channel / 2) 509 .ccmr_input(raw_channel / 2)
@@ -511,22 +511,22 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> {
511 } 511 }
512 512
513 /// Clear input interrupt. 513 /// Clear input interrupt.
514 pub fn clear_input_interrupt(&self, channel: Channel) { 514 pub fn clear_input_interrupt(&self, channel: TimerChannel) {
515 self.regs_gp16().sr().modify(|r| r.set_ccif(channel.index(), false)); 515 self.regs_gp16().sr().modify(|r| r.set_ccif(channel.index(), false));
516 } 516 }
517 517
518 /// Get input interrupt. 518 /// Get input interrupt.
519 pub fn get_input_interrupt(&self, channel: Channel) -> bool { 519 pub fn get_input_interrupt(&self, channel: TimerChannel) -> bool {
520 self.regs_gp16().sr().read().ccif(channel.index()) 520 self.regs_gp16().sr().read().ccif(channel.index())
521 } 521 }
522 522
523 /// Enable input interrupt. 523 /// Enable input interrupt.
524 pub fn enable_input_interrupt(&self, channel: Channel, enable: bool) { 524 pub fn enable_input_interrupt(&self, channel: TimerChannel, enable: bool) {
525 self.regs_gp16().dier().modify(|r| r.set_ccie(channel.index(), enable)); 525 self.regs_gp16().dier().modify(|r| r.set_ccie(channel.index(), enable));
526 } 526 }
527 527
528 /// Set input capture prescaler. 528 /// Set input capture prescaler.
529 pub fn set_input_capture_prescaler(&self, channel: Channel, factor: u8) { 529 pub fn set_input_capture_prescaler(&self, channel: TimerChannel, factor: u8) {
530 let raw_channel = channel.index(); 530 let raw_channel = channel.index();
531 self.regs_gp16() 531 self.regs_gp16()
532 .ccmr_input(raw_channel / 2) 532 .ccmr_input(raw_channel / 2)
@@ -534,7 +534,7 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> {
534 } 534 }
535 535
536 /// Set input TI selection. 536 /// Set input TI selection.
537 pub fn set_input_ti_selection(&self, channel: Channel, tisel: InputTISelection) { 537 pub fn set_input_ti_selection(&self, channel: TimerChannel, tisel: InputTISelection) {
538 let raw_channel = channel.index(); 538 let raw_channel = channel.index();
539 self.regs_gp16() 539 self.regs_gp16()
540 .ccmr_input(raw_channel / 2) 540 .ccmr_input(raw_channel / 2)
@@ -542,7 +542,7 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> {
542 } 542 }
543 543
544 /// Set input capture mode. 544 /// Set input capture mode.
545 pub fn set_input_capture_mode(&self, channel: Channel, mode: InputCaptureMode) { 545 pub fn set_input_capture_mode(&self, channel: TimerChannel, mode: InputCaptureMode) {
546 self.regs_gp16().ccer().modify(|r| match mode { 546 self.regs_gp16().ccer().modify(|r| match mode {
547 InputCaptureMode::Rising => { 547 InputCaptureMode::Rising => {
548 r.set_ccnp(channel.index(), false); 548 r.set_ccnp(channel.index(), false);
@@ -560,7 +560,7 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> {
560 } 560 }
561 561
562 /// Set output compare mode. 562 /// Set output compare mode.
563 pub fn set_output_compare_mode(&self, channel: Channel, mode: OutputCompareMode) { 563 pub fn set_output_compare_mode(&self, channel: TimerChannel, mode: OutputCompareMode) {
564 let raw_channel: usize = channel.index(); 564 let raw_channel: usize = channel.index();
565 self.regs_gp16() 565 self.regs_gp16()
566 .ccmr_output(raw_channel / 2) 566 .ccmr_output(raw_channel / 2)
@@ -568,24 +568,24 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> {
568 } 568 }
569 569
570 /// Set output polarity. 570 /// Set output polarity.
571 pub fn set_output_polarity(&self, channel: Channel, polarity: OutputPolarity) { 571 pub fn set_output_polarity(&self, channel: TimerChannel, polarity: OutputPolarity) {
572 self.regs_gp16() 572 self.regs_gp16()
573 .ccer() 573 .ccer()
574 .modify(|w| w.set_ccp(channel.index(), polarity.into())); 574 .modify(|w| w.set_ccp(channel.index(), polarity.into()));
575 } 575 }
576 576
577 /// Enable/disable a channel. 577 /// Enable/disable a channel.
578 pub fn enable_channel(&self, channel: Channel, enable: bool) { 578 pub fn enable_channel(&self, channel: TimerChannel, enable: bool) {
579 self.regs_gp16().ccer().modify(|w| w.set_cce(channel.index(), enable)); 579 self.regs_gp16().ccer().modify(|w| w.set_cce(channel.index(), enable));
580 } 580 }
581 581
582 /// Get enable/disable state of a channel 582 /// Get enable/disable state of a channel
583 pub fn get_channel_enable_state(&self, channel: Channel) -> bool { 583 pub fn get_channel_enable_state(&self, channel: TimerChannel) -> bool {
584 self.regs_gp16().ccer().read().cce(channel.index()) 584 self.regs_gp16().ccer().read().cce(channel.index())
585 } 585 }
586 586
587 /// Set compare value for a channel. 587 /// Set compare value for a channel.
588 pub fn set_compare_value(&self, channel: Channel, value: u32) { 588 pub fn set_compare_value(&self, channel: TimerChannel, value: u32) {
589 match T::BITS { 589 match T::BITS {
590 TimerBits::Bits16 => { 590 TimerBits::Bits16 => {
591 let value = unwrap!(u16::try_from(value)); 591 let value = unwrap!(u16::try_from(value));
@@ -599,7 +599,7 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> {
599 } 599 }
600 600
601 /// Get compare value for a channel. 601 /// Get compare value for a channel.
602 pub fn get_compare_value(&self, channel: Channel) -> u32 { 602 pub fn get_compare_value(&self, channel: TimerChannel) -> u32 {
603 match T::BITS { 603 match T::BITS {
604 TimerBits::Bits16 => self.regs_gp16().ccr(channel.index()).read().ccr() as u32, 604 TimerBits::Bits16 => self.regs_gp16().ccr(channel.index()).read().ccr() as u32,
605 #[cfg(not(stm32l0))] 605 #[cfg(not(stm32l0))]
@@ -608,12 +608,12 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> {
608 } 608 }
609 609
610 /// Get capture value for a channel. 610 /// Get capture value for a channel.
611 pub fn get_capture_value(&self, channel: Channel) -> u32 { 611 pub fn get_capture_value(&self, channel: TimerChannel) -> u32 {
612 self.get_compare_value(channel) 612 self.get_compare_value(channel)
613 } 613 }
614 614
615 /// Set output compare preload. 615 /// Set output compare preload.
616 pub fn set_output_compare_preload(&self, channel: Channel, preload: bool) { 616 pub fn set_output_compare_preload(&self, channel: TimerChannel, preload: bool) {
617 let channel_index = channel.index(); 617 let channel_index = channel.index();
618 self.regs_gp16() 618 self.regs_gp16()
619 .ccmr_output(channel_index / 2) 619 .ccmr_output(channel_index / 2)
@@ -631,12 +631,12 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> {
631 } 631 }
632 632
633 /// Get capture compare DMA enable state 633 /// Get capture compare DMA enable state
634 pub fn get_cc_dma_enable_state(&self, channel: Channel) -> bool { 634 pub fn get_cc_dma_enable_state(&self, channel: TimerChannel) -> bool {
635 self.regs_gp16().dier().read().ccde(channel.index()) 635 self.regs_gp16().dier().read().ccde(channel.index())
636 } 636 }
637 637
638 /// Set capture compare DMA enable state 638 /// Set capture compare DMA enable state
639 pub fn set_cc_dma_enable_state(&self, channel: Channel, ccde: bool) { 639 pub fn set_cc_dma_enable_state(&self, channel: TimerChannel, ccde: bool) {
640 self.regs_gp16().dier().modify(|w| w.set_ccde(channel.index(), ccde)) 640 self.regs_gp16().dier().modify(|w| w.set_ccde(channel.index(), ccde))
641 } 641 }
642 642
@@ -713,14 +713,14 @@ impl<'d, T: AdvancedInstance4Channel> Timer<'d, T> {
713 } 713 }
714 714
715 /// Set complementary output polarity. 715 /// Set complementary output polarity.
716 pub fn set_complementary_output_polarity(&self, channel: Channel, polarity: OutputPolarity) { 716 pub fn set_complementary_output_polarity(&self, channel: TimerChannel, polarity: OutputPolarity) {
717 self.regs_advanced() 717 self.regs_advanced()
718 .ccer() 718 .ccer()
719 .modify(|w| w.set_ccnp(channel.index(), polarity.into())); 719 .modify(|w| w.set_ccnp(channel.index(), polarity.into()));
720 } 720 }
721 721
722 /// Enable/disable a complementary channel. 722 /// Enable/disable a complementary channel.
723 pub fn enable_complementary_channel(&self, channel: Channel, enable: bool) { 723 pub fn enable_complementary_channel(&self, channel: TimerChannel, enable: bool) {
724 self.regs_advanced() 724 self.regs_advanced()
725 .ccer() 725 .ccer()
726 .modify(|w| w.set_ccne(channel.index(), enable)); 726 .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;
19 19
20/// Timer channel. 20/// Timer channel.
21#[derive(Clone, Copy)] 21#[derive(Clone, Copy)]
22pub enum Channel { 22pub enum TimerChannel {
23 /// Channel 1. 23 /// Channel 1.
24 Ch1, 24 Ch1,
25 /// Channel 2. 25 /// Channel 2.
@@ -30,14 +30,14 @@ pub enum Channel {
30 Ch4, 30 Ch4,
31} 31}
32 32
33impl Channel { 33impl TimerChannel {
34 /// Get the channel index (0..3) 34 /// Get the channel index (0..3)
35 pub fn index(&self) -> usize { 35 pub fn index(&self) -> usize {
36 match self { 36 match self {
37 Channel::Ch1 => 0, 37 TimerChannel::Ch1 => 0,
38 Channel::Ch2 => 1, 38 TimerChannel::Ch2 => 1,
39 Channel::Ch3 => 2, 39 TimerChannel::Ch3 => 2,
40 Channel::Ch4 => 3, 40 TimerChannel::Ch4 => 3,
41 } 41 }
42 } 42 }
43} 43}
@@ -51,6 +51,80 @@ pub enum Ch3 {}
51/// Channel 4 marker type. 51/// Channel 4 marker type.
52pub enum Ch4 {} 52pub enum Ch4 {}
53 53
54/// Timer channel trait.
55#[allow(private_bounds)]
56pub trait Channel: SealedChannel {
57 /// The runtime channel.
58 const CHANNEL: TimerChannel;
59}
60
61trait SealedChannel {}
62
63impl Channel for Ch1 {
64 const CHANNEL: TimerChannel = TimerChannel::Ch1;
65}
66
67impl Channel for Ch2 {
68 const CHANNEL: TimerChannel = TimerChannel::Ch2;
69}
70
71impl Channel for Ch3 {
72 const CHANNEL: TimerChannel = TimerChannel::Ch3;
73}
74
75impl Channel for Ch4 {
76 const CHANNEL: TimerChannel = TimerChannel::Ch4;
77}
78
79impl SealedChannel for Ch1 {}
80impl SealedChannel for Ch2 {}
81impl SealedChannel for Ch3 {}
82impl SealedChannel for Ch4 {}
83
84/// Timer break input.
85#[derive(Clone, Copy)]
86pub enum BkIn {
87 /// Break input 1.
88 BkIn1,
89 /// Break input 2.
90 BkIn2,
91}
92
93impl BkIn {
94 /// Get the channel index (0..3)
95 pub fn index(&self) -> usize {
96 match self {
97 BkIn::BkIn1 => 0,
98 BkIn::BkIn2 => 1,
99 }
100 }
101}
102
103/// Break input 1 marker type.
104pub enum BkIn1 {}
105/// Break input 2 marker type.
106pub enum BkIn2 {}
107
108/// Timer channel trait.
109#[allow(private_bounds)]
110pub trait BreakInput: SealedBreakInput {
111 /// The runtim timer channel.
112 const INPUT: BkIn;
113}
114
115trait SealedBreakInput {}
116
117impl BreakInput for BkIn1 {
118 const INPUT: BkIn = BkIn::BkIn1;
119}
120
121impl BreakInput for BkIn2 {
122 const INPUT: BkIn = BkIn::BkIn2;
123}
124
125impl SealedBreakInput for BkIn1 {}
126impl SealedBreakInput for BkIn2 {}
127
54/// Amount of bits of a timer. 128/// Amount of bits of a timer.
55#[derive(Clone, Copy, PartialEq, Eq, Debug)] 129#[derive(Clone, Copy, PartialEq, Eq, Debug)]
56#[cfg_attr(feature = "defmt", derive(defmt::Format))] 130#[cfg_attr(feature = "defmt", derive(defmt::Format))]
@@ -149,33 +223,20 @@ pub trait AdvancedInstance2Channel: BasicInstance + GeneralInstance2Channel + Ad
149/// Advanced 16-bit timer with 4 channels instance. 223/// Advanced 16-bit timer with 4 channels instance.
150pub trait AdvancedInstance4Channel: AdvancedInstance2Channel + GeneralInstance4Channel {} 224pub trait AdvancedInstance4Channel: AdvancedInstance2Channel + GeneralInstance4Channel {}
151 225
152pin_trait!(Channel1Pin, GeneralInstance4Channel); 226pin_trait!(TimerPin, GeneralInstance4Channel, Channel);
153pin_trait!(Channel2Pin, GeneralInstance4Channel);
154pin_trait!(Channel3Pin, GeneralInstance4Channel);
155pin_trait!(Channel4Pin, GeneralInstance4Channel);
156pin_trait!(ExternalTriggerPin, GeneralInstance4Channel); 227pin_trait!(ExternalTriggerPin, GeneralInstance4Channel);
157 228
158pin_trait!(Channel1ComplementaryPin, AdvancedInstance4Channel); 229pin_trait!(TimerComplementaryPin, AdvancedInstance4Channel, Channel);
159pin_trait!(Channel2ComplementaryPin, AdvancedInstance4Channel);
160pin_trait!(Channel3ComplementaryPin, AdvancedInstance4Channel);
161pin_trait!(Channel4ComplementaryPin, AdvancedInstance4Channel);
162
163pin_trait!(BreakInputPin, AdvancedInstance4Channel);
164pin_trait!(BreakInput2Pin, AdvancedInstance4Channel);
165 230
166pin_trait!(BreakInputComparator1Pin, AdvancedInstance4Channel); 231pin_trait!(BreakInputPin, AdvancedInstance4Channel, BreakInput);
167pin_trait!(BreakInputComparator2Pin, AdvancedInstance4Channel);
168 232
169pin_trait!(BreakInput2Comparator1Pin, AdvancedInstance4Channel); 233pin_trait!(BreakInputComparator1Pin, AdvancedInstance4Channel, BreakInput);
170pin_trait!(BreakInput2Comparator2Pin, AdvancedInstance4Channel); 234pin_trait!(BreakInputComparator2Pin, AdvancedInstance4Channel, BreakInput);
171 235
172// Update Event trigger DMA for every timer 236// Update Event trigger DMA for every timer
173dma_trait!(UpDma, BasicInstance); 237dma_trait!(UpDma, BasicInstance);
174 238
175dma_trait!(Ch1Dma, GeneralInstance4Channel); 239dma_trait!(Dma, GeneralInstance4Channel, Channel);
176dma_trait!(Ch2Dma, GeneralInstance4Channel);
177dma_trait!(Ch3Dma, GeneralInstance4Channel);
178dma_trait!(Ch4Dma, GeneralInstance4Channel);
179 240
180#[allow(unused)] 241#[allow(unused)]
181macro_rules! impl_core_timer { 242macro_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};
9use super::low_level::{ 9use super::low_level::{
10 CountingMode, FilterValue, InputCaptureMode, InputTISelection, SlaveMode, Timer, TriggerSource, 10 CountingMode, FilterValue, InputCaptureMode, InputTISelection, SlaveMode, Timer, TriggerSource,
11}; 11};
12use super::{ 12use super::{CaptureCompareInterruptHandler, ExternalTriggerPin, GeneralInstance4Channel, TimerChannel, TimerPin};
13 CaptureCompareInterruptHandler, Channel, Channel1Pin, Channel2Pin, ExternalTriggerPin, GeneralInstance4Channel,
14};
15pub use super::{Ch1, Ch2}; 13pub use super::{Ch1, Ch2};
16use crate::gpio::{AfType, AnyPin, Pull}; 14use crate::gpio::{AfType, AnyPin, Pull};
17use crate::interrupt::typelevel::{Binding, Interrupt}; 15use crate::interrupt::typelevel::{Binding, Interrupt};
@@ -48,24 +46,40 @@ pub struct TriggerPin<'d, T, C> {
48 phantom: PhantomData<(T, C)>, 46 phantom: PhantomData<(T, C)>,
49} 47}
50 48
51macro_rules! channel_impl { 49// TODO: Generify trigger inputs
52 ($new_chx:ident, $channel:ident, $pin_trait:ident) => { 50
53 impl<'d, T: GeneralInstance4Channel> TriggerPin<'d, T, $channel> { 51impl<'d, T: GeneralInstance4Channel> TriggerPin<'d, T, Ch1> {
54 #[doc = concat!("Create a new ", stringify!($channel), " trigger pin instance.")] 52 /// "Create a new Ch1 trigger pin instance.
55 pub fn $new_chx(pin: Peri<'d, impl $pin_trait<T>>, pull: Pull) -> Self { 53 pub fn new_ch1(pin: Peri<'d, impl TimerPin<T, Ch1>>, pull: Pull) -> Self {
56 pin.set_as_af(pin.af_num(), AfType::input(pull)); 54 pin.set_as_af(pin.af_num(), AfType::input(pull));
57 TriggerPin { 55 TriggerPin {
58 _pin: pin.into(), 56 _pin: pin.into(),
59 phantom: PhantomData, 57 phantom: PhantomData,
60 }
61 }
62 } 58 }
63 }; 59 }
64} 60}
65 61
66channel_impl!(new_ch1, Ch1, Channel1Pin); 62impl<'d, T: GeneralInstance4Channel> TriggerPin<'d, T, Ch2> {
67channel_impl!(new_ch2, Ch2, Channel2Pin); 63 /// "Create a new Ch2 trigger pin instance.
68channel_impl!(new_ext, Ext, ExternalTriggerPin); 64 pub fn new_ch2(pin: Peri<'d, impl TimerPin<T, Ch2>>, pull: Pull) -> Self {
65 pin.set_as_af(pin.af_num(), AfType::input(pull));
66 TriggerPin {
67 _pin: pin.into(),
68 phantom: PhantomData,
69 }
70 }
71}
72
73impl<'d, T: GeneralInstance4Channel> TriggerPin<'d, T, Ext> {
74 /// "Create a new EXT trigger pin instance.
75 pub fn new_ext(pin: Peri<'d, impl ExternalTriggerPin<T>>, pull: Pull) -> Self {
76 pin.set_as_af(pin.af_num(), AfType::input(pull));
77 TriggerPin {
78 _pin: pin.into(),
79 phantom: PhantomData,
80 }
81 }
82}
69 83
70/// One pulse driver. 84/// One pulse driver.
71/// 85///
@@ -91,9 +105,9 @@ impl<'d, T: GeneralInstance4Channel> OnePulse<'d, T> {
91 105
92 this.inner.set_trigger_source(TriggerSource::TI1F_ED); 106 this.inner.set_trigger_source(TriggerSource::TI1F_ED);
93 this.inner 107 this.inner
94 .set_input_ti_selection(Channel::Ch1, InputTISelection::Normal); 108 .set_input_ti_selection(TimerChannel::Ch1, InputTISelection::Normal);
95 this.inner 109 this.inner
96 .set_input_capture_filter(Channel::Ch1, FilterValue::NO_FILTER); 110 .set_input_capture_filter(TimerChannel::Ch1, FilterValue::NO_FILTER);
97 this.new_inner(freq, pulse_end, counting_mode); 111 this.new_inner(freq, pulse_end, counting_mode);
98 112
99 this 113 this
@@ -116,10 +130,10 @@ impl<'d, T: GeneralInstance4Channel> OnePulse<'d, T> {
116 130
117 this.inner.set_trigger_source(TriggerSource::TI1FP1); 131 this.inner.set_trigger_source(TriggerSource::TI1FP1);
118 this.inner 132 this.inner
119 .set_input_ti_selection(Channel::Ch1, InputTISelection::Normal); 133 .set_input_ti_selection(TimerChannel::Ch1, InputTISelection::Normal);
120 this.inner 134 this.inner
121 .set_input_capture_filter(Channel::Ch1, FilterValue::NO_FILTER); 135 .set_input_capture_filter(TimerChannel::Ch1, FilterValue::NO_FILTER);
122 this.inner.set_input_capture_mode(Channel::Ch1, capture_mode); 136 this.inner.set_input_capture_mode(TimerChannel::Ch1, capture_mode);
123 this.new_inner(freq, pulse_end, counting_mode); 137 this.new_inner(freq, pulse_end, counting_mode);
124 138
125 this 139 this
@@ -142,10 +156,10 @@ impl<'d, T: GeneralInstance4Channel> OnePulse<'d, T> {
142 156
143 this.inner.set_trigger_source(TriggerSource::TI2FP2); 157 this.inner.set_trigger_source(TriggerSource::TI2FP2);
144 this.inner 158 this.inner
145 .set_input_ti_selection(Channel::Ch2, InputTISelection::Normal); 159 .set_input_ti_selection(TimerChannel::Ch2, InputTISelection::Normal);
146 this.inner 160 this.inner
147 .set_input_capture_filter(Channel::Ch2, FilterValue::NO_FILTER); 161 .set_input_capture_filter(TimerChannel::Ch2, FilterValue::NO_FILTER);
148 this.inner.set_input_capture_mode(Channel::Ch2, capture_mode); 162 this.inner.set_input_capture_mode(TimerChannel::Ch2, capture_mode);
149 this.new_inner(freq, pulse_end, counting_mode); 163 this.new_inner(freq, pulse_end, counting_mode);
150 164
151 this 165 this
@@ -217,7 +231,7 @@ impl<'d, T: GeneralInstance4Channel> OnePulse<'d, T> {
217 /// Get a single channel 231 /// Get a single channel
218 /// 232 ///
219 /// If you need to use multiple channels, use [`Self::split`]. 233 /// If you need to use multiple channels, use [`Self::split`].
220 pub fn channel(&mut self, channel: Channel) -> OnePulseChannel<'_, T> { 234 pub fn channel(&mut self, channel: TimerChannel) -> OnePulseChannel<'_, T> {
221 OnePulseChannel { 235 OnePulseChannel {
222 inner: unsafe { self.inner.clone_unchecked() }, 236 inner: unsafe { self.inner.clone_unchecked() },
223 channel, 237 channel,
@@ -230,7 +244,7 @@ impl<'d, T: GeneralInstance4Channel> OnePulse<'d, T> {
230 /// 244 ///
231 /// If you need to use multiple channels, use [`Self::split`]. 245 /// If you need to use multiple channels, use [`Self::split`].
232 pub fn ch1(&mut self) -> OnePulseChannel<'_, T> { 246 pub fn ch1(&mut self) -> OnePulseChannel<'_, T> {
233 self.channel(Channel::Ch1) 247 self.channel(TimerChannel::Ch1)
234 } 248 }
235 249
236 /// Channel 2 250 /// Channel 2
@@ -239,7 +253,7 @@ impl<'d, T: GeneralInstance4Channel> OnePulse<'d, T> {
239 /// 253 ///
240 /// If you need to use multiple channels, use [`Self::split`]. 254 /// If you need to use multiple channels, use [`Self::split`].
241 pub fn ch2(&mut self) -> OnePulseChannel<'_, T> { 255 pub fn ch2(&mut self) -> OnePulseChannel<'_, T> {
242 self.channel(Channel::Ch2) 256 self.channel(TimerChannel::Ch2)
243 } 257 }
244 258
245 /// Channel 3 259 /// Channel 3
@@ -248,7 +262,7 @@ impl<'d, T: GeneralInstance4Channel> OnePulse<'d, T> {
248 /// 262 ///
249 /// If you need to use multiple channels, use [`Self::split`]. 263 /// If you need to use multiple channels, use [`Self::split`].
250 pub fn ch3(&mut self) -> OnePulseChannel<'_, T> { 264 pub fn ch3(&mut self) -> OnePulseChannel<'_, T> {
251 self.channel(Channel::Ch3) 265 self.channel(TimerChannel::Ch3)
252 } 266 }
253 267
254 /// Channel 4 268 /// Channel 4
@@ -257,7 +271,7 @@ impl<'d, T: GeneralInstance4Channel> OnePulse<'d, T> {
257 /// 271 ///
258 /// If you need to use multiple channels, use [`Self::split`]. 272 /// If you need to use multiple channels, use [`Self::split`].
259 pub fn ch4(&mut self) -> OnePulseChannel<'_, T> { 273 pub fn ch4(&mut self) -> OnePulseChannel<'_, T> {
260 self.channel(Channel::Ch4) 274 self.channel(TimerChannel::Ch4)
261 } 275 }
262 276
263 /// Splits a [`OnePulse`] into four output channels. 277 /// Splits a [`OnePulse`] into four output channels.
@@ -276,10 +290,10 @@ impl<'d, T: GeneralInstance4Channel> OnePulse<'d, T> {
276 }; 290 };
277 291
278 OnePulseChannels { 292 OnePulseChannels {
279 ch1: ch(Channel::Ch1), 293 ch1: ch(TimerChannel::Ch1),
280 ch2: ch(Channel::Ch2), 294 ch2: ch(TimerChannel::Ch2),
281 ch3: ch(Channel::Ch3), 295 ch3: ch(TimerChannel::Ch3),
282 ch4: ch(Channel::Ch4), 296 ch4: ch(TimerChannel::Ch4),
283 } 297 }
284 } 298 }
285} 299}
@@ -303,7 +317,7 @@ pub struct OnePulseChannels<'d, T: GeneralInstance4Channel> {
303/// configuration is shared with all four channels. 317/// configuration is shared with all four channels.
304pub struct OnePulseChannel<'d, T: GeneralInstance4Channel> { 318pub struct OnePulseChannel<'d, T: GeneralInstance4Channel> {
305 inner: ManuallyDrop<Timer<'d, T>>, 319 inner: ManuallyDrop<Timer<'d, T>>,
306 channel: Channel, 320 channel: TimerChannel,
307} 321}
308 322
309impl<'d, T: GeneralInstance4Channel> OnePulseChannel<'d, T> { 323impl<'d, T: GeneralInstance4Channel> OnePulseChannel<'d, T> {
@@ -350,7 +364,7 @@ impl<'d, T: GeneralInstance4Channel> OnePulseChannel<'d, T> {
350 364
351#[must_use = "futures do nothing unless you `.await` or poll them"] 365#[must_use = "futures do nothing unless you `.await` or poll them"]
352struct OnePulseFuture<T: GeneralInstance4Channel> { 366struct OnePulseFuture<T: GeneralInstance4Channel> {
353 channel: Channel, 367 channel: TimerChannel,
354 phantom: PhantomData<T>, 368 phantom: PhantomData<T>,
355} 369}
356 370
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 @@
1//! PWM Input driver. 1//! PWM Input driver.
2 2
3use super::low_level::{CountingMode, InputCaptureMode, InputTISelection, SlaveMode, Timer, TriggerSource}; 3use super::low_level::{CountingMode, InputCaptureMode, InputTISelection, SlaveMode, Timer, TriggerSource};
4use super::{Channel, Channel1Pin, Channel2Pin, GeneralInstance4Channel}; 4use super::{Ch1, Ch2, GeneralInstance4Channel, TimerChannel, TimerPin};
5use crate::gpio::{AfType, Pull}; 5use crate::gpio::{AfType, Pull};
6use crate::time::Hertz; 6use crate::time::Hertz;
7use crate::Peri; 7use crate::Peri;
8 8
9/// PWM Input driver. 9/// PWM Input driver.
10pub struct PwmInput<'d, T: GeneralInstance4Channel> { 10pub struct PwmInput<'d, T: GeneralInstance4Channel> {
11 channel: Channel, 11 channel: TimerChannel,
12 inner: Timer<'d, T>, 12 inner: Timer<'d, T>,
13} 13}
14 14
15impl<'d, T: GeneralInstance4Channel> PwmInput<'d, T> { 15impl<'d, T: GeneralInstance4Channel> PwmInput<'d, T> {
16 /// Create a new PWM input driver. 16 /// Create a new PWM input driver.
17 pub fn new(tim: Peri<'d, T>, pin: Peri<'d, impl Channel1Pin<T>>, pull: Pull, freq: Hertz) -> Self { 17 pub fn new(tim: Peri<'d, T>, pin: Peri<'d, impl TimerPin<T, Ch1>>, pull: Pull, freq: Hertz) -> Self {
18 pin.set_as_af(pin.af_num(), AfType::input(pull)); 18 pin.set_as_af(pin.af_num(), AfType::input(pull));
19 19
20 Self::new_inner(tim, freq, Channel::Ch1, Channel::Ch2) 20 Self::new_inner(tim, freq, TimerChannel::Ch1, TimerChannel::Ch2)
21 } 21 }
22 22
23 /// Create a new PWM input driver. 23 /// Create a new PWM input driver.
24 pub fn new_alt(tim: Peri<'d, T>, pin: Peri<'d, impl Channel2Pin<T>>, pull: Pull, freq: Hertz) -> Self { 24 pub fn new_alt(tim: Peri<'d, T>, pin: Peri<'d, impl TimerPin<T, Ch2>>, pull: Pull, freq: Hertz) -> Self {
25 pin.set_as_af(pin.af_num(), AfType::input(pull)); 25 pin.set_as_af(pin.af_num(), AfType::input(pull));
26 26
27 Self::new_inner(tim, freq, Channel::Ch2, Channel::Ch1) 27 Self::new_inner(tim, freq, TimerChannel::Ch2, TimerChannel::Ch1)
28 } 28 }
29 29
30 fn new_inner(tim: Peri<'d, T>, freq: Hertz, ch1: Channel, ch2: Channel) -> Self { 30 fn new_inner(tim: Peri<'d, T>, freq: Hertz, ch1: TimerChannel, ch2: TimerChannel) -> Self {
31 let mut inner = Timer::new(tim); 31 let mut inner = Timer::new(tim);
32 32
33 inner.set_counting_mode(CountingMode::EdgeAlignedUp); 33 inner.set_counting_mode(CountingMode::EdgeAlignedUp);
@@ -44,8 +44,8 @@ impl<'d, T: GeneralInstance4Channel> PwmInput<'d, T> {
44 inner.set_input_capture_mode(ch2, InputCaptureMode::Falling); 44 inner.set_input_capture_mode(ch2, InputCaptureMode::Falling);
45 45
46 inner.set_trigger_source(match ch1 { 46 inner.set_trigger_source(match ch1 {
47 Channel::Ch1 => TriggerSource::TI1FP1, 47 TimerChannel::Ch1 => TriggerSource::TI1FP1,
48 Channel::Ch2 => TriggerSource::TI2FP2, 48 TimerChannel::Ch2 => TriggerSource::TI2FP2,
49 _ => panic!("Invalid channel for PWM input"), 49 _ => panic!("Invalid channel for PWM input"),
50 }); 50 });
51 51
@@ -58,19 +58,19 @@ impl<'d, T: GeneralInstance4Channel> PwmInput<'d, T> {
58 58
59 /// Enable the given channel. 59 /// Enable the given channel.
60 pub fn enable(&mut self) { 60 pub fn enable(&mut self) {
61 self.inner.enable_channel(Channel::Ch1, true); 61 self.inner.enable_channel(TimerChannel::Ch1, true);
62 self.inner.enable_channel(Channel::Ch2, true); 62 self.inner.enable_channel(TimerChannel::Ch2, true);
63 } 63 }
64 64
65 /// Disable the given channel. 65 /// Disable the given channel.
66 pub fn disable(&mut self) { 66 pub fn disable(&mut self) {
67 self.inner.enable_channel(Channel::Ch1, false); 67 self.inner.enable_channel(TimerChannel::Ch1, false);
68 self.inner.enable_channel(Channel::Ch2, false); 68 self.inner.enable_channel(TimerChannel::Ch2, false);
69 } 69 }
70 70
71 /// Check whether given channel is enabled 71 /// Check whether given channel is enabled
72 pub fn is_enabled(&self) -> bool { 72 pub fn is_enabled(&self) -> bool {
73 self.inner.get_channel_enable_state(Channel::Ch1) 73 self.inner.get_channel_enable_state(TimerChannel::Ch1)
74 } 74 }
75 75
76 /// Get the period tick count 76 /// Get the period tick count
@@ -81,8 +81,8 @@ impl<'d, T: GeneralInstance4Channel> PwmInput<'d, T> {
81 /// Get the pulse width tick count 81 /// Get the pulse width tick count
82 pub fn get_width_ticks(&self) -> u32 { 82 pub fn get_width_ticks(&self) -> u32 {
83 self.inner.get_capture_value(match self.channel { 83 self.inner.get_capture_value(match self.channel {
84 Channel::Ch1 => Channel::Ch2, 84 TimerChannel::Ch1 => TimerChannel::Ch2,
85 Channel::Ch2 => Channel::Ch1, 85 TimerChannel::Ch2 => TimerChannel::Ch1,
86 _ => panic!("Invalid channel for PWM input"), 86 _ => panic!("Invalid channel for PWM input"),
87 }) 87 })
88 } 88 }
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;
6 6
7use super::low_level::Timer; 7use super::low_level::Timer;
8pub use super::{Ch1, Ch2}; 8pub use super::{Ch1, Ch2};
9use super::{Channel1Pin, Channel2Pin, GeneralInstance4Channel}; 9use super::{GeneralInstance4Channel, TimerPin};
10use crate::gpio::{AfType, AnyPin, Pull}; 10use crate::gpio::{AfType, AnyPin, Pull};
11use crate::Peri; 11use crate::Peri;
12 12
@@ -24,11 +24,13 @@ pub struct QeiPin<'d, T, Channel> {
24 phantom: PhantomData<(T, Channel)>, 24 phantom: PhantomData<(T, Channel)>,
25} 25}
26 26
27// TODO: generify QEI channels
28
27macro_rules! channel_impl { 29macro_rules! channel_impl {
28 ($new_chx:ident, $channel:ident, $pin_trait:ident) => { 30 ($new_chx:ident, $channel:ident, $pin_trait:ident) => {
29 impl<'d, T: GeneralInstance4Channel> QeiPin<'d, T, $channel> { 31 impl<'d, T: GeneralInstance4Channel> QeiPin<'d, T, $channel> {
30 #[doc = concat!("Create a new ", stringify!($channel), " QEI pin instance.")] 32 #[doc = concat!("Create a new ", stringify!($channel), " QEI pin instance.")]
31 pub fn $new_chx(pin: Peri<'d, impl $pin_trait<T>>) -> Self { 33 pub fn $new_chx(pin: Peri<'d, impl $pin_trait<T, $channel>>) -> Self {
32 critical_section::with(|_| { 34 critical_section::with(|_| {
33 pin.set_low(); 35 pin.set_low();
34 pin.set_as_af(pin.af_num(), AfType::input(Pull::None)); 36 pin.set_as_af(pin.af_num(), AfType::input(Pull::None));
@@ -42,8 +44,8 @@ macro_rules! channel_impl {
42 }; 44 };
43} 45}
44 46
45channel_impl!(new_ch1, Ch1, Channel1Pin); 47channel_impl!(new_ch1, Ch1, TimerPin);
46channel_impl!(new_ch2, Ch2, Channel2Pin); 48channel_impl!(new_ch2, Ch2, TimerPin);
47 49
48/// Quadrature decoder driver. 50/// Quadrature decoder driver.
49pub struct Qei<'d, T: GeneralInstance4Channel> { 51pub 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;
4use core::mem::ManuallyDrop; 4use core::mem::ManuallyDrop;
5 5
6use super::low_level::{CountingMode, OutputCompareMode, OutputPolarity, Timer}; 6use super::low_level::{CountingMode, OutputCompareMode, OutputPolarity, Timer};
7use super::{Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, GeneralInstance4Channel, TimerBits}; 7use super::{Ch1, Ch2, Ch3, Ch4, GeneralInstance4Channel, TimerBits, TimerChannel, TimerPin};
8#[cfg(gpio_v2)] 8#[cfg(gpio_v2)]
9use crate::gpio::Pull; 9use crate::gpio::Pull;
10use crate::gpio::{AfType, AnyPin, OutputType, Speed}; 10use crate::gpio::{AfType, AnyPin, OutputType, Speed};
11use crate::time::Hertz; 11use crate::time::Hertz;
12use crate::Peri; 12use crate::Peri;
13 13
14/// Channel 1 marker type.
15pub enum Ch1 {}
16/// Channel 2 marker type.
17pub enum Ch2 {}
18/// Channel 3 marker type.
19pub enum Ch3 {}
20/// Channel 4 marker type.
21pub enum Ch4 {}
22
23/// PWM pin wrapper. 14/// PWM pin wrapper.
24/// 15///
25/// This wraps a pin to make it usable with PWM. 16/// This wraps a pin to make it usable with PWM.
@@ -47,7 +38,7 @@ macro_rules! channel_impl {
47 ($new_chx:ident, $new_chx_with_config:ident, $channel:ident, $pin_trait:ident) => { 38 ($new_chx:ident, $new_chx_with_config:ident, $channel:ident, $pin_trait:ident) => {
48 impl<'d, T: GeneralInstance4Channel> PwmPin<'d, T, $channel> { 39 impl<'d, T: GeneralInstance4Channel> PwmPin<'d, T, $channel> {
49 #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance.")] 40 #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance.")]
50 pub fn $new_chx(pin: Peri<'d, impl $pin_trait<T>>, output_type: OutputType) -> Self { 41 pub fn $new_chx(pin: Peri<'d, impl $pin_trait<T, $channel>>, output_type: OutputType) -> Self {
51 critical_section::with(|_| { 42 critical_section::with(|_| {
52 pin.set_low(); 43 pin.set_low();
53 pin.set_as_af(pin.af_num(), AfType::output(output_type, Speed::VeryHigh)); 44 pin.set_as_af(pin.af_num(), AfType::output(output_type, Speed::VeryHigh));
@@ -59,7 +50,7 @@ macro_rules! channel_impl {
59 } 50 }
60 51
61 #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance with config.")] 52 #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance with config.")]
62 pub fn $new_chx_with_config(pin: Peri<'d, impl $pin_trait<T>>, pin_config: PwmPinConfig) -> Self { 53 pub fn $new_chx_with_config(pin: Peri<'d, impl $pin_trait<T, $channel>>, pin_config: PwmPinConfig) -> Self {
63 critical_section::with(|_| { 54 critical_section::with(|_| {
64 pin.set_low(); 55 pin.set_low();
65 pin.set_as_af( 56 pin.set_as_af(
@@ -79,10 +70,10 @@ macro_rules! channel_impl {
79 }; 70 };
80} 71}
81 72
82channel_impl!(new_ch1, new_ch1_with_config, Ch1, Channel1Pin); 73channel_impl!(new_ch1, new_ch1_with_config, Ch1, TimerPin);
83channel_impl!(new_ch2, new_ch2_with_config, Ch2, Channel2Pin); 74channel_impl!(new_ch2, new_ch2_with_config, Ch2, TimerPin);
84channel_impl!(new_ch3, new_ch3_with_config, Ch3, Channel3Pin); 75channel_impl!(new_ch3, new_ch3_with_config, Ch3, TimerPin);
85channel_impl!(new_ch4, new_ch4_with_config, Ch4, Channel4Pin); 76channel_impl!(new_ch4, new_ch4_with_config, Ch4, TimerPin);
86 77
87/// A single channel of a pwm, obtained from [`SimplePwm::split`], 78/// A single channel of a pwm, obtained from [`SimplePwm::split`],
88/// [`SimplePwm::channel`], [`SimplePwm::ch1`], etc. 79/// [`SimplePwm::channel`], [`SimplePwm::ch1`], etc.
@@ -91,7 +82,7 @@ channel_impl!(new_ch4, new_ch4_with_config, Ch4, Channel4Pin);
91/// the frequency configuration is shared with all four channels. 82/// the frequency configuration is shared with all four channels.
92pub struct SimplePwmChannel<'d, T: GeneralInstance4Channel> { 83pub struct SimplePwmChannel<'d, T: GeneralInstance4Channel> {
93 timer: ManuallyDrop<Timer<'d, T>>, 84 timer: ManuallyDrop<Timer<'d, T>>,
94 channel: Channel, 85 channel: TimerChannel,
95} 86}
96 87
97// TODO: check for RMW races 88// TODO: check for RMW races
@@ -216,13 +207,18 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
216 this.inner.enable_outputs(); // Required for advanced timers, see GeneralInstance4Channel for details 207 this.inner.enable_outputs(); // Required for advanced timers, see GeneralInstance4Channel for details
217 this.inner.start(); 208 this.inner.start();
218 209
219 [Channel::Ch1, Channel::Ch2, Channel::Ch3, Channel::Ch4] 210 [
220 .iter() 211 TimerChannel::Ch1,
221 .for_each(|&channel| { 212 TimerChannel::Ch2,
222 this.inner.set_output_compare_mode(channel, OutputCompareMode::PwmMode1); 213 TimerChannel::Ch3,
214 TimerChannel::Ch4,
215 ]
216 .iter()
217 .for_each(|&channel| {
218 this.inner.set_output_compare_mode(channel, OutputCompareMode::PwmMode1);
223 219
224 this.inner.set_output_compare_preload(channel, true); 220 this.inner.set_output_compare_preload(channel, true);
225 }); 221 });
226 222
227 this 223 this
228 } 224 }
@@ -230,7 +226,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
230 /// Get a single channel 226 /// Get a single channel
231 /// 227 ///
232 /// If you need to use multiple channels, use [`Self::split`]. 228 /// If you need to use multiple channels, use [`Self::split`].
233 pub fn channel(&mut self, channel: Channel) -> SimplePwmChannel<'_, T> { 229 pub fn channel(&mut self, channel: TimerChannel) -> SimplePwmChannel<'_, T> {
234 SimplePwmChannel { 230 SimplePwmChannel {
235 timer: unsafe { self.inner.clone_unchecked() }, 231 timer: unsafe { self.inner.clone_unchecked() },
236 channel, 232 channel,
@@ -243,7 +239,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
243 /// 239 ///
244 /// If you need to use multiple channels, use [`Self::split`]. 240 /// If you need to use multiple channels, use [`Self::split`].
245 pub fn ch1(&mut self) -> SimplePwmChannel<'_, T> { 241 pub fn ch1(&mut self) -> SimplePwmChannel<'_, T> {
246 self.channel(Channel::Ch1) 242 self.channel(TimerChannel::Ch1)
247 } 243 }
248 244
249 /// Channel 2 245 /// Channel 2
@@ -252,7 +248,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
252 /// 248 ///
253 /// If you need to use multiple channels, use [`Self::split`]. 249 /// If you need to use multiple channels, use [`Self::split`].
254 pub fn ch2(&mut self) -> SimplePwmChannel<'_, T> { 250 pub fn ch2(&mut self) -> SimplePwmChannel<'_, T> {
255 self.channel(Channel::Ch2) 251 self.channel(TimerChannel::Ch2)
256 } 252 }
257 253
258 /// Channel 3 254 /// Channel 3
@@ -261,7 +257,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
261 /// 257 ///
262 /// If you need to use multiple channels, use [`Self::split`]. 258 /// If you need to use multiple channels, use [`Self::split`].
263 pub fn ch3(&mut self) -> SimplePwmChannel<'_, T> { 259 pub fn ch3(&mut self) -> SimplePwmChannel<'_, T> {
264 self.channel(Channel::Ch3) 260 self.channel(TimerChannel::Ch3)
265 } 261 }
266 262
267 /// Channel 4 263 /// Channel 4
@@ -270,7 +266,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
270 /// 266 ///
271 /// If you need to use multiple channels, use [`Self::split`]. 267 /// If you need to use multiple channels, use [`Self::split`].
272 pub fn ch4(&mut self) -> SimplePwmChannel<'_, T> { 268 pub fn ch4(&mut self) -> SimplePwmChannel<'_, T> {
273 self.channel(Channel::Ch4) 269 self.channel(TimerChannel::Ch4)
274 } 270 }
275 271
276 /// Splits a [`SimplePwm`] into four pwm channels. 272 /// Splits a [`SimplePwm`] into four pwm channels.
@@ -292,10 +288,10 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
292 }; 288 };
293 289
294 SimplePwmChannels { 290 SimplePwmChannels {
295 ch1: ch(Channel::Ch1), 291 ch1: ch(TimerChannel::Ch1),
296 ch2: ch(Channel::Ch2), 292 ch2: ch(TimerChannel::Ch2),
297 ch3: ch(Channel::Ch3), 293 ch3: ch(TimerChannel::Ch3),
298 ch4: ch(Channel::Ch4), 294 ch4: ch(TimerChannel::Ch4),
299 } 295 }
300 } 296 }
301 297
@@ -326,7 +322,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
326 /// 322 ///
327 /// Note: 323 /// Note:
328 /// you will need to provide corresponding TIMx_UP DMA channel to use this method. 324 /// you will need to provide corresponding TIMx_UP DMA channel to use this method.
329 pub async fn waveform_up(&mut self, dma: Peri<'_, impl super::UpDma<T>>, channel: Channel, duty: &[u16]) { 325 pub async fn waveform_up(&mut self, dma: Peri<'_, impl super::UpDma<T>>, channel: TimerChannel, duty: &[u16]) {
330 #[allow(clippy::let_unit_value)] // eg. stm32f334 326 #[allow(clippy::let_unit_value)] // eg. stm32f334
331 let req = dma.request(); 327 let req = dma.request();
332 328
@@ -409,8 +405,8 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
409 pub async fn waveform_up_multi_channel( 405 pub async fn waveform_up_multi_channel(
410 &mut self, 406 &mut self,
411 dma: Peri<'_, impl super::UpDma<T>>, 407 dma: Peri<'_, impl super::UpDma<T>>,
412 starting_channel: Channel, 408 starting_channel: TimerChannel,
413 ending_channel: Channel, 409 ending_channel: TimerChannel,
414 duty: &[u16], 410 duty: &[u16],
415 ) { 411 ) {
416 let cr1_addr = self.inner.regs_gp16().cr1().as_ptr() as u32; 412 let cr1_addr = self.inner.regs_gp16().cr1().as_ptr() as u32;
@@ -470,13 +466,13 @@ macro_rules! impl_waveform_chx {
470 ($fn_name:ident, $dma_ch:ident, $cc_ch:ident) => { 466 ($fn_name:ident, $dma_ch:ident, $cc_ch:ident) => {
471 impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { 467 impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
472 /// Generate a sequence of PWM waveform 468 /// Generate a sequence of PWM waveform
473 pub async fn $fn_name(&mut self, dma: Peri<'_, impl super::$dma_ch<T>>, duty: &[u16]) { 469 pub async fn $fn_name(&mut self, dma: Peri<'_, impl super::$dma_ch<T, $cc_ch>>, duty: &[u16]) {
474 use crate::pac::timer::vals::Ccds; 470 use crate::pac::timer::vals::Ccds;
475 471
476 #[allow(clippy::let_unit_value)] // eg. stm32f334 472 #[allow(clippy::let_unit_value)] // eg. stm32f334
477 let req = dma.request(); 473 let req = dma.request();
478 474
479 let cc_channel = Channel::$cc_ch; 475 let cc_channel = TimerChannel::$cc_ch;
480 476
481 let original_duty_state = self.channel(cc_channel).current_duty_cycle(); 477 let original_duty_state = self.channel(cc_channel).current_duty_cycle();
482 let original_enable_state = self.channel(cc_channel).is_enabled(); 478 let original_enable_state = self.channel(cc_channel).is_enabled();
@@ -562,10 +558,10 @@ macro_rules! impl_waveform_chx {
562 }; 558 };
563} 559}
564 560
565impl_waveform_chx!(waveform_ch1, Ch1Dma, Ch1); 561impl_waveform_chx!(waveform_ch1, Dma, Ch1);
566impl_waveform_chx!(waveform_ch2, Ch2Dma, Ch2); 562impl_waveform_chx!(waveform_ch2, Dma, Ch2);
567impl_waveform_chx!(waveform_ch3, Ch3Dma, Ch3); 563impl_waveform_chx!(waveform_ch3, Dma, Ch3);
568impl_waveform_chx!(waveform_ch4, Ch4Dma, Ch4); 564impl_waveform_chx!(waveform_ch4, Dma, Ch4);
569 565
570impl<'d, T: GeneralInstance4Channel> embedded_hal_1::pwm::ErrorType for SimplePwmChannel<'d, T> { 566impl<'d, T: GeneralInstance4Channel> embedded_hal_1::pwm::ErrorType for SimplePwmChannel<'d, T> {
571 type Error = core::convert::Infallible; 567 type Error = core::convert::Infallible;
@@ -603,7 +599,7 @@ impl<'d, T: GeneralInstance4Channel> embedded_hal_1::pwm::SetDutyCycle for Simpl
603} 599}
604 600
605impl<'d, T: GeneralInstance4Channel> embedded_hal_02::Pwm for SimplePwm<'d, T> { 601impl<'d, T: GeneralInstance4Channel> embedded_hal_02::Pwm for SimplePwm<'d, T> {
606 type Channel = Channel; 602 type Channel = TimerChannel;
607 type Time = Hertz; 603 type Time = Hertz;
608 type Duty = u32; 604 type Duty = u32;
609 605