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}