mono_clock/lib.rs
1#![cfg_attr(not(test), no_std)]
2///! Embedded time wrapper for RTIC's `monotonics::now()`
3///!
4///! # Design
5///! `Clock` is implemented using the RTIC `app::monotonics::now()` which is backed
6///! by a monotonic `Monotonic`.
7use core::hash::Hash;
8pub use embedded_time;
9use embedded_time::{clock::Error, fraction::Fraction, Clock, Instant, TimeInt};
10
11#[derive(Copy, Clone, Debug)]
12pub struct MonoClock<T, const HZ: u32>(fn() -> T);
13
14impl<T, const HZ: u32> MonoClock<T, HZ> {
15 ///! Create a new `MonoClock` using e.g. RTIC's `monotonics::now()`.
16 ///!
17 ///! Args:
18 ///! * now: a closure that returns the current ticks
19 ///!
20 ///! ```
21 ///! // In your `app` `init()`, set up a `Monotonic` as usual, e.g.:
22 ///! use mono_clock::MonoClock, systick_monotonic::Systick;
23 ///! const HZ: u32 = 1_000;
24 ///! let sysclk = 400_000_000u32;
25 ///! let mono = Systick::<HZ>::new(c.core.SYST, sysclk);
26 ///! // Then build a `Clock` that is `Copy` and can be passed
27 ///! // around by value or reference:
28 ///! let clock = MonoClock::<u32, HZ>::new(|| monotonics::now());
29 ///! ```
30 pub fn new(now: fn() -> T) -> Self {
31 Self(now)
32 }
33}
34
35impl<T: Copy + TimeInt + Hash, const HZ: u32> Clock for MonoClock<T, HZ> {
36 type T = T;
37
38 // The duration of each tick in seconds.
39 const SCALING_FACTOR: Fraction = Fraction::new(1, HZ);
40
41 fn try_now(&self) -> Result<Instant<Self>, Error> {
42 Ok(Instant::new((self.0)() as T))
43 }
44}
45
46#[cfg(test)]
47mod tests {
48 use super::*;
49
50 #[test]
51 fn it_works() {
52 let c = MonoClock::<u32, 1_000>::new(|| 42);
53 assert_eq!(c.try_now(), Ok(Instant::<MonoClock<_, 1_000>>::new(42)));
54 }
55}