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