1use crate::hal::{self, Direction};
3use crate::stm32::RCC;
4
5use crate::gpio::gpioa::*;
6use crate::gpio::gpiob::*;
7use crate::gpio::gpioc::*;
8use crate::gpio::gpiod::*;
9use crate::gpio::gpioe::*;
10use crate::gpio::gpiof::*;
11use crate::gpio::gpioh::*;
12use crate::gpio::gpioi::*;
13use crate::gpio::{Alternate, AF1, AF2, AF3};
14
15use crate::stm32::{TIM1, TIM5, TIM2, TIM3, TIM4, TIM8};
16
17pub trait Pins<TIM> {}
18pub trait PinC1<TIM> {}
19pub trait PinC2<TIM> {}
20
21impl<TIM, PC1, PC2> Pins<TIM> for (PC1, PC2)
22where
23 PC1: PinC1<TIM>,
24 PC2: PinC2<TIM>,
25{
26}
27
28impl PinC1<TIM1> for PA8<Alternate<AF1>> {}
29impl PinC2<TIM1> for PA9<Alternate<AF1>> {}
30impl PinC1<TIM1> for PE9<Alternate<AF1>> {}
31impl PinC2<TIM1> for PE11<Alternate<AF1>> {}
32impl PinC1<TIM2> for PA0<Alternate<AF1>> {}
33impl PinC1<TIM2> for PA5<Alternate<AF1>> {}
34impl PinC1<TIM2> for PA15<Alternate<AF1>> {}
35impl PinC2<TIM2> for PA1<Alternate<AF1>> {}
36impl PinC2<TIM2> for PB3<Alternate<AF1>> {}
37impl PinC1<TIM2> for PB8<Alternate<AF1>> {}
38impl PinC2<TIM2> for PB9<Alternate<AF1>> {}
39impl PinC1<TIM3> for PA6<Alternate<AF2>> {}
40impl PinC2<TIM3> for PA7<Alternate<AF2>> {}
41impl PinC1<TIM3> for PB4<Alternate<AF2>> {}
42impl PinC2<TIM3> for PB5<Alternate<AF2>> {}
43impl PinC1<TIM3> for PC6<Alternate<AF2>> {}
44impl PinC2<TIM3> for PC7<Alternate<AF2>> {}
45impl PinC1<TIM4> for PB6<Alternate<AF2>> {}
46impl PinC2<TIM4> for PB7<Alternate<AF2>> {}
47impl PinC1<TIM4> for PD12<Alternate<AF2>> {}
48impl PinC2<TIM4> for PD13<Alternate<AF2>> {}
49impl PinC1<TIM5> for PA0<Alternate<AF2>> {}
50impl PinC2<TIM5> for PA1<Alternate<AF2>> {}
51impl PinC1<TIM5> for PB12<Alternate<AF2>> {}
52impl PinC1<TIM5> for PF3<Alternate<AF2>> {}
53impl PinC2<TIM5> for PF4<Alternate<AF2>> {}
54impl PinC1<TIM5> for PH10<Alternate<AF2>> {}
55impl PinC2<TIM5> for PH11<Alternate<AF2>> {}
56impl PinC1<TIM8> for PC6<Alternate<AF3>> {}
57impl PinC2<TIM8> for PC7<Alternate<AF3>> {}
58impl PinC1<TIM8> for PI5<Alternate<AF3>> {}
59impl PinC2<TIM8> for PI6<Alternate<AF3>> {}
60
61pub struct Qei<TIM, PINS> {
63 tim: TIM,
64 pins: PINS,
65}
66
67macro_rules! hal {
68 ($($TIM:ident: ($tim:ident, $timXen:ident, $timXrst:ident, $apbenr:ident, $apbrstr:ident, $bits:ident),)+) => {
69 $(
70 impl<PINS> Qei<$TIM, PINS> {
71 pub fn $tim(tim: $TIM, pins: PINS) -> Self
73 where
74 PINS: Pins<$TIM>
75 {
76 let rcc = unsafe { &(*RCC::ptr()) };
77 rcc.$apbenr.modify(|_, w| w.$timXen().set_bit());
79 rcc.$apbrstr.modify(|_, w| w.$timXrst().set_bit());
80 rcc.$apbrstr.modify(|_, w| w.$timXrst().clear_bit());
81
82 tim.ccmr1_output
84 .write(|w| unsafe { w.cc1s().bits(0b01).cc2s().bits(0b01) });
85
86 tim.ccer.write(|w| {
88 w.cc1e()
89 .set_bit()
90 .cc1p()
91 .clear_bit()
92 .cc2e()
93 .set_bit()
94 .cc2p()
95 .clear_bit()
96 });
97
98 #[allow(unused_unsafe)]
101 tim.smcr.write(|w| unsafe { w.sms().bits(3) });
102
103 tim.arr.write(|w| unsafe { w.bits(core::u32::MAX) });
104 tim.cr1.write(|w| w.cen().set_bit());
105
106 Qei { tim, pins }
107 }
108
109 pub fn release(self) -> ($TIM, PINS) {
111 (self.tim, self.pins)
112 }
113 }
114
115 impl<PINS> hal::Qei for Qei<$TIM, PINS> {
116 type Count = $bits;
117
118 fn count(&self) -> $bits {
119 self.tim.cnt.read().bits() as $bits
120 }
121
122 fn direction(&self) -> Direction {
123 if self.tim.cr1.read().dir().bit_is_clear() {
124 hal::Direction::Upcounting
125 } else {
126 hal::Direction::Downcounting
127 }
128 }
129 }
130
131 )+
132 }
133}
134
135hal! {
136 TIM1: (tim1, tim1en, tim1rst, apb2enr, apb2rstr, u16),
137 TIM5: (tim5, tim5en, tim5rst, apb1enr, apb1rstr, u32),
138 TIM2: (tim2, tim2en, tim2rst, apb1enr, apb1rstr, u32),
139 TIM3: (tim3, tim3en, tim3rst, apb1enr, apb1rstr, u16),
140 TIM4: (tim4, tim4en, tim4rst, apb1enr, apb1rstr, u16),
141 TIM8: (tim8, tim8en, tim8rst, apb2enr, apb2rstr, u16),
142}