1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
use core::convert::Infallible;

use nb;
use void::Void;

use crate::{
    traits::wg::timer,
    peripherals::ctimer::Ctimer,
    time::Microseconds,
    typestates::init_state,
};

/// Return the current time elapsed for the timer.
/// If the timer has not started or stopped, this unit may not be accurate.
pub trait Lap <Unit>{
    fn lap(&self) -> Unit;
}

pub struct Timer<TIMER>
where
    TIMER: Ctimer<init_state::Enabled>,
{
    timer: TIMER,
}

impl <TIMER> Timer<TIMER>
where TIMER: Ctimer<init_state::Enabled> {

    pub fn new(timer: TIMER) -> Self{
        Self {
            timer: timer,
        }
    }

    pub fn release(self) -> TIMER {
        self.timer
    }

}

type TimeUnits = Microseconds;

impl <TIMER> Lap<TimeUnits> for Timer<TIMER>
where TIMER: Ctimer<init_state::Enabled> {
    fn lap(&self) -> TimeUnits{
        Microseconds(self.timer.tc.read().bits())
    }
}


impl<TIMER> timer::CountDown for Timer<TIMER>
where TIMER: Ctimer<init_state::Enabled>
{
    type Time = TimeUnits;

    fn start<T>(&mut self, count: T)
    where T: Into<Self::Time>
    {
        // Match should reset and stop timer, and generate interrupt.
        self.timer.mcr.modify(|_,w| {
            w.mr0i().set_bit()
            .mr0r().set_bit()
            .mr0s().set_bit()
        } );

        // Set match to target time.  Ctimer fixed input 1MHz.
        self.timer.mr[0].write(|w| unsafe { w.bits(count.into().0) });

        // No divsion necessary.
        self.timer.pr.write(|w| unsafe {w.bits(0)});

        // clear interrupt
        self.timer.ir.modify(|_,w| { w.mr0int().set_bit() });

        // Start timer
        self.timer.tcr.write(|w| {
            w.crst().clear_bit()
            .cen().set_bit()
        });
    }

    fn wait(&mut self) -> nb::Result<(), Void> {
        if self.timer.ir.read().mr0int().bit_is_set() {
            self.timer.tcr.write(|w| {
                w.crst().set_bit()
                .cen().clear_bit()
            });
            return Ok(());
        }

        Err(nb::Error::WouldBlock)
    }
}

impl<TIMER> timer::Cancel for Timer<TIMER>
where TIMER: Ctimer<init_state::Enabled>
{
    type Error = Infallible;
    fn cancel(&mut self) -> Result<(), Self::Error>{
        self.timer.tcr.write(|w| {
            w.crst().set_bit()
            .cen().clear_bit()
        });
        self.timer.ir.write(|w| {w.mr0int().set_bit()});
        Ok(())
    }
}