1use cortex_m::peripheral::DWT;
2
3#[derive(PartialEq, PartialOrd, Clone, Copy)]
4pub struct Bps(pub u32);
5
6#[derive(PartialEq, PartialOrd, Clone, Copy)]
7pub struct Hertz(pub u32);
8
9#[derive(PartialEq, PartialOrd, Clone, Copy)]
10pub struct MicroSeconds(pub u32);
11
12pub trait U32Ext {
14 fn bps(self) -> Bps;
16
17 fn hz(self) -> Hertz;
19
20 fn khz(self) -> Hertz;
22
23 fn mhz(self) -> Hertz;
25
26 fn us(self) -> MicroSeconds;
28
29 fn ms(self) -> MicroSeconds;
31}
32
33pub trait MonoTimerExt {
34 fn monotonic<T>(self, sys_clk: T) -> MonoTimer
35 where
36 T: Into<Hertz>;
37}
38
39impl U32Ext for u32 {
40 fn bps(self) -> Bps {
41 Bps(self)
42 }
43
44 fn hz(self) -> Hertz {
45 Hertz(self)
46 }
47
48 fn khz(self) -> Hertz {
49 Hertz(self * 1_000)
50 }
51
52 fn mhz(self) -> Hertz {
53 Hertz(self * 1_000_000)
54 }
55
56 fn ms(self) -> MicroSeconds {
57 MicroSeconds(self * 1_000)
58 }
59
60 fn us(self) -> MicroSeconds {
61 MicroSeconds(self)
62 }
63}
64
65impl Into<MicroSeconds> for Hertz {
66 fn into(self) -> MicroSeconds {
67 let freq = self.0;
68 assert!(freq != 0 && freq <= 1_000_000);
69 MicroSeconds(1_000_000 / freq)
70 }
71}
72
73impl Into<Hertz> for MicroSeconds {
74 fn into(self) -> Hertz {
75 let period = self.0;
76 assert!(period != 0 && period <= 1_000_000);
77 Hertz(1_000_000 / period)
78 }
79}
80
81#[derive(Clone, Copy)]
83pub struct MonoTimer {
84 frequency: Hertz,
85}
86
87impl MonoTimer {
88 pub fn new<T>(mut dwt: DWT, sys_clk: T) -> Self
90 where
91 T: Into<Hertz>,
92 {
93 dwt.enable_cycle_counter();
94
95 drop(dwt);
97
98 MonoTimer {
99 frequency: sys_clk.into(),
100 }
101 }
102
103 pub fn frequency(&self) -> Hertz {
105 self.frequency
106 }
107
108 pub fn now(&self) -> Instant {
110 Instant {
111 now: DWT::get_cycle_count(),
112 }
113 }
114}
115
116impl MonoTimerExt for DWT {
117 fn monotonic<T>(self, sys_clk: T) -> MonoTimer
118 where
119 T: Into<Hertz>,
120 {
121 MonoTimer::new(self, sys_clk)
122 }
123}
124
125#[derive(Clone, Copy)]
127pub struct Instant {
128 now: u32,
129}
130
131impl Instant {
132 pub fn elapsed(&self) -> u32 {
134 DWT::get_cycle_count().wrapping_sub(self.now)
135 }
136}