Skip to content

Commit

Permalink
Add cancel and more duartion tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Sh3Rm4n committed Aug 11, 2021
1 parent 0514302 commit 4ae3b73
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 21 deletions.
1 change: 1 addition & 0 deletions testsuite/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ enumset = { version = "1.0.6" }
stm32f3xx-hal = { path = "..", features = ["rt", "defmt-trace", "can", "ld", "enumset"]}
panic-probe = { version = "0.2.0", features = ["print-defmt"] }
nb = "1.0.0"
num-traits = { version = "0.2.14", default-features = false }

[features]
# enable all defmt logging levels
Expand Down
75 changes: 54 additions & 21 deletions testsuite/tests/timer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,16 @@ use core::sync::atomic::{AtomicBool, Ordering};
use defmt_rtt as _;
use panic_probe as _;

use num_traits::float::FloatCore;

use stm32f3xx_hal as hal;

use hal::delay::Delay;
use hal::hal::timer::Cancel;
use hal::interrupts::InterruptNumber;
use hal::rcc::{Clocks, APB1};
use hal::timer::{Event, MonoTimer, Timer};
use hal::time::{duration, fixed_point::FixedPoint};
use hal::timer::{AlreadyCancled, Event, MonoTimer, Timer};
use hal::{interrupt, pac, prelude::*};

use pac::TIM2;
Expand All @@ -20,6 +25,7 @@ struct State {
mono_timer: MonoTimer,
clocks: Clocks,
apb1: APB1,
delay: Delay,
}

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

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

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

Expand All @@ -52,6 +58,7 @@ mod tests {
mono_timer,
clocks,
apb1: rcc.apb1,
delay,
}
}

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

let instant = state.mono_timer.now();
timer.start(1.seconds());
assert!(!timer.is_event_triggered(Event::Update));
unwrap!(nb::block!(timer.wait()).ok());
let elapsed = instant.elapsed();
let durations: [duration::Generic<u32>; 5] = [
100.microseconds().into(),
1.milliseconds().into(),
100.milliseconds().into(),
1.seconds().into(),
10.seconds().into(),
// 100.seconds().into(),
];

for dur in durations {
defmt::trace!("Duration: {}", defmt::Debug2Format(&dur));

timer.start(dur);
assert!(!timer.is_event_triggered(Event::Update));
// call instant after start, because starting the timer is the last thing done in the
// start function, and therefor no overhead is added to the timing.
let instant = state.mono_timer.now();
unwrap!(nb::block!(timer.wait()).ok());
let elapsed = instant.elapsed();

defmt::debug!("elapsed: {}", elapsed);

let ratio = f64::from(elapsed) / f64::from(freqcyc)
* (f64::from(*dur.scaling_factor().denominator()))
/ f64::from(dur.integer());

let deviation = (ratio - 1.).abs();

// Deviation is high for smaller timer durations. Higher duratinons are pretty accurate.
// TODO: Maybe the allowed deviation should changed depending on the duration?
#[cfg(not(debug_assertions))]
defmt::assert!(deviation < 15e-4);
#[cfg(debug_assertions)]
defmt::assert!(deviation < 40e-4);
}
state.timer = Some(timer);
}

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

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

assert!(matches!(timer.cancel(), Ok(())));
assert!(matches!(timer.cancel(), Err(AlreadyCancled)));
state.timer = Some(timer);
}

// TODO(Sh3Rm4n): For that we have to introduce a new API. (Maybe Centihertz or Something?)
// #[test]
// fn test_delay_longer_then_second(state: &mut State) {

// }

#[test]
fn test_interrupt(state: &mut State) {
let mut timer = unwrap!(state.timer.take());
Expand Down

0 comments on commit 4ae3b73

Please sign in to comment.