1#![allow(non_snake_case)]
31
32use core::ops;
33use cortex_m::peripheral::{DCB, DWT};
34
35use crate::os_trait::{prelude::*, utils::FrequencyHolder};
36use crate::rcc::Clocks;
37
38#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Debug)]
40pub struct Bps(pub u32);
41
42pub use fugit::{
43 Duration, HertzU32, KilohertzU32, MegahertzU32, MicrosDurationU32, MillisDurationU32,
44 RateExtU32,
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) -> HertzU32 {
60 HertzU32::from_raw(val)
61}
62
63pub const fn kHz(val: u32) -> KilohertzU32 {
64 KilohertzU32::from_raw(val)
65}
66
67pub const fn MHz(val: u32) -> MegahertzU32 {
68 MegahertzU32::from_raw(val)
69}
70
71pub const fn ms(val: u32) -> MillisDurationU32 {
72 MillisDurationU32::from_ticks(val)
73}
74
75pub const fn us(val: u32) -> MicrosDurationU32 {
76 MicrosDurationU32::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: HertzU32,
129}
130
131pub static FREQUENCY: FrequencyHolder = FrequencyHolder::new(KilohertzU32::MHz(1));
132
133impl MonoTimer {
134 pub fn new(mut dwt: DWT, mut dcb: DCB, clocks: &Clocks) -> Self {
136 dcb.enable_trace();
137 dwt.enable_cycle_counter();
138 FREQUENCY.set(clocks.hclk().to_kHz().kHz());
139 MonoTimer {
142 frequency: clocks.hclk(),
143 }
144 }
145
146 pub fn frequency(self) -> HertzU32 {
148 self.frequency
149 }
150
151 pub fn now(self) -> Instant {
153 Instant {
154 now: DWT::cycle_count(),
155 }
156 }
157}
158
159#[derive(Clone, Copy)]
161pub struct Instant {
162 now: u32,
163}
164
165impl Instant {
166 pub fn elapsed(self) -> u32 {
168 DWT::cycle_count().wrapping_sub(self.now)
169 }
170}
171
172#[derive(Copy, Clone)]
176pub struct DwtInstant {
177 tick: u32,
178}
179impl TickInstant for DwtInstant {
180 fn frequency() -> KilohertzU32 {
181 FREQUENCY.get()
182 }
183
184 #[inline(always)]
185 fn now() -> Self {
186 Self {
187 tick: DWT::cycle_count(),
188 }
189 }
190
191 #[inline(always)]
192 fn tick_since(self, earlier: Self) -> u32 {
193 if self.tick >= earlier.tick {
194 self.tick - earlier.tick
195 } else {
196 self.tick + (u32::MAX - earlier.tick + 1)
197 }
198 }
199}