time: split driver into a separate embassy-time-driver crate.

This commit is contained in:
Dario Nieuwenhuis
2024-01-11 16:38:44 +01:00
parent dcffad6b05
commit 15f94fb0fc
21 changed files with 711 additions and 227 deletions

View File

@@ -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

View File

@@ -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.
#! <details>
#! <summary>Available tick rates:</summary>
#! <!-- Next line must be left empty for the features to render correctly! -->
#!
# 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
#! </details>
[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" }

View File

@@ -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.

View File

@@ -0,0 +1 @@
fn main() {}

View File

@@ -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')

View File

@@ -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, dont 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<AlarmHandle> {
//! 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#"<span class="stab portability"><code>{feature}</code></span>"#)]
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<AlarmHandle>;
/// 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<AlarmHandle>;
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<AlarmHandle> {
_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)
}
};
}

View File

@@ -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;