1#![allow(non_snake_case)]
31
32use core::ops;
33use cortex_m::peripheral::{DCB, DWT};
34
35use crate::rcc::Clocks;
36use waiter_trait::{Interval, TickInstant, TickWaiter};
37
38#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Debug)]
40pub struct Bps(pub u32);
41
42pub use fugit::{
43 Duration, HertzU32 as Hertz, KilohertzU32 as KiloHertz, MegahertzU32 as MegaHertz,
44 MicrosDurationU32 as MicroSeconds, MillisDurationU32 as MilliSeconds, NanosDurationU64,
45};
46
47pub trait U32Ext {
49 fn bps(self) -> Bps;
51}
52
53impl U32Ext for u32 {
54 fn bps(self) -> Bps {
55 Bps(self)
56 }
57}
58
59pub const fn Hz(val: u32) -> Hertz {
60 Hertz::from_raw(val)
61}
62
63pub const fn kHz(val: u32) -> KiloHertz {
64 KiloHertz::from_raw(val)
65}
66
67pub const fn MHz(val: u32) -> MegaHertz {
68 MegaHertz::from_raw(val)
69}
70
71pub const fn ms(val: u32) -> MilliSeconds {
72 MilliSeconds::from_ticks(val)
73}
74
75pub const fn us(val: u32) -> MicroSeconds {
76 MicroSeconds::from_ticks(val)
77}
78
79macro_rules! impl_arithmetic {
82 ($wrapper:ty, $wrapped:ty) => {
83 impl ops::Mul<$wrapped> for $wrapper {
84 type Output = Self;
85 fn mul(self, rhs: $wrapped) -> Self {
86 Self(self.0 * rhs)
87 }
88 }
89
90 impl ops::MulAssign<$wrapped> for $wrapper {
91 fn mul_assign(&mut self, rhs: $wrapped) {
92 self.0 *= rhs;
93 }
94 }
95
96 impl ops::Div<$wrapped> for $wrapper {
97 type Output = Self;
98 fn div(self, rhs: $wrapped) -> Self {
99 Self(self.0 / rhs)
100 }
101 }
102
103 impl ops::Div<$wrapper> for $wrapper {
104 type Output = $wrapped;
105 fn div(self, rhs: $wrapper) -> $wrapped {
106 self.0 / rhs.0
107 }
108 }
109
110 impl ops::DivAssign<$wrapped> for $wrapper {
111 fn div_assign(&mut self, rhs: $wrapped) {
112 self.0 /= rhs;
113 }
114 }
115 };
116}
117
118impl_arithmetic!(Bps, u32);
119
120#[derive(Clone, Copy)]
127pub struct MonoTimer {
128 frequency: Hertz,
129}
130
131impl MonoTimer {
132 pub fn new(mut dwt: DWT, mut dcb: DCB, clocks: &Clocks) -> Self {
134 dcb.enable_trace();
135 dwt.enable_cycle_counter();
136
137 MonoTimer {
140 frequency: clocks.hclk(),
141 }
142 }
143
144 pub fn frequency(self) -> Hertz {
146 self.frequency
147 }
148
149 pub fn now(self) -> Instant {
151 Instant {
152 now: DWT::cycle_count(),
153 }
154 }
155
156 pub fn waiter_us<I: Interval>(
157 &self,
158 timeout: MicroSeconds,
159 interval: I,
160 ) -> TickWaiter<DwtInstant, I, u32> {
161 TickWaiter::us(timeout.ticks(), interval, self.frequency.raw())
162 }
163
164 pub fn waiter_ns<I: Interval>(
166 &self,
167 timeout: NanosDurationU64,
168 interval: I,
169 ) -> TickWaiter<DwtInstant, I, u64> {
170 TickWaiter::ns(timeout.ticks(), interval, self.frequency.raw())
171 }
172}
173
174#[derive(Clone, Copy)]
176pub struct Instant {
177 now: u32,
178}
179
180impl Instant {
181 pub fn elapsed(self) -> u32 {
183 DWT::cycle_count().wrapping_sub(self.now)
184 }
185}
186
187#[derive(Copy, Clone)]
191pub struct DwtInstant {
192 tick: u32,
193}
194impl TickInstant for DwtInstant {
195 #[inline(always)]
196 fn now() -> Self {
197 Self {
198 tick: DWT::cycle_count(),
199 }
200 }
201
202 #[inline(always)]
203 fn tick_since(self, earlier: Self) -> u32 {
204 if self.tick >= earlier.tick {
205 self.tick - earlier.tick
206 } else {
207 self.tick + (u32::MAX - earlier.tick + 1)
208 }
209 }
210}