diff options
| author | Brian Schwind <[email protected]> | 2025-09-29 22:05:27 +0900 |
|---|---|---|
| committer | Brian Schwind <[email protected]> | 2025-09-29 22:05:27 +0900 |
| commit | 165fa1debd7f8aa6131c467825477a25e1862539 (patch) | |
| tree | 439c7c221cc44da6a8d6c27dfe6fa6267a37138d /embassy-stm32/src/timer | |
| parent | a791e9f1fc17eda2b05df97a72b94264ee6a4c12 (diff) | |
Add a Config struct for the Qei peripheral
Diffstat (limited to 'embassy-stm32/src/timer')
| -rw-r--r-- | embassy-stm32/src/timer/qei.rs | 65 |
1 files changed, 60 insertions, 5 deletions
diff --git a/embassy-stm32/src/timer/qei.rs b/embassy-stm32/src/timer/qei.rs index 25e8c3705..2e438bc74 100644 --- a/embassy-stm32/src/timer/qei.rs +++ b/embassy-stm32/src/timer/qei.rs | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | //! Quadrature decoder using a timer. | 1 | //! Quadrature decoder using a timer. |
| 2 | 2 | ||
| 3 | use stm32_metapac::timer::vals; | 3 | use stm32_metapac::timer::vals::{self, Sms}; |
| 4 | 4 | ||
| 5 | use super::low_level::Timer; | 5 | use super::low_level::Timer; |
| 6 | pub use super::{Ch1, Ch2}; | 6 | pub use super::{Ch1, Ch2}; |
| @@ -9,6 +9,51 @@ use crate::gpio::{AfType, AnyPin, Pull}; | |||
| 9 | use crate::timer::TimerChannel; | 9 | use crate::timer::TimerChannel; |
| 10 | use crate::Peri; | 10 | use crate::Peri; |
| 11 | 11 | ||
| 12 | /// Qei driver config. | ||
| 13 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 14 | #[derive(Clone, Copy)] | ||
| 15 | pub struct Config { | ||
| 16 | /// Configures the internal pull up/down resistor for Qei's channel 1 pin. | ||
| 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, | ||
| 22 | } | ||
| 23 | |||
| 24 | impl Default for Config { | ||
| 25 | /// Arbitrary defaults to preserve backwards compatibility | ||
| 26 | fn default() -> Self { | ||
| 27 | Self { | ||
| 28 | ch1_pull: Pull::None, | ||
| 29 | ch2_pull: Pull::None, | ||
| 30 | mode: QeiMode::Mode3, | ||
| 31 | } | ||
| 32 | } | ||
| 33 | } | ||
| 34 | |||
| 35 | /// See STMicro AN4013 for ยง2.3 for more information | ||
| 36 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 37 | #[derive(Clone, Copy)] | ||
| 38 | pub enum QeiMode { | ||
| 39 | /// Direct alias for [`Sms::ENCODER_MODE_1`] | ||
| 40 | Mode1, | ||
| 41 | /// Direct alias for [`Sms::ENCODER_MODE_2`] | ||
| 42 | Mode2, | ||
| 43 | /// Direct alias for [`Sms::ENCODER_MODE_3`] | ||
| 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, | ||
| 53 | } | ||
| 54 | } | ||
| 55 | } | ||
| 56 | |||
| 12 | /// Counting direction | 57 | /// Counting direction |
| 13 | pub enum Direction { | 58 | pub enum Direction { |
| 14 | /// Counting up. | 59 | /// Counting up. |
| @@ -37,20 +82,30 @@ pub struct Qei<'d, T: GeneralInstance4Channel> { | |||
| 37 | } | 82 | } |
| 38 | 83 | ||
| 39 | impl<'d, T: GeneralInstance4Channel> Qei<'d, T> { | 84 | impl<'d, T: GeneralInstance4Channel> Qei<'d, T> { |
| 40 | /// Create a new quadrature decoder driver. | 85 | /// Create a new quadrature decoder driver, with a given [`Config`]. |
| 41 | #[allow(unused)] | 86 | #[allow(unused)] |
| 42 | pub fn new<CH1: QeiChannel, CH2: QeiChannel, #[cfg(afio)] A>( | 87 | pub fn new<CH1: QeiChannel, CH2: QeiChannel, #[cfg(afio)] A>( |
| 43 | tim: Peri<'d, T>, | 88 | tim: Peri<'d, T>, |
| 44 | ch1: Peri<'d, if_afio!(impl TimerPin<T, CH1, A>)>, | 89 | ch1: Peri<'d, if_afio!(impl TimerPin<T, CH1, A>)>, |
| 45 | ch2: Peri<'d, if_afio!(impl TimerPin<T, CH2, A>)>, | 90 | ch2: Peri<'d, if_afio!(impl TimerPin<T, CH2, A>)>, |
| 46 | ) -> Self { | 91 | ) -> Self { |
| 92 | Self::new_with_config(tim, ch1, ch2, Default::default()) | ||
| 93 | } | ||
| 94 | /// Create a new quadrature decoder driver, with a given [`Config`]. | ||
| 95 | #[allow(unused)] | ||
| 96 | pub fn new_with_config<CH1: QeiChannel, CH2: QeiChannel, #[cfg(afio)] A>( | ||
| 97 | tim: Peri<'d, T>, | ||
| 98 | ch1: Peri<'d, if_afio!(impl TimerPin<T, CH1, A>)>, | ||
| 99 | ch2: Peri<'d, if_afio!(impl TimerPin<T, CH2, A>)>, | ||
| 100 | config: Config, | ||
| 101 | ) -> Self { | ||
| 47 | // Configure the pins to be used for the QEI peripheral. | 102 | // Configure the pins to be used for the QEI peripheral. |
| 48 | critical_section::with(|_| { | 103 | critical_section::with(|_| { |
| 49 | ch1.set_low(); | 104 | ch1.set_low(); |
| 50 | set_as_af!(ch1, AfType::input(Pull::None)); | 105 | set_as_af!(ch1, AfType::input(config.ch1_pull)); |
| 51 | 106 | ||
| 52 | ch2.set_low(); | 107 | ch2.set_low(); |
| 53 | set_as_af!(ch2, AfType::input(Pull::None)); | 108 | set_as_af!(ch2, AfType::input(config.ch2_pull)); |
| 54 | }); | 109 | }); |
| 55 | 110 | ||
| 56 | let inner = Timer::new(tim); | 111 | let inner = Timer::new(tim); |
| @@ -72,7 +127,7 @@ impl<'d, T: GeneralInstance4Channel> Qei<'d, T> { | |||
| 72 | }); | 127 | }); |
| 73 | 128 | ||
| 74 | r.smcr().modify(|w| { | 129 | r.smcr().modify(|w| { |
| 75 | w.set_sms(vals::Sms::ENCODER_MODE_3); | 130 | w.set_sms(config.mode.into()); |
| 76 | }); | 131 | }); |
| 77 | 132 | ||
| 78 | r.arr().modify(|w| w.set_arr(u16::MAX)); | 133 | r.arr().modify(|w| w.set_arr(u16::MAX)); |
