Skip to content

Commit aaa5644

Browse files
committed
feat(Clock): Allow Clock impls to be stateful
1 parent 9977521 commit aaa5644

File tree

5 files changed

+53
-57
lines changed

5 files changed

+53
-57
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
### Changed
1313

14+
- Add `&mut self` to `Clock` functions (make stateful, or at least allow stateful implementations)
1415
- All time-type inner types from signed to unsigned
1516
- `Instant::duration_since()` return type to `Result`
1617
- Refactor `examples/nrf52_dk`

examples/nrf52_dk/main.rs

Lines changed: 27 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,58 +3,51 @@
33

44
extern crate panic_rtt;
55

6-
use cortex_m::mutex::CriticalSectionMutex as Mutex;
76
use cortex_m_rt::entry;
8-
use embedded_time::{self as time, traits::*, Clock, Instant, Period};
9-
use mutex_trait::Mutex as _;
7+
use embedded_time::{self as time, Clock, Instant, Period, TimeInt};
108

119
pub mod nrf52 {
1210
pub use nrf52832_hal::{
1311
gpio,
1412
prelude::*,
1513
target::{self as pac, Peripherals},
1614
};
15+
}
1716

18-
pub struct Clock64 {
19-
low: pac::TIMER0,
20-
high: pac::TIMER1,
21-
capture_task: pac::EGU0,
22-
}
23-
24-
impl Clock64 {
25-
pub fn take(low: pac::TIMER0, high: pac::TIMER1, capture_task: pac::EGU0) -> Self {
26-
Self {
27-
low,
28-
high,
29-
capture_task,
30-
}
31-
}
17+
pub struct SysClock {
18+
low: nrf52::pac::TIMER0,
19+
high: nrf52::pac::TIMER1,
20+
capture_task: nrf52::pac::EGU0,
21+
}
3222

33-
pub(crate) fn read(&mut self) -> u64 {
34-
self.capture_task.tasks_trigger[0].write(|write| unsafe { write.bits(1) });
35-
self.low.cc[0].read().bits() as u64 | ((self.high.cc[0].read().bits() as u64) << 32)
23+
impl SysClock {
24+
pub fn take(
25+
low: nrf52::pac::TIMER0,
26+
high: nrf52::pac::TIMER1,
27+
capture_task: nrf52::pac::EGU0,
28+
) -> Self {
29+
Self {
30+
low,
31+
high,
32+
capture_task,
3633
}
3734
}
3835
}
3936

40-
pub struct SysClock;
41-
4237
impl time::Clock for SysClock {
4338
type Rep = u64;
4439
const PERIOD: Period = <Period>::new(1, 16_000_000);
4540

46-
fn now() -> Instant<Self> {
47-
let ticks = (&CLOCK64).lock(|clock| match clock {
48-
Some(clock) => clock.read(),
49-
None => 0,
50-
});
41+
fn now(&mut self) -> Instant<Self> {
42+
self.capture_task.tasks_trigger[0].write(|write| unsafe { write.bits(1) });
43+
44+
let ticks =
45+
self.low.cc[0].read().bits() as u64 | ((self.high.cc[0].read().bits() as u64) << 32);
5146

5247
Instant::new(ticks as Self::Rep)
5348
}
5449
}
5550

56-
static CLOCK64: Mutex<Option<nrf52::Clock64>> = Mutex::new(None);
57-
5851
#[entry]
5952
fn main() -> ! {
6053
let device = nrf52::pac::Peripherals::take().unwrap();
@@ -106,8 +99,7 @@ fn main() -> ! {
10699
// This moves these peripherals to prevent conflicting usage, however not the entire EGU0 is
107100
// used. A ref to EGU0 could be sent instead, although that provides no protection for the
108101
// fields that are being used by Clock64.
109-
let clock64 = nrf52::Clock64::take(device.TIMER0, device.TIMER1, device.EGU0);
110-
(&CLOCK64).lock(|ticks| *ticks = Some(clock64));
102+
let mut clock = SysClock::take(device.TIMER0, device.TIMER1, device.EGU0);
111103

112104
let port0 = nrf52::gpio::p0::Parts::new(device.P0);
113105

@@ -136,6 +128,7 @@ fn main() -> ! {
136128
&mut led2.degrade(),
137129
&mut led3.degrade(),
138130
&mut led4.degrade(),
131+
&mut clock,
139132
)
140133
.unwrap();
141134

@@ -147,6 +140,7 @@ fn run<Led>(
147140
led2: &mut Led,
148141
led3: &mut Led,
149142
led4: &mut Led,
143+
clock: &mut SysClock,
150144
) -> Result<(), <Led as nrf52::OutputPin>::Error>
151145
where
152146
Led: nrf52::OutputPin,
@@ -156,12 +150,12 @@ where
156150
led2.set_high()?;
157151
led3.set_high()?;
158152
led4.set_low()?;
159-
SysClock::delay(250_u32.milliseconds());
153+
clock.delay(250_u32.milliseconds());
160154

161155
led1.set_high()?;
162156
led2.set_low()?;
163157
led3.set_low()?;
164158
led4.set_high()?;
165-
SysClock::delay(250_u32.milliseconds());
159+
clock.delay(250_u32.milliseconds());
166160
}
167161
}

src/clock.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ pub trait Clock: Sized {
1010
const PERIOD: Period;
1111

1212
/// Get the current Instant
13-
fn now() -> Instant<Self>;
13+
fn now(&mut self) -> Instant<Self>;
1414

1515
/// Blocking delay
16-
fn delay<Dur: Duration>(dur: Dur)
16+
fn delay<Dur: Duration>(&mut self, dur: Dur)
1717
where
1818
Self::Rep: TryFrom<Dur::Rep>,
1919
{
20-
let start = Self::now();
20+
let start = self.now();
2121
let end = start + dur;
22-
while Self::now() < end {}
22+
while self.now() < end {}
2323
}
2424
}

src/instant.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ impl<Clock: crate::Clock> Instant<Clock> {
3838
/// type Rep = u32;
3939
/// const PERIOD: Period = <Period>::new(1, 1_000);
4040
/// // ...
41-
/// # fn now() -> Instant<Self> {unimplemented!()}
41+
/// # fn now(&mut self) -> Instant<Self> {unimplemented!()}
4242
/// }
4343
///
4444
/// assert_eq!(Instant::<Clock>::new(5).duration_since::<Microseconds<u64>>(&Instant::<Clock>::new(3)),
@@ -137,7 +137,7 @@ impl<Clock: crate::Clock> PartialOrd for Instant<Clock> {
137137
/// type Rep = u32;
138138
/// const PERIOD: Period =<Period>::new(1, 1_000);
139139
/// // ...
140-
/// # fn now() -> Instant<Self> {unimplemented!()}
140+
/// # fn now(&mut self) -> Instant<Self> {unimplemented!()}
141141
/// }
142142
///
143143
/// assert!(Instant::<Clock>::new(5) > Instant::<Clock>::new(3));
@@ -193,7 +193,7 @@ where
193193
/// type Rep = u32;
194194
/// const PERIOD: Period =<Period>::new(1, 1_000);
195195
/// // ...
196-
/// # fn now() -> Instant<Self> {unimplemented!()}
196+
/// # fn now(&mut self) -> Instant<Self> {unimplemented!()}
197197
/// }
198198
///
199199
/// let _ = Instant::<Clock>::new(0) + Milliseconds(i32::MAX as u32 + 1);
@@ -210,7 +210,7 @@ where
210210
/// type Rep = u32;
211211
/// const PERIOD: Period =<Period>::new(1, 1_000);
212212
/// // ...
213-
/// # fn now() -> Instant<Self> {unimplemented!()}
213+
/// # fn now(&mut self) -> Instant<Self> {unimplemented!()}
214214
/// }
215215
///
216216
/// assert_eq!(Instant::<Clock>::new(1) + Seconds(3_u32), Instant::<Clock>::new(3_001));
@@ -266,7 +266,7 @@ where
266266
/// type Rep = u32;
267267
/// const PERIOD: Period = <Period>::new(1, 1_000);
268268
/// // ...
269-
/// # fn now() -> Instant<Self> {unimplemented!()}
269+
/// # fn now(&mut self) -> Instant<Self> {unimplemented!()}
270270
/// }
271271
///
272272
/// let _ = Instant::<Clock>::new(u32::MAX) - Milliseconds(i32::MAX as u32 + 1);
@@ -283,7 +283,7 @@ where
283283
/// type Rep = u32;
284284
/// const PERIOD: Period =<Period>::new(1, 1_000);
285285
/// // ...
286-
/// # fn now() -> Instant<Self> {unimplemented!()}
286+
/// # fn now(&mut self) -> Instant<Self> {unimplemented!()}
287287
/// }
288288
///
289289
/// assert_eq!(Instant::<Clock>::new(800) - Milliseconds(700_u32), Instant::<Clock>::new(100));

src/lib.rs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,16 @@
4646
//! type Rep = u64;
4747
//! const PERIOD: Period = <Period>::new(1, 16_000_000);
4848
//!
49-
//! fn now() -> Instant<Self> {
49+
//! fn now(&mut self) -> Instant<Self> {
5050
//! // ...
5151
//! # unimplemented!()
5252
//! }
5353
//! }
5454
//!
55-
//! let instant1 = SomeClock::now();
55+
//! let mut clock = SomeClock;
56+
//! let instant1 = clock.now();
5657
//! // ...
57-
//! let instant2 = SomeClock::now();
58+
//! let instant2 = clock.now();
5859
//! assert!(instant1 < instant2); // instant1 is *before* instant2
5960
//!
6061
//! // duration is the difference between the instances
@@ -121,7 +122,7 @@ mod tests {
121122
type Rep = u64;
122123
const PERIOD: time::Period = <time::Period>::new(1, 64_000_000);
123124

124-
fn now() -> time::Instant<Self> {
125+
fn now(&mut self) -> time::Instant<Self> {
125126
time::Instant::new(128_000_000)
126127
}
127128
}
@@ -133,25 +134,25 @@ mod tests {
133134
type Rep = u32;
134135
const PERIOD: time::Period = <time::Period>::new(1, 16_000_000);
135136

136-
fn now() -> time::Instant<Self> {
137+
fn now(&mut self) -> time::Instant<Self> {
137138
time::Instant::new(32_000_000)
138139
}
139140
}
140141

141-
fn get_time<M: time::Clock>()
142-
where
143-
u32: TryFrom<M::Rep>,
144-
{
145-
assert_eq!(M::now().duration_since_epoch(), Ok(Seconds(2_u32)));
142+
fn get_time(clock: &mut impl time::Clock) {
143+
assert_eq!(clock.now().duration_since_epoch(), Ok(Seconds(2_u32)));
146144
}
147145

148146
#[test]
149147
fn common_types() {
150-
let then = MockClock32::now();
151-
let now = MockClock32::now();
148+
let then = MockClock32.now();
149+
let now = MockClock32.now();
150+
151+
let mut clock64 = MockClock64 {};
152+
let mut clock32 = MockClock32 {};
152153

153-
get_time::<MockClock64>();
154-
get_time::<MockClock32>();
154+
get_time(&mut clock64);
155+
get_time(&mut clock32);
155156

156157
let then = then - Seconds(1_u32);
157158
assert_ne!(then, now);

0 commit comments

Comments
 (0)