feat: add display UI with splash screen, dashboard, and RSSI sparkline

Implement full SSD1306 OLED display support:
- Splash screen on boot (1.5s) with project name, version, board
- Dashboard showing radio state, config, counters, RSSI/SNR
- RSSI history sparkline (64-sample ring buffer, 2px-wide bars)
- DisplayOn/DisplayOff host commands routed via dedicated channel
- Pure render functions against generic DrawTarget (no hardware coupling)
- Display on/off control bypasses radio task entirely

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
swaitsandClaude Opus 4.6 committed 2026-03-29 20:42:54 -06:00
1 parent 7064110293
commit 3102fc747a
17624 files changed
+4564928 -38

No files matched your search

+194
View File
@@ -0,0 +1,194 @@
#![no_std]
#![doc = include_str!("../README.md")]
#![warn(missing_docs)]
//! ## 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).
//!
//! 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-driver/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<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!()
//! }
//! }
//!
//! embassy_time_driver::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)
}
};
}
+482
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;