1use void::Void;
4use cast::{u16, u32};
5use hal::timer::{CountDown, Periodic};
6use nb;
7use stm32f429::{TIM1, TIM2, TIM3, TIM4, TIM5,
8 TIM6, TIM7, TIM8, TIM9, TIM10,
9 TIM11, TIM12, TIM13, TIM14};
10
11use rcc::{APB1, APB2, Clocks};
12use time::Hertz;
13
14pub struct Timer<TIM> {
16 clocks: Clocks,
17 tim: TIM,
18 timeout: Hertz,
19}
20
21pub enum Event {
23 TimeOut,
25}
26
27macro_rules! hal {
28 ($($TIM:ident: ($tim:ident, $APB:ident, $timXen:ident, $timXrst:ident),)+) => {
29 $(
30 impl Periodic for Timer<$TIM> {}
31
32 impl CountDown for Timer<$TIM> {
33 type Time = Hertz;
34
35 #[allow(unused_unsafe)]
38 fn start<T>(&mut self, timeout: T)
39 where
40 T: Into<Hertz>,
41 {
42 self.tim.cr1.modify(|_, w| w.cen().clear_bit());
44 self.tim.cnt.reset();
46
47 self.timeout = timeout.into();
48
49 let frequency = self.timeout.0;
50 let ticks = self.clocks.pclk1().0 * if self.clocks.ppre1() == 1 { 1 } else { 2 }
51 / frequency;
52
53 let psc = u16((ticks - 1) / (1 << 16)).unwrap();
54 self.tim.psc.write(|w| unsafe { w.psc().bits(psc) });
55
56 let arr = u16(ticks / u32(psc + 1)).unwrap();
57 self.tim.arr.write(|w| unsafe { w.bits(u32(arr)) });
58
59 self.tim.cr1.modify(|_, w| w.cen().set_bit());
61 }
62
63 fn wait(&mut self) -> nb::Result<(), Void> {
64 if self.tim.sr.read().uif().bit_is_clear() {
65 Err(nb::Error::WouldBlock)
66 } else {
67 self.tim.sr.modify(|_, w| w.uif().clear_bit());
68 Ok(())
69 }
70 }
71 }
72
73 impl Timer<$TIM> {
74 pub fn $tim<T>(tim: $TIM, timeout: T, clocks: Clocks, apb: &mut $APB) -> Self
79 where
80 T: Into<Hertz>,
81 {
82 apb.enr().modify(|_, w| w.$timXen().set_bit());
84 apb.rstr().modify(|_, w| w.$timXrst().set_bit());
85 apb.rstr().modify(|_, w| w.$timXrst().clear_bit());
86
87 let mut timer = Timer {
88 clocks,
89 tim,
90 timeout: Hertz(0),
91 };
92 timer.start(timeout);
93
94 timer
95 }
96
97 pub fn listen(&mut self, event: Event) {
99 match event {
100 Event::TimeOut => {
101 self.tim.dier.write(|w| w.uie().set_bit());
103 }
104 }
105 }
106
107 pub fn unlisten(&mut self, event: Event) {
109 match event {
110 Event::TimeOut => {
111 self.tim.dier.write(|w| w.uie().clear_bit());
113 }
114 }
115 }
116
117 pub fn free(self) -> $TIM {
119 self.tim.cr1.modify(|_, w| w.cen().clear_bit());
121 self.tim
122 }
123 }
124 )+
125 }
126}
127
128hal! {
129 TIM1: (tim1, APB2, tim1en, tim1rst),
130 TIM2: (tim2, APB1, tim2en, tim2rst),
131 TIM3: (tim3, APB1, tim3en, tim3rst),
132 TIM4: (tim4, APB1, tim4en, tim4rst),
133 TIM5: (tim5, APB1, tim5en, tim5rst),
134 TIM6: (tim6, APB1, tim6en, tim6rst),
135 TIM7: (tim7, APB1, tim7en, tim7rst),
136 TIM8: (tim8, APB2, tim8en, tim8rst),
137 TIM9: (tim9, APB2, tim9en, tim9rst),
138 TIM10: (tim10, APB2, tim10en, tim10rst),
139 TIM11: (tim11, APB2, tim11en, tim11rst),
140 TIM12: (tim12, APB1, tim12en, tim12rst),
141 TIM13: (tim13, APB1, tim13en, tim13rst),
142 TIM14: (tim14, APB1, tim14en, tim14rst),
143}