| 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 | |