Skip to content

Commit 723b740

Browse files
authored
Implement Cancel trait for Timer<SYST> (#137)
Implement Cancel trait for Timer<SYST> Partially solves issue #106
1 parent de1b149 commit 723b740

File tree

3 files changed

+89
-1
lines changed

3 files changed

+89
-1
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1111

1212
- Wait 16 cycles after setting prescalers for some clock domains to follow manual.
1313

14+
### Added
15+
16+
- Implement `timer::Cancel` trait for `Timer<SYST>`.
17+
1418
## [v0.7.0] - 2020-03-07
1519

1620
### Changed

examples/timer-syst.rs

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
//! Start and stop a periodic system timer.
2+
//!
3+
//! This example should run on all stm32f4xx boards but it was tested with
4+
//! stm32f4-discovery board (model STM32F407G-DISC1).
5+
//!
6+
//! ```bash
7+
//! cargo run --release --features stm32f407,rt --example timer-syst
8+
//! ```
9+
10+
#![no_std]
11+
#![no_main]
12+
13+
extern crate panic_halt;
14+
15+
use cortex_m;
16+
use cortex_m_rt::entry;
17+
use cortex_m_semihosting::hprintln;
18+
19+
use embedded_hal::timer::Cancel;
20+
use hal::timer;
21+
use hal::timer::Timer;
22+
use nb;
23+
use stm32f4xx_hal as hal;
24+
25+
use crate::hal::{prelude::*, stm32};
26+
27+
#[entry]
28+
fn main() -> ! {
29+
let dp = stm32::Peripherals::take().unwrap();
30+
let cp = cortex_m::peripheral::Peripherals::take().unwrap();
31+
let rcc = dp.RCC.constrain();
32+
let clocks = rcc.cfgr.sysclk(24.mhz()).freeze();
33+
34+
// Create a timer based on SysTick
35+
let mut timer = Timer::syst(cp.SYST, 24.hz(), clocks);
36+
37+
hprintln!("hello!").unwrap();
38+
// wait until timer expires
39+
nb::block!(timer.wait()).unwrap();
40+
hprintln!("timer expired 1").unwrap();
41+
42+
// the function syst() creates a periodic timer, so it is automatically
43+
// restarted
44+
nb::block!(timer.wait()).unwrap();
45+
hprintln!("timer expired 2").unwrap();
46+
47+
// cancel current timer
48+
timer.cancel().unwrap();
49+
50+
// start it again
51+
timer.start(24.hz());
52+
nb::block!(timer.wait()).unwrap();
53+
hprintln!("timer expired 3").unwrap();
54+
55+
timer.cancel().unwrap();
56+
let cancel_outcome = timer.cancel();
57+
assert_eq!(cancel_outcome, Err(timer::Error::Disabled));
58+
hprintln!("ehy, you cannot cancel a timer two times!").unwrap();
59+
// this time the timer was not restarted, therefore this function should
60+
// wait forever
61+
nb::block!(timer.wait()).unwrap();
62+
// you should never see this print
63+
hprintln!("if you see this there is something wrong").unwrap();
64+
panic!();
65+
}

src/timer.rs

+20-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use cast::{u16, u32};
44
use cortex_m::peripheral::syst::SystClkSource;
55
use cortex_m::peripheral::SYST;
6-
use embedded_hal::timer::{CountDown, Periodic};
6+
use embedded_hal::timer::{Cancel, CountDown, Periodic};
77
use void::Void;
88

99
use crate::stm32::RCC;
@@ -97,6 +97,12 @@ pub enum Event {
9797
TimeOut,
9898
}
9999

100+
#[derive(Debug, PartialEq)]
101+
pub enum Error {
102+
/// Timer is disabled
103+
Disabled,
104+
}
105+
100106
impl Timer<SYST> {
101107
/// Configures the SYST clock as a periodic count down timer
102108
pub fn syst<T>(mut syst: SYST, timeout: T, clocks: Clocks) -> Self
@@ -149,6 +155,19 @@ impl CountDown for Timer<SYST> {
149155
}
150156
}
151157

158+
impl Cancel for Timer<SYST> {
159+
type Error = Error;
160+
161+
fn cancel(&mut self) -> Result<(), Self::Error> {
162+
if !self.tim.is_counter_enabled() {
163+
return Err(Self::Error::Disabled);
164+
}
165+
166+
self.tim.disable_counter();
167+
Ok(())
168+
}
169+
}
170+
152171
impl Periodic for Timer<SYST> {}
153172

154173
macro_rules! hal {

0 commit comments

Comments
 (0)