diff options
| author | Dario Nieuwenhuis <[email protected]> | 2020-09-25 23:38:42 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2020-09-25 23:38:42 +0200 |
| commit | 19a89b5c143205cc2a2d05b07cc4bffd15246e98 (patch) | |
| tree | fea04036b1378fc860ac6da49a44129ad9d67e34 | |
| parent | cf1d60474965d9d72d24f47ff552c6078c784aff (diff) | |
Add Clock trait
| -rw-r--r-- | embassy-nrf/src/rtc.rs | 16 | ||||
| -rw-r--r-- | embassy/src/time.rs | 39 | ||||
| -rw-r--r-- | embassy/src/util/mod.rs | 2 | ||||
| -rw-r--r-- | examples/src/bin/rtc_async.rs | 4 | ||||
| -rw-r--r-- | examples/src/bin/rtc_raw.rs | 2 |
5 files changed, 44 insertions, 19 deletions
diff --git a/embassy-nrf/src/rtc.rs b/embassy-nrf/src/rtc.rs index f28ad1dad..ae8d0dbc1 100644 --- a/embassy-nrf/src/rtc.rs +++ b/embassy-nrf/src/rtc.rs | |||
| @@ -2,6 +2,8 @@ use core::cell::Cell; | |||
| 2 | use core::ops::Deref; | 2 | use core::ops::Deref; |
| 3 | use core::sync::atomic::{AtomicU32, Ordering}; | 3 | use core::sync::atomic::{AtomicU32, Ordering}; |
| 4 | 4 | ||
| 5 | use embassy::time::Clock; | ||
| 6 | |||
| 5 | use crate::interrupt; | 7 | use crate::interrupt; |
| 6 | use crate::interrupt::{CriticalSection, Mutex}; | 8 | use crate::interrupt::{CriticalSection, Mutex}; |
| 7 | use crate::pac::{rtc0, Interrupt, RTC0, RTC1}; | 9 | use crate::pac::{rtc0, Interrupt, RTC0, RTC1}; |
| @@ -100,12 +102,6 @@ impl<T: Instance> RTC<T> { | |||
| 100 | interrupt::enable(T::INTERRUPT); | 102 | interrupt::enable(T::INTERRUPT); |
| 101 | } | 103 | } |
| 102 | 104 | ||
| 103 | pub fn now(&self) -> u64 { | ||
| 104 | let counter = self.rtc.counter.read().bits(); | ||
| 105 | let period = self.period.load(Ordering::Relaxed); | ||
| 106 | calc_now(period, counter) | ||
| 107 | } | ||
| 108 | |||
| 109 | fn on_interrupt(&self) { | 105 | fn on_interrupt(&self) { |
| 110 | if self.rtc.events_ovrflw.read().bits() == 1 { | 106 | if self.rtc.events_ovrflw.read().bits() == 1 { |
| 111 | self.rtc.events_ovrflw.write(|w| w); | 107 | self.rtc.events_ovrflw.write(|w| w); |
| @@ -203,6 +199,14 @@ impl<T: Instance> RTC<T> { | |||
| 203 | } | 199 | } |
| 204 | } | 200 | } |
| 205 | 201 | ||
| 202 | impl<T: Instance> embassy::time::Clock for RTC<T> { | ||
| 203 | fn now(&self) -> u64 { | ||
| 204 | let counter = self.rtc.counter.read().bits(); | ||
| 205 | let period = self.period.load(Ordering::Relaxed); | ||
| 206 | calc_now(period, counter) | ||
| 207 | } | ||
| 208 | } | ||
| 209 | |||
| 206 | pub struct Alarm<T: Instance> { | 210 | pub struct Alarm<T: Instance> { |
| 207 | n: usize, | 211 | n: usize, |
| 208 | rtc: &'static RTC<T>, | 212 | rtc: &'static RTC<T>, |
diff --git a/embassy/src/time.rs b/embassy/src/time.rs index eba2e6eb2..29453bc02 100644 --- a/embassy/src/time.rs +++ b/embassy/src/time.rs | |||
| @@ -7,21 +7,17 @@ use core::ptr; | |||
| 7 | use core::sync::atomic::{AtomicPtr, Ordering}; | 7 | use core::sync::atomic::{AtomicPtr, Ordering}; |
| 8 | use core::task::{Context, Poll}; | 8 | use core::task::{Context, Poll}; |
| 9 | 9 | ||
| 10 | use crate::util::*; | ||
| 10 | use fi::LocalTimer; | 11 | use fi::LocalTimer; |
| 11 | use futures_intrusive::timer as fi; | 12 | use futures_intrusive::timer as fi; |
| 13 | static mut CLOCK: Option<&'static dyn Clock> = None; | ||
| 12 | 14 | ||
| 13 | static mut CLOCK: fn() -> u64 = clock_not_set; | 15 | pub unsafe fn set_clock(clock: &'static dyn Clock) { |
| 14 | 16 | CLOCK = Some(clock); | |
| 15 | fn clock_not_set() -> u64 { | ||
| 16 | panic!("No clock set. You must call embassy::time::set_clock() before trying to use the clock") | ||
| 17 | } | ||
| 18 | |||
| 19 | pub unsafe fn set_clock(clock: fn() -> u64) { | ||
| 20 | CLOCK = clock; | ||
| 21 | } | 17 | } |
| 22 | 18 | ||
| 23 | fn now() -> u64 { | 19 | fn now() -> u64 { |
| 24 | unsafe { CLOCK() } | 20 | unsafe { CLOCK.dexpect(defmt::intern!("No clock set")).now() } |
| 25 | } | 21 | } |
| 26 | 22 | ||
| 27 | #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] | 23 | #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] |
| @@ -270,6 +266,19 @@ impl Future for Timer { | |||
| 270 | unsafe { Pin::new_unchecked(&mut self.get_unchecked_mut().inner) }.poll(cx) | 266 | unsafe { Pin::new_unchecked(&mut self.get_unchecked_mut().inner) }.poll(cx) |
| 271 | } | 267 | } |
| 272 | } | 268 | } |
| 269 | /// Monotonic clock | ||
| 270 | pub trait Clock { | ||
| 271 | /// Return the current timestamp in ticks. | ||
| 272 | /// This is guaranteed to be monotonic, i.e. a call to now() will always return | ||
| 273 | /// a greater or equal value than earler calls. | ||
| 274 | fn now(&self) -> u64; | ||
| 275 | } | ||
| 276 | |||
| 277 | impl<T: Clock + ?Sized> Clock for &T { | ||
| 278 | fn now(&self) -> u64 { | ||
| 279 | T::now(self) | ||
| 280 | } | ||
| 281 | } | ||
| 273 | 282 | ||
| 274 | /// Trait to register a callback at a given timestamp. | 283 | /// Trait to register a callback at a given timestamp. |
| 275 | pub trait Alarm { | 284 | pub trait Alarm { |
| @@ -289,3 +298,15 @@ pub trait Alarm { | |||
| 289 | /// If no alarm was set, this is a noop. | 298 | /// If no alarm was set, this is a noop. |
| 290 | fn clear(&self); | 299 | fn clear(&self); |
| 291 | } | 300 | } |
| 301 | |||
| 302 | impl<T: Alarm + ?Sized> Alarm for &T { | ||
| 303 | fn set_callback(&self, callback: fn()) { | ||
| 304 | T::set_callback(self, callback); | ||
| 305 | } | ||
| 306 | fn set(&self, timestamp: u64) { | ||
| 307 | T::set(self, timestamp); | ||
| 308 | } | ||
| 309 | fn clear(&self) { | ||
| 310 | T::clear(self) | ||
| 311 | } | ||
| 312 | } | ||
diff --git a/embassy/src/util/mod.rs b/embassy/src/util/mod.rs index 3a0f11e6f..601a9b4af 100644 --- a/embassy/src/util/mod.rs +++ b/embassy/src/util/mod.rs | |||
| @@ -11,7 +11,7 @@ pub use waker_store::*; | |||
| 11 | mod drop_bomb; | 11 | mod drop_bomb; |
| 12 | pub use drop_bomb::*; | 12 | pub use drop_bomb::*; |
| 13 | 13 | ||
| 14 | use defmt::{warn, error}; | 14 | use defmt::{debug, error, info, intern, trace, warn}; |
| 15 | 15 | ||
| 16 | pub trait Dewrap<T> { | 16 | pub trait Dewrap<T> { |
| 17 | /// dewrap = defmt unwrap | 17 | /// dewrap = defmt unwrap |
diff --git a/examples/src/bin/rtc_async.rs b/examples/src/bin/rtc_async.rs index 3bffabf0f..a4149ef1e 100644 --- a/examples/src/bin/rtc_async.rs +++ b/examples/src/bin/rtc_async.rs | |||
| @@ -9,7 +9,7 @@ use example_common::*; | |||
| 9 | use core::mem::MaybeUninit; | 9 | use core::mem::MaybeUninit; |
| 10 | use cortex_m_rt::entry; | 10 | use cortex_m_rt::entry; |
| 11 | use embassy::executor::{task, Executor, WfeModel}; | 11 | use embassy::executor::{task, Executor, WfeModel}; |
| 12 | use embassy::time::{Duration, Instant, Timer}; | 12 | use embassy::time::{Clock, Duration, Timer}; |
| 13 | use embassy_nrf::pac; | 13 | use embassy_nrf::pac; |
| 14 | use embassy_nrf::rtc; | 14 | use embassy_nrf::rtc; |
| 15 | use nrf52840_hal::clocks; | 15 | use nrf52840_hal::clocks; |
| @@ -51,7 +51,7 @@ fn main() -> ! { | |||
| 51 | }; | 51 | }; |
| 52 | 52 | ||
| 53 | rtc.start(); | 53 | rtc.start(); |
| 54 | unsafe { embassy::time::set_clock(|| RTC.as_ptr().as_ref().unwrap().now()) }; | 54 | unsafe { embassy::time::set_clock(rtc) }; |
| 55 | 55 | ||
| 56 | let executor: &'static _ = unsafe { | 56 | let executor: &'static _ = unsafe { |
| 57 | let ptr = EXECUTOR.as_mut_ptr(); | 57 | let ptr = EXECUTOR.as_mut_ptr(); |
diff --git a/examples/src/bin/rtc_raw.rs b/examples/src/bin/rtc_raw.rs index 8311c1bc0..4453ecae1 100644 --- a/examples/src/bin/rtc_raw.rs +++ b/examples/src/bin/rtc_raw.rs | |||
| @@ -8,7 +8,7 @@ use example_common::*; | |||
| 8 | 8 | ||
| 9 | use core::mem::MaybeUninit; | 9 | use core::mem::MaybeUninit; |
| 10 | use cortex_m_rt::entry; | 10 | use cortex_m_rt::entry; |
| 11 | use embassy::time::Alarm; | 11 | use embassy::time::{Alarm, Clock}; |
| 12 | use embassy_nrf::rtc; | 12 | use embassy_nrf::rtc; |
| 13 | use nrf52840_hal::clocks; | 13 | use nrf52840_hal::clocks; |
| 14 | 14 | ||
