1#![allow(non_snake_case)]
31
32use core::ops;
33use cortex_m::peripheral::{DCB, DWT};
34
35use crate::rcc::Clocks;
36use waiter_trait::{NonInterval, 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,
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(&self, timeout: MicroSeconds) -> TickWaiter<DwtInstant, NonInterval, u32> {
157 TickWaiter::us(timeout, NonInterval::new(), self.frequency.raw())
158 }
159}
160
161#[derive(Clone, Copy)]
163pub struct Instant {
164 now: u32,
165}
166
167impl Instant {
168 pub fn elapsed(self) -> u32 {
170 DWT::cycle_count().wrapping_sub(self.now)
171 }
172}
173
174#[derive(Copy, Clone)]
178pub struct DwtInstant {
179 tick: u32,
180}
181impl TickInstant for DwtInstant {
182 #[inline(always)]
183 fn now() -> Self {
184 Self {
185 tick: DWT::cycle_count(),
186 }
187 }
188
189 #[inline(always)]
190 fn tick_since(self, earlier: Self) -> u32 {
191 if self.tick >= earlier.tick {
192 self.tick - earlier.tick
193 } else {
194 self.tick + (u32::MAX - earlier.tick + 1)
195 }
196 }
197}