aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2020-09-24 23:26:24 +0200
committerDario Nieuwenhuis <[email protected]>2020-09-24 23:26:24 +0200
commit05ca563e7d61eb13e3a136092177986623d68617 (patch)
tree961760af38e0a362e74dadf22518aa63a708f356
parentafcf7255196c4362df72b9e675813cf40876750a (diff)
Add clock::Monotonic trait.
-rw-r--r--embassy-nrf/src/rtc.rs34
-rw-r--r--embassy/Cargo.toml1
-rw-r--r--embassy/src/clock.rs21
-rw-r--r--embassy/src/lib.rs3
-rw-r--r--examples/src/bin/rtc_async.rs1
-rw-r--r--examples/src/bin/rtc_raw.rs1
6 files changed, 44 insertions, 17 deletions
diff --git a/embassy-nrf/src/rtc.rs b/embassy-nrf/src/rtc.rs
index 95ee1a068..55869c6e5 100644
--- a/embassy-nrf/src/rtc.rs
+++ b/embassy-nrf/src/rtc.rs
@@ -1,8 +1,8 @@
1use core::cell::Cell; 1use core::cell::Cell;
2use core::ops::Deref; 2use core::ops::Deref;
3use core::sync::atomic::{AtomicU32, Ordering}; 3use core::sync::atomic::{AtomicU32, Ordering};
4
5use defmt::trace; 4use defmt::trace;
5use embassy::clock::Monotonic;
6 6
7use crate::interrupt; 7use crate::interrupt;
8use crate::interrupt::Mutex; 8use crate::interrupt::Mutex;
@@ -121,12 +121,6 @@ impl<T: Instance> RTC<T> {
121 }) 121 })
122 } 122 }
123 123
124 pub fn now(&self) -> u64 {
125 let counter = self.rtc.counter.read().bits();
126 let period = self.period.load(Ordering::Relaxed);
127 calc_now(period, counter)
128 }
129
130 fn trigger_alarm(&self) { 124 fn trigger_alarm(&self) {
131 self.rtc.intenclr.write(|w| w.compare1().clear()); 125 self.rtc.intenclr.write(|w| w.compare1().clear());
132 interrupt::free(|cs| { 126 interrupt::free(|cs| {
@@ -139,19 +133,19 @@ impl<T: Instance> RTC<T> {
139 }); 133 });
140 } 134 }
141 135
142 fn do_set_alarm(&self, at: u64, f: Option<fn()>) { 136 fn do_set_alarm(&self, timestamp: u64, callback: Option<fn()>) {
143 interrupt::free(|cs| { 137 interrupt::free(|cs| {
144 self.alarm.borrow(cs).set((at, f)); 138 self.alarm.borrow(cs).set((timestamp, callback));
145 139
146 let t = self.now(); 140 let t = self.now();
147 if at <= t { 141 if timestamp <= t {
148 self.trigger_alarm(); 142 self.trigger_alarm();
149 return; 143 return;
150 } 144 }
151 145
152 let diff = at - t; 146 let diff = timestamp - t;
153 if diff < 0xc00000 { 147 if diff < 0xc00000 {
154 self.rtc.cc[1].write(|w| unsafe { w.bits(at as u32 & 0xFFFFFF) }); 148 self.rtc.cc[1].write(|w| unsafe { w.bits(timestamp as u32 & 0xFFFFFF) });
155 self.rtc.intenset.write(|w| w.compare1().set()); 149 self.rtc.intenset.write(|w| w.compare1().set());
156 150
157 // We may have been preempted for arbitrary time between checking if `at` is in the past 151 // We may have been preempted for arbitrary time between checking if `at` is in the past
@@ -159,7 +153,7 @@ impl<T: Instance> RTC<T> {
159 // So, we check again just in case. 153 // So, we check again just in case.
160 154
161 let t = self.now(); 155 let t = self.now();
162 if at <= t { 156 if timestamp <= t {
163 self.trigger_alarm(); 157 self.trigger_alarm();
164 return; 158 return;
165 } 159 }
@@ -168,12 +162,20 @@ impl<T: Instance> RTC<T> {
168 } 162 }
169 }) 163 })
170 } 164 }
165}
166
167impl<T: Instance> Monotonic for RTC<T> {
168 fn now(&self) -> u64 {
169 let counter = self.rtc.counter.read().bits();
170 let period = self.period.load(Ordering::Relaxed);
171 calc_now(period, counter)
172 }
171 173
172 pub fn set_alarm(&self, at: u64, f: fn()) { 174 fn set_alarm(&self, timestamp: u64, callback: fn()) {
173 self.do_set_alarm(at, Some(f)); 175 self.do_set_alarm(timestamp, Some(callback));
174 } 176 }
175 177
176 pub fn clear_alarm(&self) { 178 fn clear_alarm(&self) {
177 self.do_set_alarm(u64::MAX, None); 179 self.do_set_alarm(u64::MAX, None);
178 } 180 }
179} 181}
diff --git a/embassy/Cargo.toml b/embassy/Cargo.toml
index f621015ab..5826e8ba6 100644
--- a/embassy/Cargo.toml
+++ b/embassy/Cargo.toml
@@ -12,3 +12,4 @@ defmt = "0.1.0"
12cortex-m = "0.6.3" 12cortex-m = "0.6.3"
13futures = { version = "0.3.5", default-features = false, features = [ "async-await" ] } 13futures = { version = "0.3.5", default-features = false, features = [ "async-await" ] }
14pin-project = { version = "0.4.23", default-features = false } 14pin-project = { version = "0.4.23", default-features = false }
15futures-intrusive = { version = "0.3.1", default-features = false }
diff --git a/embassy/src/clock.rs b/embassy/src/clock.rs
new file mode 100644
index 000000000..ca5f26a05
--- /dev/null
+++ b/embassy/src/clock.rs
@@ -0,0 +1,21 @@
1/// Monotonic clock with support for setting an alarm.
2///
3/// The clock uses a "tick" time unit, whose length is an implementation-dependent constant.
4pub trait Monotonic {
5 /// Returns the current timestamp in ticks.
6 /// This is guaranteed to be monotonic, i.e. a call to now() will always return
7 /// a greater or equal value than earler calls.
8 fn now(&self) -> u64;
9
10 /// Sets an alarm at the given timestamp. When the clock reaches that
11 /// timestamp, the provided callback funcion will be called.
12 ///
13 /// When callback is called, it is guaranteed that now() will return a value greater or equal than timestamp.
14 ///
15 /// Only one alarm can be active at a time. This overwrites any previously-set alarm if any.
16 fn set_alarm(&self, timestamp: u64, callback: fn());
17
18 /// Clears the previously-set alarm.
19 /// If no alarm was set, this is a noop.
20 fn clear_alarm(&self);
21}
diff --git a/embassy/src/lib.rs b/embassy/src/lib.rs
index 45716c6cf..89eef3f4c 100644
--- a/embassy/src/lib.rs
+++ b/embassy/src/lib.rs
@@ -3,6 +3,7 @@
3#![feature(generic_associated_types)] 3#![feature(generic_associated_types)]
4#![feature(const_fn)] 4#![feature(const_fn)]
5 5
6pub mod clock;
6pub mod flash; 7pub mod flash;
7pub mod util;
8pub mod io; 8pub mod io;
9pub mod util;
diff --git a/examples/src/bin/rtc_async.rs b/examples/src/bin/rtc_async.rs
index 838a0faef..977621d4c 100644
--- a/examples/src/bin/rtc_async.rs
+++ b/examples/src/bin/rtc_async.rs
@@ -8,6 +8,7 @@ use example_common::*;
8 8
9use core::mem::MaybeUninit; 9use core::mem::MaybeUninit;
10use cortex_m_rt::entry; 10use cortex_m_rt::entry;
11use embassy::clock::Monotonic;
11use embassy_nrf::rtc; 12use embassy_nrf::rtc;
12use futures_intrusive::timer::{Clock, LocalTimer, LocalTimerService}; 13use futures_intrusive::timer::{Clock, LocalTimer, LocalTimerService};
13use nrf52840_hal::clocks; 14use nrf52840_hal::clocks;
diff --git a/examples/src/bin/rtc_raw.rs b/examples/src/bin/rtc_raw.rs
index 8debf12e3..aa98409c4 100644
--- a/examples/src/bin/rtc_raw.rs
+++ b/examples/src/bin/rtc_raw.rs
@@ -8,6 +8,7 @@ use example_common::*;
8 8
9use core::mem::MaybeUninit; 9use core::mem::MaybeUninit;
10use cortex_m_rt::entry; 10use cortex_m_rt::entry;
11use embassy::clock::Monotonic;
11use embassy_nrf::rtc; 12use embassy_nrf::rtc;
12use nrf52840_hal::clocks; 13use nrf52840_hal::clocks;
13 14