aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src/timer/qei.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-stm32/src/timer/qei.rs')
-rw-r--r--embassy-stm32/src/timer/qei.rs56
1 files changed, 34 insertions, 22 deletions
diff --git a/embassy-stm32/src/timer/qei.rs b/embassy-stm32/src/timer/qei.rs
index f3c81667c..82b5968b0 100644
--- a/embassy-stm32/src/timer/qei.rs
+++ b/embassy-stm32/src/timer/qei.rs
@@ -6,8 +6,9 @@ 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::timer::TimerChannel;
11use crate::Peri; 12use crate::Peri;
12 13
13/// Counting direction 14/// Counting direction
@@ -19,31 +20,37 @@ pub enum Direction {
19} 20}
20 21
21/// Wrapper for using a pin with QEI. 22/// Wrapper for using a pin with QEI.
22pub struct QeiPin<'d, T, Channel> { 23pub struct QeiPin<'d, T, Channel, #[cfg(afio)] A> {
23 _pin: Peri<'d, AnyPin>, 24 #[allow(unused)]
24 phantom: PhantomData<(T, Channel)>, 25 pin: Peri<'d, AnyPin>,
26 phantom: PhantomData<if_afio!((T, Channel, A))>,
25} 27}
26 28
27macro_rules! channel_impl { 29impl<'d, T: GeneralInstance4Channel, C: QeiChannel, #[cfg(afio)] A> if_afio!(QeiPin<'d, T, C, A>) {
28 ($new_chx:ident, $channel:ident, $pin_trait:ident) => { 30 /// Create a new QEI pin instance.
29 impl<'d, T: GeneralInstance4Channel> QeiPin<'d, T, $channel> { 31 pub fn new(pin: Peri<'d, if_afio!(impl TimerPin<T, C, A>)>) -> Self {
30 #[doc = concat!("Create a new ", stringify!($channel), " QEI pin instance.")] 32 critical_section::with(|_| {
31 pub fn $new_chx(pin: Peri<'d, impl $pin_trait<T>>) -> Self { 33 pin.set_low();
32 critical_section::with(|_| { 34 set_as_af!(pin, AfType::input(Pull::None));
33 pin.set_low(); 35 });
34 pin.set_as_af(pin.af_num(), AfType::input(Pull::None)); 36 QeiPin {
35 }); 37 pin: pin.into(),
36 QeiPin { 38 phantom: PhantomData,
37 _pin: pin.into(),
38 phantom: PhantomData,
39 }
40 }
41 } 39 }
42 }; 40 }
43} 41}
44 42
45channel_impl!(new_ch1, Ch1, Channel1Pin); 43trait SealedQeiChannel: TimerChannel {}
46channel_impl!(new_ch2, Ch2, Channel2Pin); 44
45/// Marker trait for a timer channel eligible for use with QEI.
46#[expect(private_bounds)]
47pub trait QeiChannel: SealedQeiChannel {}
48
49impl QeiChannel for Ch1 {}
50impl QeiChannel for Ch2 {}
51
52impl SealedQeiChannel for Ch1 {}
53impl SealedQeiChannel for Ch2 {}
47 54
48/// Quadrature decoder driver. 55/// Quadrature decoder driver.
49pub struct Qei<'d, T: GeneralInstance4Channel> { 56pub struct Qei<'d, T: GeneralInstance4Channel> {
@@ -52,7 +59,12 @@ pub struct Qei<'d, T: GeneralInstance4Channel> {
52 59
53impl<'d, T: GeneralInstance4Channel> Qei<'d, T> { 60impl<'d, T: GeneralInstance4Channel> Qei<'d, T> {
54 /// Create a new quadrature decoder driver. 61 /// Create a new quadrature decoder driver.
55 pub fn new(tim: Peri<'d, T>, _ch1: QeiPin<'d, T, Ch1>, _ch2: QeiPin<'d, T, Ch2>) -> Self { 62 #[allow(unused)]
63 pub fn new<#[cfg(afio)] A>(
64 tim: Peri<'d, T>,
65 ch1: if_afio!(QeiPin<'d, T, Ch1, A>),
66 ch2: if_afio!(QeiPin<'d, T, Ch2, A>),
67 ) -> Self {
56 Self::new_inner(tim) 68 Self::new_inner(tim)
57 } 69 }
58 70