Skip to content

Commit c5fb56d

Browse files
committed
feat(Clock): Allow Clock impls to be stateful
1 parent 522c03d commit c5fb56d

File tree

5 files changed

+52
-56
lines changed

5 files changed

+52
-56
lines changed

CHANGELOG.md

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

99
### Changed
1010

11+
- Add `&mut self` to `Clock` functions (make stateful, or at least allow stateful implementations)
1112
- Refactor `examples/nrf52_dk`
1213

1314
[unreleased]: https://github.com/FluenTech/embedded-time/compare/v0.5.2...HEAD

examples/nrf52_dk/main.rs

Lines changed: 26 additions & 32 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;
87
use embedded_time::{self as time, Clock, Instant, Period, TimeInt};
9-
use mutex_trait::Mutex as _;
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 = i64;
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.milliseconds());
153+
clock.delay(250.milliseconds());
160154

161155
led1.set_high()?;
162156
led2.set_low()?;
163157
led3.set_low()?;
164158
led4.set_high()?;
165-
SysClock::delay(250.milliseconds());
159+
clock.delay(250.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
@@ -33,7 +33,7 @@ impl<Clock: crate::Clock> Instant<Clock> {
3333
/// type Rep = i32;
3434
/// const PERIOD: Period = Period::new(1, 1_000);
3535
/// // ...
36-
/// # fn now() -> Instant<Self> {unimplemented!()}
36+
/// # fn now(&mut self) -> Instant<Self> {unimplemented!()}
3737
/// }
3838
///
3939
/// let diff: Option<Milliseconds<_>> = Instant::<Clock>::new(5).duration_since(&Instant::<Clock>::new(3));
@@ -99,7 +99,7 @@ impl<Clock: crate::Clock> PartialOrd for Instant<Clock> {
9999
/// type Rep = i32;
100100
/// const PERIOD: Period = Period::new(1, 1_000);
101101
/// // ...
102-
/// # fn now() -> Instant<Self> {unimplemented!()}
102+
/// # fn now(&mut self) -> Instant<Self> {unimplemented!()}
103103
/// }
104104
///
105105
/// assert!(Instant::<Clock>::new(5) > Instant::<Clock>::new(3));
@@ -138,7 +138,7 @@ where
138138
/// type Rep = i32;
139139
/// const PERIOD: Period = Period::new(1, 1_000);
140140
/// // ...
141-
/// # fn now() -> Instant<Self> {unimplemented!()}
141+
/// # fn now(&mut self) -> Instant<Self> {unimplemented!()}
142142
/// }
143143
///
144144
/// Instant::<Clock>::new(1) + Seconds(i32::MAX);
@@ -154,7 +154,7 @@ where
154154
/// type Rep = i32;
155155
/// const PERIOD: Period = Period::new(1, 1_000);
156156
/// // ...
157-
/// # fn now() -> Instant<Self> {unimplemented!()}
157+
/// # fn now(&mut self) -> Instant<Self> {unimplemented!()}
158158
/// }
159159
///
160160
/// assert_eq!(Instant::<Clock>::new(1) + Seconds(3), Instant::<Clock>::new(3_001));
@@ -190,7 +190,7 @@ where
190190
/// type Rep = i32;
191191
/// const PERIOD: Period = Period::new(1, 1_000);
192192
/// // ...
193-
/// # fn now() -> Instant<Self> {unimplemented!()}
193+
/// # fn now(&mut self) -> Instant<Self> {unimplemented!()}
194194
/// }
195195
///
196196
/// Instant::<Clock>::new(1) - Seconds(i32::MAX);
@@ -206,7 +206,7 @@ where
206206
/// type Rep = i32;
207207
/// const PERIOD: Period = Period::new(1, 1_000);
208208
/// // ...
209-
/// # fn now() -> Instant<Self> {unimplemented!()}
209+
/// # fn now(&mut self) -> Instant<Self> {unimplemented!()}
210210
/// }
211211
///
212212
/// assert_eq!(Instant::<Clock>::new(1) - Seconds(3), Instant::<Clock>::new(-2_999));

src/lib.rs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,16 @@
4646
//! type Rep = i64;
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
@@ -117,7 +118,7 @@ mod tests {
117118
type Rep = i64;
118119
const PERIOD: time::Period = time::Period::new(1, 64_000_000);
119120

120-
fn now() -> time::Instant<Self> {
121+
fn now(&mut self) -> time::Instant<Self> {
121122
time::Instant::new(128_000_000)
122123
}
123124
}
@@ -129,25 +130,25 @@ mod tests {
129130
type Rep = i32;
130131
const PERIOD: time::Period = time::Period::new(1, 16_000_000);
131132

132-
fn now() -> time::Instant<Self> {
133+
fn now(&mut self) -> time::Instant<Self> {
133134
time::Instant::new(32_000_000)
134135
}
135136
}
136137

137-
fn get_time<M>()
138-
where
139-
M: time::Clock,
140-
{
141-
assert_eq!(M::now().duration_since_epoch(), Some(Seconds(2)));
138+
fn get_time(clock: &mut impl time::Clock) {
139+
assert_eq!(clock.now().duration_since_epoch(), Some(Seconds(2)));
142140
}
143141

144142
#[test]
145143
fn common_types() {
146-
let then = MockClock32::now();
147-
let now = MockClock32::now();
144+
let then = MockClock32.now();
145+
let now = MockClock32.now();
146+
147+
let mut clock64 = MockClock64 {};
148+
let mut clock32 = MockClock32 {};
148149

149-
get_time::<MockClock64>();
150-
get_time::<MockClock32>();
150+
get_time(&mut clock64);
151+
get_time(&mut clock32);
151152

152153
let then = then - Seconds(1);
153154
assert_ne!(then, now);

0 commit comments

Comments
 (0)