Skip to content

Commit

Permalink
Support TIM3 on more devices. (stm32-rs#308)
Browse files Browse the repository at this point in the history
* Support TIM3 on more devices.

* Allow cancelling timers.
  • Loading branch information
reitermarkus committed Apr 21, 2022
1 parent b92f6aa commit 8037c59
Showing 1 changed file with 51 additions and 36 deletions.
87 changes: 51 additions & 36 deletions src/timer.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
//! Timers

use crate::hal::timer::{CountDown, Periodic};
// missing PAC support
/*
use core::convert::Infallible;

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

#[cfg(any(
feature = "stm32l451",
// feature = "stm32l451",
feature = "stm32l452",
feature = "stm32l462",
feature = "stm32l471",
// feature = "stm32l471",
feature = "stm32l475",
feature = "stm32l476",
feature = "stm32l485",
Expand All @@ -20,11 +21,11 @@ use crate::hal::timer::{CountDown, Periodic};
// feature = "stm32l4s5",
// feature = "stm32l4r7",
// feature = "stm32l4s7",
feature = "stm32l4r9",
feature = "stm32l4s9",
// feature = "stm32l4r9",
// feature = "stm32l4s9",
))]
use crate::stm32::TIM3;
*/

#[cfg(not(any(
feature = "stm32l412",
feature = "stm32l422",
Expand Down Expand Up @@ -88,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 @@ -107,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 @@ -128,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 @@ -171,7 +183,7 @@ 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());


Expand All @@ -180,7 +192,7 @@ macro_rules! hal {
// 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 @@ -204,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 @@ -224,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 @@ -235,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 @@ -246,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 All @@ -265,14 +284,11 @@ hal! {
TIM16: (tim16, free_running_tim16, APB2, u16),
}

// missing PAC support
// RCC_APB1RSTR1->TIM3RST not defined
/*
#[cfg(any(
feature = "stm32l451",
// feature = "stm32l451",
feature = "stm32l452",
feature = "stm32l462",
feature = "stm32l471",
// feature = "stm32l471",
feature = "stm32l475",
feature = "stm32l476",
feature = "stm32l485",
Expand All @@ -285,13 +301,12 @@ hal! {
// feature = "stm32l4s5",
// feature = "stm32l4r7",
// feature = "stm32l4s7",
feature = "stm32l4r9",
feature = "stm32l4s9",
// feature = "stm32l4r9",
// feature = "stm32l4s9",
))]
hal! {
TIM3: (tim3, free_running_tim3, tim3en, tim3rst, APB1R1, u32),
TIM3: (tim3, free_running_tim3, APB1R1, u16),
}
*/

#[cfg(not(any(
feature = "stm32l412",
Expand Down

0 comments on commit 8037c59

Please sign in to comment.