Skip to content

Commit 701abb2

Browse files
committed
CountDownTimer
1 parent 6710c45 commit 701abb2

File tree

6 files changed

+62
-35
lines changed

6 files changed

+62
-35
lines changed

examples/analog-stopwatch-with-spi-ssd1306.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use crate::hal::{
1717
rcc::{Clocks, Rcc},
1818
spi::Spi,
1919
stm32,
20-
timer::{Event, Timer},
20+
timer::{CountDownTimer, Event, Timer},
2121
};
2222

2323
use arrayvec::ArrayString;
@@ -47,7 +47,8 @@ use ssd1306::{prelude::*, Builder};
4747
// Set up global state. It's all mutexed up for concurrency safety.
4848
static ELAPSED_MS: Mutex<Cell<u32>> = Mutex::new(Cell::new(0u32));
4949
static ELAPSED_RESET_MS: Mutex<Cell<u32>> = Mutex::new(Cell::new(0u32));
50-
static TIMER_TIM2: Mutex<RefCell<Option<Timer<stm32::TIM2>>>> = Mutex::new(RefCell::new(None));
50+
static TIMER_TIM2: Mutex<RefCell<Option<CountDownTimer<stm32::TIM2>>>> =
51+
Mutex::new(RefCell::new(None));
5152
static STATE: Mutex<Cell<StopwatchState>> = Mutex::new(Cell::new(StopwatchState::Ready));
5253
static BUTTON: Mutex<RefCell<Option<PA0<Input<PullDown>>>>> = Mutex::new(RefCell::new(None));
5354

