Skip to content

Commit ed18017

Browse files
author
James Munns
committed
Remove the use of macros by the Timer, and change trait usage
1 parent 748504b commit ed18017

File tree

1 file changed

+149
-110
lines changed

1 file changed

+149
-110
lines changed

nrf-hal-common/src/timer.rs

Lines changed: 149 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ use void::{unreachable, Void};
2020
#[cfg(any(feature = "52832", feature = "52833", feature = "52840"))]
2121
use crate::pac::{TIMER3, TIMER4};
2222

23+
use crate::pac;
24+
2325
use core::marker::PhantomData;
2426

2527
pub struct OneShot;
@@ -231,135 +233,172 @@ where
231233
}
232234
}
233235

234-
/// Implemented by all `timer0::TIMER` instances.
235-
pub trait Instance {
236+
/// Implemented by all TIMER* instances.
237+
pub trait Instance: sealed::Sealed {
236238
/// This interrupt associated with this RTC instance.
237239
const INTERRUPT: Interrupt;
238240

241+
fn as_timer0(&self) -> &pac::timer0::RegisterBlock;
242+
239243
fn timer_start<Time>(&self, cycles: Time)
240244
where
241-
Time: Into<u32>;
245+
Time: Into<u32>,
246+
{
247+
// If the following sequence of events occurs, the COMPARE event will be
248+
// set here:
249+
// 1. `start` is called.
250+
// 2. The timer runs out but `wait` is _not_ called.
251+
// 3. `start` is called again
252+
//
253+
// If that happens, then we need to reset the event here explicitly, as
254+
// nothing else this method does will reset the event, and if it's still
255+
// active after this method exits, then the next call to `wait` will
256+
// return immediately, no matter how much time has actually passed.
257+
self.as_timer0().events_compare[0].reset();
258+
259+
// Configure timer to trigger EVENTS_COMPARE when given number of cycles
260+
// is reached.
261+
#[cfg(not(feature = "51"))]
262+
self.as_timer0().cc[0].write(|w|
263+
// The timer mode was set to 32 bits above, so all possible values
264+
// of `cycles` are valid.
265+
unsafe { w.cc().bits(cycles.into()) });
266+
267+
#[cfg(feature = "51")]
268+
self.as_timer0().cc[0].write(|w| unsafe { w.bits(cycles.into()) });
269+
270+
// Clear the counter value.
271+
self.as_timer0().tasks_clear.write(|w| unsafe { w.bits(1) });
272+
273+
// Start the timer.
274+
self.as_timer0().tasks_start.write(|w| unsafe { w.bits(1) });
275+
}
276+
277+
fn timer_reset_event(&self) {
278+
self.as_timer0().events_compare[0].write(|w| w);
279+
}
280+
281+
fn timer_cancel(&self) {
282+
self.as_timer0().tasks_stop.write(|w| unsafe { w.bits(1) });
283+
self.timer_reset_event();
284+
}
242285

243-
fn timer_reset_event(&self);
286+
fn timer_running(&self) -> bool {
287+
self.as_timer0().events_compare[0].read().bits() == 0
288+
}
289+
290+
fn read_counter(&self) -> u32 {
291+
self.as_timer0().tasks_capture[1].write(|w| unsafe { w.bits(1) });
292+
self.as_timer0().cc[1].read().bits()
293+
}
294+
295+
fn disable_interrupt(&self) {
296+
self.as_timer0()
297+
.intenclr
298+
.modify(|_, w| w.compare0().clear());
299+
}
244300

245-
fn timer_cancel(&self);
301+
fn enable_interrupt(&self) {
302+
self.as_timer0().intenset.modify(|_, w| w.compare0().set());
303+
}
246304

247-
fn timer_running(&self) -> bool;
305+
fn set_shorts_periodic(&self) {
306+
self.as_timer0()
307+
.shorts
308+
.write(|w| w.compare0_clear().enabled().compare0_stop().disabled());
309+
}
248310

249-
fn read_counter(&self) -> u32;
311+
fn set_shorts_oneshot(&self) {
312+
self.as_timer0()
313+
.shorts
314+
.write(|w| w.compare0_clear().enabled().compare0_stop().enabled());
315+
}
250316

251-
fn disable_interrupt(&self);
317+
fn set_periodic(&self) {
318+
self.set_shorts_periodic();
319+
self.as_timer0().prescaler.write(
320+
|w| unsafe { w.prescaler().bits(4) }, // 1 MHz
321+
);
322+
self.as_timer0().bitmode.write(|w| w.bitmode()._32bit());
323+
}
252324

253-
fn enable_interrupt(&self);
325+
fn set_oneshot(&self) {
326+
self.set_shorts_oneshot();
327+
self.as_timer0().prescaler.write(
328+
|w| unsafe { w.prescaler().bits(4) }, // 1 MHz
329+
);
330+
self.as_timer0().bitmode.write(|w| w.bitmode()._32bit());
331+
}
332+
}
254333

255-
fn set_shorts_periodic(&self);
334+
impl Instance for TIMER0 {
335+
const INTERRUPT: Interrupt = Interrupt::TIMER0;
256336

257-
fn set_shorts_oneshot(&self);
337+
#[inline(always)]
338+
fn as_timer0(&self) -> &pac::timer0::RegisterBlock {
339+
self
340+
}
341+
}
258342

259-
fn set_periodic(&self);
343+
impl Instance for TIMER1 {
344+
const INTERRUPT: Interrupt = Interrupt::TIMER1;
260345

261-
fn set_oneshot(&self);
346+
#[inline(always)]
347+
fn as_timer0(&self) -> &pac::timer0::RegisterBlock {
348+
self
349+
}
262350
}
263351

264-
macro_rules! impl_instance {
265-
($($name:ident,)*) => {
266-
$(
267-
impl Instance for $name {
268-
const INTERRUPT: Interrupt = Interrupt::$name;
269-
270-
fn timer_start<Time>(&self, cycles: Time)
271-
where
272-
Time: Into<u32>,
273-
{
274-
// If the following sequence of events occurs, the COMPARE event will be
275-
// set here:
276-
// 1. `start` is called.
277-
// 2. The timer runs out but `wait` is _not_ called.
278-
// 3. `start` is called again
279-
//
280-
// If that happens, then we need to reset the event here explicitly, as
281-
// nothing else this method does will reset the event, and if it's still
282-
// active after this method exits, then the next call to `wait` will
283-
// return immediately, no matter how much time has actually passed.
284-
self.events_compare[0].reset();
285-
286-
// Configure timer to trigger EVENTS_COMPARE when given number of cycles
287-
// is reached.
288-
#[cfg(not(feature = "51"))]
289-
self.cc[0].write(|w|
290-
// The timer mode was set to 32 bits above, so all possible values
291-
// of `cycles` are valid.
292-
unsafe { w.cc().bits(cycles.into()) });
293-
294-
#[cfg(feature = "51")]
295-
self.cc[0].write(|w| unsafe { w.bits(cycles.into())} );
296-
297-
// Clear the counter value.
298-
self.tasks_clear.write(|w| unsafe { w.bits(1) });
299-
300-
// Start the timer.
301-
self.tasks_start.write(|w| unsafe { w.bits(1) });
302-
}
303-
304-
fn timer_reset_event(&self) {
305-
self.events_compare[0].write(|w| w);
306-
}
307-
308-
fn timer_cancel(&self) {
309-
self.tasks_stop.write(|w| unsafe { w.bits(1) });
310-
self.timer_reset_event();
311-
}
312-
313-
fn timer_running(&self) -> bool {
314-
self.events_compare[0].read().bits() == 0
315-
}
316-
317-
fn read_counter(&self) -> u32 {
318-
self.tasks_capture[1].write(|w| unsafe { w.bits(1) });
319-
self.cc[1].read().bits()
320-
}
321-
322-
fn disable_interrupt(&self) {
323-
self.intenclr.modify(|_, w| w.compare0().clear());
324-
}
325-
326-
fn enable_interrupt(&self) {
327-
self.intenset.modify(|_, w| w.compare0().set());
328-
}
329-
330-
fn set_shorts_periodic(&self) {
331-
self
332-
.shorts
333-
.write(|w| w.compare0_clear().enabled().compare0_stop().disabled());
334-
}
335-
336-
fn set_shorts_oneshot(&self) {
337-
self
338-
.shorts
339-
.write(|w| w.compare0_clear().enabled().compare0_stop().enabled());
340-
}
341-
342-
fn set_periodic(&self) {
343-
self.set_shorts_periodic();
344-
self.prescaler.write(
345-
|w| unsafe { w.prescaler().bits(4) }, // 1 MHz
346-
);
347-
self.bitmode.write(|w| w.bitmode()._32bit());
348-
}
349-
350-
fn set_oneshot(&self) {
351-
self.set_shorts_oneshot();
352-
self.prescaler.write(
353-
|w| unsafe { w.prescaler().bits(4) }, // 1 MHz
354-
);
355-
self.bitmode.write(|w| w.bitmode()._32bit());
356-
}
357-
}
358-
)*
352+
impl Instance for TIMER2 {
353+
const INTERRUPT: Interrupt = Interrupt::TIMER2;
354+
355+
#[inline(always)]
356+
fn as_timer0(&self) -> &pac::timer0::RegisterBlock {
357+
self
359358
}
360359
}
361360

362-
impl_instance!(TIMER0, TIMER1, TIMER2,);
361+
#[cfg(any(feature = "52832", feature = "52833", feature = "52840"))]
362+
impl Instance for TIMER3 {
363+
const INTERRUPT: Interrupt = Interrupt::TIMER3;
364+
365+
#[inline(always)]
366+
fn as_timer0(&self) -> &pac::timer0::RegisterBlock {
367+
let rb: &pac::timer3::RegisterBlock = self;
368+
let rb_ptr: *const pac::timer3::RegisterBlock = rb;
369+
370+
// SAFETY: TIMER0 and TIMER3 register layouts are identical, except
371+
// that TIMER3 has 6 CC registers, while TIMER0 has 4. There is
372+
// appropriate padding to allow other operations to work correctly
373+
unsafe { &*rb_ptr.cast() }
374+
}
375+
}
363376

364377
#[cfg(any(feature = "52832", feature = "52833", feature = "52840"))]
365-
impl_instance!(TIMER3, TIMER4,);
378+
impl Instance for TIMER4 {
379+
const INTERRUPT: Interrupt = Interrupt::TIMER4;
380+
381+
#[inline(always)]
382+
fn as_timer0(&self) -> &pac::timer0::RegisterBlock {
383+
let rb: &pac::timer3::RegisterBlock = self;
384+
let rb_ptr: *const pac::timer3::RegisterBlock = rb;
385+
386+
// SAFETY: TIMER0 and TIMER3 register layouts are identical, except
387+
// that TIMER3 has 6 CC registers, while TIMER0 has 4. There is
388+
// appropriate padding to allow other operations to work correctly
389+
unsafe { &*rb_ptr.cast() }
390+
}
391+
}
392+
393+
mod sealed {
394+
pub trait Sealed {}
395+
impl Sealed for super::TIMER0 {}
396+
impl Sealed for super::TIMER1 {}
397+
impl Sealed for super::TIMER2 {}
398+
399+
#[cfg(any(feature = "52832", feature = "52833", feature = "52840"))]
400+
impl Sealed for super::TIMER3 {}
401+
402+
#[cfg(any(feature = "52832", feature = "52833", feature = "52840"))]
403+
impl Sealed for super::TIMER4 {}
404+
}

0 commit comments

Comments
 (0)