stm32g0xx_hal/timer/
stopwatch.rs1use crate::rcc::*;
2use crate::stm32::*;
3use crate::time::{duration, Hertz, Instant, MicroSecond};
4
5pub trait StopwatchExt<TIM> {
6 fn stopwatch(self, rcc: &mut Rcc) -> Stopwatch<TIM>;
7}
8
9pub struct Stopwatch<TIM> {
10 clk: Hertz,
11 tim: TIM,
12}
13
14macro_rules! stopwatches {
15 ($($TIM:ident: $tim:ident, $depth:ident,)+) => {
16 $(
17 impl Stopwatch<$TIM> {
18 pub fn $tim(tim: $TIM, rcc: &mut Rcc) -> Self {
19 assert!(rcc.clocks.apb_tim_clk.raw() > 1_000_000);
20 $TIM::enable(rcc);
21 $TIM::reset(rcc);
22
23 tim.cr1.modify(|_, w| w.cen().set_bit());
24 Stopwatch {
25 tim,
26 clk: rcc.clocks.apb_tim_clk,
27 }
28 }
29
30 pub fn set_clock(&mut self, clk: Hertz) {
35 assert!(clk.raw() > 1_000_000);
36 self.clk = clk;
37 }
38
39 pub fn set_prescaler(&mut self, prescaler: u16) {
43 self.tim.psc.write(|w| unsafe { w.psc().bits(prescaler) });
44 self.tim.egr.write(|w| w.ug().set_bit());
45 }
46
47 pub fn reset(&mut self) {
48 self.tim.cnt.reset();
49 }
50
51 pub fn pause(&mut self) {
52 self.tim.cr1.modify(|_, w| w.cen().clear_bit());
53 }
54
55 pub fn resume(&mut self) {
56 self.tim.cr1.modify(|_, w| w.cen().set_bit());
57 }
58
59 pub fn release(self) -> $TIM {
60 self.tim
61 }
62
63 pub fn now(&self) -> Instant {
64 Instant::from_ticks(self.tim.cnt.read().bits())
65 }
66
67 pub fn elapsed(&self, ts: Instant) -> MicroSecond {
68 let now = self.now().ticks();
69 let cycles = (now as $depth).wrapping_sub(ts.ticks() as $depth) as u32;
70 duration(self.clk, cycles * (1 + self.tim.psc.read().bits()))
71 }
72
73 pub fn trace<F>(&self, mut closure: F) -> MicroSecond
74 where
75 F: FnMut(),
76 {
77 let started = self.now().ticks();
78 closure();
79 let now = self.now().ticks();
80 duration(self.clk, now.wrapping_sub(started) * (1 + self.tim.psc.read().bits()))
81 }
82 }
83
84 impl StopwatchExt<$TIM> for $TIM {
85 fn stopwatch(self, rcc: &mut Rcc) -> Stopwatch<$TIM> {
86 Stopwatch::$tim(self, rcc)
87 }
88 }
89 )+
90 }
91}
92
93stopwatches! {
94 TIM1: tim1, u16,
95 TIM3: tim3, u16,
96 TIM14: tim14, u16,
97 TIM16: tim16, u16,
98 TIM17: tim17, u16,
99}
100
101#[cfg(feature = "stm32g0x1")]
102stopwatches! {
103 TIM2: tim2, u32,
104}
105
106#[cfg(any(feature = "stm32g070", feature = "stm32g071", feature = "stm32g081"))]
107stopwatches! {
108 TIM6: tim6, u16,
109 TIM7: tim7, u16,
110 TIM15: tim15, u16,
111}