1use stm32::{RCC, TIM1, TIM14, TIM15, TIM16, TIM17, TIM3, TIM6, TIM7};
2
3use cast::{u16, u32};
4use hal::timer::{CountDown, Periodic};
5use nb;
6use rcc::Clocks;
7use void::Void;
8
9use time::Hertz;
10
11pub struct Timer<TIM> {
13 clocks: Clocks,
14 tim: TIM,
15 timeout: Hertz,
16}
17
18pub enum Event {
20 TimeOut,
22}
23
24macro_rules! timers {
25 ($($TIM:ident: ($tim:ident, $timXen:ident, $timXrst:ident, $apbenr:ident, $apbrstr:ident),)+) => {
26 $(
27 impl Periodic for Timer<$TIM> {}
28
29 impl CountDown for Timer<$TIM> {
30 type Time = Hertz;
31
32 #[allow(unused_unsafe)]
35 fn start<T>(&mut self, timeout: T)
36 where
37 T: Into<Hertz>,
38 {
39 self.tim.cr1.modify(|_, w| w.cen().clear_bit());
41 self.tim.cnt.reset();
43
44 self.timeout = timeout.into();
45
46 let frequency = self.timeout.0;
47 let ticks = self.clocks.pclk().0 / frequency;
48
49 let psc = u16((ticks - 1) / (1 << 16)).unwrap();
50 self.tim.psc.write(|w| unsafe { w.psc().bits(psc) });
51
52 let arr = u16(ticks / u32(psc + 1)).unwrap();
53 self.tim.arr.write(|w| unsafe { w.bits(u32(arr)) });
54
55 self.tim.cr1.modify(|_, w| w.cen().set_bit());
57 }
58
59 fn wait(&mut self) -> nb::Result<(), Void> {
60 if self.tim.sr.read().uif().bit_is_clear() {
61 Err(nb::Error::WouldBlock)
62 } else {
63 self.tim.sr.modify(|_, w| w.uif().clear_bit());
64 Ok(())
65 }
66 }
67 }
68
69 impl Timer<$TIM> {
70 pub fn $tim<T>(tim: $TIM, timeout: T, clocks: Clocks) -> Self
75 where
76 T: Into<Hertz>,
77 {
78 let rcc = unsafe { &(*RCC::ptr()) };
80 rcc.$apbenr.modify(|_, w| w.$timXen().set_bit());
82 rcc.$apbrstr.modify(|_, w| w.$timXrst().set_bit());
83 rcc.$apbrstr.modify(|_, w| w.$timXrst().clear_bit());
84
85 let mut timer = Timer {
86 clocks,
87 tim,
88 timeout: Hertz(0),
89 };
90 timer.start(timeout);
91
92 timer
93 }
94
95 pub fn listen(&mut self, event: Event) {
97 match event {
98 Event::TimeOut => {
99 self.tim.dier.write(|w| w.uie().set_bit());
101 }
102 }
103 }
104
105 pub fn unlisten(&mut self, event: Event) {
107 match event {
108 Event::TimeOut => {
109 self.tim.dier.write(|w| w.uie().clear_bit());
111 }
112 }
113 }
114
115 pub fn free(self) -> $TIM {
117 self.tim.cr1.modify(|_, w| w.cen().clear_bit());
119 self.tim
120 }
121 }
122 )+
123 }
124}
125
126#[cfg(any(
127 feature = "stm32f030f4",
128 feature = "stm32f030k6",
129 feature = "stm32f030c6",
130 feature = "stm32f030c8",
131 feature = "stm32f030r8",
132 feature = "stm32f030cc",
133 feature = "stm32f030rc"
134))]
135timers! {
136 TIM1: (tim1, tim1en, tim1rst, apb2enr, apb2rstr),
137 TIM3: (tim3, tim3en, tim3rst, apb1enr, apb1rstr),
138 TIM14: (tim14, tim14en, tim14rst, apb1enr, apb1rstr),
139 TIM16: (tim16, tim16en, tim16rst, apb2enr, apb2rstr),
140 TIM17: (tim17, tim17en, tim17rst, apb2enr, apb2rstr),
141}
142
143#[cfg(any(
144 feature = "stm32f030c8",
145 feature = "stm32f030r8",
146 feature = "stm32f030cc",
147 feature = "stm32f030rc"
148))]
149timers! {
150 TIM6: (tim6, tim6en, tim6rst, apb1enr, apb1rstr),
151 TIM15: (tim15, tim15en, tim15rst, apb2enr, apb2rstr),
152}
153
154#[cfg(any(feature = "stm32f030cc", feature = "stm32f030rc"))]
155timers! {
156 TIM7: (tim7, tim7en, tim7rst, apb1enr, apb1rstr),
157}