diff --git a/embassy/src/time/mod.rs b/embassy/src/time/mod.rs index d6a9a301..2b463155 100644 --- a/embassy/src/time/mod.rs +++ b/embassy/src/time/mod.rs @@ -5,7 +5,7 @@ mod traits; pub use duration::Duration; pub use instant::Instant; -pub use timer::Timer; +pub use timer::{Ticker, Timer}; pub use traits::*; use crate::fmt::*; diff --git a/embassy/src/time/timer.rs b/embassy/src/time/timer.rs index 10956300..8756368c 100644 --- a/embassy/src/time/timer.rs +++ b/embassy/src/time/timer.rs @@ -1,6 +1,7 @@ use core::future::Future; use core::pin::Pin; use core::task::{Context, Poll}; +use futures::Stream; use futures_intrusive::timer::{LocalTimer, LocalTimerFuture}; use super::{Duration, Instant}; @@ -28,3 +29,35 @@ impl Future for Timer { unsafe { Pin::new_unchecked(&mut self.get_unchecked_mut().inner) }.poll(cx) } } + +pub struct Ticker { + inner: LocalTimerFuture<'static>, + next: Instant, + dur: Duration, +} + +impl Ticker { + pub fn every(dur: Duration) -> Self { + let next = Instant::now() + dur; + Self { + inner: current_timer_queue().deadline(next.as_ticks()), + next, + dur, + } + } +} + +impl Stream for Ticker { + type Item = (); + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let this = unsafe { self.get_unchecked_mut() }; + match unsafe { Pin::new_unchecked(&mut this.inner) }.poll(cx) { + Poll::Ready(_) => { + this.next += this.dur; + this.inner = current_timer_queue().deadline(this.next.as_ticks()); + Poll::Ready(Some(())) + } + Poll::Pending => Poll::Pending, + } + } +}