diff options
| author | chasingRs <[email protected]> | 2025-10-10 10:26:46 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-10-10 10:26:46 +0800 |
| commit | 944fda48a94c2d6cb6bea56c8c8471858d75da7d (patch) | |
| tree | 1e3e2f463c2440afe81ca37b2e161f85d0bfc374 /embassy-stm32/src/timer | |
| parent | 04171d903d3676d87aa0fd85719878d3087028f3 (diff) | |
| parent | 35b0ba4ce0fed7588febe504e16bbf1788384f5a (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.rs | 6 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/input_capture.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/one_pulse.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/pwm_input.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/qei.rs | 102 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/simple_pwm.rs | 2 |
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}; | |||
| 7 | use super::low_level::{CountingMode, OutputPolarity, Timer}; | 7 | use super::low_level::{CountingMode, OutputPolarity, Timer}; |
| 8 | use super::simple_pwm::PwmPin; | 8 | use super::simple_pwm::PwmPin; |
| 9 | use super::{AdvancedInstance4Channel, Ch1, Ch2, Ch3, Ch4, Channel, TimerComplementaryPin}; | 9 | use super::{AdvancedInstance4Channel, Ch1, Ch2, Ch3, Ch4, Channel, TimerComplementaryPin}; |
| 10 | use crate::Peri; | ||
| 10 | use crate::gpio::{AnyPin, OutputType}; | 11 | use crate::gpio::{AnyPin, OutputType}; |
| 11 | use crate::time::Hertz; | 12 | use crate::time::Hertz; |
| 12 | use crate::timer::low_level::OutputCompareMode; | ||
| 13 | use crate::timer::TimerChannel; | 13 | use crate::timer::TimerChannel; |
| 14 | use crate::Peri; | 14 | use 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)] |
| 390 | mod tests { | 390 | mod 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}; | |||
| 8 | use super::low_level::{CountingMode, FilterValue, InputCaptureMode, InputTISelection, Timer}; | 8 | use super::low_level::{CountingMode, FilterValue, InputCaptureMode, InputTISelection, Timer}; |
| 9 | use super::{CaptureCompareInterruptHandler, Channel, GeneralInstance4Channel, TimerPin}; | 9 | use super::{CaptureCompareInterruptHandler, Channel, GeneralInstance4Channel, TimerPin}; |
| 10 | pub use super::{Ch1, Ch2, Ch3, Ch4}; | 10 | pub use super::{Ch1, Ch2, Ch3, Ch4}; |
| 11 | use crate::Peri; | ||
| 11 | use crate::gpio::{AfType, AnyPin, Pull}; | 12 | use crate::gpio::{AfType, AnyPin, Pull}; |
| 12 | use crate::interrupt::typelevel::{Binding, Interrupt}; | 13 | use crate::interrupt::typelevel::{Binding, Interrupt}; |
| 13 | use crate::time::Hertz; | 14 | use crate::time::Hertz; |
| 14 | use crate::timer::TimerChannel; | 15 | use crate::timer::TimerChannel; |
| 15 | use 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 | }; |
| 12 | use super::{CaptureCompareInterruptHandler, Channel, ExternalTriggerPin, GeneralInstance4Channel, TimerPin}; | 12 | use super::{CaptureCompareInterruptHandler, Channel, ExternalTriggerPin, GeneralInstance4Channel, TimerPin}; |
| 13 | pub use super::{Ch1, Ch2}; | 13 | pub use super::{Ch1, Ch2}; |
| 14 | use crate::Peri; | ||
| 14 | use crate::gpio::{AfType, AnyPin, Pull}; | 15 | use crate::gpio::{AfType, AnyPin, Pull}; |
| 15 | use crate::interrupt::typelevel::{Binding, Interrupt}; | 16 | use crate::interrupt::typelevel::{Binding, Interrupt}; |
| 16 | use crate::pac::timer::vals::Etp; | 17 | use crate::pac::timer::vals::Etp; |
| 17 | use crate::time::Hertz; | 18 | use crate::time::Hertz; |
| 18 | use crate::timer::TimerChannel; | 19 | use crate::timer::TimerChannel; |
| 19 | use crate::Peri; | ||
| 20 | 20 | ||
| 21 | /// External input marker type. | 21 | /// External input marker type. |
| 22 | pub enum Ext {} | 22 | pub 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 | ||
| 3 | use super::low_level::{CountingMode, InputCaptureMode, InputTISelection, SlaveMode, Timer, TriggerSource}; | 3 | use super::low_level::{CountingMode, InputCaptureMode, InputTISelection, SlaveMode, Timer, TriggerSource}; |
| 4 | use super::{Ch1, Ch2, Channel, GeneralInstance4Channel, TimerPin}; | 4 | use super::{Ch1, Ch2, Channel, GeneralInstance4Channel, TimerPin}; |
| 5 | use crate::Peri; | ||
| 5 | use crate::gpio::{AfType, Pull}; | 6 | use crate::gpio::{AfType, Pull}; |
| 6 | use crate::time::Hertz; | 7 | use crate::time::Hertz; |
| 7 | use 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 | ||
| 3 | use core::marker::PhantomData; | 3 | use stm32_metapac::timer::vals::{self, Sms}; |
| 4 | |||
| 5 | use stm32_metapac::timer::vals; | ||
| 6 | 4 | ||
| 7 | use super::low_level::Timer; | 5 | use super::low_level::Timer; |
| 8 | pub use super::{Ch1, Ch2}; | 6 | pub use super::{Ch1, Ch2}; |
| 9 | use super::{GeneralInstance4Channel, TimerPin}; | 7 | use super::{GeneralInstance4Channel, TimerPin}; |
| 8 | use crate::Peri; | ||
| 10 | use crate::gpio::{AfType, AnyPin, Pull}; | 9 | use crate::gpio::{AfType, AnyPin, Pull}; |
| 11 | use crate::timer::TimerChannel; | 10 | use crate::timer::TimerChannel; |
| 12 | use crate::Peri; | ||
| 13 | 11 | ||
| 14 | /// Counting direction | 12 | /// Qei driver config. |
| 15 | pub enum Direction { | 13 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 16 | /// Counting up. | 14 | #[derive(Clone, Copy)] |
| 17 | Upcounting, | 15 | pub 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. | 24 | impl Default for Config { |
| 23 | pub 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 | ||
| 29 | impl<'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(|_| { | 38 | pub 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 | |||
| 47 | impl 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 | ||
| 58 | pub enum Direction { | ||
| 59 | /// Counting up. | ||
| 60 | Upcounting, | ||
| 61 | /// Counting down. | ||
| 62 | Downcounting, | ||
| 63 | } | ||
| 64 | |||
| 43 | trait SealedQeiChannel: TimerChannel {} | 65 | trait 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. |
| 56 | pub struct Qei<'d, T: GeneralInstance4Channel> { | 78 | pub 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 | ||
| 60 | impl<'d, T: GeneralInstance4Channel> Qei<'d, T> { | 84 | impl<'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 | ||
| 6 | use super::low_level::{CountingMode, OutputCompareMode, OutputPolarity, Timer}; | 6 | use super::low_level::{CountingMode, OutputCompareMode, OutputPolarity, Timer}; |
| 7 | use super::{Ch1, Ch2, Ch3, Ch4, Channel, GeneralInstance4Channel, TimerBits, TimerChannel, TimerPin}; | 7 | use super::{Ch1, Ch2, Ch3, Ch4, Channel, GeneralInstance4Channel, TimerBits, TimerChannel, TimerPin}; |
| 8 | use crate::Peri; | ||
| 8 | #[cfg(gpio_v2)] | 9 | #[cfg(gpio_v2)] |
| 9 | use crate::gpio::Pull; | 10 | use crate::gpio::Pull; |
| 10 | use crate::gpio::{AfType, AnyPin, OutputType, Speed}; | 11 | use crate::gpio::{AfType, AnyPin, OutputType, Speed}; |
| 11 | use crate::time::Hertz; | 12 | use crate::time::Hertz; |
| 12 | use crate::Peri; | ||
| 13 | 13 | ||
| 14 | /// PWM pin wrapper. | 14 | /// PWM pin wrapper. |
| 15 | /// | 15 | /// |
