stm32g0xx_hal/timer/
mod.rs1use crate::rcc::*;
3use crate::stm32::*;
4use crate::time::{Hertz, MicroSecond};
5use core::marker::PhantomData;
6use cortex_m::peripheral::syst::SystClkSource;
7use cortex_m::peripheral::SYST;
8use hal::timer::{CountDown, Periodic};
9use void::Void;
10
11pub mod delay;
12pub mod opm;
13pub mod pins;
14pub mod pwm;
15pub mod qei;
16pub mod stopwatch;
17
18pub struct Timer<TIM> {
20 clk: Hertz,
21 tim: TIM,
22}
23
24pub struct Channel1;
25pub struct Channel2;
26pub struct Channel3;
27pub struct Channel4;
28
29impl Timer<SYST> {
31 pub fn syst(mut syst: SYST, rcc: &mut Rcc) -> Self {
33 syst.set_clock_source(SystClkSource::Core);
34 Timer {
35 tim: syst,
36 clk: rcc.clocks.apb_tim_clk,
37 }
38 }
39
40 pub fn listen(&mut self) {
42 self.tim.enable_interrupt()
43 }
44
45 pub fn unlisten(&mut self) {
47 self.tim.disable_interrupt()
48 }
49
50 pub fn get_current(&self) -> u32 {
51 SYST::get_current()
52 }
53}
54
55impl Timer<SYST> {
56 pub fn start(&mut self, timeout: MicroSecond) {
57 let cycles = crate::time::cycles(timeout, self.clk);
58 assert!(cycles < 0x00ff_ffff);
59 self.tim.set_reload(cycles);
60 self.tim.clear_current();
61 self.tim.enable_counter();
62 }
63
64 pub fn wait(&mut self) -> nb::Result<(), Void> {
65 if self.tim.has_wrapped() {
66 Ok(())
67 } else {
68 Err(nb::Error::WouldBlock)
69 }
70 }
71}
72
73impl CountDown for Timer<SYST> {
74 type Time = MicroSecond;
75
76 fn start<T>(&mut self, timeout: T)
77 where
78 T: Into<MicroSecond>,
79 {
80 self.start(timeout.into())
81 }
82
83 fn wait(&mut self) -> nb::Result<(), Void> {
84 self.wait()
85 }
86}
87
88pub trait TimerExt<TIM> {
89 fn timer(self, rcc: &mut Rcc) -> Timer<TIM>;
90}
91
92impl TimerExt<SYST> for SYST {
93 fn timer(self, rcc: &mut Rcc) -> Timer<SYST> {
94 Timer::syst(self, rcc)
95 }
96}
97
98impl Periodic for Timer<SYST> {}
99
100macro_rules! timers {
101 ($($TIM:ident: ($tim:ident, $cnt:ident $(,$cnt_h:ident)*),)+) => {
102 $(
103 impl Timer<$TIM> {
104 pub fn $tim(tim: $TIM, rcc: &mut Rcc) -> Self {
106 $TIM::enable(rcc);
107 $TIM::reset(rcc);
108
109 Timer {
110 tim,
111 clk: rcc.clocks.apb_tim_clk,
112 }
113 }
114
115 pub fn pause(&mut self) {
117 self.tim.cr1.modify(|_, w| w.cen().clear_bit());
118 }
119
120 pub fn resume(&mut self) {
122 self.tim.cr1.modify(|_, w| w.cen().set_bit());
123 }
124
125 pub fn listen(&mut self) {
127 self.tim.dier.write(|w| w.uie().set_bit());
128 }
129
130 pub fn unlisten(&mut self) {
132 self.tim.dier.write(|w| w.uie().clear_bit());
133 }
134
135 pub fn clear_irq(&mut self) {
137 self.tim.sr.modify(|_, w| w.uif().clear_bit());
138 }
139
140 pub fn reset(&mut self) {
142 self.tim.cnt.reset();
143 }
144
145 pub fn get_current(&self) -> u32 {
147 let _high = 0;
148 $(
149 let _high = self.tim.cnt.read().$cnt_h().bits() as u32;
150 )*
151 let low = self.tim.cnt.read().$cnt().bits() as u32;
152 low | (_high << 16)
153 }
154
155 pub fn start(&mut self, timeout: MicroSecond) {
156 self.tim.cr1.modify(|_, w| w.cen().clear_bit().urs().set_bit());
159 self.tim.cnt.reset();
161 self.tim.sr.modify(|_, w| w.uif().clear_bit());
163
164 let cycles = crate::time::cycles(timeout, self.clk);
166 let psc = cycles / 0xffff;
167 let arr = cycles / (psc + 1);
168
169 self.tim.psc.write(|w| unsafe { w.psc().bits(psc as u16) });
170 self.tim.arr.write(|w| unsafe { w.bits(arr) });
171
172 self.tim.egr.write(|w| w.ug().set_bit());
175
176 self.tim.cr1.modify(|_, w| w.cen().set_bit());
177 }
178
179 pub fn wait(&mut self) -> nb::Result<(), Void> {
180 if self.tim.sr.read().uif().bit_is_clear() {
181 Err(nb::Error::WouldBlock)
182 } else {
183 self.tim.sr.modify(|_, w| w.uif().clear_bit());
184 Ok(())
185 }
186 }
187
188 pub fn release(self) -> $TIM {
190 self.tim
191 }
192 }
193
194 impl TimerExt<$TIM> for $TIM {
195 fn timer(self, rcc: &mut Rcc) -> Timer<$TIM> {
196 Timer::$tim(self, rcc)
197 }
198 }
199
200 impl CountDown for Timer<$TIM> {
201 type Time = MicroSecond;
202
203 fn start<T>(&mut self, timeout: T)
204 where
205 T: Into<MicroSecond>,
206 {
207 self.start(timeout.into())
208 }
209
210 fn wait(&mut self) -> nb::Result<(), Void> {
211 self.wait()
212 }
213 }
214
215 impl Periodic for Timer<$TIM> {}
216 )+
217 }
218}
219
220pub enum ExternalClockMode {
221 Mode1,
222 Mode2,
223}
224
225pub trait ExternalClock {
226 fn mode(&self) -> ExternalClockMode;
227}
228
229macro_rules! timers_external_clocks {
230 ($($TIM:ident: ($tim:ident, $sms:ident $(,$ece:ident)*),)+) => {
231 $(
232 impl Timer<$TIM> {
233 pub fn use_external_clock<C: ExternalClock>(&mut self, clk: C, freq: Hertz) {
234 self.clk = freq;
235 match clk.mode() {
236 ExternalClockMode::Mode1 => {
237 self.tim.smcr.modify(|_, w| unsafe { w.$sms().bits(0b111) });
238 $(
239 self.tim.smcr.modify(|_, w| w.$ece().clear_bit());
240 )*
241 },
242 ExternalClockMode::Mode2 => {
243 self.tim.smcr.modify(|_, w| unsafe { w.$sms().bits(0b0) });
244 $(
245 self.tim.smcr.modify(|_, w| w.$ece().set_bit());
246 )*
247 },
248 }
249 }
250 }
251 )+
252 }
253}
254
255timers_external_clocks! {
256 TIM1: (tim1, sms, ece),
257 TIM3: (tim3, sms, ece),
258}
259
260#[cfg(feature = "stm32g0x1")]
261timers_external_clocks! {
262 TIM2: (tim2, sms, ece),
263}
264
265#[cfg(any(feature = "stm32g070", feature = "stm32g071"))]
266timers_external_clocks! {
267 TIM15: (tim15, sms1),
268}
269
270timers! {
271 TIM1: (tim1, cnt),
272 TIM3: (tim3, cnt_l, cnt_h),
273 TIM14: (tim14, cnt),
274 TIM16: (tim16, cnt),
275 TIM17: (tim17, cnt),
276}
277
278#[cfg(feature = "stm32g0x1")]
279timers! {
280 TIM2: (tim2, cnt_l, cnt_h),
281}
282
283#[cfg(any(feature = "stm32g070", feature = "stm32g071", feature = "stm32g081"))]
284timers! {
285 TIM6: (tim6, cnt),
286 TIM7: (tim7, cnt),
287 TIM15: (tim15, cnt),
288}