Skip to main content

embedded_hal_timer/
lib.rs

1#![no_std]
2#![deny(missing_docs)]
3
4//! Definition of [Timer] and [Alarm] traits.
5//!
6//! These traits are intended to be eventually included into embedded-hal & embedded-hal-async.
7//! As such these traits are work in progress and the crate may receive breaking changes.
8
9use core::{error::Error, fmt::Display};
10
11/// A timer that can be started from 0 and keeps track of the time until it overflows.
12///
13/// This trait may be implemented directly on top of short running hardware timers
14/// or on top of 'virtual' long running timers.
15///
16/// A driver using this trait should document the minimum required tick resolution and
17/// the minimum required max time. The driver may choose to check if these invariants
18/// are kept using the [`tickrate`](Self::tickrate) and the various [`max_*`](Self::max_ticks) functions.
19pub trait Timer {
20    /// Start or restart the timer at 0.
21    ///
22    /// The elapsed time is undefined before this function has been called.
23    fn start(&mut self);
24
25    /// Get the amount of ticks per second.
26    fn tickrate(&self) -> u64;
27    /// Return the number of elapsed ticks.
28    fn elapsed_ticks(&self) -> Result<u64, OverflowError>;
29
30    /// Return the number of elapsed nanoseconds, rounded down.
31    fn elapsed_nanos(&self) -> Result<u64, OverflowError>;
32    /// Return the number of elapsed microseconds, rounded down.
33    fn elapsed_micros(&self) -> Result<u64, OverflowError>;
34    /// Return the number of elapsed milliseconds, rounded down.
35    fn elapsed_millis(&self) -> Result<u64, OverflowError>;
36    /// Return the number of elapsed seconds, rounded down.
37    fn elapsed_secs(&self) -> Result<u64, OverflowError>;
38
39    /// The (inclusive) maximum number of ticks that can happen before the overflow occurs
40    /// if [start](Self::start) were called now.
41    ///
42    /// This value is not necessarily constant as implementations built on top of continuously running
43    /// timers will have shrinking amount of time left.
44    fn max_ticks(&self) -> u64;
45    /// The (inclusive) maximum number of nanoseconds that can happen before the overflow occurs
46    /// if [start](Self::start) were called now.
47    ///
48    /// This value is not necessarily constant as implementations built on top of continuously running
49    /// timers will have shrinking amount of time left.
50    fn max_nanos(&self) -> u64;
51    /// The (inclusive) maximum number of microseconds that can happen before the overflow occurs
52    /// if [start](Self::start) were called now.
53    ///
54    /// This value is not necessarily constant as implementations built on top of continuously running
55    /// timers will have shrinking amount of time left.
56    fn max_micros(&self) -> u64;
57    /// The (inclusive) maximum number of milliseconds that can happen before the overflow occurs
58    /// if [start](Self::start) were called now.
59    ///
60    /// This value is not necessarily constant as implementations built on top of continuously running
61    /// timers will have shrinking amount of time left.
62    fn max_millis(&self) -> u64;
63    /// The (inclusive) maximum number of seconds that can happen before the overflow occurs
64    /// if [start](Self::start) were called now.
65    ///
66    /// This value is not necessarily constant as implementations built on top of continuously running
67    /// timers will have shrinking amount of time left.
68    fn max_secs(&self) -> u64;
69}
70
71/// An alarm that can be used to wait for a time to come.
72#[allow(async_fn_in_trait)]
73pub trait Alarm: Timer {
74    /// Wait until the timer reaches the alarm specified in ticks since the timer has started.
75    /// If the alarm is already reached, the function exits immediately.
76    ///
77    /// The function returns an overflow error if the alarm value is higher than is supported by the implementation.
78    async fn wait_until_ticks(&mut self, value: u64) -> Result<(), OverflowError>;
79    /// Wait until the timer reaches the alarm specified in nanoseconds since the timer has started.
80    /// If the alarm is already reached, the function exits immediately.
81    ///
82    /// The function returns an overflow error if the alarm value is higher than is supported by the implementation.
83    async fn wait_until_nanos(&mut self, value: u64) -> Result<(), OverflowError>;
84    /// Wait until the timer reaches the alarm specified in microseconds since the timer has started.
85    /// If the alarm is already reached, the function exits immediately.
86    ///
87    /// The function returns an overflow error if the alarm value is higher than is supported by the implementation.
88    async fn wait_until_micros(&mut self, value: u64) -> Result<(), OverflowError>;
89    /// Wait until the timer reaches the alarm specified in milliseconds since the timer has started.
90    /// If the alarm is already reached, the function exits immediately.
91    ///
92    /// The function returns an overflow error if the alarm value is higher than is supported by the implementation.
93    async fn wait_until_millis(&mut self, value: u64) -> Result<(), OverflowError>;
94    /// Wait until the timer reaches the alarm specified in seconds since the timer has started.
95    /// If the alarm is already reached, the function exits immediately.
96    ///
97    /// The function returns an overflow error if the alarm value is higher than is supported by the implementation.
98    async fn wait_until_secs(&mut self, value: u64) -> Result<(), OverflowError>;
99}
100
101/// The timer has overflowed
102#[derive(Clone, Copy, PartialEq, Eq, Debug, Default, Hash, PartialOrd, Ord)]
103pub struct OverflowError;
104
105#[cfg(feature = "defmt")]
106impl defmt::Format for OverflowError {
107    fn format(&self, fmt: defmt::Formatter) {
108        defmt::write!(fmt, "overflow")
109    }
110}
111
112impl Display for OverflowError {
113    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
114        write!(f, "overflow")
115    }
116}
117
118impl Error for OverflowError {}