1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
use crate::gpio::gpioa::{PA0, PA1, PA6, PA7, PA8, PA9};
use crate::gpio::{AltFunction, DefaultMode};
use crate::hal::{self, Direction};
use crate::rcc::Rcc;
use crate::stm32::{TIM1, TIM2, TIM3};
pub trait Pins<TIM> {
fn setup(&self);
}
impl Pins<TIM1> for (PA8<DefaultMode>, PA9<DefaultMode>) {
fn setup(&self) {
self.0.set_alt_mode(AltFunction::AF2);
self.1.set_alt_mode(AltFunction::AF2);
}
}
impl Pins<TIM2> for (PA0<DefaultMode>, PA1<DefaultMode>) {
fn setup(&self) {
self.0.set_alt_mode(AltFunction::AF2);
self.1.set_alt_mode(AltFunction::AF2);
}
}
impl Pins<TIM3> for (PA6<DefaultMode>, PA7<DefaultMode>) {
fn setup(&self) {
self.0.set_alt_mode(AltFunction::AF2);
self.1.set_alt_mode(AltFunction::AF2);
}
}
pub struct Qei<TIM, PINS> {
tim: TIM,
pins: PINS,
}
pub trait QeiExt<TIM, PINS>
where
PINS: Pins<TIM>,
{
fn qei(self, pins: PINS, rcc: &mut Rcc) -> Qei<TIM, PINS>;
}
macro_rules! qei {
($($TIMX:ident: ($tim:ident, $timXen:ident, $timXrst:ident, $apbenr:ident, $apbrstr:ident, $arr:ident, $cnt:ident),)+) => {
$(
impl<PINS> Qei<$TIMX, PINS> where PINS: Pins<$TIMX> {
fn $tim(tim: $TIMX, pins: PINS, rcc: &mut Rcc) -> Self {
pins.setup();
rcc.rb.$apbenr.modify(|_, w| w.$timXen().set_bit());
rcc.rb.$apbrstr.modify(|_, w| w.$timXrst().set_bit());
rcc.rb.$apbrstr.modify(|_, w| w.$timXrst().clear_bit());
tim.ccmr1_output.write(|w| unsafe {
w.cc1s().bits(0b01).cc2s().bits(0b01)
});
tim.smcr.write(|w| unsafe { w.sms().bits(0b011) });
tim.ccer.write(|w| {
w.cc1e()
.set_bit()
.cc2e()
.set_bit()
.cc1p()
.clear_bit()
.cc2p()
.clear_bit()
.cc1np()
.clear_bit()
.cc2np()
.clear_bit()
});
tim.arr.write(|w| unsafe { w.$arr().bits(0xffff) });
tim.cr1.write(|w| w.cen().set_bit());
Qei { tim, pins }
}
pub fn release(self) -> ($TIMX, PINS) {
(self.tim, self.pins)
}
}
impl<PINS> hal::Qei for Qei<$TIMX, PINS> {
type Count = u16;
fn count(&self) -> u16 {
self.tim.cnt.read().$cnt().bits()
}
fn direction(&self) -> Direction {
if self.tim.cr1.read().dir().bit_is_clear() {
hal::Direction::Upcounting
} else {
hal::Direction::Downcounting
}
}
}
impl<PINS> QeiExt<$TIMX, PINS> for $TIMX where PINS: Pins<$TIMX> {
fn qei(self, pins: PINS, rcc: &mut Rcc) -> Qei<$TIMX, PINS> {
Qei::$tim(self, pins, rcc)
}
}
)+
}
}
qei! {
TIM1: (tim1, tim1en, tim1rst, apbenr2, apbrstr2, arr, cnt),
TIM2: (tim2, tim2en, tim2rst, apbenr1, apbrstr1, arr_l, cnt_l),
TIM3: (tim3, tim3en, tim3rst, apbenr1, apbrstr1, arr_l, cnt_l),
}