Add Clock trait

This commit is contained in:
Dario Nieuwenhuis 2020-09-25 23:38:42 +02:00
parent cf1d604749
commit 19a89b5c14
5 changed files with 44 additions and 19 deletions

View file

@ -2,6 +2,8 @@ use core::cell::Cell;
use core::ops::Deref;
use core::sync::atomic::{AtomicU32, Ordering};
use embassy::time::Clock;
use crate::interrupt;
use crate::interrupt::{CriticalSection, Mutex};
use crate::pac::{rtc0, Interrupt, RTC0, RTC1};
@ -100,12 +102,6 @@ impl<T: Instance> RTC<T> {
interrupt::enable(T::INTERRUPT);
}
pub fn now(&self) -> u64 {
let counter = self.rtc.counter.read().bits();
let period = self.period.load(Ordering::Relaxed);
calc_now(period, counter)
}
fn on_interrupt(&self) {
if self.rtc.events_ovrflw.read().bits() == 1 {
self.rtc.events_ovrflw.write(|w| w);
@ -203,6 +199,14 @@ impl<T: Instance> RTC<T> {
}
}
impl<T: Instance> embassy::time::Clock for RTC<T> {
fn now(&self) -> u64 {
let counter = self.rtc.counter.read().bits();
let period = self.period.load(Ordering::Relaxed);
calc_now(period, counter)
}
}
pub struct Alarm<T: Instance> {
n: usize,
rtc: &'static RTC<T>,

View file

@ -7,21 +7,17 @@ use core::ptr;
use core::sync::atomic::{AtomicPtr, Ordering};
use core::task::{Context, Poll};
use crate::util::*;
use fi::LocalTimer;
use futures_intrusive::timer as fi;
static mut CLOCK: Option<&'static dyn Clock> = None;
static mut CLOCK: fn() -> u64 = clock_not_set;
fn clock_not_set() -> u64 {
panic!("No clock set. You must call embassy::time::set_clock() before trying to use the clock")
}
pub unsafe fn set_clock(clock: fn() -> u64) {
CLOCK = clock;
pub unsafe fn set_clock(clock: &'static dyn Clock) {
CLOCK = Some(clock);
}
fn now() -> u64 {
unsafe { CLOCK() }
unsafe { CLOCK.dexpect(defmt::intern!("No clock set")).now() }
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
@ -270,6 +266,19 @@ impl Future for Timer {
unsafe { Pin::new_unchecked(&mut self.get_unchecked_mut().inner) }.poll(cx)
}
}
/// Monotonic clock
pub trait Clock {
/// Return the current timestamp in ticks.
/// This is guaranteed to be monotonic, i.e. a call to now() will always return
/// a greater or equal value than earler calls.
fn now(&self) -> u64;
}
impl<T: Clock + ?Sized> Clock for &T {
fn now(&self) -> u64 {
T::now(self)
}
}
/// Trait to register a callback at a given timestamp.
pub trait Alarm {
@ -289,3 +298,15 @@ pub trait Alarm {
/// If no alarm was set, this is a noop.
fn clear(&self);
}
impl<T: Alarm + ?Sized> Alarm for &T {
fn set_callback(&self, callback: fn()) {
T::set_callback(self, callback);
}
fn set(&self, timestamp: u64) {
T::set(self, timestamp);
}
fn clear(&self) {
T::clear(self)
}
}

View file

@ -11,7 +11,7 @@ pub use waker_store::*;
mod drop_bomb;
pub use drop_bomb::*;
use defmt::{warn, error};
use defmt::{debug, error, info, intern, trace, warn};
pub trait Dewrap<T> {
/// dewrap = defmt unwrap

View file

@ -9,7 +9,7 @@ use example_common::*;
use core::mem::MaybeUninit;
use cortex_m_rt::entry;
use embassy::executor::{task, Executor, WfeModel};
use embassy::time::{Duration, Instant, Timer};
use embassy::time::{Clock, Duration, Timer};
use embassy_nrf::pac;
use embassy_nrf::rtc;
use nrf52840_hal::clocks;
@ -51,7 +51,7 @@ fn main() -> ! {
};
rtc.start();
unsafe { embassy::time::set_clock(|| RTC.as_ptr().as_ref().unwrap().now()) };
unsafe { embassy::time::set_clock(rtc) };
let executor: &'static _ = unsafe {
let ptr = EXECUTOR.as_mut_ptr();

View file

@ -8,7 +8,7 @@ use example_common::*;
use core::mem::MaybeUninit;
use cortex_m_rt::entry;
use embassy::time::Alarm;
use embassy::time::{Alarm, Clock};
use embassy_nrf::rtc;
use nrf52840_hal::clocks;