aboutsummaryrefslogtreecommitdiff
path: root/rtic-time/src/monotonic.rs
diff options
context:
space:
mode:
authorGravatar Finomnis <Finomnis@users.noreply.github.com> 2023-12-01 08:59:22 +0100
committerGravatar GitHub <noreply@github.com> 2023-12-01 07:59:22 +0000
commit612a47ef4d09da3553145d77bf1750314bbb7b16 (patch)
tree7f6f6beca7e0c81397994b4f835c6a7f0bbee331 /rtic-time/src/monotonic.rs
parent9f5820da1d36a8c84455b1bc0458d34eb7dd9a70 (diff)
downloadrtic-612a47ef4d09da3553145d77bf1750314bbb7b16.tar.gz
rtic-612a47ef4d09da3553145d77bf1750314bbb7b16.tar.zst
rtic-612a47ef4d09da3553145d77bf1750314bbb7b16.zip
Fix mono delay (#843)
* rtic-time: Compenstate for timer uncertainty * Update changelog and incorrect cargo.lock in an example * Fix Monotonic impls * Fix tests * Fix other monotonics, again * Update changelog * Fix example * Fix DelayUs and DelayMs impls * Minor coding style fix in u64 conversions * Fix all changelogs * Fix changelog * Fix blocking DelayUs * Minor monotonic rework * Add delay precision test * Add more tests * Add rust-version tags to Cargo.toml * Fix imxrt, rp2040 and systick timer * Fix more monotonics * Fix systick monotonic * Some reverts * Fix imxrt * Fix nrf * Fix rp2040 * Fix stm32 * Fix systick * Fix rtic-time tests * Bump to e-h.rc2 * Apply e-h.rc2 fixes to rtic-time * Apply fixes from arbiter * Fix clippy warning * Minor beautification * Revert previous changes * Fix variable name * Add blocking tests, but disable them by default
Diffstat (limited to 'rtic-time/src/monotonic.rs')
-rw-r--r--rtic-time/src/monotonic.rs153
1 files changed, 153 insertions, 0 deletions
diff --git a/rtic-time/src/monotonic.rs b/rtic-time/src/monotonic.rs
index ad79bf20..0c0d6f35 100644
--- a/rtic-time/src/monotonic.rs
+++ b/rtic-time/src/monotonic.rs
@@ -10,6 +10,9 @@ pub trait Monotonic {
/// The time at time zero.
const ZERO: Self::Instant;
+ /// The duration between two timer ticks.
+ const TICK_PERIOD: Self::Duration;
+
/// The type for instant, defining an instant in time.
///
/// **Note:** In all APIs in RTIC that use instants from this monotonic, this type will be used.
@@ -65,3 +68,153 @@ pub trait Monotonic {
/// NOTE: This may be called more than once.
fn disable_timer() {}
}
+
+/// Creates impl blocks for `embedded_hal::delay::DelayUs`,
+/// based on `fugit::ExtU64Ceil`.
+#[macro_export]
+macro_rules! embedded_hal_delay_impl_fugit64 {
+ ($t:ty) => {
+ impl ::embedded_hal::delay::DelayNs for $t {
+ fn delay_ns(&mut self, ns: u32) {
+ use ::fugit::ExtU64Ceil;
+
+ let now = Self::now();
+ let mut done = now + u64::from(ns).nanos_at_least();
+ if now != done {
+ // Compensate for sub-tick uncertainty
+ done += Self::TICK_PERIOD;
+ }
+
+ while Self::now() < done {}
+ }
+
+ fn delay_us(&mut self, us: u32) {
+ use ::fugit::ExtU64Ceil;
+
+ let now = Self::now();
+ let mut done = now + u64::from(us).micros_at_least();
+ if now != done {
+ // Compensate for sub-tick uncertainty
+ done += Self::TICK_PERIOD;
+ }
+
+ while Self::now() < done {}
+ }
+
+ fn delay_ms(&mut self, ms: u32) {
+ use ::fugit::ExtU64Ceil;
+
+ let now = Self::now();
+ let mut done = now + u64::from(ms).millis_at_least();
+ if now != done {
+ // Compensate for sub-tick uncertainty
+ done += Self::TICK_PERIOD;
+ }
+
+ while Self::now() < done {}
+ }
+ }
+ };
+}
+
+/// Creates impl blocks for `embedded_hal_async::delay::DelayUs`,
+/// based on `fugit::ExtU64Ceil`.
+#[macro_export]
+macro_rules! embedded_hal_async_delay_impl_fugit64 {
+ ($t:ty) => {
+ impl ::embedded_hal_async::delay::DelayNs for $t {
+ #[inline]
+ async fn delay_ns(&mut self, ns: u32) {
+ use ::fugit::ExtU64Ceil;
+ Self::delay(u64::from(ns).nanos_at_least()).await;
+ }
+
+ #[inline]
+ async fn delay_us(&mut self, us: u32) {
+ use ::fugit::ExtU64Ceil;
+ Self::delay(u64::from(us).micros_at_least()).await;
+ }
+
+ #[inline]
+ async fn delay_ms(&mut self, ms: u32) {
+ use ::fugit::ExtU64Ceil;
+ Self::delay(u64::from(ms).millis_at_least()).await;
+ }
+ }
+ };
+}
+
+/// Creates impl blocks for `embedded_hal::delay::DelayUs`,
+/// based on `fugit::ExtU32Ceil`.
+#[macro_export]
+macro_rules! embedded_hal_delay_impl_fugit32 {
+ ($t:ty) => {
+ impl ::embedded_hal::delay::DelayNs for $t {
+ fn delay_ns(&mut self, ns: u32) {
+ use ::fugit::ExtU32Ceil;
+
+ let now = Self::now();
+ let mut done = now + ns.nanos_at_least();
+ if now != done {
+ // Compensate for sub-tick uncertainty
+ done += Self::TICK_PERIOD;
+ }
+
+ while Self::now() < done {}
+ }
+
+ fn delay_us(&mut self, us: u32) {
+ use ::fugit::ExtU32Ceil;
+
+ let now = Self::now();
+ let mut done = now + us.micros_at_least();
+ if now != done {
+ // Compensate for sub-tick uncertainty
+ done += Self::TICK_PERIOD;
+ }
+
+ while Self::now() < done {}
+ }
+
+ fn delay_ms(&mut self, ms: u32) {
+ use ::fugit::ExtU32Ceil;
+
+ let now = Self::now();
+ let mut done = now + ms.millis_at_least();
+ if now != done {
+ // Compensate for sub-tick uncertainty
+ done += Self::TICK_PERIOD;
+ }
+
+ while Self::now() < done {}
+ }
+ }
+ };
+}
+
+/// Creates impl blocks for `embedded_hal_async::delay::DelayUs`,
+/// based on `fugit::ExtU32Ceil`.
+#[macro_export]
+macro_rules! embedded_hal_async_delay_impl_fugit32 {
+ ($t:ty) => {
+ impl ::embedded_hal_async::delay::DelayNs for $t {
+ #[inline]
+ async fn delay_ns(&mut self, ns: u32) {
+ use ::fugit::ExtU32Ceil;
+ Self::delay(ns.nanos_at_least()).await;
+ }
+
+ #[inline]
+ async fn delay_us(&mut self, us: u32) {
+ use ::fugit::ExtU32Ceil;
+ Self::delay(us.micros_at_least()).await;
+ }
+
+ #[inline]
+ async fn delay_ms(&mut self, ms: u32) {
+ use ::fugit::ExtU32Ceil;
+ Self::delay(ms.millis_at_least()).await;
+ }
+ }
+ };
+}