embassy_stm32/
time.rs

1//! Time units
2
3use core::fmt::Display;
4use core::ops::{Div, Mul};
5
6/// Hertz
7#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Debug)]
8pub struct Hertz(pub u32);
9
10impl Display for Hertz {
11    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
12        write!(f, "{} Hz", self.0)
13    }
14}
15
16#[cfg(feature = "defmt")]
17impl defmt::Format for Hertz {
18    fn format(&self, f: defmt::Formatter) {
19        defmt::write!(f, "{=u32} Hz", self.0)
20    }
21}
22
23impl Hertz {
24    /// Create a `Hertz` from the given hertz.
25    pub const fn hz(hertz: u32) -> Self {
26        Self(hertz)
27    }
28
29    /// Create a `Hertz` from the given kilohertz.
30    pub const fn khz(kilohertz: u32) -> Self {
31        Self(kilohertz * 1_000)
32    }
33
34    /// Create a `Hertz` from the given megahertz.
35    pub const fn mhz(megahertz: u32) -> Self {
36        Self(megahertz * 1_000_000)
37    }
38}
39
40/// This is a convenience shortcut for [`Hertz::hz`]
41pub const fn hz(hertz: u32) -> Hertz {
42    Hertz::hz(hertz)
43}
44
45/// This is a convenience shortcut for [`Hertz::khz`]
46pub const fn khz(kilohertz: u32) -> Hertz {
47    Hertz::khz(kilohertz)
48}
49
50/// This is a convenience shortcut for [`Hertz::mhz`]
51pub const fn mhz(megahertz: u32) -> Hertz {
52    Hertz::mhz(megahertz)
53}
54
55impl Mul<u32> for Hertz {
56    type Output = Hertz;
57    fn mul(self, rhs: u32) -> Self::Output {
58        Hertz(self.0 * rhs)
59    }
60}
61
62impl Div<u32> for Hertz {
63    type Output = Hertz;
64    fn div(self, rhs: u32) -> Self::Output {
65        Hertz(self.0 / rhs)
66    }
67}
68
69impl Mul<u16> for Hertz {
70    type Output = Hertz;
71    fn mul(self, rhs: u16) -> Self::Output {
72        self * (rhs as u32)
73    }
74}
75
76impl Div<u16> for Hertz {
77    type Output = Hertz;
78    fn div(self, rhs: u16) -> Self::Output {
79        self / (rhs as u32)
80    }
81}
82
83impl Mul<u8> for Hertz {
84    type Output = Hertz;
85    fn mul(self, rhs: u8) -> Self::Output {
86        self * (rhs as u32)
87    }
88}
89
90impl Div<u8> for Hertz {
91    type Output = Hertz;
92    fn div(self, rhs: u8) -> Self::Output {
93        self / (rhs as u32)
94    }
95}
96
97impl Div<Hertz> for Hertz {
98    type Output = u32;
99    fn div(self, rhs: Hertz) -> Self::Output {
100        self.0 / rhs.0
101    }
102}
103
104#[repr(C)]
105#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Debug, Default)]
106#[cfg_attr(feature = "defmt", derive(defmt::Format))]
107/// A variant on [Hertz] that acts as an `Option<Hertz>` that is smaller and repr C.
108///
109/// An `Option<Hertz>` can be `.into()`'d into this type and back.
110/// The only restriction is that that [Hertz] cannot have the value 0 since that's
111/// seen as the `None` variant.
112pub struct MaybeHertz(u32);
113
114impl MaybeHertz {
115    /// Same as calling the `.into()` function, but without type inference.
116    pub fn to_hertz(self) -> Option<Hertz> {
117        self.into()
118    }
119}
120
121impl From<Option<Hertz>> for MaybeHertz {
122    fn from(value: Option<Hertz>) -> Self {
123        match value {
124            Some(Hertz(0)) => panic!("Hertz cannot be 0"),
125            Some(Hertz(val)) => Self(val),
126            None => Self(0),
127        }
128    }
129}
130
131impl From<MaybeHertz> for Option<Hertz> {
132    fn from(value: MaybeHertz) -> Self {
133        match value {
134            MaybeHertz(0) => None,
135            MaybeHertz(val) => Some(Hertz(val)),
136        }
137    }
138}