diff --git a/CHANGELOG.md b/CHANGELOG.md index d5ba3d8..bb65728 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Changed - Updated the `cast` dependency from 0.2 to 0.3 +- The IwdgTimeout can now be any type that implements Into ### Added @@ -18,6 +19,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - PWM complementary output capability for TIM1 with new example to demonstrate - Implement interface for reading and writing to the internal flash memory and an example for demonstration. - PWM output on complementary channels only for single channel timers (TIM16 + TIM17) +- Types for Microseconds, Milliseconds and Seconds in time.rs ### Fixed diff --git a/src/time.rs b/src/time.rs index d870961..ed31ec3 100644 --- a/src/time.rs +++ b/src/time.rs @@ -1,16 +1,25 @@ /// Bits per second -#[derive(PartialEq, PartialOrd, Clone, Copy)] +#[derive(Debug, PartialEq, PartialOrd, Clone, Copy)] pub struct Bps(pub u32); -#[derive(PartialEq, PartialOrd, Clone, Copy)] +#[derive(Debug, PartialEq, PartialOrd, Clone, Copy)] pub struct Hertz(pub u32); -#[derive(PartialEq, PartialOrd, Clone, Copy)] +#[derive(Debug, PartialEq, PartialOrd, Clone, Copy)] pub struct KiloHertz(pub u32); -#[derive(PartialEq, PartialOrd, Clone, Copy)] +#[derive(Debug, PartialEq, PartialOrd, Clone, Copy)] pub struct MegaHertz(pub u32); +#[derive(Debug, PartialEq, PartialOrd, Clone, Copy)] +pub struct MicroSecond(pub u32); + +#[derive(Debug, PartialEq, PartialOrd, Clone, Copy)] +pub struct MilliSecond(pub u32); + +#[derive(Debug, PartialEq, PartialOrd, Clone, Copy)] +pub struct Second(pub u32); + /// Extension trait that adds convenience methods to the `u32` type pub trait U32Ext { /// Wrap in `Bps` @@ -24,6 +33,15 @@ pub trait U32Ext { /// Wrap in `MegaHertz` fn mhz(self) -> MegaHertz; + + /// Wrap in `MicroSecond` + fn us(self) -> MicroSecond; + + /// Wrap in `MilliSecond` + fn ms(self) -> MilliSecond; + + /// Wrap in `Second` + fn seconds(self) -> Second; } impl U32Ext for u32 { @@ -42,6 +60,18 @@ impl U32Ext for u32 { fn mhz(self) -> MegaHertz { MegaHertz(self) } + + fn us(self) -> MicroSecond { + MicroSecond(self) + } + + fn ms(self) -> MilliSecond { + MilliSecond(self) + } + + fn seconds(self) -> Second { + Second(self) + } } impl From for Hertz { @@ -61,3 +91,47 @@ impl From for KiloHertz { KiloHertz(mhz.0 * 1_000) } } + +impl Hertz { + pub fn duration(self, cycles: u32) -> MicroSecond { + let cycles = cycles as u64; + let clk = self.0 as u64; + let us = cycles.saturating_mul(1_000_000_u64) / clk; + MicroSecond(us as u32) + } +} + +impl MicroSecond { + pub fn cycles(self, clk: Hertz) -> u32 { + assert!(self.0 > 0); + let clk = clk.0 as u64; + let period = self.0 as u64; + let cycles = clk.saturating_mul(period) / 1_000_000_u64; + cycles as u32 + } +} + +impl From for MicroSecond { + fn from(period: Second) -> MicroSecond { + MicroSecond(period.0 * 1_000_000) + } +} + +impl From for MicroSecond { + fn from(period: MilliSecond) -> MicroSecond { + MicroSecond(period.0 * 1_000) + } +} + +impl From for MilliSecond { + fn from(period: Second) -> MilliSecond { + MilliSecond(period.0 * 1_000) + } +} + +impl From for MicroSecond { + fn from(freq: Hertz) -> MicroSecond { + assert!(freq.0 <= 1_000_000); + MicroSecond(1_000_000 / freq.0) + } +} diff --git a/src/watchdog.rs b/src/watchdog.rs index 643d10d..7f54d6b 100644 --- a/src/watchdog.rs +++ b/src/watchdog.rs @@ -30,8 +30,8 @@ //! //! use crate::hal::pac; //! use crate::hal::prelude::*; -//! use crate::hal:watchdog::Watchdog; -//! use crate::hal:time::Hertz; +//! use crate::hal::watchdog::Watchdog; +//! use crate::hal::time::Hertz; //! //! let mut p = pac::Peripherals::take().unwrap(); //! @@ -44,7 +44,7 @@ use embedded_hal::watchdog; use crate::pac::IWDG; -use crate::time::Hertz; +use crate::time::{MicroSecond, U32Ext}; /// Watchdog instance pub struct Watchdog { @@ -66,13 +66,16 @@ pub struct IwdgTimeout { reload: u16, } -impl From for IwdgTimeout { +impl From for IwdgTimeout +where + T: Into, +{ /// This converts the value so it's usable by the IWDG /// Due to conversion losses, the specified frequency is a maximum /// /// It can also only represent values < 10000 Hertz - fn from(hz: Hertz) -> Self { - let mut time = 40_000 / 4 / hz.0; + fn from(period: T) -> Self { + let mut time = period.into().cycles((40_000 / 4).hz()); let mut psc = 0; let mut reload = 0; while psc < 7 { @@ -83,9 +86,8 @@ impl From for IwdgTimeout { psc += 1; time /= 2; } - // As we get an integer value, reload is always below 0xFFF let reload = reload as u16; - IwdgTimeout { psc, reload } + Self { psc, reload } } }