Skip to content

Commit

Permalink
Allow cancelling timers.
Browse files Browse the repository at this point in the history
  • Loading branch information
reitermarkus committed Apr 19, 2022
1 parent 73f82e4 commit e1b20c9
Showing 1 changed file with 41 additions and 20 deletions.
61 changes: 41 additions & 20 deletions src/timer.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//! Timers

use crate::hal::timer::{CountDown, Periodic};
use core::convert::Infallible;

use crate::hal::timer::{Cancel, CountDown, Periodic};

#[cfg(any(
// feature = "stm32l451",
Expand Down Expand Up @@ -87,17 +89,16 @@ macro_rules! hal {
type Time = Hertz;

// NOTE(allow) `w.psc().bits()` is safe for TIM{6,7} but not for TIM{2,3,4} due to
// some SVD omission
// some SVD omission.
#[allow(unused_unsafe)]
fn start<T>(&mut self, timeout: T)
where
T: Into<Hertz>,
{
// pause
self.tim.cr1.modify(|_, w| w.cen().clear_bit());
self.pause();

self.timeout = timeout.into();
let ticks = self.clocks.pclk1() / self.timeout; // TODO check pclk that timer is on
let ticks = self.clocks.pclk1() / self.timeout; // TODO: Check pclk that timer is on.
let psc = u16((ticks - 1) / (1 << 16)).unwrap();

self.tim.psc.write(|w| unsafe { w.psc().bits(psc) });
Expand All @@ -106,14 +107,15 @@ macro_rules! hal {

self.tim.arr.write(|w| unsafe { w.bits(u32(arr)) });

// Trigger an update event to load the prescaler value to the clock
// Trigger an update event to load the prescaler value to the clock.
self.tim.egr.write(|w| w.ug().set_bit());

// The above line raises an update event which will indicate
// that the timer is already finished. Since this is not the case,
// it should be cleared
// it should be cleared.
self.clear_update_interrupt_flag();

// start counter
// Start counter.
self.tim.cr1.modify(|_, w| w.cen().set_bit());
}

Expand All @@ -127,6 +129,17 @@ macro_rules! hal {
}
}

impl Cancel for Timer<$TIM> {
type Error = Infallible;

fn cancel(&mut self) -> Result<(), Self::Error> {
self.pause();
self.reset();

Ok(())
}
}

impl Timer<$TIM> {
// XXX(why not name this `new`?) bummer: constructors need to have different names
// even if the `$TIM` are non overlapping (compare to the `free` function below
Expand Down Expand Up @@ -170,15 +183,16 @@ macro_rules! hal {
let max = core::$width::MAX;
tim.arr.write(|w| unsafe { w.bits(max.into()) });

// Trigger an update event to load the prescaler value to the clock
// Trigger an update event to load the prescaler value to the clock.
tim.egr.write(|w| w.ug().set_bit());


// The above line raises an update event which will indicate
// that the timer is already finished. Since this is not the case,
// it should be cleared
tim.sr.modify(|_, w| w.uif().clear_bit());

// start counter
// Start counter.
tim.cr1.modify(|_, w| {
w.cen().set_bit();

Expand All @@ -202,17 +216,16 @@ macro_rules! hal {
pub fn listen(&mut self, event: Event) {
match event {
Event::TimeOut => {
// Enable update event interrupt
// Enable update event interrupt.
self.tim.dier.write(|w| w.uie().set_bit());
}
}
}


/// Clears interrupt associated with `event`.
///
/// If the interrupt is not cleared, it will immediately retrigger after
/// the ISR has finished.
/// If the interrupt is not cleared, it will immediately
/// retrigger after the ISR has finished.
pub fn clear_interrupt(&mut self, event: Event) {
match event {
Event::TimeOut => {
Expand All @@ -222,8 +235,7 @@ macro_rules! hal {
}
}


/// Stops listening for an `event`
/// Stops listening for an `event`.
pub fn unlisten(&mut self, event: Event) {
match event {
Event::TimeOut => {
Expand All @@ -233,7 +245,7 @@ macro_rules! hal {
}
}

/// Clears Update Interrupt Flag
/// Clear the update interrupt flag.
pub fn clear_update_interrupt_flag(&mut self) {
self.tim.sr.modify(|_, w| w.uif().clear_bit());
}
Expand All @@ -244,10 +256,19 @@ macro_rules! hal {
cnt.cnt().bits()
}

/// Releases the TIM peripheral
pub fn free(self) -> $TIM {
// pause counter
/// Pause the counter.
pub fn pause(&mut self) {
self.tim.cr1.modify(|_, w| w.cen().clear_bit());
}

/// Reset the counter.
pub fn reset(&mut self) {
self.tim.cnt.modify(|_, w| unsafe { w.bits(0) });
}

/// Releases the TIM peripheral.
pub fn free(mut self) -> $TIM {
self.pause();
self.tim
}
}
Expand Down

0 comments on commit e1b20c9

Please sign in to comment.