lpc55_hal/drivers/
timer.rs

1use core::convert::Infallible;
2
3use nb;
4use void::Void;
5
6use crate::{
7    peripherals::ctimer::Ctimer, time::Microseconds, traits::wg::timer, typestates::init_state,
8};
9
10/// Return the current time elapsed for the timer.
11/// If the timer has not started or stopped, this unit may not be accurate.
12pub trait Elapsed: timer::CountDown {
13    fn elapsed(&self) -> Self::Time;
14}
15
16pub struct Timer<TIMER>
17where
18    TIMER: Ctimer<init_state::Enabled>,
19{
20    timer: TIMER,
21}
22
23impl<TIMER> Timer<TIMER>
24where
25    TIMER: Ctimer<init_state::Enabled>,
26{
27    pub fn new(timer: TIMER) -> Self {
28        Self { timer }
29    }
30
31    pub fn release(self) -> TIMER {
32        self.timer
33    }
34}
35
36type TimeUnits = Microseconds;
37
38impl<TIMER> Elapsed for Timer<TIMER>
39where
40    TIMER: Ctimer<init_state::Enabled>,
41{
42    fn elapsed(&self) -> Microseconds {
43        Microseconds(self.timer.tc.read().bits())
44    }
45}
46
47impl<TIMER> timer::CountDown for Timer<TIMER>
48where
49    TIMER: Ctimer<init_state::Enabled>,
50{
51    type Time = TimeUnits;
52
53    fn start<T>(&mut self, count: T)
54    where
55        T: Into<Self::Time>,
56    {
57        // Match should reset and stop timer, and generate interrupt.
58        self.timer
59            .mcr
60            .modify(|_, w| w.mr0i().set_bit().mr0r().set_bit().mr0s().set_bit());
61
62        // Set match to target time.  Ctimer fixed input 1MHz.
63        self.timer.mr[0].write(|w| unsafe { w.bits(count.into().0) });
64
65        // No divsion necessary.
66        self.timer.pr.write(|w| unsafe { w.bits(0) });
67
68        // clear interrupt
69        self.timer.ir.modify(|_, w| w.mr0int().set_bit());
70
71        // Start timer
72        self.timer
73            .tcr
74            .write(|w| w.crst().clear_bit().cen().set_bit());
75    }
76
77    fn wait(&mut self) -> nb::Result<(), Void> {
78        if self.timer.ir.read().mr0int().bit_is_set() {
79            self.timer
80                .tcr
81                .write(|w| w.crst().set_bit().cen().clear_bit());
82            return Ok(());
83        }
84
85        Err(nb::Error::WouldBlock)
86    }
87}
88
89impl<TIMER> timer::Cancel for Timer<TIMER>
90where
91    TIMER: Ctimer<init_state::Enabled>,
92{
93    type Error = Infallible;
94    fn cancel(&mut self) -> Result<(), Self::Error> {
95        self.timer
96            .tcr
97            .write(|w| w.crst().set_bit().cen().clear_bit());
98        self.timer.ir.write(|w| w.mr0int().set_bit());
99        Ok(())
100    }
101}