Skip to content

Commit 4ae3b73

Browse files
committed
Add cancel and more duartion tests
1 parent 0514302 commit 4ae3b73

File tree

2 files changed

+55
-21
lines changed

2 files changed

+55
-21
lines changed

testsuite/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ enumset = { version = "1.0.6" }
5555
stm32f3xx-hal = { path = "..", features = ["rt", "defmt-trace", "can", "ld", "enumset"]}
5656
panic-probe = { version = "0.2.0", features = ["print-defmt"] }
5757
nb = "1.0.0"
58+
num-traits = { version = "0.2.14", default-features = false }
5859

5960
[features]
6061
# enable all defmt logging levels

testsuite/tests/timer.rs

Lines changed: 54 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,16 @@ use core::sync::atomic::{AtomicBool, Ordering};
66
use defmt_rtt as _;
77
use panic_probe as _;
88

9+
use num_traits::float::FloatCore;
10+
911
use stm32f3xx_hal as hal;
1012

13+
use hal::delay::Delay;
14+
use hal::hal::timer::Cancel;
1115
use hal::interrupts::InterruptNumber;
1216
use hal::rcc::{Clocks, APB1};
13-
use hal::timer::{Event, MonoTimer, Timer};
17+
use hal::time::{duration, fixed_point::FixedPoint};
18+
use hal::timer::{AlreadyCancled, Event, MonoTimer, Timer};
1419
use hal::{interrupt, pac, prelude::*};
1520

1621
use pac::TIM2;
@@ -20,6 +25,7 @@ struct State {
2025
mono_timer: MonoTimer,
2126
clocks: Clocks,
2227
apb1: APB1,
28+
delay: Delay,
2329
}
2430

2531
static INTERRUPT_FIRED: AtomicBool = AtomicBool::new(false);
@@ -28,7 +34,6 @@ static INTERRUPT_FIRED: AtomicBool = AtomicBool::new(false);
2834
mod tests {
2935
use super::*;
3036
use defmt::{self, assert, unwrap};
31-
use hal::time::fixed_point::FixedPoint;
3237

3338
#[init]
3439
fn init() -> State {
@@ -42,6 +47,7 @@ mod tests {
4247
// Let's use a timer, which is avaliable for every chip
4348
let timer = Timer::new(dp.TIM2, clocks, &mut rcc.apb1);
4449
let mono_timer = MonoTimer::new(cp.DWT, clocks, &mut cp.DCB);
50+
let delay = Delay::new(cp.SYST, clocks);
4551

4652
assert!(mono_timer.frequency() == clocks.hclk());
4753

@@ -52,6 +58,7 @@ mod tests {
5258
mono_timer,
5359
clocks,
5460
apb1: rcc.apb1,
61+
delay,
5562
}
5663
}
5764

@@ -70,31 +77,57 @@ mod tests {
7077
defmt::trace!("{}", state.mono_timer);
7178
let freqcyc = state.mono_timer.frequency().integer();
7279

73-
let instant = state.mono_timer.now();
74-
timer.start(1.seconds());
75-
assert!(!timer.is_event_triggered(Event::Update));
76-
unwrap!(nb::block!(timer.wait()).ok());
77-
let elapsed = instant.elapsed();
80+
let durations: [duration::Generic<u32>; 5] = [
81+
100.microseconds().into(),
82+
1.milliseconds().into(),
83+
100.milliseconds().into(),
84+
1.seconds().into(),
85+
10.seconds().into(),
86+
// 100.seconds().into(),
87+
];
88+
89+
for dur in durations {
90+
defmt::trace!("Duration: {}", defmt::Debug2Format(&dur));
91+
92+
timer.start(dur);
93+
assert!(!timer.is_event_triggered(Event::Update));
94+
// call instant after start, because starting the timer is the last thing done in the
95+
// start function, and therefor no overhead is added to the timing.
96+
let instant = state.mono_timer.now();
97+
unwrap!(nb::block!(timer.wait()).ok());
98+
let elapsed = instant.elapsed();
99+
100+
defmt::debug!("elapsed: {}", elapsed);
101+
102+
let ratio = f64::from(elapsed) / f64::from(freqcyc)
103+
* (f64::from(*dur.scaling_factor().denominator()))
104+
/ f64::from(dur.integer());
105+
106+
let deviation = (ratio - 1.).abs();
107+
108+
// Deviation is high for smaller timer durations. Higher duratinons are pretty accurate.
109+
// TODO: Maybe the allowed deviation should changed depending on the duration?
110+
#[cfg(not(debug_assertions))]
111+
defmt::assert!(deviation < 15e-4);
112+
#[cfg(debug_assertions)]
113+
defmt::assert!(deviation < 40e-4);
114+
}
115+
state.timer = Some(timer);
116+
}
78117

79-
defmt::info!("elapsed: {}", elapsed);
80-
// TODO: Test multiple frequencies and change the cycle counter window to a percentage
81-
// to measure the overhead of start?
118+
#[test]
119+
fn test_cancel(state: &mut State) {
120+
let mut timer = unwrap!(state.timer.take());
121+
defmt::trace!("{}", state.mono_timer);
82122

83-
// Differentiate between releas and debug build.
84-
#[cfg(not(debug_assertions))]
85-
assert!(((freqcyc - 500)..(freqcyc + 500)).contains(&elapsed));
86-
#[cfg(debug_assertions)]
87-
assert!(((freqcyc - 2000)..(freqcyc + 2000)).contains(&elapsed));
123+
timer.start(10.milliseconds());
124+
state.delay.delay_ms(5u32);
88125

126+
assert!(matches!(timer.cancel(), Ok(())));
127+
assert!(matches!(timer.cancel(), Err(AlreadyCancled)));
89128
state.timer = Some(timer);
90129
}
91130

92-
// TODO(Sh3Rm4n): For that we have to introduce a new API. (Maybe Centihertz or Something?)
93-
// #[test]
94-
// fn test_delay_longer_then_second(state: &mut State) {
95-
96-
// }
97-
98131
#[test]
99132
fn test_interrupt(state: &mut State) {
100133
let mut timer = unwrap!(state.timer.take());

0 commit comments

Comments
 (0)