rtic_time/monotonic/
timer_queue_based_monotonic.rs

1use crate::{timer_queue::TimerQueueBackend, TimeoutError};
2
3use crate::Monotonic;
4
5/// A [`Monotonic`] that is backed by the [`TimerQueue`](crate::timer_queue::TimerQueue).
6pub trait TimerQueueBasedMonotonic {
7    /// The backend for the timer queue
8    type Backend: TimerQueueBackend;
9
10    /// The type for instant, defining an instant in time.
11    ///
12    /// **Note:** In all APIs in RTIC that use instants from this monotonic, this type will be used.
13    type Instant: TimerQueueBasedInstant<Ticks = <Self::Backend as TimerQueueBackend>::Ticks>
14        + core::ops::Add<Self::Duration, Output = Self::Instant>
15        + core::ops::Sub<Self::Duration, Output = Self::Instant>
16        + core::ops::Sub<Self::Instant, Output = Self::Duration>;
17
18    /// The type for duration, defining a duration of time.
19    ///
20    /// **Note:** In all APIs in RTIC that use duration from this monotonic, this type will be used.
21    type Duration: TimerQueueBasedDuration<Ticks = <Self::Backend as TimerQueueBackend>::Ticks>;
22}
23
24impl<T: TimerQueueBasedMonotonic> Monotonic for T {
25    type Instant = T::Instant;
26    type Duration = T::Duration;
27
28    fn now() -> Self::Instant {
29        Self::Instant::from_ticks(T::Backend::timer_queue().now())
30    }
31
32    async fn delay(duration: Self::Duration) {
33        T::Backend::timer_queue().delay(duration.ticks()).await
34    }
35
36    async fn delay_until(instant: Self::Instant) {
37        T::Backend::timer_queue().delay_until(instant.ticks()).await
38    }
39
40    async fn timeout_at<F: core::future::Future>(
41        instant: Self::Instant,
42        future: F,
43    ) -> Result<F::Output, TimeoutError> {
44        T::Backend::timer_queue()
45            .timeout_at(instant.ticks(), future)
46            .await
47    }
48
49    async fn timeout_after<F: core::future::Future>(
50        duration: Self::Duration,
51        future: F,
52    ) -> Result<F::Output, TimeoutError> {
53        T::Backend::timer_queue()
54            .timeout_after(duration.ticks(), future)
55            .await
56    }
57}
58
59/// An instant that can be used in [`TimerQueueBasedMonotonic`].
60pub trait TimerQueueBasedInstant: Ord + Copy {
61    /// The internal type of the instant
62    type Ticks;
63    /// Convert from ticks to the instant
64    fn from_ticks(ticks: Self::Ticks) -> Self;
65    /// Convert the instant to ticks
66    fn ticks(self) -> Self::Ticks;
67}
68
69/// A duration that can be used in [`TimerQueueBasedMonotonic`].
70pub trait TimerQueueBasedDuration: Copy {
71    /// The internal type of the duration
72    type Ticks;
73    /// Convert the duration to ticks
74    fn ticks(self) -> Self::Ticks;
75}
76
77impl<const NOM: u32, const DENOM: u32> TimerQueueBasedInstant for fugit::Instant<u64, NOM, DENOM> {
78    type Ticks = u64;
79    fn from_ticks(ticks: Self::Ticks) -> Self {
80        Self::from_ticks(ticks)
81    }
82    fn ticks(self) -> Self::Ticks {
83        Self::ticks(&self)
84    }
85}
86
87impl<const NOM: u32, const DENOM: u32> TimerQueueBasedInstant for fugit::Instant<u32, NOM, DENOM> {
88    type Ticks = u32;
89    fn from_ticks(ticks: Self::Ticks) -> Self {
90        Self::from_ticks(ticks)
91    }
92    fn ticks(self) -> Self::Ticks {
93        Self::ticks(&self)
94    }
95}
96
97impl<const NOM: u32, const DENOM: u32> TimerQueueBasedDuration
98    for fugit::Duration<u64, NOM, DENOM>
99{
100    type Ticks = u64;
101    fn ticks(self) -> Self::Ticks {
102        Self::ticks(&self)
103    }
104}
105
106impl<const NOM: u32, const DENOM: u32> TimerQueueBasedDuration
107    for fugit::Duration<u32, NOM, DENOM>
108{
109    type Ticks = u32;
110    fn ticks(self) -> Self::Ticks {
111        Self::ticks(&self)
112    }
113}