stm32l1xx_hal/
time.rs

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
12/// Extension trait that adds convenience methods to the `u32` type
13pub trait U32Ext {
14    /// Wrap in `Bps`
15    fn bps(self) -> Bps;
16
17    /// Wrap in `Hertz`
18    fn hz(self) -> Hertz;
19
20    /// Wrap in `Hertz`
21    fn khz(self) -> Hertz;
22
23    /// Wrap in `Hertz`
24    fn mhz(self) -> Hertz;
25
26    /// Wrap in `MicroSeconds`
27    fn us(self) -> MicroSeconds;
28
29    /// Wrap in `MicroSeconds`
30    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/// A monotonic nondecreasing timer
82#[derive(Clone, Copy)]
83pub struct MonoTimer {
84    frequency: Hertz,
85}
86
87impl MonoTimer {
88    /// Creates a new `Monotonic` timer
89    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        // now the CYCCNT counter can't be stopped or resetted
96        drop(dwt);
97
98        MonoTimer {
99            frequency: sys_clk.into(),
100        }
101    }
102
103    /// Returns the frequency at which the monotonic timer is operating at
104    pub fn frequency(&self) -> Hertz {
105        self.frequency
106    }
107
108    /// Returns an `Instant` corresponding to "now"
109    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/// A measurement of a monotonically nondecreasing clock
126#[derive(Clone, Copy)]
127pub struct Instant {
128    now: u32,
129}
130
131impl Instant {
132    /// Ticks elapsed since the `Instant` was created
133    pub fn elapsed(&self) -> u32 {
134        DWT::get_cycle_count().wrapping_sub(self.now)
135    }
136}