From 4ea73021d62bda15ce9a7b36123e4a237c8e4255 Mon Sep 17 00:00:00 2001 From: Nils Fitinghoff Date: Thu, 24 Aug 2023 16:29:20 +0200 Subject: [PATCH] rtic-monotonics: Add 64-bit SysTick monotonic Counting at 1 kHz, 32 bits for counting ticks is not enough to ensure monotonicity for more than 50 days. Add a feature to change the backing storage to 64 bits. --- rtic-monotonics/CHANGELOG.md | 4 ++++ rtic-monotonics/Cargo.toml | 2 ++ rtic-monotonics/src/systick.rs | 34 +++++++++++++++++++++++++++------- xtask/src/argument_parsing.rs | 3 +++ 4 files changed, 36 insertions(+), 7 deletions(-) diff --git a/rtic-monotonics/CHANGELOG.md b/rtic-monotonics/CHANGELOG.md index b19a4783e5..8437fa00f2 100644 --- a/rtic-monotonics/CHANGELOG.md +++ b/rtic-monotonics/CHANGELOG.md @@ -7,6 +7,10 @@ For each category, *Added*, *Changed*, *Fixed* add new entries at the top! ## Unreleased +### Added + +- Feature `systick-64bit` to get 64-bit backed `TimerInstantU64` instead of `TimerInstantU32` from the SysTick-based monotonic timer + ## v1.0.1 - 2023-08-20 ### Added diff --git a/rtic-monotonics/Cargo.toml b/rtic-monotonics/Cargo.toml index b88b0881be..de94d3f5fb 100644 --- a/rtic-monotonics/Cargo.toml +++ b/rtic-monotonics/Cargo.toml @@ -48,6 +48,8 @@ defmt = ["fugit/defmt"] cortex-m-systick = ["dep:cortex-m"] systick-100hz = [] systick-10khz = [] +# Use 64-bit wide backing storage for the Instant +systick-64bit = [] # Timer peripheral on the RP2040 rp2040 = ["dep:cortex-m", "dep:rp2040-pac"] diff --git a/rtic-monotonics/src/systick.rs b/rtic-monotonics/src/systick.rs index fe66a20aed..9b8fca8ac2 100644 --- a/rtic-monotonics/src/systick.rs +++ b/rtic-monotonics/src/systick.rs @@ -34,10 +34,22 @@ use super::Monotonic; pub use super::{TimeoutError, TimerQueue}; -use atomic_polyfill::{AtomicU32, Ordering}; +use atomic_polyfill::Ordering; use core::future::Future; use cortex_m::peripheral::SYST; -pub use fugit::{self, ExtU32}; +pub use fugit; +cfg_if::cfg_if! { + if #[cfg(feature = "systick-64bit")] { + pub use fugit::ExtU64; + use atomic_polyfill::AtomicU64; + static SYSTICK_CNT: AtomicU64 = AtomicU64::new(0); + } else { + pub use fugit::ExtU32; + use atomic_polyfill::AtomicU32; + static SYSTICK_CNT: AtomicU32 = AtomicU32::new(0); + } +} +static SYSTICK_TIMER_QUEUE: TimerQueue = TimerQueue::new(); // Features should be additive, here systick-100hz gets picked if both // `systick-100hz` and `systick-10khz` are enabled. @@ -94,9 +106,6 @@ impl Systick { } } -static SYSTICK_CNT: AtomicU32 = AtomicU32::new(0); -static SYSTICK_TIMER_QUEUE: TimerQueue = TimerQueue::new(); - // Forward timerqueue interface impl Systick { /// Used to access the underlying timer queue @@ -136,8 +145,15 @@ impl Systick { } impl Monotonic for Systick { - type Instant = fugit::TimerInstantU32; - type Duration = fugit::TimerDurationU32; + cfg_if::cfg_if! { + if #[cfg(feature = "systick-64bit")] { + type Instant = fugit::TimerInstantU64; + type Duration = fugit::TimerDurationU64; + } else { + type Instant = fugit::TimerInstantU32; + type Duration = fugit::TimerDurationU32; + } + } const ZERO: Self::Instant = Self::Instant::from_ticks(0); @@ -175,10 +191,14 @@ impl Monotonic for Systick { #[cfg(feature = "embedded-hal-async")] impl embedded_hal_async::delay::DelayUs for Systick { async fn delay_us(&mut self, us: u32) { + #[cfg(feature = "systick-64bit")] + let us = u64::from(us); Self::delay(us.micros()).await; } async fn delay_ms(&mut self, ms: u32) { + #[cfg(feature = "systick-64bit")] + let ms = u64::from(ms); Self::delay(ms.millis()).await; } } diff --git a/xtask/src/argument_parsing.rs b/xtask/src/argument_parsing.rs index 2e1eef4882..88ac1e5d8d 100644 --- a/xtask/src/argument_parsing.rs +++ b/xtask/src/argument_parsing.rs @@ -67,6 +67,9 @@ impl Package { "cortex-m-systick,embedded-hal-async", "cortex-m-systick,systick-100hz,embedded-hal-async", "cortex-m-systick,systick-10khz,embedded-hal-async", + "cortex-m-systick,embedded-hal-async,systick-64bit", + "cortex-m-systick,systick-100hz,embedded-hal-async,systick-64bit", + "cortex-m-systick,systick-10khz,embedded-hal-async,systick-64bit", "rp2040,embedded-hal-async", "nrf52810,embedded-hal-async", "nrf52811,embedded-hal-async",