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    ///
27    /// This value should remain constant unless explicitly changed by the user of this trait out-of-band.
28    fn tickrate(&self) -> u64;
29    /// Return the number of elapsed ticks.
30    fn elapsed_ticks(&self) -> Result<u64, OverflowError>;
31
32    /// Return the number of elapsed nanoseconds, rounded down.
33    fn elapsed_nanos(&self) -> Result<u64, OverflowError>;
34    /// Return the number of elapsed microseconds, rounded down.
35    fn elapsed_micros(&self) -> Result<u64, OverflowError>;
36    /// Return the number of elapsed milliseconds, rounded down.
37    fn elapsed_millis(&self) -> Result<u64, OverflowError>;
38    /// Return the number of elapsed seconds, rounded down.
39    fn elapsed_secs(&self) -> Result<u64, OverflowError>;
40
41    /// The (inclusive) maximum number of ticks that can elapse after [start](Self::start) before the timer overflows.
42    ///
43    /// This value must remain constant unless the user made an explicit out-of-band change to the timer.
44    ///
45    /// When the timer is designed to (practically) never overflow,
46    /// a value of [`u64::MAX`] may be used even when the implementation doesn't have a constant max value.
47    fn max_ticks(&self) -> u64;
48    /// The (inclusive) maximum number of nanoseconds that can elapse after [start](Self::start) before the timer overflows.
49    ///
50    /// This value must remain constant unless the user made an explicit out-of-band change to the timer.
51    ///
52    /// When the timer is designed to (practically) never overflow,
53    /// a value of [`u64::MAX`] may be used even when the implementation doesn't have a constant max value.
54    fn max_nanos(&self) -> u64;
55    /// The (inclusive) maximum number of microseconds that can elapse after [start](Self::start) before the timer overflows.
56    ///
57    /// This value must remain constant unless the user made an explicit out-of-band change to the timer.
58    ///
59    /// When the timer is designed to (practically) never overflow,
60    /// a value of [`u64::MAX`] may be used even when the implementation doesn't have a constant max value.
61    fn max_micros(&self) -> u64;
62    /// The (inclusive) maximum number of milliseconds that can elapse after [start](Self::start) before the timer overflows.
63    ///
64    /// This value must remain constant unless the user made an explicit out-of-band change to the timer.
65    ///
66    /// When the timer is designed to (practically) never overflow,
67    /// a value of [`u64::MAX`] may be used even when the implementation doesn't have a constant max value.
68    fn max_millis(&self) -> u64;
69    /// The (inclusive) maximum number of seconds that can elapse after [start](Self::start) before the timer overflows.
70    ///
71    /// This value must remain constant unless the user made an explicit out-of-band change to the timer.
72    ///
73    /// When the timer is designed to (practically) never overflow,
74    /// a value of [`u64::MAX`] may be used even when the implementation doesn't have a constant max value.
75    fn max_secs(&self) -> u64;
76}
77
78/// An alarm that can be used to wait for a time to come.
79#[allow(async_fn_in_trait)]
80pub trait Alarm: Timer {
81    /// Wait until the timer reaches the alarm specified in ticks since the timer has started.
82    /// If the alarm is already reached, the function exits immediately.
83    ///
84    /// The function returns an overflow error if the alarm value is higher than is supported by the implementation.
85    async fn wait_until_ticks(&mut self, value: u64) -> Result<(), OverflowError>;
86    /// Wait until the timer reaches the alarm specified in nanoseconds since the timer has started.
87    /// If the alarm is already reached, the function exits immediately.
88    ///
89    /// The function returns an overflow error if the alarm value is higher than is supported by the implementation.
90    async fn wait_until_nanos(&mut self, value: u64) -> Result<(), OverflowError>;
91    /// Wait until the timer reaches the alarm specified in microseconds since the timer has started.
92    /// If the alarm is already reached, the function exits immediately.
93    ///
94    /// The function returns an overflow error if the alarm value is higher than is supported by the implementation.
95    async fn wait_until_micros(&mut self, value: u64) -> Result<(), OverflowError>;
96    /// Wait until the timer reaches the alarm specified in milliseconds since the timer has started.
97    /// If the alarm is already reached, the function exits immediately.
98    ///
99    /// The function returns an overflow error if the alarm value is higher than is supported by the implementation.
100    async fn wait_until_millis(&mut self, value: u64) -> Result<(), OverflowError>;
101    /// Wait until the timer reaches the alarm specified in seconds since the timer has started.
102    /// If the alarm is already reached, the function exits immediately.
103    ///
104    /// The function returns an overflow error if the alarm value is higher than is supported by the implementation.
105    async fn wait_until_secs(&mut self, value: u64) -> Result<(), OverflowError>;
106}
107
108/// The timer has overflowed
109#[derive(Clone, Copy, PartialEq, Eq, Debug, Default, Hash, PartialOrd, Ord)]
110pub struct OverflowError;
111
112#[cfg(feature = "defmt")]
113impl defmt::Format for OverflowError {
114    fn format(&self, fmt: defmt::Formatter) {
115        defmt::write!(fmt, "overflow")
116    }
117}
118
119impl Display for OverflowError {
120    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
121        write!(f, "overflow")
122    }
123}
124
125impl Error for OverflowError {}