time: add more tick rates, use 1mhz as default.

This commit is contained in:
Dario Nieuwenhuis
2022-09-02 00:58:31 +02:00
parent 835b69456d
commit 5327b9c289
38 changed files with 418 additions and 135 deletions

View File

@ -11,8 +11,8 @@ features = ["nightly", "defmt", "unstable-traits", "std"]
target = "x86_64-unknown-linux-gnu"
[features]
std = ["tick-1mhz"]
wasm = ["dep:wasm-bindgen", "dep:js-sys", "dep:wasm-timer", "tick-1mhz"]
std = ["tick-hz-1_000_000"]
wasm = ["dep:wasm-bindgen", "dep:js-sys", "dep:wasm-timer", "tick-hz-1_000_000"]
# Enable nightly-only features
nightly = ["embedded-hal-async"]
@ -26,13 +26,79 @@ unstable-traits = ["embedded-hal-1"]
defmt-timestamp-uptime = ["defmt"]
# Set the `embassy_time` tick rate.
# NOTE: This feature is only intended to be enabled by crates providing the time driver implementation.
# If you're not writing your own driver, check the driver documentation to customize the tick rate.
# If you're writing a driver and your tick rate is not listed here, please add it and send a PR!
tick-32768hz = []
tick-1000hz = []
tick-1mhz = []
tick-16mhz = []
#
# 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.
# BEGIN TICKS
# Generated by gen_tick.py. DO NOT EDIT.
tick-hz-1 = []
tick-hz-10 = []
tick-hz-100 = []
tick-hz-1_000 = []
tick-hz-10_000 = []
tick-hz-100_000 = []
tick-hz-1_000_000 = []
tick-hz-10_000_000 = []
tick-hz-100_000_000 = []
tick-hz-1_000_000_000 = []
tick-hz-2 = []
tick-hz-4 = []
tick-hz-8 = []
tick-hz-16 = []
tick-hz-32 = []
tick-hz-64 = []
tick-hz-128 = []
tick-hz-256 = []
tick-hz-512 = []
tick-hz-1_024 = []
tick-hz-2_048 = []
tick-hz-4_096 = []
tick-hz-8_192 = []
tick-hz-16_384 = []
tick-hz-32_768 = []
tick-hz-65_536 = []
tick-hz-131_072 = []
tick-hz-262_144 = []
tick-hz-524_288 = []
tick-hz-1_048_576 = []
tick-hz-2_097_152 = []
tick-hz-4_194_304 = []
tick-hz-8_388_608 = []
tick-hz-16_777_216 = []
tick-hz-2_000_000 = []
tick-hz-3_000_000 = []
tick-hz-4_000_000 = []
tick-hz-6_000_000 = []
tick-hz-8_000_000 = []
tick-hz-9_000_000 = []
tick-hz-12_000_000 = []
tick-hz-16_000_000 = []
tick-hz-18_000_000 = []
tick-hz-24_000_000 = []
tick-hz-32_000_000 = []
tick-hz-36_000_000 = []
tick-hz-48_000_000 = []
tick-hz-64_000_000 = []
tick-hz-72_000_000 = []
tick-hz-96_000_000 = []
tick-hz-128_000_000 = []
tick-hz-144_000_000 = []
tick-hz-192_000_000 = []
tick-hz-256_000_000 = []
tick-hz-288_000_000 = []
tick-hz-384_000_000 = []
tick-hz-512_000_000 = []
tick-hz-576_000_000 = []
tick-hz-768_000_000 = []
# END TICKS
[dependencies]
defmt = { version = "0.3", optional = true }

50
embassy-time/gen_tick.py Normal file
View File

