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}