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