@ -0,0 +1,50 @@
import os
import toml
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, 10):
ticks.append(2**i * 1000000)
ticks.append(2**i * 9 // 8 * 1000000)
ticks.append(2**i * 3 // 2 * 1000000)
seen = set()
ticks = [x for x in ticks if not (x in seen or seen.add(x))]
# ========= Update Cargo.toml
things = {f'tick-hz-{hz:_}': [] for hz in ticks}
SEPARATOR_START = '# BEGIN TICKS\n'
SEPARATOR_END = '# END TICKS\n'
HELP = '# Generated by gen_tick.py. DO NOT EDIT.\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)
data = before + SEPARATOR_START + HELP + toml.dumps(things) + SEPARATOR_END + after
with open('Cargo.toml', 'w') as f:
f.write(data)
# ========= 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

@ -1,7 +1,7 @@
use core::fmt;
use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
use super::{GCD_1K, GCD_1M, TICKS_PER_SECOND};
use super::{GCD_1K, GCD_1M, TICK_HZ};
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
@ -23,17 +23,17 @@ impl Duration {
/// Convert the `Duration` to seconds, rounding down.
pub const fn as_secs(&self) -> u64 {
self.ticks / TICKS_PER_SECOND
self.ticks / TICK_HZ
}
/// Convert the `Duration` to milliseconds, rounding down.
pub const fn as_millis(&self) -> u64 {
self.ticks * (1000 / GCD_1K) / (TICKS_PER_SECOND / GCD_1K)
self.ticks * (1000 / GCD_1K) / (TICK_HZ / GCD_1K)
}
/// Convert the `Duration` to microseconds, rounding down.
pub const fn as_micros(&self) -> u64 {
self.ticks * (1_000_000 / GCD_1M) / (TICKS_PER_SECOND / GCD_1M)
self.ticks * (1_000_000 / GCD_1M) / (TICK_HZ / GCD_1M)
}
/// Creates a duration from the specified number of clock ticks
@ -43,15 +43,13 @@ impl Duration {
/// Creates a duration from the specified number of seconds, rounding up.
pub const fn from_secs(secs: u64) -> Duration {
Duration {
ticks: secs * TICKS_PER_SECOND,
}
Duration { ticks: secs * TICK_HZ }
}
/// Creates a duration from the specified number of milliseconds, rounding up.
pub const fn from_millis(millis: u64) -> Duration {
Duration {
ticks: div_ceil(millis * (TICKS_PER_SECOND / GCD_1K), 1000 / GCD_1K),
ticks: div_ceil(millis * (TICK_HZ / GCD_1K), 1000 / GCD_1K),
}
}
@ -59,21 +57,19 @@ impl Duration {
/// NOTE: Delays this small may be inaccurate.
pub const fn from_micros(micros: u64) -> Duration {
Duration {
ticks: div_ceil(micros * (TICKS_PER_SECOND / GCD_1M), 1_000_000 / GCD_1M),
ticks: div_ceil(micros * (TICK_HZ / GCD_1M), 1_000_000 / GCD_1M),
}
}
/// Creates a duration from the specified number of seconds, rounding down.
pub const fn from_secs_floor(secs: u64) -> Duration {
Duration {
ticks: secs * TICKS_PER_SECOND,
}
Duration { ticks: secs * TICK_HZ }
}
/// Creates a duration from the specified number of milliseconds, rounding down.
pub const fn from_millis_floor(millis: u64) -> Duration {
Duration {
ticks: millis * (TICKS_PER_SECOND / GCD_1K) / (1000 / GCD_1K),
ticks: millis * (TICK_HZ / GCD_1K) / (1000 / GCD_1K),
}
}
@ -81,7 +77,7 @@ impl Duration {
/// NOTE: Delays this small may be inaccurate.
pub const fn from_micros_floor(micros: u64) -> Duration {
Duration {
ticks: micros * (TICKS_PER_SECOND / GCD_1M) / (1_000_000 / GCD_1M),
ticks: micros * (TICK_HZ / GCD_1M) / (1_000_000 / GCD_1M),
}
}

View File

@ -1,7 +1,7 @@
use core::fmt;
use core::ops::{Add, AddAssign, Sub, SubAssign};
use super::{driver, Duration, GCD_1K, GCD_1M, TICKS_PER_SECOND};
use super::{driver, Duration, GCD_1K, GCD_1M, TICK_HZ};
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
@ -29,21 +29,21 @@ impl Instant {
/// Create an Instant from a microsecond count since system boot.
pub const fn from_micros(micros: u64) -> Self {
Self {
ticks: micros * (TICKS_PER_SECOND / GCD_1M) / (1_000_000 / GCD_1M),
ticks: micros * (TICK_HZ / GCD_1M) / (1_000_000 / GCD_1M),
}
}
/// Create an Instant from a millisecond count since system boot.
pub const fn from_millis(millis: u64) -> Self {
Self {
ticks: millis * (TICKS_PER_SECOND / GCD_1K) / (1000 / GCD_1K),
ticks: millis * (TICK_HZ / GCD_1K) / (1000 / GCD_1K),
}
}
/// Create an Instant from a second count since system boot.
pub const fn from_secs(seconds: u64) -> Self {
Self {
ticks: seconds * TICKS_PER_SECOND,
ticks: seconds * TICK_HZ,
}
}
@ -54,17 +54,17 @@ impl Instant {
/// Seconds since system boot.
pub const fn as_secs(&self) -> u64 {
self.ticks / TICKS_PER_SECOND
self.ticks / TICK_HZ
}
/// Milliseconds since system boot.
pub const fn as_millis(&self) -> u64 {
self.ticks * (1000 / GCD_1K) / (TICKS_PER_SECOND / GCD_1K)
self.ticks * (1000 / GCD_1K) / (TICK_HZ / GCD_1K)
}
/// Microseconds since system boot.
pub const fn as_micros(&self) -> u64 {
self.ticks * (1_000_000 / GCD_1M) / (TICKS_PER_SECOND / GCD_1M)
self.ticks * (1_000_000 / GCD_1M) / (TICK_HZ / GCD_1M)
}
/// Duration between this Instant and another Instant

View File

@ -11,6 +11,7 @@ mod delay;
pub mod driver;
mod duration;
mod instant;
mod tick;
mod timer;
#[cfg(feature = "std")]
@ -23,25 +24,13 @@ pub use duration::Duration;
pub use instant::Instant;
pub use timer::{with_timeout, Ticker, TimeoutError, Timer};
#[cfg(feature = "tick-1000hz")]
const TPS: u64 = 1_000;
#[cfg(feature = "tick-32768hz")]
const TPS: u64 = 32_768;
#[cfg(feature = "tick-1mhz")]
const TPS: u64 = 1_000_000;
#[cfg(feature = "tick-16mhz")]
const TPS: u64 = 16_000_000;
/// Ticks per second of the global timebase.
///
/// This value is specified by the `tick-*` Cargo features, which
/// should be set by the time driver. Some drivers support a fixed tick rate, others
/// allow you to choose a tick rate with Cargo features of their own. You should not
/// set the `tick-*` features for embassy yourself as an end user.
pub const TICKS_PER_SECOND: u64 = TPS;
pub const TICK_HZ: u64 = tick::TICK_HZ;
const fn gcd(a: u64, b: u64) -> u64 {
if b == 0 {
@ -51,8 +40,8 @@ const fn gcd(a: u64, b: u64) -> u64 {
}
}
pub(crate) const GCD_1K: u64 = gcd(TICKS_PER_SECOND, 1_000);
pub(crate) const GCD_1M: u64 = gcd(TICKS_PER_SECOND, 1_000_000);
pub(crate) const GCD_1K: u64 = gcd(TICK_HZ, 1_000);
pub(crate) const GCD_1M: u64 = gcd(TICK_HZ, 1_000_000);
#[cfg(feature = "defmt-timestamp-uptime")]
defmt::timestamp! {"{=u64:us}", Instant::now().as_micros() }

182
embassy-time/src/tick.rs Normal file
View File

@ -0,0 +1,182 @@
// Generated by gen_tick.py. DO NOT EDIT.
#[cfg(feature = "tick-hz-1")]
pub const TICK_HZ: u64 = 1;
#[cfg(feature = "tick-hz-10")]
pub const TICK_HZ: u64 = 10;
#[cfg(feature = "tick-hz-100")]
pub const TICK_HZ: u64 = 100;
#[cfg(feature = "tick-hz-1_000")]
pub const TICK_HZ: u64 = 1_000;
#[cfg(feature = "tick-hz-10_000")]
pub const TICK_HZ: u64 = 10_000;
#[cfg(feature = "tick-hz-100_000")]
pub const TICK_HZ: u64 = 100_000;
#[cfg(feature = "tick-hz-1_000_000")]
pub const TICK_HZ: u64 = 1_000_000;
#[cfg(feature = "tick-hz-10_000_000")]
pub const TICK_HZ: u64 = 10_000_000;
#[cfg(feature = "tick-hz-100_000_000")]
pub const TICK_HZ: u64 = 100_000_000;
#[cfg(feature = "tick-hz-1_000_000_000")]
pub const TICK_HZ: u64 = 1_000_000_000;
#[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-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-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_024")]
pub const TICK_HZ: u64 = 1_024;
#[cfg(feature = "tick-hz-2_048")]
pub const TICK_HZ: u64 = 2_048;
#[cfg(feature = "tick-hz-4_096")]
pub const TICK_HZ: u64 = 4_096;
#[cfg(feature = "tick-hz-8_192")]
pub const TICK_HZ: u64 = 8_192;
#[cfg(feature = "tick-hz-16_384")]
pub const TICK_HZ: u64 = 16_384;
#[cfg(feature = "tick-hz-32_768")]
pub const TICK_HZ: u64 = 32_768;
#[cfg(feature = "tick-hz-65_536")]
pub const TICK_HZ: u64 = 65_536;
#[cfg(feature = "tick-hz-131_072")]
pub const TICK_HZ: u64 = 131_072;
#[cfg(feature = "tick-hz-262_144")]
pub const TICK_HZ: u64 = 262_144;
#[cfg(feature = "tick-hz-524_288")]
pub const TICK_HZ: u64 = 524_288;
#[cfg(feature = "tick-hz-1_048_576")]
pub const TICK_HZ: u64 = 1_048_576;
#[cfg(feature = "tick-hz-2_097_152")]
pub const TICK_HZ: u64 = 2_097_152;
#[cfg(feature = "tick-hz-4_194_304")]
pub const TICK_HZ: u64 = 4_194_304;
#[cfg(feature = "tick-hz-8_388_608")]
pub const TICK_HZ: u64 = 8_388_608;
#[cfg(feature = "tick-hz-16_777_216")]
pub const TICK_HZ: u64 = 16_777_216;
#[cfg(feature = "tick-hz-2_000_000")]
pub const TICK_HZ: u64 = 2_000_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-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-9_000_000")]
pub const TICK_HZ: u64 = 9_000_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-18_000_000")]
pub const TICK_HZ: u64 = 18_000_000;
#[cfg(feature = "tick-hz-24_000_000")]
pub const TICK_HZ: u64 = 24_000_000;
#[cfg(feature = "tick-hz-32_000_000")]
pub const TICK_HZ: u64 = 32_000_000;
#[cfg(feature = "tick-hz-36_000_000")]
pub const TICK_HZ: u64 = 36_000_000;
#[cfg(feature = "tick-hz-48_000_000")]
pub const TICK_HZ: u64 = 48_000_000;
#[cfg(feature = "tick-hz-64_000_000")]
pub const TICK_HZ: u64 = 64_000_000;
#[cfg(feature = "tick-hz-72_000_000")]
pub const TICK_HZ: u64 = 72_000_000;
#[cfg(feature = "tick-hz-96_000_000")]
pub const TICK_HZ: u64 = 96_000_000;
#[cfg(feature = "tick-hz-128_000_000")]
pub const TICK_HZ: u64 = 128_000_000;
#[cfg(feature = "tick-hz-144_000_000")]
pub const TICK_HZ: u64 = 144_000_000;
#[cfg(feature = "tick-hz-192_000_000")]
pub const TICK_HZ: u64 = 192_000_000;
#[cfg(feature = "tick-hz-256_000_000")]
pub const TICK_HZ: u64 = 256_000_000;
#[cfg(feature = "tick-hz-288_000_000")]
pub const TICK_HZ: u64 = 288_000_000;
#[cfg(feature = "tick-hz-384_000_000")]
pub const TICK_HZ: u64 = 384_000_000;
#[cfg(feature = "tick-hz-512_000_000")]
pub const TICK_HZ: u64 = 512_000_000;
#[cfg(feature = "tick-hz-576_000_000")]
pub const TICK_HZ: u64 = 576_000_000;
#[cfg(feature = "tick-hz-768_000_000")]
pub const TICK_HZ: u64 = 768_000_000;
#[cfg(not(any(
feature = "tick-hz-1",
feature = "tick-hz-10",
feature = "tick-hz-100",
feature = "tick-hz-1_000",
feature = "tick-hz-10_000",
feature = "tick-hz-100_000",
feature = "tick-hz-1_000_000",
feature = "tick-hz-10_000_000",
feature = "tick-hz-100_000_000",
feature = "tick-hz-1_000_000_000",
feature = "tick-hz-2",
feature = "tick-hz-4",
feature = "tick-hz-8",
feature = "tick-hz-16",
feature = "tick-hz-32",
feature = "tick-hz-64",
feature = "tick-hz-128",
feature = "tick-hz-256",
feature = "tick-hz-512",
feature = "tick-hz-1_024",
feature = "tick-hz-2_048",
feature = "tick-hz-4_096",
feature = "tick-hz-8_192",
feature = "tick-hz-16_384",
feature = "tick-hz-32_768",
feature = "tick-hz-65_536",
feature = "tick-hz-131_072",
feature = "tick-hz-262_144",
feature = "tick-hz-524_288",
feature = "tick-hz-1_048_576",
feature = "tick-hz-2_097_152",
feature = "tick-hz-4_194_304",
feature = "tick-hz-8_388_608",
feature = "tick-hz-16_777_216",
feature = "tick-hz-2_000_000",
feature = "tick-hz-3_000_000",
feature = "tick-hz-4_000_000",
feature = "tick-hz-6_000_000",
feature = "tick-hz-8_000_000",
feature = "tick-hz-9_000_000",
feature = "tick-hz-12_000_000",
feature = "tick-hz-16_000_000",
feature = "tick-hz-18_000_000",
feature = "tick-hz-24_000_000",
feature = "tick-hz-32_000_000",
feature = "tick-hz-36_000_000",
feature = "tick-hz-48_000_000",
feature = "tick-hz-64_000_000",
feature = "tick-hz-72_000_000",
feature = "tick-hz-96_000_000",
feature = "tick-hz-128_000_000",
feature = "tick-hz-144_000_000",
feature = "tick-hz-192_000_000",
feature = "tick-hz-256_000_000",
feature = "tick-hz-288_000_000",
feature = "tick-hz-384_000_000",
feature = "tick-hz-512_000_000",
feature = "tick-hz-576_000_000",
feature = "tick-hz-768_000_000",
)))]
pub const TICK_HZ: u64 = 1_000_000;