umsh_hal/
embassy_clock.rs

1//! `embassy-time`-backed [`Clock`](crate::Clock).
2//!
3//! This is the single shared implementation used by both host (arch-std) and
4//! embedded targets. The concrete `embassy-time` driver is provided by the
5//! binary, not this wrapper, so the same zero-sized clock works everywhere the
6//! global driver is installed.
7
8use core::future::Future;
9use core::pin::pin;
10use core::task::{Context, Poll};
11
12use embassy_time::{Instant, Timer};
13
14/// Monotonic [`Clock`](crate::Clock) backed by the global `embassy-time` driver.
15///
16/// Zero-sized: shares the global driver. Clone freely.
17#[derive(Clone, Copy, Default, Debug)]
18pub struct EmbassyClock;
19
20impl crate::Clock for EmbassyClock {
21    fn now_ms(&self) -> u64 {
22        Instant::now().as_millis()
23    }
24
25    fn poll_delay_until(&self, cx: &mut Context<'_>, deadline_ms: u64) -> Poll<()> {
26        let target = Instant::from_millis(deadline_ms);
27        if Instant::now() >= target {
28            return Poll::Ready(());
29        }
30        // Poll a freshly-pinned timer once to register `cx.waker()` with
31        // embassy's global timer queue. The waker registration outlives the
32        // future itself, so dropping the timer here is safe.
33        let mut timer = pin!(Timer::at(target));
34        timer.as_mut().poll(cx)
35    }
36}