From 15f94fb0fc70463b9a50c997083fee3f5758b17a Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Thu, 11 Jan 2024 16:38:44 +0100 Subject: time: split driver into a separate embassy-time-driver crate. --- embassy-time-driver/CHANGELOG.md | 51 +++++ embassy-time-driver/Cargo.toml | 391 +++++++++++++++++++++++++++++++ embassy-time-driver/README.md | 20 ++ embassy-time-driver/build.rs | 1 + embassy-time-driver/gen_tick.py | 81 +++++++ embassy-time-driver/src/lib.rs | 200 ++++++++++++++++ embassy-time-driver/src/tick.rs | 482 +++++++++++++++++++++++++++++++++++++++ 7 files changed, 1226 insertions(+) create mode 100644 embassy-time-driver/CHANGELOG.md create mode 100644 embassy-time-driver/Cargo.toml create mode 100644 embassy-time-driver/README.md create mode 100644 embassy-time-driver/build.rs create mode 100644 embassy-time-driver/gen_tick.py create mode 100644 embassy-time-driver/src/lib.rs create mode 100644 embassy-time-driver/src/tick.rs (limited to 'embassy-time-driver') diff --git a/embassy-time-driver/CHANGELOG.md b/embassy-time-driver/CHANGELOG.md new file mode 100644 index 000000000..d8c0c7d08 --- /dev/null +++ b/embassy-time-driver/CHANGELOG.md @@ -0,0 +1,51 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## 0.2.0 - 2023-12-04 + +- Added tick rates in multiples of 10 kHz +- Remove nightly and unstable-traits features in preparation for 1.75. +- Update heapless to 0.8. + +## 0.1.5 - 2023-10-16 + +- Added `links` key to Cargo.toml, to prevent multiple copies of this crate in the same binary. + Needed because different copies might get different tick rates, causing + wrong delays if the time driver is using one copy and user code is using another. + This is especially common when mixing crates from crates.io and git. + +## 0.1.4 - 2023-10-12 + +- Added more tick rates + +## 0.1.3 - 2023-08-28 + +- Update `embedded-hal-async` to `1.0.0-rc.2` +- Update `embedded-hal v1` to `1.0.0-rc.2` + +## 0.1.2 - 2023-07-05 + +- Update `embedded-hal-async` to `0.2.0-alpha.2`. +- Update `embedded-hal v1` to `1.0.0-alpha.11`. (Note: v0.2 support is kept unchanged). + +## 0.1.1 - 2023-04-13 + +- Update `embedded-hal-async` to `0.2.0-alpha.1` (uses `async fn` in traits). +- Update `embedded-hal v1` to `1.0.0-alpha.10`. (Note: v0.2 support is kept unchanged). +- Remove dep on `embassy-sync`. +- Fix reentrancy issues in the `std` time driver (#1177) +- Add `Duration::from_hz()`. +- impl `From` conversions to/from `core::time::Duration`. +- Add `#[must_use]` to all futures. +- Add inherent `async fn tick()` to `Ticker`, so you can use it directly without the `Stream` trait. +- Add more tick rates. +- impl `Default` for `Signal` +- Remove unnecessary uses of `atomic-polyfill` + +## 0.1.0 - 2022-08-26 + +- First release diff --git a/embassy-time-driver/Cargo.toml b/embassy-time-driver/Cargo.toml new file mode 100644 index 000000000..2ed250d4d --- /dev/null +++ b/embassy-time-driver/Cargo.toml @@ -0,0 +1,391 @@ +[package] +name = "embassy-time-driver" +version = "0.1.0" +edition = "2021" +description = "Driver trait for embassy-time" +repository = "https://github.com/embassy-rs/embassy" +readme = "README.md" +license = "MIT OR Apache-2.0" +categories = [ + "embedded", + "no-std", + "concurrency", + "asynchronous", +] + +# Prevent multiple copies of this crate in the same binary. +# Needed because different copies might get different tick rates, causing +# wrong delays if the time driver is using one copy and user code is using another. +# This is especially common when mixing crates from crates.io and git. +links = "embassy-time" + +[package.metadata.embassy_docs] +src_base = "https://github.com/embassy-rs/embassy/blob/embassy-time-driver-v$VERSION/embassy-time-driver/src/" +src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-time-driver/src/" +target = "x86_64-unknown-linux-gnu" + +[features] +#! ### Tick Rate +#! +#! At most 1 `tick-*` feature can be enabled. If none is enabled, a default of 1MHz is used. +#! +#! If the time driver in use supports using arbitrary tick rates, you can enable one `tick-*` +#! feature from your binary crate to set the tick rate. The driver will use configured tick rate. +#! If the time driver supports a fixed tick rate, it will enable one feature itself, so you should +#! not enable one. Check the time driver documentation for details. +#! +#! When using embassy-time from libraries, you should *not* enable any `tick-*` feature, to allow the +#! end user or the driver to pick. +#!
+#! Available tick rates: +#! +#! + +# BEGIN TICKS +# Generated by gen_tick.py. DO NOT EDIT. +## 1Hz Tick Rate +tick-hz-1 = [] +## 2Hz Tick Rate +tick-hz-2 = [] +## 4Hz Tick Rate +tick-hz-4 = [] +## 8Hz Tick Rate +tick-hz-8 = [] +## 10Hz Tick Rate +tick-hz-10 = [] +## 16Hz Tick Rate +tick-hz-16 = [] +## 32Hz Tick Rate +tick-hz-32 = [] +## 64Hz Tick Rate +tick-hz-64 = [] +## 100Hz Tick Rate +tick-hz-100 = [] +## 128Hz Tick Rate +tick-hz-128 = [] +## 256Hz Tick Rate +tick-hz-256 = [] +## 512Hz Tick Rate +tick-hz-512 = [] +## 1.0kHz Tick Rate +tick-hz-1_000 = [] +## 1.024kHz Tick Rate +tick-hz-1_024 = [] +## 2.0kHz Tick Rate +tick-hz-2_000 = [] +## 2.048kHz Tick Rate +tick-hz-2_048 = [] +## 4.0kHz Tick Rate +tick-hz-4_000 = [] +## 4.096kHz Tick Rate +tick-hz-4_096 = [] +## 8.0kHz Tick Rate +tick-hz-8_000 = [] +## 8.192kHz Tick Rate +tick-hz-8_192 = [] +## 10.0kHz Tick Rate +tick-hz-10_000 = [] +## 16.0kHz Tick Rate +tick-hz-16_000 = [] +## 16.384kHz Tick Rate +tick-hz-16_384 = [] +## 20.0kHz Tick Rate +tick-hz-20_000 = [] +## 32.0kHz Tick Rate +tick-hz-32_000 = [] +## 32.768kHz Tick Rate +tick-hz-32_768 = [] +## 40.0kHz Tick Rate +tick-hz-40_000 = [] +## 64.0kHz Tick Rate +tick-hz-64_000 = [] +## 65.536kHz Tick Rate +tick-hz-65_536 = [] +## 80.0kHz Tick Rate +tick-hz-80_000 = [] +## 100.0kHz Tick Rate +tick-hz-100_000 = [] +## 128.0kHz Tick Rate +tick-hz-128_000 = [] +## 131.072kHz Tick Rate +tick-hz-131_072 = [] +## 160.0kHz Tick Rate +tick-hz-160_000 = [] +## 256.0kHz Tick Rate +tick-hz-256_000 = [] +## 262.144kHz Tick Rate +tick-hz-262_144 = [] +## 320.0kHz Tick Rate +tick-hz-320_000 = [] +## 512.0kHz Tick Rate +tick-hz-512_000 = [] +## 524.288kHz Tick Rate +tick-hz-524_288 = [] +## 640.0kHz Tick Rate +tick-hz-640_000 = [] +## 1.0MHz Tick Rate +tick-hz-1_000_000 = [] +## 1.024MHz Tick Rate +tick-hz-1_024_000 = [] +## 1.048576MHz Tick Rate +tick-hz-1_048_576 = [] +## 1.28MHz Tick Rate +tick-hz-1_280_000 = [] +## 2.0MHz Tick Rate +tick-hz-2_000_000 = [] +## 2.048MHz Tick Rate +tick-hz-2_048_000 = [] +## 2.097152MHz Tick Rate +tick-hz-2_097_152 = [] +## 2.56MHz Tick Rate +tick-hz-2_560_000 = [] +## 3.0MHz Tick Rate +tick-hz-3_000_000 = [] +## 4.0MHz Tick Rate +tick-hz-4_000_000 = [] +## 4.096MHz Tick Rate +tick-hz-4_096_000 = [] +## 4.194304MHz Tick Rate +tick-hz-4_194_304 = [] +## 5.12MHz Tick Rate +tick-hz-5_120_000 = [] +## 6.0MHz Tick Rate +tick-hz-6_000_000 = [] +## 8.0MHz Tick Rate +tick-hz-8_000_000 = [] +## 8.192MHz Tick Rate +tick-hz-8_192_000 = [] +## 8.388608MHz Tick Rate +tick-hz-8_388_608 = [] +## 9.0MHz Tick Rate +tick-hz-9_000_000 = [] +## 10.0MHz Tick Rate +tick-hz-10_000_000 = [] +## 10.24MHz Tick Rate +tick-hz-10_240_000 = [] +## 12.0MHz Tick Rate +tick-hz-12_000_000 = [] +## 16.0MHz Tick Rate +tick-hz-16_000_000 = [] +## 16.384MHz Tick Rate +tick-hz-16_384_000 = [] +## 16.777216MHz Tick Rate +tick-hz-16_777_216 = [] +## 18.0MHz Tick Rate +tick-hz-18_000_000 = [] +## 20.0MHz Tick Rate +tick-hz-20_000_000 = [] +## 20.48MHz Tick Rate +tick-hz-20_480_000 = [] +## 24.0MHz Tick Rate +tick-hz-24_000_000 = [] +## 30.0MHz Tick Rate +tick-hz-30_000_000 = [] +## 32.0MHz Tick Rate +tick-hz-32_000_000 = [] +## 32.768MHz Tick Rate +tick-hz-32_768_000 = [] +## 36.0MHz Tick Rate +tick-hz-36_000_000 = [] +## 40.0MHz Tick Rate +tick-hz-40_000_000 = [] +## 40.96MHz Tick Rate +tick-hz-40_960_000 = [] +## 48.0MHz Tick Rate +tick-hz-48_000_000 = [] +## 50.0MHz Tick Rate +tick-hz-50_000_000 = [] +## 60.0MHz Tick Rate +tick-hz-60_000_000 = [] +## 64.0MHz Tick Rate +tick-hz-64_000_000 = [] +## 65.536MHz Tick Rate +tick-hz-65_536_000 = [] +## 70.0MHz Tick Rate +tick-hz-70_000_000 = [] +## 72.0MHz Tick Rate +tick-hz-72_000_000 = [] +## 80.0MHz Tick Rate +tick-hz-80_000_000 = [] +## 81.92MHz Tick Rate +tick-hz-81_920_000 = [] +## 90.0MHz Tick Rate +tick-hz-90_000_000 = [] +## 96.0MHz Tick Rate +tick-hz-96_000_000 = [] +## 100.0MHz Tick Rate +tick-hz-100_000_000 = [] +## 110.0MHz Tick Rate +tick-hz-110_000_000 = [] +## 120.0MHz Tick Rate +tick-hz-120_000_000 = [] +## 128.0MHz Tick Rate +tick-hz-128_000_000 = [] +## 130.0MHz Tick Rate +tick-hz-130_000_000 = [] +## 131.072MHz Tick Rate +tick-hz-131_072_000 = [] +## 140.0MHz Tick Rate +tick-hz-140_000_000 = [] +## 144.0MHz Tick Rate +tick-hz-144_000_000 = [] +## 150.0MHz Tick Rate +tick-hz-150_000_000 = [] +## 160.0MHz Tick Rate +tick-hz-160_000_000 = [] +## 163.84MHz Tick Rate +tick-hz-163_840_000 = [] +## 170.0MHz Tick Rate +tick-hz-170_000_000 = [] +## 180.0MHz Tick Rate +tick-hz-180_000_000 = [] +## 190.0MHz Tick Rate +tick-hz-190_000_000 = [] +## 192.0MHz Tick Rate +tick-hz-192_000_000 = [] +## 200.0MHz Tick Rate +tick-hz-200_000_000 = [] +## 210.0MHz Tick Rate +tick-hz-210_000_000 = [] +## 220.0MHz Tick Rate +tick-hz-220_000_000 = [] +## 230.0MHz Tick Rate +tick-hz-230_000_000 = [] +## 240.0MHz Tick Rate +tick-hz-240_000_000 = [] +## 250.0MHz Tick Rate +tick-hz-250_000_000 = [] +## 256.0MHz Tick Rate +tick-hz-256_000_000 = [] +## 260.0MHz Tick Rate +tick-hz-260_000_000 = [] +## 262.144MHz Tick Rate +tick-hz-262_144_000 = [] +## 270.0MHz Tick Rate +tick-hz-270_000_000 = [] +## 280.0MHz Tick Rate +tick-hz-280_000_000 = [] +## 288.0MHz Tick Rate +tick-hz-288_000_000 = [] +## 290.0MHz Tick Rate +tick-hz-290_000_000 = [] +## 300.0MHz Tick Rate +tick-hz-300_000_000 = [] +## 320.0MHz Tick Rate +tick-hz-320_000_000 = [] +## 327.68MHz Tick Rate +tick-hz-327_680_000 = [] +## 340.0MHz Tick Rate +tick-hz-340_000_000 = [] +## 360.0MHz Tick Rate +tick-hz-360_000_000 = [] +## 380.0MHz Tick Rate +tick-hz-380_000_000 = [] +## 384.0MHz Tick Rate +tick-hz-384_000_000 = [] +## 400.0MHz Tick Rate +tick-hz-400_000_000 = [] +## 420.0MHz Tick Rate +tick-hz-420_000_000 = [] +## 440.0MHz Tick Rate +tick-hz-440_000_000 = [] +## 460.0MHz Tick Rate +tick-hz-460_000_000 = [] +## 480.0MHz Tick Rate +tick-hz-480_000_000 = [] +## 500.0MHz Tick Rate +tick-hz-500_000_000 = [] +## 512.0MHz Tick Rate +tick-hz-512_000_000 = [] +## 520.0MHz Tick Rate +tick-hz-520_000_000 = [] +## 524.288MHz Tick Rate +tick-hz-524_288_000 = [] +## 540.0MHz Tick Rate +tick-hz-540_000_000 = [] +## 560.0MHz Tick Rate +tick-hz-560_000_000 = [] +## 576.0MHz Tick Rate +tick-hz-576_000_000 = [] +## 580.0MHz Tick Rate +tick-hz-580_000_000 = [] +## 600.0MHz Tick Rate +tick-hz-600_000_000 = [] +## 620.0MHz Tick Rate +tick-hz-620_000_000 = [] +## 640.0MHz Tick Rate +tick-hz-640_000_000 = [] +## 655.36MHz Tick Rate +tick-hz-655_360_000 = [] +## 660.0MHz Tick Rate +tick-hz-660_000_000 = [] +## 680.0MHz Tick Rate +tick-hz-680_000_000 = [] +## 700.0MHz Tick Rate +tick-hz-700_000_000 = [] +## 720.0MHz Tick Rate +tick-hz-720_000_000 = [] +## 740.0MHz Tick Rate +tick-hz-740_000_000 = [] +## 760.0MHz Tick Rate +tick-hz-760_000_000 = [] +## 768.0MHz Tick Rate +tick-hz-768_000_000 = [] +## 780.0MHz Tick Rate +tick-hz-780_000_000 = [] +## 800.0MHz Tick Rate +tick-hz-800_000_000 = [] +## 820.0MHz Tick Rate +tick-hz-820_000_000 = [] +## 840.0MHz Tick Rate +tick-hz-840_000_000 = [] +## 860.0MHz Tick Rate +tick-hz-860_000_000 = [] +## 880.0MHz Tick Rate +tick-hz-880_000_000 = [] +## 900.0MHz Tick Rate +tick-hz-900_000_000 = [] +## 920.0MHz Tick Rate +tick-hz-920_000_000 = [] +## 940.0MHz Tick Rate +tick-hz-940_000_000 = [] +## 960.0MHz Tick Rate +tick-hz-960_000_000 = [] +## 980.0MHz Tick Rate +tick-hz-980_000_000 = [] +## 1.0GHz Tick Rate +tick-hz-1_000_000_000 = [] +## 1.31072GHz Tick Rate +tick-hz-1_310_720_000 = [] +## 2.62144GHz Tick Rate +tick-hz-2_621_440_000 = [] +## 5.24288GHz Tick Rate +tick-hz-5_242_880_000 = [] +# END TICKS + +#!
+ +[dependencies] +defmt = { version = "0.3", optional = true } +log = { version = "0.4.14", optional = true } + +embedded-hal-02 = { package = "embedded-hal", version = "0.2.6" } +embedded-hal-1 = { package = "embedded-hal", version = "1.0" } +embedded-hal-async = { version = "1.0" } + +futures-util = { version = "0.3.17", default-features = false } +critical-section = "1.1" +cfg-if = "1.0.0" +heapless = "0.8" + +document-features = "0.2.7" + +# WASM dependencies +wasm-bindgen = { version = "0.2.81", optional = true } +js-sys = { version = "0.3", optional = true } +wasm-timer = { version = "0.2.5", optional = true } + +[dev-dependencies] +serial_test = "0.9" +critical-section = { version = "1.1", features = ["std"] } +embassy-executor = { version = "0.4.0", path = "../embassy-executor" } diff --git a/embassy-time-driver/README.md b/embassy-time-driver/README.md new file mode 100644 index 000000000..74a5b7876 --- /dev/null +++ b/embassy-time-driver/README.md @@ -0,0 +1,20 @@ +# embassy-time-driver + + +This crate contains the driver trait necessary for adding [`embassy-time`](https://crates.io/crates/embassy-time) support +for a new hardware platform. + +If you want to *use* `embassy-time` with already made drivers, you should depend on the main `embassy-time` crate, not on this crate. + +If you are writing a driver, you should depend only on this crate, not on the main `embassy-time` crate. +This will allow your driver to continue working for newer `embassy-time` major versions, without needing an update, +if the driver trait has not had breaking changes. + +## How it works + +`embassy-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. diff --git a/embassy-time-driver/build.rs b/embassy-time-driver/build.rs new file mode 100644 index 000000000..f328e4d9d --- /dev/null +++ b/embassy-time-driver/build.rs @@ -0,0 +1 @@ +fn main() {} diff --git a/embassy-time-driver/gen_tick.py b/embassy-time-driver/gen_tick.py new file mode 100644 index 000000000..af194c31f --- /dev/null +++ b/embassy-time-driver/gen_tick.py @@ -0,0 +1,81 @@ +import os +from glob import glob + +abspath = os.path.abspath(__file__) +dname = os.path.dirname(abspath) +os.chdir(dname) + +ticks = [] +for i in range(10): + ticks.append(10**i) +for i in range(1, 25): + ticks.append(2**i) +for i in range(1, 20): + ticks.append(2**i * 1000) +for i in range(1, 20): + ticks.append(2**i * 10000) +for i in range(1, 10): + ticks.append(2**i * 1000000) + ticks.append(2**i * 9 // 8 * 1000000) + ticks.append(2**i * 3 // 2 * 1000000) +for i in range(1, 30): + ticks.append(10 * i * 1_000_000) +for i in range(15, 50): + ticks.append(20 * i * 1_000_000) + +seen = set() +ticks = sorted([x for x in ticks if not (x in seen or seen.add(x))]) + +# ========= Update Cargo.toml + +SEPARATOR_START = '# BEGIN TICKS\n' +SEPARATOR_END = '# END TICKS\n' +HELP = '# Generated by gen_tick.py. DO NOT EDIT.\n' + +feats_time = '' +feats_driver = '' +for freq in ticks: + feature = f'tick-hz-{freq:_}' + if freq >= 1_000_000_000: + freq_human = f"{freq / 1_000_000_000}GHz" + elif freq >= 1_000_000: + freq_human = f"{freq / 1_000_000}MHz" + elif freq >= 1_000: + freq_human = f"{freq / 1000}kHz" + else: + freq_human = f"{freq}Hz" + + feats_time += f"## {freq_human} Tick Rate\n" + feats_time += f"{feature} = [\"embassy-time-driver/{feature}\"]\n" + feats_driver += f"## {freq_human} Tick Rate\n" + feats_driver += f"{feature} = []\n" + +with open('Cargo.toml', 'r') as f: + data = f.read() +before, data = data.split(SEPARATOR_START, maxsplit=1) +_, after = data.split(SEPARATOR_END, maxsplit=1) +with open('Cargo.toml', 'w') as f: + f.write(before + SEPARATOR_START + HELP + feats_driver + SEPARATOR_END + after) + +with open('../embassy-time/Cargo.toml', 'r') as f: + data = f.read() +before, data = data.split(SEPARATOR_START, maxsplit=1) +_, after = data.split(SEPARATOR_END, maxsplit=1) +with open('../embassy-time/Cargo.toml', 'w') as f: + f.write(before + SEPARATOR_START + HELP + feats_time + SEPARATOR_END + after) + +# ========= Update src/tick.rs + +with open('src/tick.rs', 'w') as f: + + f.write('// Generated by gen_tick.py. DO NOT EDIT.\n\n') + for hz in ticks: + f.write( + f'#[cfg(feature = "tick-hz-{hz:_}")] pub const TICK_HZ: u64 = {hz:_};\n') + f.write('#[cfg(not(any(\n') + for hz in ticks: + f.write(f'feature = "tick-hz-{hz:_}",\n') + f.write(')))] pub const TICK_HZ: u64 = 1_000_000;') + + +os.system('rustfmt src/tick.rs') diff --git a/embassy-time-driver/src/lib.rs b/embassy-time-driver/src/lib.rs new file mode 100644 index 000000000..39a772aa5 --- /dev/null +++ b/embassy-time-driver/src/lib.rs @@ -0,0 +1,200 @@ +#![no_std] +#![doc = include_str!("../README.md")] +#![warn(missing_docs)] + +//! Time driver interface +//! +//! This module defines the interface a driver needs to implement to power the `embassy_time` module. +//! +//! # Implementing a driver +//! +//! - Define a struct `MyDriver` +//! - Implement [`Driver`] for it +//! - Register it as the global driver with [`time_driver_impl`](crate::time_driver_impl). +//! - Enable the Cargo feature `embassy-executor/time` +//! +//! If your driver has a single set tick rate, enable the corresponding [`tick-hz-*`](crate#tick-rate) feature, +//! which will prevent users from needing to configure it themselves (or selecting an incorrect configuration). +//! +//! If your driver supports a small number of set tick rates, expose your own cargo features and have each one +//! enable the corresponding `embassy-time/tick-*`. +//! +//! Otherwise, don’t enable any `tick-hz-*` feature to let the user configure the tick rate themselves by +//! enabling a feature on `embassy-time`. +//! +//! # Linkage details +//! +//! Instead of the usual "trait + generic params" approach, calls from embassy to the driver are done via `extern` functions. +//! +//! `embassy` internally defines the driver functions as `extern "Rust" { fn _embassy_time_now() -> u64; }` and calls them. +//! The driver crate defines the functions as `#[no_mangle] fn _embassy_time_now() -> u64`. The linker will resolve the +//! calls from the `embassy` crate to call into the driver crate. +//! +//! If there is none or multiple drivers in the crate tree, linking will fail. +//! +//! This method has a few key advantages for something as foundational as timekeeping: +//! +//! - The time driver is available everywhere easily, without having to thread the implementation +//! through generic parameters. This is especially helpful for libraries. +//! - It means comparing `Instant`s will always make sense: if there were multiple drivers +//! active, one could compare an `Instant` from driver A to an `Instant` from driver B, which +//! would yield incorrect results. +//! +//! # Example +//! +//! ``` +//! use embassy_time::driver::{Driver, AlarmHandle}; +//! +//! struct MyDriver{} // not public! +//! +//! impl Driver for MyDriver { +//! fn now(&self) -> u64 { +//! todo!() +//! } +//! unsafe fn allocate_alarm(&self) -> Option { +//! todo!() +//! } +//! fn set_alarm_callback(&self, alarm: AlarmHandle, callback: fn(*mut ()), ctx: *mut ()) { +//! todo!() +//! } +//! fn set_alarm(&self, alarm: AlarmHandle, timestamp: u64) -> bool { +//! todo!() +//! } +//! } +//! ``` +//! ```ignore +//! embassy_time::time_driver_impl!(static DRIVER: MyDriver = MyDriver{}); +//! ``` + +//! ## Feature flags +#![doc = document_features::document_features!(feature_label = r#"{feature}"#)] + +mod tick; + +/// Ticks per second of the global timebase. +/// +/// This value is specified by the [`tick-*` Cargo features](crate#tick-rate) +pub const TICK_HZ: u64 = tick::TICK_HZ; + +/// Alarm handle, assigned by the driver. +#[derive(Clone, Copy)] +pub struct AlarmHandle { + id: u8, +} + +impl AlarmHandle { + /// Create an AlarmHandle + /// + /// Safety: May only be called by the current global Driver impl. + /// The impl is allowed to rely on the fact that all `AlarmHandle` instances + /// are created by itself in unsafe code (e.g. indexing operations) + pub unsafe fn new(id: u8) -> Self { + Self { id } + } + + /// Get the ID of the AlarmHandle. + pub fn id(&self) -> u8 { + self.id + } +} + +/// Time driver +pub trait Driver: Send + Sync + 'static { + /// Return the current timestamp in ticks. + /// + /// Implementations MUST ensure that: + /// - This is guaranteed to be monotonic, i.e. a call to now() will always return + /// a greater or equal value than earler calls. Time can't "roll backwards". + /// - It "never" overflows. It must not overflow in a sufficiently long time frame, say + /// in 10_000 years (Human civilization is likely to already have self-destructed + /// 10_000 years from now.). This means if your hardware only has 16bit/32bit timers + /// you MUST extend them to 64-bit, for example by counting overflows in software, + /// or chaining multiple timers together. + fn now(&self) -> u64; + + /// Try allocating an alarm handle. Returns None if no alarms left. + /// Initially the alarm has no callback set, and a null `ctx` pointer. + /// + /// # Safety + /// It is UB to make the alarm fire before setting a callback. + unsafe fn allocate_alarm(&self) -> Option; + + /// Sets the callback function to be called when the alarm triggers. + /// The callback may be called from any context (interrupt or thread mode). + fn set_alarm_callback(&self, alarm: AlarmHandle, callback: fn(*mut ()), ctx: *mut ()); + + /// Sets an alarm at the given timestamp. When the current timestamp reaches the alarm + /// timestamp, the provided callback function will be called. + /// + /// The `Driver` implementation should guarantee that the alarm callback is never called synchronously from `set_alarm`. + /// Rather - if `timestamp` is already in the past - `false` should be returned and alarm should not be set, + /// or alternatively, the driver should return `true` and arrange to call the alarm callback as soon as possible, but not synchronously. + /// There is a rare third possibility that the alarm was barely in the future, and by the time it was enabled, it had slipped into the + /// past. This is can be detected by double-checking that the alarm is still in the future after enabling it; if it isn't, `false` + /// should also be returned to indicate that the callback may have been called already by the alarm, but it is not guaranteed, so the + /// caller should also call the callback, just like in the more common `false` case. (Note: This requires idempotency of the callback.) + /// + /// When callback is called, it is guaranteed that now() will return a value greater or equal than timestamp. + /// + /// Only one alarm can be active at a time for each AlarmHandle. This overwrites any previously-set alarm if any. + fn set_alarm(&self, alarm: AlarmHandle, timestamp: u64) -> bool; +} + +extern "Rust" { + fn _embassy_time_now() -> u64; + fn _embassy_time_allocate_alarm() -> Option; + fn _embassy_time_set_alarm_callback(alarm: AlarmHandle, callback: fn(*mut ()), ctx: *mut ()); + fn _embassy_time_set_alarm(alarm: AlarmHandle, timestamp: u64) -> bool; +} + +/// See [`Driver::now`] +pub fn now() -> u64 { + unsafe { _embassy_time_now() } +} + +/// See [`Driver::allocate_alarm`] +/// +/// Safety: it is UB to make the alarm fire before setting a callback. +pub unsafe fn allocate_alarm() -> Option { + _embassy_time_allocate_alarm() +} + +/// See [`Driver::set_alarm_callback`] +pub fn set_alarm_callback(alarm: AlarmHandle, callback: fn(*mut ()), ctx: *mut ()) { + unsafe { _embassy_time_set_alarm_callback(alarm, callback, ctx) } +} + +/// See [`Driver::set_alarm`] +pub fn set_alarm(alarm: AlarmHandle, timestamp: u64) -> bool { + unsafe { _embassy_time_set_alarm(alarm, timestamp) } +} + +/// Set the time Driver implementation. +/// +/// See the module documentation for an example. +#[macro_export] +macro_rules! time_driver_impl { + (static $name:ident: $t: ty = $val:expr) => { + static $name: $t = $val; + + #[no_mangle] + fn _embassy_time_now() -> u64 { + <$t as $crate::Driver>::now(&$name) + } + + #[no_mangle] + unsafe fn _embassy_time_allocate_alarm() -> Option<$crate::AlarmHandle> { + <$t as $crate::Driver>::allocate_alarm(&$name) + } + + #[no_mangle] + fn _embassy_time_set_alarm_callback(alarm: $crate::AlarmHandle, callback: fn(*mut ()), ctx: *mut ()) { + <$t as $crate::Driver>::set_alarm_callback(&$name, alarm, callback, ctx) + } + + #[no_mangle] + fn _embassy_time_set_alarm(alarm: $crate::AlarmHandle, timestamp: u64) -> bool { + <$t as $crate::Driver>::set_alarm(&$name, alarm, timestamp) + } + }; +} diff --git a/embassy-time-driver/src/tick.rs b/embassy-time-driver/src/tick.rs new file mode 100644 index 000000000..916ae9498 --- /dev/null +++ b/embassy-time-driver/src/tick.rs @@ -0,0 +1,482 @@ +// Generated by gen_tick.py. DO NOT EDIT. + +#[cfg(feature = "tick-hz-1")] +pub const TICK_HZ: u64 = 1; +#[cfg(feature = "tick-hz-2")] +pub const TICK_HZ: u64 = 2; +#[cfg(feature = "tick-hz-4")] +pub const TICK_HZ: u64 = 4; +#[cfg(feature = "tick-hz-8")] +pub const TICK_HZ: u64 = 8; +#[cfg(feature = "tick-hz-10")] +pub const TICK_HZ: u64 = 10; +#[cfg(feature = "tick-hz-16")] +pub const TICK_HZ: u64 = 16; +#[cfg(feature = "tick-hz-32")] +pub const TICK_HZ: u64 = 32; +#[cfg(feature = "tick-hz-64")] +pub const TICK_HZ: u64 = 64; +#[cfg(feature = "tick-hz-100")] +pub const TICK_HZ: u64 = 100; +#[cfg(feature = "tick-hz-128")] +pub const TICK_HZ: u64 = 128; +#[cfg(feature = "tick-hz-256")] +pub const TICK_HZ: u64 = 256; +#[cfg(feature = "tick-hz-512")] +pub const TICK_HZ: u64 = 512; +#[cfg(feature = "tick-hz-1_000")] +pub const TICK_HZ: u64 = 1_000; +#[cfg(feature = "tick-hz-1_024")] +pub const TICK_HZ: u64 = 1_024; +#[cfg(feature = "tick-hz-2_000")] +pub const TICK_HZ: u64 = 2_000; +#[cfg(feature = "tick-hz-2_048")] +pub const TICK_HZ: u64 = 2_048; +#[cfg(feature = "tick-hz-4_000")] +pub const TICK_HZ: u64 = 4_000; +#[cfg(feature = "tick-hz-4_096")] +pub const TICK_HZ: u64 = 4_096; +#[cfg(feature = "tick-hz-8_000")] +pub const TICK_HZ: u64 = 8_000; +#[cfg(feature = "tick-hz-8_192")] +pub const TICK_HZ: u64 = 8_192; +#[cfg(feature = "tick-hz-10_000")] +pub const TICK_HZ: u64 = 10_000; +#[cfg(feature = "tick-hz-16_000")] +pub const TICK_HZ: u64 = 16_000; +#[cfg(feature = "tick-hz-16_384")] +pub const TICK_HZ: u64 = 16_384; +#[cfg(feature = "tick-hz-20_000")] +pub const TICK_HZ: u64 = 20_000; +#[cfg(feature = "tick-hz-32_000")] +pub const TICK_HZ: u64 = 32_000; +#[cfg(feature = "tick-hz-32_768")] +pub const TICK_HZ: u64 = 32_768; +#[cfg(feature = "tick-hz-40_000")] +pub const TICK_HZ: u64 = 40_000; +#[cfg(feature = "tick-hz-64_000")] +pub const TICK_HZ: u64 = 64_000; +#[cfg(feature = "tick-hz-65_536")] +pub const TICK_HZ: u64 = 65_536; +#[cfg(feature = "tick-hz-80_000")] +pub const TICK_HZ: u64 = 80_000; +#[cfg(feature = "tick-hz-100_000")] +pub const TICK_HZ: u64 = 100_000; +#[cfg(feature = "tick-hz-128_000")] +pub const TICK_HZ: u64 = 128_000; +#[cfg(feature = "tick-hz-131_072")] +pub const TICK_HZ: u64 = 131_072; +#[cfg(feature = "tick-hz-160_000")] +pub const TICK_HZ: u64 = 160_000; +#[cfg(feature = "tick-hz-256_000")] +pub const TICK_HZ: u64 = 256_000; +#[cfg(feature = "tick-hz-262_144")] +pub const TICK_HZ: u64 = 262_144; +#[cfg(feature = "tick-hz-320_000")] +pub const TICK_HZ: u64 = 320_000; +#[cfg(feature = "tick-hz-512_000")] +pub const TICK_HZ: u64 = 512_000; +#[cfg(feature = "tick-hz-524_288")] +pub const TICK_HZ: u64 = 524_288; +#[cfg(feature = "tick-hz-640_000")] +pub const TICK_HZ: u64 = 640_000; +#[cfg(feature = "tick-hz-1_000_000")] +pub const TICK_HZ: u64 = 1_000_000; +#[cfg(feature = "tick-hz-1_024_000")] +pub const TICK_HZ: u64 = 1_024_000; +#[cfg(feature = "tick-hz-1_048_576")] +pub const TICK_HZ: u64 = 1_048_576; +#[cfg(feature = "tick-hz-1_280_000")] +pub const TICK_HZ: u64 = 1_280_000; +#[cfg(feature = "tick-hz-2_000_000")] +pub const TICK_HZ: u64 = 2_000_000; +#[cfg(feature = "tick-hz-2_048_000")] +pub const TICK_HZ: u64 = 2_048_000; +#[cfg(feature = "tick-hz-2_097_152")] +pub const TICK_HZ: u64 = 2_097_152; +#[cfg(feature = "tick-hz-2_560_000")] +pub const TICK_HZ: u64 = 2_560_000; +#[cfg(feature = "tick-hz-3_000_000")] +pub const TICK_HZ: u64 = 3_000_000; +#[cfg(feature = "tick-hz-4_000_000")] +pub const TICK_HZ: u64 = 4_000_000; +#[cfg(feature = "tick-hz-4_096_000")] +pub const TICK_HZ: u64 = 4_096_000; +#[cfg(feature = "tick-hz-4_194_304")] +pub const TICK_HZ: u64 = 4_194_304; +#[cfg(feature = "tick-hz-5_120_000")] +pub const TICK_HZ: u64 = 5_120_000; +#[cfg(feature = "tick-hz-6_000_000")] +pub const TICK_HZ: u64 = 6_000_000; +#[cfg(feature = "tick-hz-8_000_000")] +pub const TICK_HZ: u64 = 8_000_000; +#[cfg(feature = "tick-hz-8_192_000")] +pub const TICK_HZ: u64 = 8_192_000; +#[cfg(feature = "tick-hz-8_388_608")] +pub const TICK_HZ: u64 = 8_388_608; +#[cfg(feature = "tick-hz-9_000_000")] +pub const TICK_HZ: u64 = 9_000_000; +#[cfg(feature = "tick-hz-10_000_000")] +pub const TICK_HZ: u64 = 10_000_000; +#[cfg(feature = "tick-hz-10_240_000")] +pub const TICK_HZ: u64 = 10_240_000; +#[cfg(feature = "tick-hz-12_000_000")] +pub const TICK_HZ: u64 = 12_000_000; +#[cfg(feature = "tick-hz-16_000_000")] +pub const TICK_HZ: u64 = 16_000_000; +#[cfg(feature = "tick-hz-16_384_000")] +pub const TICK_HZ: u64 = 16_384_000; +#[cfg(feature = "tick-hz-16_777_216")] +pub const TICK_HZ: u64 = 16_777_216; +#[cfg(feature = "tick-hz-18_000_000")] +pub const TICK_HZ: u64 = 18_000_000; +#[cfg(feature = "tick-hz-20_000_000")] +pub const TICK_HZ: u64 = 20_000_000; +#[cfg(feature = "tick-hz-20_480_000")] +pub const TICK_HZ: u64 = 20_480_000; +#[cfg(feature = "tick-hz-24_000_000")] +pub const TICK_HZ: u64 = 24_000_000; +#[cfg(feature = "tick-hz-30_000_000")] +pub const TICK_HZ: u64 = 30_000_000; +#[cfg(feature = "tick-hz-32_000_000")] +pub const TICK_HZ: u64 = 32_000_000; +#[cfg(feature = "tick-hz-32_768_000")] +pub const TICK_HZ: u64 = 32_768_000; +#[cfg(feature = "tick-hz-36_000_000")] +pub const TICK_HZ: u64 = 36_000_000; +#[cfg(feature = "tick-hz-40_000_000")] +pub const TICK_HZ: u64 = 40_000_000; +#[cfg(feature = "tick-hz-40_960_000")] +pub const TICK_HZ: u64 = 40_960_000; +#[cfg(feature = "tick-hz-48_000_000")] +pub const TICK_HZ: u64 = 48_000_000; +#[cfg(feature = "tick-hz-50_000_000")] +pub const TICK_HZ: u64 = 50_000_000; +#[cfg(feature = "tick-hz-60_000_000")] +pub const TICK_HZ: u64 = 60_000_000; +#[cfg(feature = "tick-hz-64_000_000")] +pub const TICK_HZ: u64 = 64_000_000; +#[cfg(feature = "tick-hz-65_536_000")] +pub const TICK_HZ: u64 = 65_536_000; +#[cfg(feature = "tick-hz-70_000_000")] +pub const TICK_HZ: u64 = 70_000_000; +#[cfg(feature = "tick-hz-72_000_000")] +pub const TICK_HZ: u64 = 72_000_000; +#[cfg(feature = "tick-hz-80_000_000")] +pub const TICK_HZ: u64 = 80_000_000; +#[cfg(feature = "tick-hz-81_920_000")] +pub const TICK_HZ: u64 = 81_920_000; +#[cfg(feature = "tick-hz-90_000_000")] +pub const TICK_HZ: u64 = 90_000_000; +#[cfg(feature = "tick-hz-96_000_000")] +pub const TICK_HZ: u64 = 96_000_000; +#[cfg(feature = "tick-hz-100_000_000")] +pub const TICK_HZ: u64 = 100_000_000; +#[cfg(feature = "tick-hz-110_000_000")] +pub const TICK_HZ: u64 = 110_000_000; +#[cfg(feature = "tick-hz-120_000_000")] +pub const TICK_HZ: u64 = 120_000_000; +#[cfg(feature = "tick-hz-128_000_000")] +pub const TICK_HZ: u64 = 128_000_000; +#[cfg(feature = "tick-hz-130_000_000")] +pub const TICK_HZ: u64 = 130_000_000; +#[cfg(feature = "tick-hz-131_072_000")] +pub const TICK_HZ: u64 = 131_072_000; +#[cfg(feature = "tick-hz-140_000_000")] +pub const TICK_HZ: u64 = 140_000_000; +#[cfg(feature = "tick-hz-144_000_000")] +pub const TICK_HZ: u64 = 144_000_000; +#[cfg(feature = "tick-hz-150_000_000")] +pub const TICK_HZ: u64 = 150_000_000; +#[cfg(feature = "tick-hz-160_000_000")] +pub const TICK_HZ: u64 = 160_000_000; +#[cfg(feature = "tick-hz-163_840_000")] +pub const TICK_HZ: u64 = 163_840_000; +#[cfg(feature = "tick-hz-170_000_000")] +pub const TICK_HZ: u64 = 170_000_000; +#[cfg(feature = "tick-hz-180_000_000")] +pub const TICK_HZ: u64 = 180_000_000; +#[cfg(feature = "tick-hz-190_000_000")] +pub const TICK_HZ: u64 = 190_000_000; +#[cfg(feature = "tick-hz-192_000_000")] +pub const TICK_HZ: u64 = 192_000_000; +#[cfg(feature = "tick-hz-200_000_000")] +pub const TICK_HZ: u64 = 200_000_000; +#[cfg(feature = "tick-hz-210_000_000")] +pub const TICK_HZ: u64 = 210_000_000; +#[cfg(feature = "tick-hz-220_000_000")] +pub const TICK_HZ: u64 = 220_000_000; +#[cfg(feature = "tick-hz-230_000_000")] +pub const TICK_HZ: u64 = 230_000_000; +#[cfg(feature = "tick-hz-240_000_000")] +pub const TICK_HZ: u64 = 240_000_000; +#[cfg(feature = "tick-hz-250_000_000")] +pub const TICK_HZ: u64 = 250_000_000; +#[cfg(feature = "tick-hz-256_000_000")] +pub const TICK_HZ: u64 = 256_000_000; +#[cfg(feature = "tick-hz-260_000_000")] +pub const TICK_HZ: u64 = 260_000_000; +#[cfg(feature = "tick-hz-262_144_000")] +pub const TICK_HZ: u64 = 262_144_000; +#[cfg(feature = "tick-hz-270_000_000")] +pub const TICK_HZ: u64 = 270_000_000; +#[cfg(feature = "tick-hz-280_000_000")] +pub const TICK_HZ: u64 = 280_000_000; +#[cfg(feature = "tick-hz-288_000_000")] +pub const TICK_HZ: u64 = 288_000_000; +#[cfg(feature = "tick-hz-290_000_000")] +pub const TICK_HZ: u64 = 290_000_000; +#[cfg(feature = "tick-hz-300_000_000")] +pub const TICK_HZ: u64 = 300_000_000; +#[cfg(feature = "tick-hz-320_000_000")] +pub const TICK_HZ: u64 = 320_000_000; +#[cfg(feature = "tick-hz-327_680_000")] +pub const TICK_HZ: u64 = 327_680_000; +#[cfg(feature = "tick-hz-340_000_000")] +pub const TICK_HZ: u64 = 340_000_000; +#[cfg(feature = "tick-hz-360_000_000")] +pub const TICK_HZ: u64 = 360_000_000; +#[cfg(feature = "tick-hz-380_000_000")] +pub const TICK_HZ: u64 = 380_000_000; +#[cfg(feature = "tick-hz-384_000_000")] +pub const TICK_HZ: u64 = 384_000_000; +#[cfg(feature = "tick-hz-400_000_000")] +pub const TICK_HZ: u64 = 400_000_000; +#[cfg(feature = "tick-hz-420_000_000")] +pub const TICK_HZ: u64 = 420_000_000; +#[cfg(feature = "tick-hz-440_000_000")] +pub const TICK_HZ: u64 = 440_000_000; +#[cfg(feature = "tick-hz-460_000_000")] +pub const TICK_HZ: u64 = 460_000_000; +#[cfg(feature = "tick-hz-480_000_000")] +pub const TICK_HZ: u64 = 480_000_000; +#[cfg(feature = "tick-hz-500_000_000")] +pub const TICK_HZ: u64 = 500_000_000; +#[cfg(feature = "tick-hz-512_000_000")] +pub const TICK_HZ: u64 = 512_000_000; +#[cfg(feature = "tick-hz-520_000_000")] +pub const TICK_HZ: u64 = 520_000_000; +#[cfg(feature = "tick-hz-524_288_000")] +pub const TICK_HZ: u64 = 524_288_000; +#[cfg(feature = "tick-hz-540_000_000")] +pub const TICK_HZ: u64 = 540_000_000; +#[cfg(feature = "tick-hz-560_000_000")] +pub const TICK_HZ: u64 = 560_000_000; +#[cfg(feature = "tick-hz-576_000_000")] +pub const TICK_HZ: u64 = 576_000_000; +#[cfg(feature = "tick-hz-580_000_000")] +pub const TICK_HZ: u64 = 580_000_000; +#[cfg(feature = "tick-hz-600_000_000")] +pub const TICK_HZ: u64 = 600_000_000; +#[cfg(feature = "tick-hz-620_000_000")] +pub const TICK_HZ: u64 = 620_000_000; +#[cfg(feature = "tick-hz-640_000_000")] +pub const TICK_HZ: u64 = 640_000_000; +#[cfg(feature = "tick-hz-655_360_000")] +pub const TICK_HZ: u64 = 655_360_000; +#[cfg(feature = "tick-hz-660_000_000")] +pub const TICK_HZ: u64 = 660_000_000; +#[cfg(feature = "tick-hz-680_000_000")] +pub const TICK_HZ: u64 = 680_000_000; +#[cfg(feature = "tick-hz-700_000_000")] +pub const TICK_HZ: u64 = 700_000_000; +#[cfg(feature = "tick-hz-720_000_000")] +pub const TICK_HZ: u64 = 720_000_000; +#[cfg(feature = "tick-hz-740_000_000")] +pub const TICK_HZ: u64 = 740_000_000; +#[cfg(feature = "tick-hz-760_000_000")] +pub const TICK_HZ: u64 = 760_000_000; +#[cfg(feature = "tick-hz-768_000_000")] +pub const TICK_HZ: u64 = 768_000_000; +#[cfg(feature = "tick-hz-780_000_000")] +pub const TICK_HZ: u64 = 780_000_000; +#[cfg(feature = "tick-hz-800_000_000")] +pub const TICK_HZ: u64 = 800_000_000; +#[cfg(feature = "tick-hz-820_000_000")] +pub const TICK_HZ: u64 = 820_000_000; +#[cfg(feature = "tick-hz-840_000_000")] +pub const TICK_HZ: u64 = 840_000_000; +#[cfg(feature = "tick-hz-860_000_000")] +pub const TICK_HZ: u64 = 860_000_000; +#[cfg(feature = "tick-hz-880_000_000")] +pub const TICK_HZ: u64 = 880_000_000; +#[cfg(feature = "tick-hz-900_000_000")] +pub const TICK_HZ: u64 = 900_000_000; +#[cfg(feature = "tick-hz-920_000_000")] +pub const TICK_HZ: u64 = 920_000_000; +#[cfg(feature = "tick-hz-940_000_000")] +pub const TICK_HZ: u64 = 940_000_000; +#[cfg(feature = "tick-hz-960_000_000")] +pub const TICK_HZ: u64 = 960_000_000; +#[cfg(feature = "tick-hz-980_000_000")] +pub const TICK_HZ: u64 = 980_000_000; +#[cfg(feature = "tick-hz-1_000_000_000")] +pub const TICK_HZ: u64 = 1_000_000_000; +#[cfg(feature = "tick-hz-1_310_720_000")] +pub const TICK_HZ: u64 = 1_310_720_000; +#[cfg(feature = "tick-hz-2_621_440_000")] +pub const TICK_HZ: u64 = 2_621_440_000; +#[cfg(feature = "tick-hz-5_242_880_000")] +pub const TICK_HZ: u64 = 5_242_880_000; +#[cfg(not(any( + feature = "tick-hz-1", + feature = "tick-hz-2", + feature = "tick-hz-4", + feature = "tick-hz-8", + feature = "tick-hz-10", + feature = "tick-hz-16", + feature = "tick-hz-32", + feature = "tick-hz-64", + feature = "tick-hz-100", + feature = "tick-hz-128", + feature = "tick-hz-256", + feature = "tick-hz-512", + feature = "tick-hz-1_000", + feature = "tick-hz-1_024", + feature = "tick-hz-2_000", + feature = "tick-hz-2_048", + feature = "tick-hz-4_000", + feature = "tick-hz-4_096", + feature = "tick-hz-8_000", + feature = "tick-hz-8_192", + feature = "tick-hz-10_000", + feature = "tick-hz-16_000", + feature = "tick-hz-16_384", + feature = "tick-hz-20_000", + feature = "tick-hz-32_000", + feature = "tick-hz-32_768", + feature = "tick-hz-40_000", + feature = "tick-hz-64_000", + feature = "tick-hz-65_536", + feature = "tick-hz-80_000", + feature = "tick-hz-100_000", + feature = "tick-hz-128_000", + feature = "tick-hz-131_072", + feature = "tick-hz-160_000", + feature = "tick-hz-256_000", + feature = "tick-hz-262_144", + feature = "tick-hz-320_000", + feature = "tick-hz-512_000", + feature = "tick-hz-524_288", + feature = "tick-hz-640_000", + feature = "tick-hz-1_000_000", + feature = "tick-hz-1_024_000", + feature = "tick-hz-1_048_576", + feature = "tick-hz-1_280_000", + feature = "tick-hz-2_000_000", + feature = "tick-hz-2_048_000", + feature = "tick-hz-2_097_152", + feature = "tick-hz-2_560_000", + feature = "tick-hz-3_000_000", + feature = "tick-hz-4_000_000", + feature = "tick-hz-4_096_000", + feature = "tick-hz-4_194_304", + feature = "tick-hz-5_120_000", + feature = "tick-hz-6_000_000", + feature = "tick-hz-8_000_000", + feature = "tick-hz-8_192_000", + feature = "tick-hz-8_388_608", + feature = "tick-hz-9_000_000", + feature = "tick-hz-10_000_000", + feature = "tick-hz-10_240_000", + feature = "tick-hz-12_000_000", + feature = "tick-hz-16_000_000", + feature = "tick-hz-16_384_000", + feature = "tick-hz-16_777_216", + feature = "tick-hz-18_000_000", + feature = "tick-hz-20_000_000", + feature = "tick-hz-20_480_000", + feature = "tick-hz-24_000_000", + feature = "tick-hz-30_000_000", + feature = "tick-hz-32_000_000", + feature = "tick-hz-32_768_000", + feature = "tick-hz-36_000_000", + feature = "tick-hz-40_000_000", + feature = "tick-hz-40_960_000", + feature = "tick-hz-48_000_000", + feature = "tick-hz-50_000_000", + feature = "tick-hz-60_000_000", + feature = "tick-hz-64_000_000", + feature = "tick-hz-65_536_000", + feature = "tick-hz-70_000_000", + feature = "tick-hz-72_000_000", + feature = "tick-hz-80_000_000", + feature = "tick-hz-81_920_000", + feature = "tick-hz-90_000_000", + feature = "tick-hz-96_000_000", + feature = "tick-hz-100_000_000", + feature = "tick-hz-110_000_000", + feature = "tick-hz-120_000_000", + feature = "tick-hz-128_000_000", + feature = "tick-hz-130_000_000", + feature = "tick-hz-131_072_000", + feature = "tick-hz-140_000_000", + feature = "tick-hz-144_000_000", + feature = "tick-hz-150_000_000", + feature = "tick-hz-160_000_000", + feature = "tick-hz-163_840_000", + feature = "tick-hz-170_000_000", + feature = "tick-hz-180_000_000", + feature = "tick-hz-190_000_000", + feature = "tick-hz-192_000_000", + feature = "tick-hz-200_000_000", + feature = "tick-hz-210_000_000", + feature = "tick-hz-220_000_000", + feature = "tick-hz-230_000_000", + feature = "tick-hz-240_000_000", + feature = "tick-hz-250_000_000", + feature = "tick-hz-256_000_000", + feature = "tick-hz-260_000_000", + feature = "tick-hz-262_144_000", + feature = "tick-hz-270_000_000", + feature = "tick-hz-280_000_000", + feature = "tick-hz-288_000_000", + feature = "tick-hz-290_000_000", + feature = "tick-hz-300_000_000", + feature = "tick-hz-320_000_000", + feature = "tick-hz-327_680_000", + feature = "tick-hz-340_000_000", + feature = "tick-hz-360_000_000", + feature = "tick-hz-380_000_000", + feature = "tick-hz-384_000_000", + feature = "tick-hz-400_000_000", + feature = "tick-hz-420_000_000", + feature = "tick-hz-440_000_000", + feature = "tick-hz-460_000_000", + feature = "tick-hz-480_000_000", + feature = "tick-hz-500_000_000", + feature = "tick-hz-512_000_000", + feature = "tick-hz-520_000_000", + feature = "tick-hz-524_288_000", + feature = "tick-hz-540_000_000", + feature = "tick-hz-560_000_000", + feature = "tick-hz-576_000_000", + feature = "tick-hz-580_000_000", + feature = "tick-hz-600_000_000", + feature = "tick-hz-620_000_000", + feature = "tick-hz-640_000_000", + feature = "tick-hz-655_360_000", + feature = "tick-hz-660_000_000", + feature = "tick-hz-680_000_000", + feature = "tick-hz-700_000_000", + feature = "tick-hz-720_000_000", + feature = "tick-hz-740_000_000", + feature = "tick-hz-760_000_000", + feature = "tick-hz-768_000_000", + feature = "tick-hz-780_000_000", + feature = "tick-hz-800_000_000", + feature = "tick-hz-820_000_000", + feature = "tick-hz-840_000_000", + feature = "tick-hz-860_000_000", + feature = "tick-hz-880_000_000", + feature = "tick-hz-900_000_000", + feature = "tick-hz-920_000_000", + feature = "tick-hz-940_000_000", + feature = "tick-hz-960_000_000", + feature = "tick-hz-980_000_000", + feature = "tick-hz-1_000_000_000", + feature = "tick-hz-1_310_720_000", + feature = "tick-hz-2_621_440_000", + feature = "tick-hz-5_242_880_000", +)))] +pub const TICK_HZ: u64 = 1_000_000; -- cgit