use core::convert::Infallible;
use nb;
use void::Void;
use crate::{
peripherals::ctimer::Ctimer, time::Microseconds, traits::wg::timer, typestates::init_state,
};
pub trait Elapsed: timer::CountDown {
fn elapsed(&self) -> Self::Time;
}
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 }
}
pub fn release(self) -> TIMER {
self.timer
}
}
type TimeUnits = Microseconds;
impl<TIMER> Elapsed for Timer<TIMER>
where
TIMER: Ctimer<init_state::Enabled>,
{
fn elapsed(&self) -> Microseconds {
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>,
{
self.timer
.mcr
.modify(|_, w| w.mr0i().set_bit().mr0r().set_bit().mr0s().set_bit());
self.timer.mr[0].write(|w| unsafe { w.bits(count.into().0) });
self.timer.pr.write(|w| unsafe { w.bits(0) });
self.timer.ir.modify(|_, w| w.mr0int().set_bit());
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(())
}
}