aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src/timer
diff options
context:
space:
mode:
authorchasingRs <[email protected]>2025-10-10 10:26:46 +0800
committerGitHub <[email protected]>2025-10-10 10:26:46 +0800
commit944fda48a94c2d6cb6bea56c8c8471858d75da7d (patch)
tree1e3e2f463c2440afe81ca37b2e161f85d0bfc374 /embassy-stm32/src/timer
parent04171d903d3676d87aa0fd85719878d3087028f3 (diff)
parent35b0ba4ce0fed7588febe504e16bbf1788384f5a (diff)
Merge branch 'embassy-rs:main' into fix/simple-pwm-32bit-timer-support
Diffstat (limited to 'embassy-stm32/src/timer')
-rw-r--r--embassy-stm32/src/timer/complementary_pwm.rs6
-rw-r--r--embassy-stm32/src/timer/input_capture.rs2
-rw-r--r--embassy-stm32/src/timer/one_pulse.rs2
-rw-r--r--embassy-stm32/src/timer/pwm_input.rs2
-rw-r--r--embassy-stm32/src/timer/qei.rs102
-rw-r--r--embassy-stm32/src/timer/simple_pwm.rs2
6 files changed, 75 insertions, 41 deletions
diff --git a/embassy-stm32/src/timer/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs
index 484aae1d0..75a83629c 100644
--- a/embassy-stm32/src/timer/complementary_pwm.rs
+++ b/embassy-stm32/src/timer/complementary_pwm.rs
@@ -7,11 +7,11 @@ pub use stm32_metapac::timer::vals::{Ckd, Ossi, Ossr};
7use super::low_level::{CountingMode, OutputPolarity, Timer}; 7use super::low_level::{CountingMode, OutputPolarity, Timer};
8use super::simple_pwm::PwmPin; 8use super::simple_pwm::PwmPin;
9use super::{AdvancedInstance4Channel, Ch1, Ch2, Ch3, Ch4, Channel, TimerComplementaryPin}; 9use super::{AdvancedInstance4Channel, Ch1, Ch2, Ch3, Ch4, Channel, TimerComplementaryPin};
10use crate::Peri;
10use crate::gpio::{AnyPin, OutputType}; 11use crate::gpio::{AnyPin, OutputType};
11use crate::time::Hertz; 12use crate::time::Hertz;
12use crate::timer::low_level::OutputCompareMode;
13use crate::timer::TimerChannel; 13use crate::timer::TimerChannel;
14use crate::Peri; 14use crate::timer::low_level::OutputCompareMode;
15 15
16/// Complementary PWM pin wrapper. 16/// Complementary PWM pin wrapper.
17/// 17///
@@ -388,7 +388,7 @@ fn compute_dead_time_value(value: u16) -> (Ckd, u8) {
388 388
389#[cfg(test)] 389#[cfg(test)]
390mod tests { 390mod tests {
391 use super::{compute_dead_time_value, Ckd}; 391 use super::{Ckd, compute_dead_time_value};
392 392
393 #[test] 393 #[test]
394 fn test_compute_dead_time_value() { 394 fn test_compute_dead_time_value() {
diff --git a/embassy-stm32/src/timer/input_capture.rs b/embassy-stm32/src/timer/input_capture.rs
index 7a25e6c21..2a4ec2db0 100644
--- a/embassy-stm32/src/timer/input_capture.rs
+++ b/embassy-stm32/src/timer/input_capture.rs
@@ -8,11 +8,11 @@ use core::task::{Context, Poll};
8use super::low_level::{CountingMode, FilterValue, InputCaptureMode, InputTISelection, Timer}; 8use super::low_level::{CountingMode, FilterValue, InputCaptureMode, InputTISelection, Timer};
9use super::{CaptureCompareInterruptHandler, Channel, GeneralInstance4Channel, TimerPin}; 9use super::{CaptureCompareInterruptHandler, Channel, GeneralInstance4Channel, TimerPin};
10pub use super::{Ch1, Ch2, Ch3, Ch4}; 10pub use super::{Ch1, Ch2, Ch3, Ch4};
11use crate::Peri;
11use crate::gpio::{AfType, AnyPin, Pull}; 12use crate::gpio::{AfType, AnyPin, Pull};
12use crate::interrupt::typelevel::{Binding, Interrupt}; 13use crate::interrupt::typelevel::{Binding, Interrupt};
13use crate::time::Hertz; 14use crate::time::Hertz;
14use crate::timer::TimerChannel; 15use crate::timer::TimerChannel;
15use crate::Peri;
16 16
17/// Capture pin wrapper. 17/// Capture pin wrapper.
18/// 18///
diff --git a/embassy-stm32/src/timer/one_pulse.rs b/embassy-stm32/src/timer/one_pulse.rs
index a75b41bd7..fe8681356 100644
--- a/embassy-stm32/src/timer/one_pulse.rs
+++ b/embassy-stm32/src/timer/one_pulse.rs
@@ -11,12 +11,12 @@ use super::low_level::{
11}; 11};
12use super::{CaptureCompareInterruptHandler, Channel, ExternalTriggerPin, GeneralInstance4Channel, TimerPin}; 12use super::{CaptureCompareInterruptHandler, Channel, ExternalTriggerPin, GeneralInstance4Channel, TimerPin};
13pub use super::{Ch1, Ch2}; 13pub use super::{Ch1, Ch2};
14use crate::Peri;
14use crate::gpio::{AfType, AnyPin, Pull}; 15use crate::gpio::{AfType, AnyPin, Pull};
15use crate::interrupt::typelevel::{Binding, Interrupt}; 16use crate::interrupt::typelevel::{Binding, Interrupt};
16use crate::pac::timer::vals::Etp; 17use crate::pac::timer::vals::Etp;
17use crate::time::Hertz; 18use crate::time::Hertz;
18use crate::timer::TimerChannel; 19use crate::timer::TimerChannel;
19use crate::Peri;
20 20
21/// External input marker type. 21/// External input marker type.
22pub enum Ext {} 22pub enum Ext {}
diff --git a/embassy-stm32/src/timer/pwm_input.rs b/embassy-stm32/src/timer/pwm_input.rs
index 159b5a177..da8a79b09 100644
--- a/embassy-stm32/src/timer/pwm_input.rs
+++ b/embassy-stm32/src/timer/pwm_input.rs
@@ -2,9 +2,9 @@
2 2
3use super::low_level::{CountingMode, InputCaptureMode, InputTISelection, SlaveMode, Timer, TriggerSource}; 3use super::low_level::{CountingMode, InputCaptureMode, InputTISelection, SlaveMode, Timer, TriggerSource};
4use super::{Ch1, Ch2, Channel, GeneralInstance4Channel, TimerPin}; 4use super::{Ch1, Ch2, Channel, GeneralInstance4Channel, TimerPin};
5use crate::Peri;
5use crate::gpio::{AfType, Pull}; 6use crate::gpio::{AfType, Pull};
6use crate::time::Hertz; 7use crate::time::Hertz;
7use crate::Peri;
8 8
9/// PWM Input driver. 9/// PWM Input driver.
10/// 10///
diff --git a/embassy-stm32/src/timer/qei.rs b/embassy-stm32/src/timer/qei.rs
index 82b5968b0..a547a2a19 100644
--- a/embassy-stm32/src/timer/qei.rs
+++ b/embassy-stm32/src/timer/qei.rs
@@ -1,45 +1,67 @@
1//! Quadrature decoder using a timer. 1//! Quadrature decoder using a timer.
2 2
3use core::marker::PhantomData; 3use stm32_metapac::timer::vals::{self, Sms};
4
5use stm32_metapac::timer::vals;
6 4
7use super::low_level::Timer; 5use super::low_level::Timer;
8pub use super::{Ch1, Ch2}; 6pub use super::{Ch1, Ch2};
9use super::{GeneralInstance4Channel, TimerPin}; 7use super::{GeneralInstance4Channel, TimerPin};
8use crate::Peri;
10use crate::gpio::{AfType, AnyPin, Pull}; 9use crate::gpio::{AfType, AnyPin, Pull};
11use crate::timer::TimerChannel; 10use crate::timer::TimerChannel;
12use crate::Peri;
13 11
14/// Counting direction 12/// Qei driver config.
15pub enum Direction { 13#[cfg_attr(feature = "defmt", derive(defmt::Format))]
16 /// Counting up. 14#[derive(Clone, Copy)]
17 Upcounting, 15pub struct Config {
18 /// Counting down. 16 /// Configures the internal pull up/down resistor for Qei's channel 1 pin.
19 Downcounting, 17 pub ch1_pull: Pull,
18 /// Configures the internal pull up/down resistor for Qei's channel 2 pin.
19 pub ch2_pull: Pull,
20 /// Specifies the encoder mode to use for the Qei peripheral.
21 pub mode: QeiMode,
20} 22}
21 23
22/// Wrapper for using a pin with QEI. 24impl Default for Config {
23pub struct QeiPin<'d, T, Channel, #[cfg(afio)] A> { 25 /// Arbitrary defaults to preserve backwards compatibility
24 #[allow(unused)] 26 fn default() -> Self {
25 pin: Peri<'d, AnyPin>, 27 Self {
26 phantom: PhantomData<if_afio!((T, Channel, A))>, 28 ch1_pull: Pull::None,
29 ch2_pull: Pull::None,
30 mode: QeiMode::Mode3,
31 }
32 }
27} 33}
28 34
29impl<'d, T: GeneralInstance4Channel, C: QeiChannel, #[cfg(afio)] A> if_afio!(QeiPin<'d, T, C, A>) { 35/// See STMicro AN4013 for ยง2.3 for more information
30 /// Create a new QEI pin instance. 36#[cfg_attr(feature = "defmt", derive(defmt::Format))]
31 pub fn new(pin: Peri<'d, if_afio!(impl TimerPin<T, C, A>)>) -> Self { 37#[derive(Clone, Copy)]
32 critical_section::with(|_| { 38pub enum QeiMode {
33 pin.set_low(); 39 /// Direct alias for [`Sms::ENCODER_MODE_1`]
34 set_as_af!(pin, AfType::input(Pull::None)); 40 Mode1,
35 }); 41 /// Direct alias for [`Sms::ENCODER_MODE_2`]
36 QeiPin { 42 Mode2,
37 pin: pin.into(), 43 /// Direct alias for [`Sms::ENCODER_MODE_3`]
38 phantom: PhantomData, 44 Mode3,
45}
46
47impl From<QeiMode> for Sms {
48 fn from(mode: QeiMode) -> Self {
49 match mode {
50 QeiMode::Mode1 => Sms::ENCODER_MODE_1,
51 QeiMode::Mode2 => Sms::ENCODER_MODE_2,
52 QeiMode::Mode3 => Sms::ENCODER_MODE_3,
39 } 53 }
40 } 54 }
41} 55}
42 56
57/// Counting direction
58pub enum Direction {
59 /// Counting up.
60 Upcounting,
61 /// Counting down.
62 Downcounting,
63}
64
43trait SealedQeiChannel: TimerChannel {} 65trait SealedQeiChannel: TimerChannel {}
44 66
45/// Marker trait for a timer channel eligible for use with QEI. 67/// Marker trait for a timer channel eligible for use with QEI.
@@ -55,20 +77,28 @@ impl SealedQeiChannel for Ch2 {}
55/// Quadrature decoder driver. 77/// Quadrature decoder driver.
56pub struct Qei<'d, T: GeneralInstance4Channel> { 78pub struct Qei<'d, T: GeneralInstance4Channel> {
57 inner: Timer<'d, T>, 79 inner: Timer<'d, T>,
80 _ch1: Peri<'d, AnyPin>,
81 _ch2: Peri<'d, AnyPin>,
58} 82}
59 83
60impl<'d, T: GeneralInstance4Channel> Qei<'d, T> { 84impl<'d, T: GeneralInstance4Channel> Qei<'d, T> {
61 /// Create a new quadrature decoder driver. 85 /// Create a new quadrature decoder driver, with a given [`Config`].
62 #[allow(unused)] 86 #[allow(unused)]
63 pub fn new<#[cfg(afio)] A>( 87 pub fn new<CH1: QeiChannel, CH2: QeiChannel, #[cfg(afio)] A>(
64 tim: Peri<'d, T>, 88 tim: Peri<'d, T>,
65 ch1: if_afio!(QeiPin<'d, T, Ch1, A>), 89 ch1: Peri<'d, if_afio!(impl TimerPin<T, CH1, A>)>,
66 ch2: if_afio!(QeiPin<'d, T, Ch2, A>), 90 ch2: Peri<'d, if_afio!(impl TimerPin<T, CH2, A>)>,
91 config: Config,
67 ) -> Self { 92 ) -> Self {
68 Self::new_inner(tim) 93 // Configure the pins to be used for the QEI peripheral.
69 } 94 critical_section::with(|_| {
95 ch1.set_low();
96 set_as_af!(ch1, AfType::input(config.ch1_pull));
97
98 ch2.set_low();
99 set_as_af!(ch2, AfType::input(config.ch2_pull));
100 });
70 101
71 fn new_inner(tim: Peri<'d, T>) -> Self {
72 let inner = Timer::new(tim); 102 let inner = Timer::new(tim);
73 let r = inner.regs_gp16(); 103 let r = inner.regs_gp16();
74 104
@@ -88,13 +118,17 @@ impl<'d, T: GeneralInstance4Channel> Qei<'d, T> {
88 }); 118 });
89 119
90 r.smcr().modify(|w| { 120 r.smcr().modify(|w| {
91 w.set_sms(vals::Sms::ENCODER_MODE_3); 121 w.set_sms(config.mode.into());
92 }); 122 });
93 123
94 r.arr().modify(|w| w.set_arr(u16::MAX)); 124 r.arr().modify(|w| w.set_arr(u16::MAX));
95 r.cr1().modify(|w| w.set_cen(true)); 125 r.cr1().modify(|w| w.set_cen(true));
96 126
97 Self { inner } 127 Self {
128 inner,
129 _ch1: ch1.into(),
130 _ch2: ch2.into(),
131 }
98 } 132 }
99 133
100 /// Get direction. 134 /// Get direction.
diff --git a/embassy-stm32/src/timer/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs
index e60bb5b06..36303aeb4 100644
--- a/embassy-stm32/src/timer/simple_pwm.rs
+++ b/embassy-stm32/src/timer/simple_pwm.rs
@@ -5,11 +5,11 @@ use core::mem::ManuallyDrop;
5 5
6use super::low_level::{CountingMode, OutputCompareMode, OutputPolarity, Timer}; 6use super::low_level::{CountingMode, OutputCompareMode, OutputPolarity, Timer};
7use super::{Ch1, Ch2, Ch3, Ch4, Channel, GeneralInstance4Channel, TimerBits, TimerChannel, TimerPin}; 7use super::{Ch1, Ch2, Ch3, Ch4, Channel, GeneralInstance4Channel, TimerBits, TimerChannel, TimerPin};
8use crate::Peri;
8#[cfg(gpio_v2)] 9#[cfg(gpio_v2)]
9use crate::gpio::Pull; 10use crate::gpio::Pull;
10use crate::gpio::{AfType, AnyPin, OutputType, Speed}; 11use crate::gpio::{AfType, AnyPin, OutputType, Speed};
11use crate::time::Hertz; 12use crate::time::Hertz;
12use crate::Peri;
13 13
14/// PWM pin wrapper. 14/// PWM pin wrapper.
15/// 15///