diff --git a/src/lib.rs b/src/lib.rs index fd00e54..1c9b5c5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,7 +6,11 @@ //! These traits are intended to be eventually included into embedded-hal & embedded-hal-async. //! As such these traits are work in progress and the crate may receive breaking changes. -use core::{error::Error, fmt::Display}; +use core::{error::Error, fmt::Display, num::NonZeroU64}; + +const MILLIS_PER_SEC: u64 = 1_000; +const MICROS_PER_SEC: u64 = 1_000_000; +const NANOS_PER_SEC: u64 = 1_000_000_000; /// A timer that can be started from 0 and keeps track of the time until it overflows. /// @@ -23,18 +27,26 @@ pub trait Timer { fn start(&mut self); /// Get the amount of ticks per second. - fn tickrate(&self) -> u64; + fn tickrate(&self) -> NonZeroU64; /// Return the number of elapsed ticks. fn elapsed_ticks(&self) -> Result; /// Return the number of elapsed nanoseconds, rounded down. - fn elapsed_nanos(&self) -> Result; + fn elapsed_nanos(&self) -> Result { + Ok((self.elapsed_ticks()? * NANOS_PER_SEC) / self.tickrate()) + } /// Return the number of elapsed microseconds, rounded down. - fn elapsed_micros(&self) -> Result; + fn elapsed_micros(&self) -> Result { + Ok((self.elapsed_ticks()? * MICROS_PER_SEC) / self.tickrate()) + } /// Return the number of elapsed milliseconds, rounded down. - fn elapsed_millis(&self) -> Result; + fn elapsed_millis(&self) -> Result { + Ok((self.elapsed_ticks()? * MILLIS_PER_SEC) / self.tickrate()) + } /// Return the number of elapsed seconds, rounded down. - fn elapsed_secs(&self) -> Result; + fn elapsed_secs(&self) -> Result { + Ok(self.elapsed_ticks()? / self.tickrate()) + } /// The (inclusive) maximum number of ticks that can happen before the overflow occurs /// if [start](Self::start) were called now. @@ -47,25 +59,33 @@ pub trait Timer { /// /// This value is not necessarily constant as implementations built on top of continuously running /// timers will have shrinking amount of time left. - fn max_nanos(&self) -> u64; + fn max_nanos(&self) -> u64 { + (self.max_ticks() * NANOS_PER_SEC) / self.tickrate() + } /// The (inclusive) maximum number of microseconds that can happen before the overflow occurs /// if [start](Self::start) were called now. /// /// This value is not necessarily constant as implementations built on top of continuously running /// timers will have shrinking amount of time left. - fn max_micros(&self) -> u64; + fn max_micros(&self) -> u64 { + (self.max_ticks() * MICROS_PER_SEC) / self.tickrate() + } /// The (inclusive) maximum number of milliseconds that can happen before the overflow occurs /// if [start](Self::start) were called now. /// /// This value is not necessarily constant as implementations built on top of continuously running /// timers will have shrinking amount of time left. - fn max_millis(&self) -> u64; + fn max_millis(&self) -> u64 { + (self.max_ticks() * MILLIS_PER_SEC) / self.tickrate() + } /// The (inclusive) maximum number of seconds that can happen before the overflow occurs /// if [start](Self::start) were called now. /// /// This value is not necessarily constant as implementations built on top of continuously running /// timers will have shrinking amount of time left. - fn max_secs(&self) -> u64; + fn max_secs(&self) -> u64 { + self.max_ticks() / self.tickrate() + } } /// An alarm that can be used to wait for a time to come. @@ -80,22 +100,34 @@ pub trait Alarm: Timer { /// If the alarm is already reached, the function exits immediately. /// /// The function returns an overflow error if the alarm value is higher than is supported by the implementation. - async fn wait_until_nanos(&mut self, value: u64) -> Result<(), OverflowError>; + fn wait_until_nanos(&mut self, value: u64) -> impl Future> { + let ticks = (value * self.tickrate().get()) / NANOS_PER_SEC; + self.wait_until_ticks(ticks) + } /// Wait until the timer reaches the alarm specified in microseconds since the timer has started. /// If the alarm is already reached, the function exits immediately. /// /// The function returns an overflow error if the alarm value is higher than is supported by the implementation. - async fn wait_until_micros(&mut self, value: u64) -> Result<(), OverflowError>; + fn wait_until_micros(&mut self, value: u64) -> impl Future> { + let ticks = (value * self.tickrate().get()) / MICROS_PER_SEC; + self.wait_until_ticks(ticks) + } /// Wait until the timer reaches the alarm specified in milliseconds since the timer has started. /// If the alarm is already reached, the function exits immediately. /// /// The function returns an overflow error if the alarm value is higher than is supported by the implementation. - async fn wait_until_millis(&mut self, value: u64) -> Result<(), OverflowError>; + fn wait_until_millis(&mut self, value: u64) -> impl Future> { + let ticks = (value * self.tickrate().get()) / MILLIS_PER_SEC; + self.wait_until_ticks(ticks) + } /// Wait until the timer reaches the alarm specified in seconds since the timer has started. /// If the alarm is already reached, the function exits immediately. /// /// The function returns an overflow error if the alarm value is higher than is supported by the implementation. - async fn wait_until_secs(&mut self, value: u64) -> Result<(), OverflowError>; + fn wait_until_secs(&mut self, value: u64) -> impl Future> { + let ticks = value * self.tickrate().get(); + self.wait_until_ticks(ticks) + } } /// The timer has overflowed