@@ -129,7 +130,7 @@ fn main() -> ! {
129130
disp.flush().unwrap();
130131

131132
// Create a 1ms periodic interrupt from TIM2
132-
let mut timer = Timer::tim2(dp.TIM2, 1.khz(), clocks);
133+
let mut timer = Timer::tim2(dp.TIM2, &clocks).start_count_down(1.hz());
133134
timer.listen(Event::TimeOut);
134135

135136
free(|cs| {

examples/blinky-timer-irq.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use crate::hal::{
1414
gpio::{gpioa, Output, PushPull},
1515
prelude::*,
1616
stm32::{interrupt, Interrupt, Peripherals, TIM2},
17-
timer::{Event, Timer},
17+
timer::{CountDownTimer, Event, Timer},
1818
};
1919

2020
use core::cell::RefCell;
@@ -36,14 +36,14 @@ type LEDPIN = gpioa::PA5<Output<PushPull>>;
3636
static G_LED: Mutex<RefCell<Option<LEDPIN>>> = Mutex::new(RefCell::new(None));
3737

3838
// Make timer interrupt registers globally available
39-
static G_TIM: Mutex<RefCell<Option<Timer<TIM2>>>> = Mutex::new(RefCell::new(None));
39+
static G_TIM: Mutex<RefCell<Option<CountDownTimer<TIM2>>>> = Mutex::new(RefCell::new(None));
4040

4141
// Define an interupt handler, i.e. function to call when interrupt occurs.
4242
// This specific interrupt will "trip" when the timer TIM2 times out
4343
#[interrupt]
4444
fn TIM2() {
4545
static mut LED: Option<LEDPIN> = None;
46-
static mut TIM: Option<Timer<TIM2>> = None;
46+
static mut TIM: Option<CountDownTimer<TIM2>> = None;
4747

4848
let led = LED.get_or_insert_with(|| {
4949
cortex_m::interrupt::free(|cs| {
@@ -79,7 +79,7 @@ fn main() -> ! {
7979
cortex_m::interrupt::free(|cs| *G_LED.borrow(cs).borrow_mut() = Some(led));
8080

8181
// Set up a timer expiring after 1s
82-
let mut timer = Timer::tim2(dp.TIM2, 1.hz(), &clocks);
82+
let mut timer = Timer::tim2(dp.TIM2, &clocks).start_count_down(1.hz());
8383

8484
// Generate an interrupt when the timer expires
8585
timer.listen(Event::TimeOut);

examples/stopwatch-with-ssd1306-and-interrupts.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use crate::hal::{
2828
prelude::*,
2929
rcc::{Clocks, Rcc},
3030
stm32,
31-
timer::{Event, Timer},
31+
timer::{CountDownTimer, Event, Timer},
3232
};
3333
use arrayvec::ArrayString;
3434
use core::cell::{Cell, RefCell};
@@ -46,7 +46,8 @@ use ssd1306::{prelude::*, Builder, I2CDIBuilder};
4646

4747
// Set up global state. It's all mutexed up for concurrency safety.
4848
static ELAPSED_MS: Mutex<Cell<u32>> = Mutex::new(Cell::new(0u32));
49-
static TIMER_TIM2: Mutex<RefCell<Option<Timer<stm32::TIM2>>>> = Mutex::new(RefCell::new(None));
49+
static TIMER_TIM2: Mutex<RefCell<Option<CountDownTimer<stm32::TIM2>>>> =
50+
Mutex::new(RefCell::new(None));
5051
static STATE: Mutex<Cell<StopwatchState>> = Mutex::new(Cell::new(StopwatchState::Ready));
5152
static BUTTON: Mutex<RefCell<Option<PC13<Input<PullUp>>>>> = Mutex::new(RefCell::new(None));
5253

@@ -88,7 +89,7 @@ fn main() -> ! {
8889
disp.flush().unwrap();
8990

9091
// Create a 1ms periodic interrupt from TIM2
91-
let mut timer = Timer::tim2(dp.TIM2, 1.khz(), &clocks);
92+
let mut timer = Timer::tim2(dp.TIM2, &clocks).start_count_down(1.hz());
9293
timer.listen(Event::TimeOut);
9394

9495
free(|cs| {

examples/timer-periph.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ fn main() -> ! {
2929
let clocks = rcc.cfgr.sysclk(24.mhz()).freeze();
3030

3131
// Create a timer based on SysTick
32-
let mut timer = Timer::tim1(dp.TIM1, 1.hz(), &clocks);
32+
let mut timer = Timer::tim1(dp.TIM1, &clocks).start_count_down(1.hz());
3333

3434
hprintln!("hello!").unwrap();
3535
// wait until timer expires

examples/timer-syst.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ fn main() -> ! {
3030
let clocks = rcc.cfgr.sysclk(24.mhz()).freeze();
3131

3232
// Create a timer based on SysTick
33-
let mut timer = Timer::syst(cp.SYST, 24.hz(), &clocks);
33+
let mut timer = Timer::syst(cp.SYST, &clocks).start_count_down(24.hz());
3434

3535
hprintln!("hello!").unwrap();
3636
// wait until timer expires

src/timer.rs

Lines changed: 48 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,39 +14,57 @@ use crate::pac::RCC;
1414
use crate::rcc::{Clocks, Enable, Reset};
1515
use crate::time::Hertz;
1616

17-
/// Hardware timers
17+
/// Timer wrapper
1818
pub struct Timer<TIM> {
19+
pub(crate) tim: TIM,
20+
pub(crate) clk: Hertz,
21+
}
22+
23+
/// Hardware timers
24+
pub struct CountDownTimer<TIM> {
1925
clk: Hertz,
2026
tim: TIM,
2127
}
2228

2329
/// Interrupt events
2430
pub enum Event {
25-
/// Timer timed out / count down ended
31+
/// CountDownTimer timed out / count down ended
2632
TimeOut,
2733
}
2834

2935
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
3036
pub enum Error {
31-
/// Timer is disabled
37+
/// CountDownTimer is disabled
3238
Disabled,
3339
}
3440

3541
impl Timer<SYST> {
42+
/// Initialize timer
43+
pub fn syst(mut syst: SYST, clocks: &Clocks) -> Self {
44+
syst.set_clock_source(SystClkSource::Core);
45+
Self {
46+
tim: syst,
47+
clk: clocks.sysclk(),
48+
}
49+
}
50+
3651
/// Configures the SYST clock as a periodic count down timer
37-
pub fn syst<T>(mut syst: SYST, timeout: T, clocks: &Clocks) -> Self
52+
pub fn start_count_down<T>(self, timeout: T) -> CountDownTimer<SYST>
3853
where
3954
T: Into<Hertz>,
4055
{
41-
syst.set_clock_source(SystClkSource::Core);
42-
let mut timer = Self {
43-
tim: syst,
44-
clk: clocks.sysclk(),
45-
};
56+
let Self { tim, clk } = self;
57+
let mut timer = CountDownTimer { tim, clk };
4658
timer.start(timeout);
4759
timer
4860
}
4961

62+
pub fn release(self) -> SYST {
63+
self.tim
64+
}
65+
}
66+
67+
impl CountDownTimer<SYST> {
5068
/// Starts listening for an `event`
5169
pub fn listen(&mut self, event: Event) {
5270
match event {
@@ -62,7 +80,7 @@ impl Timer<SYST> {
6280
}
6381
}
6482

65-
impl CountDown for Timer<SYST> {
83+
impl CountDown for CountDownTimer<SYST> {
6684
type Time = Hertz;
6785

6886
fn start<T>(&mut self, timeout: T)
@@ -87,7 +105,7 @@ impl CountDown for Timer<SYST> {
87105
}
88106
}
89107

90-
impl Cancel for Timer<SYST> {
108+
impl Cancel for CountDownTimer<SYST> {
91109
type Error = Error;
92110

93111
fn cancel(&mut self) -> Result<(), Self::Error> {
@@ -100,7 +118,7 @@ impl Cancel for Timer<SYST> {
100118
}
101119
}
102120

103-
impl Periodic for Timer<SYST> {}
121+
impl Periodic for CountDownTimer<SYST> {}
104122

105123
/// A monotonic non-decreasing timer
106124
///
@@ -157,11 +175,8 @@ macro_rules! hal {
157175
($($TIM:ty: ($tim:ident, $pclk:ident, $ppre:ident),)+) => {
158176
$(
159177
impl Timer<$TIM> {
160-
/// Configures a TIM peripheral as a periodic count down timer
161-
pub fn $tim<T>(tim: $TIM, timeout: T, clocks: &Clocks) -> Self
162-
where
163-
T: Into<Hertz>,
164-
{
178+
/// Initialize timer
179+
pub fn $tim(tim: $TIM, clocks: &Clocks) -> Self {
165180
unsafe {
166181
//NOTE(unsafe) this reference will only be used for atomic writes with no side effects
167182
let rcc = &(*RCC::ptr());
@@ -172,15 +187,25 @@ macro_rules! hal {
172187

173188
let pclk_mul = if clocks.$ppre() == 1 { 1 } else { 2 };
174189

175-
let mut timer = Self {
190+
Self {
176191
clk: Hertz(clocks.$pclk().0 * pclk_mul),
177192
tim,
178-
};
179-
timer.start(timeout);
193+
}
194+
}
180195

196+
/// Starts timer in count down mode at a given frequency
197+
pub fn start_count_down<T>(self, timeout: T) -> CountDownTimer<$TIM>
198+
where
199+
T: Into<Hertz>,
200+
{
201+
let Self { tim, clk } = self;
202+
let mut timer = CountDownTimer { tim, clk };
203+
timer.start(timeout);
181204
timer
182205
}
183206

207+
}
208+
impl CountDownTimer<$TIM> {
184209
/// Starts listening for an `event`
185210
///
186211
/// Note, you will also have to enable the TIM2 interrupt in the NVIC to start
@@ -225,7 +250,7 @@ macro_rules! hal {
225250
}
226251
}
227252

228-
impl CountDown for Timer<$TIM> {
253+
impl CountDown for CountDownTimer<$TIM> {
229254
type Time = Hertz;
230255

231256
fn start<T>(&mut self, timeout: T)
@@ -265,7 +290,7 @@ macro_rules! hal {
265290
}
266291
}
267292

268-
impl Cancel for Timer<$TIM>
293+
impl Cancel for CountDownTimer<$TIM>
269294
{
270295
type Error = Error;
271296

@@ -281,7 +306,7 @@ macro_rules! hal {
281306
}
282307
}
283308

284-
impl Periodic for Timer<$TIM> {}
309+
impl Periodic for CountDownTimer<$TIM> {}
285310
)+
286311
}
287312
}

0 commit comments

Comments
 (0)