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