1use core::u16;
8
9use core::marker::PhantomData;
10
11use crate::hal::{self, Direction};
12#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity",))]
13use crate::pac::TIM1;
14#[cfg(feature = "medium")]
15use crate::pac::TIM4;
16use crate::pac::{TIM2, TIM3};
17
18use crate::afio::MAPR;
19
20use crate::pwm_input::Pins;
21use crate::timer::{sealed::Remap, Timer};
22
23#[derive(Copy, Clone, Debug)]
25pub enum SlaveMode {
26 EncoderMode1 = 0b001,
28 EncoderMode2 = 0b010,
30 EncoderMode3 = 0b011,
33 ResetMode = 0b100,
36 TriggerMode = 0b110,
39 ExternalClockMode1 = 0b111,
41}
42
43#[derive(Copy, Clone, Debug)]
48pub struct QeiOptions {
49 pub slave_mode: SlaveMode,
51
52 pub auto_reload_value: u16,
57}
58
59impl Default for QeiOptions {
60 fn default() -> Self {
61 Self {
62 slave_mode: SlaveMode::EncoderMode3,
63 auto_reload_value: u16::MAX,
64 }
65 }
66}
67
68pub struct Qei<TIM, REMAP, PINS> {
69 tim: TIM,
70 pins: PINS,
71 _remap: PhantomData<REMAP>,
72}
73
74#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity",))]
75impl Timer<TIM1> {
76 pub fn qei<REMAP, PINS>(
77 self,
78 pins: PINS,
79 mapr: &mut MAPR,
80 options: QeiOptions,
81 ) -> Qei<TIM1, REMAP, PINS>
82 where
83 REMAP: Remap<Periph = TIM1>,
84 PINS: Pins<REMAP>,
85 {
86 mapr.modify_mapr(|_, w| unsafe { w.tim1_remap().bits(REMAP::REMAP) });
87
88 let Self { tim, clk: _ } = self;
89 Qei::_tim1(tim, pins, options)
90 }
91}
92
93impl Timer<TIM2> {
94 pub fn qei<REMAP, PINS>(
95 self,
96 pins: PINS,
97 mapr: &mut MAPR,
98 options: QeiOptions,
99 ) -> Qei<TIM2, REMAP, PINS>
100 where
101 REMAP: Remap<Periph = TIM2>,
102 PINS: Pins<REMAP>,
103 {
104 mapr.modify_mapr(|_, w| unsafe { w.tim2_remap().bits(REMAP::REMAP) });
105
106 let Self { tim, clk: _ } = self;
107 Qei::_tim2(tim, pins, options)
108 }
109}
110
111impl Timer<TIM3> {
112 pub fn qei<REMAP, PINS>(
113 self,
114 pins: PINS,
115 mapr: &mut MAPR,
116 options: QeiOptions,
117 ) -> Qei<TIM3, REMAP, PINS>
118 where
119 REMAP: Remap<Periph = TIM3>,
120 PINS: Pins<REMAP>,
121 {
122 mapr.modify_mapr(|_, w| unsafe { w.tim3_remap().bits(REMAP::REMAP) });
123
124 let Self { tim, clk: _ } = self;
125 Qei::_tim3(tim, pins, options)
126 }
127}
128
129#[cfg(feature = "medium")]
130impl Timer<TIM4> {
131 pub fn qei<REMAP, PINS>(
132 self,
133 pins: PINS,
134 mapr: &mut MAPR,
135 options: QeiOptions,
136 ) -> Qei<TIM4, REMAP, PINS>
137 where
138 REMAP: Remap<Periph = TIM4>,
139 PINS: Pins<REMAP>,
140 {
141 mapr.modify_mapr(|_, w| w.tim4_remap().bit(REMAP::REMAP == 1));
142
143 let Self { tim, clk: _ } = self;
144 Qei::_tim4(tim, pins, options)
145 }
146}
147
148macro_rules! hal {
149 ($($TIMX:ident: ($timX:ident, $timXen:ident, $timXrst:ident),)+) => {
150 $(
151 impl<REMAP, PINS> Qei<$TIMX, REMAP, PINS> {
152 fn $timX(tim: $TIMX, pins: PINS, options: QeiOptions) -> Self {
153 tim.ccmr1_input().write(|w| w.cc1s().ti1().cc2s().ti2());
155
156 tim.ccer.write(|w| {
158 w.cc1e()
159 .set_bit()
160 .cc1p()
161 .clear_bit()
162 .cc2e()
163 .set_bit()
164 .cc2p()
165 .clear_bit()
166 });
167
168 tim.smcr.write(|w| w.sms().bits(options.slave_mode as u8));
170
171 tim.arr.write(|w| w.arr().bits(options.auto_reload_value));
172 tim.cr1.write(|w| w.cen().set_bit());
173
174 Qei { tim, pins, _remap: PhantomData }
175 }
176
177 pub fn release(self) -> ($TIMX, PINS) {
178 (self.tim, self.pins)
179 }
180 }
181
182 impl<REMAP, PINS> hal::Qei for Qei<$TIMX, REMAP, PINS> {
183 type Count = u16;
184
185 fn count(&self) -> u16 {
186 self.tim.cnt.read().cnt().bits()
187 }
188
189 fn direction(&self) -> Direction {
190 if self.tim.cr1.read().dir().bit_is_clear() {
191 hal::Direction::Upcounting
192 } else {
193 hal::Direction::Downcounting
194 }
195 }
196 }
197
198 )+
199 }
200}
201
202#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity",))]
203hal! {
204 TIM1: (_tim1, tim1en, tim1rst),
205}
206hal! {
207 TIM2: (_tim2, tim2en, tim2rst),
208 TIM3: (_tim3, tim3en, tim3rst),
209}
210#[cfg(feature = "medium")]
211hal! {
212 TIM4: (_tim4, tim4en, tim4rst),
213}