From 5daa173ce4b153a532b4daa9e94c7a248231f25b Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Wed, 17 Aug 2022 23:40:16 +0200 Subject: Split embassy-time from embassy-executor. --- embassy-time/src/lib.rs | 99 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 embassy-time/src/lib.rs (limited to 'embassy-time/src/lib.rs') diff --git a/embassy-time/src/lib.rs b/embassy-time/src/lib.rs new file mode 100644 index 000000000..a6454d55e --- /dev/null +++ b/embassy-time/src/lib.rs @@ -0,0 +1,99 @@ +#![cfg_attr(not(any(feature = "std", feature = "wasm")), no_std)] +#![cfg_attr(feature = "nightly", feature(generic_associated_types, type_alias_impl_trait))] +#![allow(clippy::new_without_default)] +#![warn(missing_docs)] + +//! Timekeeping, delays and timeouts. +//! +//! Timekeeping is done with elapsed time since system boot. Time is represented in +//! ticks, where the tick rate is defined by the current driver, usually to match +//! the tick rate of the hardware. +//! +//! Tick counts are 64 bits. At the highest supported tick rate of 1Mhz this supports +//! representing time spans of up to ~584558 years, which is big enough for all practical +//! purposes and allows not having to worry about overflows. +//! +//! [`Instant`] represents a given instant of time (relative to system boot), and [`Duration`] +//! represents the duration of a span of time. They implement the math operations you'd expect, +//! like addition and substraction. +//! +//! # Delays and timeouts +//! +//! [`Timer`] allows performing async delays. [`Ticker`] allows periodic delays without drifting over time. +//! +//! An implementation of the `embedded-hal` delay traits is provided by [`Delay`], for compatibility +//! with libraries from the ecosystem. +//! +//! # Wall-clock time +//! +//! The `time` module deals exclusively with a monotonically increasing tick count. +//! Therefore it has no direct support for wall-clock time ("real life" datetimes +//! like `2021-08-24 13:33:21`). +//! +//! If persistence across reboots is not needed, support can be built on top of +//! `embassy_time` by storing the offset between "seconds elapsed since boot" +//! and "seconds since unix epoch". +//! +//! # Time driver +//! +//! The `time` module is backed by a global "time driver" specified at build time. +//! Only one driver can be active in a program. +//! +//! All methods and structs transparently call into the active driver. This makes it +//! possible for libraries to use `embassy_time` in a driver-agnostic way without +//! requiring generic parameters. +//! +//! For more details, check the [`driver`] module. + +// This mod MUST go first, so that the others see its macros. +pub(crate) mod fmt; + +mod delay; +pub mod driver; +mod duration; +mod instant; +mod timer; + +#[cfg(feature = "std")] +mod driver_std; +#[cfg(feature = "wasm")] +mod driver_wasm; + +pub use delay::{block_for, Delay}; +pub use duration::Duration; +pub use instant::Instant; +pub use timer::{with_timeout, Ticker, TimeoutError, Timer}; + +#[cfg(feature = "tick-1000hz")] +const TPS: u64 = 1_000; + +#[cfg(feature = "tick-32768hz")] +const TPS: u64 = 32_768; + +#[cfg(feature = "tick-1mhz")] +const TPS: u64 = 1_000_000; + +#[cfg(feature = "tick-16mhz")] +const TPS: u64 = 16_000_000; + +/// Ticks per second of the global timebase. +/// +/// This value is specified by the `tick-*` Cargo features, which +/// should be set by the time driver. Some drivers support a fixed tick rate, others +/// allow you to choose a tick rate with Cargo features of their own. You should not +/// set the `tick-*` features for embassy yourself as an end user. +pub const TICKS_PER_SECOND: u64 = TPS; + +const fn gcd(a: u64, b: u64) -> u64 { + if b == 0 { + a + } else { + gcd(b, a % b) + } +} + +pub(crate) const GCD_1K: u64 = gcd(TICKS_PER_SECOND, 1_000); +pub(crate) const GCD_1M: u64 = gcd(TICKS_PER_SECOND, 1_000_000); + +#[cfg(feature = "defmt-timestamp-uptime")] +defmt::timestamp! {"{=u64:us}", Instant::now().as_micros() } -- cgit