embedded_time/clock.rs
1//! Abstraction for hardware timers/clocks
2
3use crate::{
4 duration::Duration, fixed_point::FixedPoint, fraction::Fraction, instant::Instant,
5 time_int::TimeInt, timer::param, timer::Timer,
6};
7use core::hash::Hash;
8
9/// Potential `Clock` errors
10#[non_exhaustive]
11#[derive(Debug, Eq, PartialEq, Hash)]
12pub enum Error {
13 /// Exact cause of failure is unknown
14 Unspecified,
15 /// The clock has either stopped or never started
16 NotRunning,
17}
18
19impl Default for Error {
20 fn default() -> Self {
21 Self::Unspecified
22 }
23}
24
25/// The `Clock` trait provides an abstraction for hardware-specific timer peripherals, external
26/// timer devices, RTCs, etc.
27///
28/// The `Clock` is characterized by an inner unsigned integer storage type (either [`u32`] or
29/// [`u64`]), a [`u32`]/[`u32`] [`Fraction`] defining the duration (in seconds) of one
30/// count of the `Clock`, and a custom error type representing errors that may be generated by the
31/// implementation.
32///
33/// In addition to the [`Clock::try_now()`] method which returns an [`Instant`],
34/// software [`Timer`]s can be spawned from a `Clock` object.
35pub trait Clock: Sized {
36 /// The type to hold the tick count
37 type T: TimeInt + Hash;
38
39 /// The duration of one clock tick in seconds, AKA the clock precision.
40 const SCALING_FACTOR: Fraction;
41
42 /// Get the current Instant
43 ///
44 /// # Errors
45 ///
46 /// - [`Error::NotRunning`]
47 /// - [`Error::Unspecified`]
48 fn try_now(&self) -> Result<Instant<Self>, Error>;
49
50 /// Spawn a new, `OneShot` [`Timer`] from this clock
51 fn new_timer<Dur: Duration>(
52 &self,
53 duration: Dur,
54 ) -> Timer<param::OneShot, param::Armed, Self, Dur>
55 where
56 Dur: FixedPoint,
57 {
58 Timer::<param::None, param::None, Self, Dur>::new(&self, duration)
59 }
60}