#![allow(non_snake_case)]
use core::ops;
use cortex_m::peripheral::{DCB, DWT};
use crate::rcc::Clocks;
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Debug)]
pub struct Bps(pub u32);
pub use fugit::{
HertzU32 as Hertz, KilohertzU32 as KiloHertz, MegahertzU32 as MegaHertz,
MicrosDurationU32 as MicroSeconds, MillisDurationU32 as MilliSeconds,
};
pub trait U32Ext {
fn bps(self) -> Bps;
}
impl U32Ext for u32 {
fn bps(self) -> Bps {
Bps(self)
}
}
pub const fn Hz(val: u32) -> Hertz {
Hertz::from_raw(val)
}
pub const fn kHz(val: u32) -> KiloHertz {
KiloHertz::from_raw(val)
}
pub const fn MHz(val: u32) -> MegaHertz {
MegaHertz::from_raw(val)
}
pub const fn ms(val: u32) -> MilliSeconds {
MilliSeconds::from_ticks(val)
}
pub const fn us(val: u32) -> MicroSeconds {
MicroSeconds::from_ticks(val)
}
macro_rules! impl_arithmetic {
($wrapper:ty, $wrapped:ty) => {
impl ops::Mul<$wrapped> for $wrapper {
type Output = Self;
fn mul(self, rhs: $wrapped) -> Self {
Self(self.0 * rhs)
}
}
impl ops::MulAssign<$wrapped> for $wrapper {
fn mul_assign(&mut self, rhs: $wrapped) {
self.0 *= rhs;
}
}
impl ops::Div<$wrapped> for $wrapper {
type Output = Self;
fn div(self, rhs: $wrapped) -> Self {
Self(self.0 / rhs)
}
}
impl ops::Div<$wrapper> for $wrapper {
type Output = $wrapped;
fn div(self, rhs: $wrapper) -> $wrapped {
self.0 / rhs.0
}
}
impl ops::DivAssign<$wrapped> for $wrapper {
fn div_assign(&mut self, rhs: $wrapped) {
self.0 /= rhs;
}
}
};
}
impl_arithmetic!(Bps, u32);
#[derive(Clone, Copy)]
pub struct MonoTimer {
frequency: Hertz,
}
impl MonoTimer {
pub fn new(mut dwt: DWT, mut dcb: DCB, clocks: Clocks) -> Self {
dcb.enable_trace();
dwt.enable_cycle_counter();
MonoTimer {
frequency: clocks.hclk(),
}
}
pub fn frequency(self) -> Hertz {
self.frequency
}
pub fn now(self) -> Instant {
Instant {
now: DWT::cycle_count(),
}
}
}
#[derive(Clone, Copy)]
pub struct Instant {
now: u32,
}
impl Instant {
pub fn elapsed(self) -> u32 {
DWT::cycle_count().wrapping_sub(self.now)
}
}