pounder_test/src/hardware/cycle_counter.rs

67 lines
1.9 KiB
Rust
Raw Permalink Normal View History

2021-02-17 19:08:03 +08:00
use rtic::cyccnt::{Duration, Instant, U32Ext};
use stm32h7xx_hal::time::Hertz;
2021-02-18 00:26:54 +08:00
/// A simple clock for counting elapsed milliseconds.
2021-02-17 19:08:03 +08:00
pub struct CycleCounter {
2021-02-18 00:26:54 +08:00
// The time of the next millisecond in the system.
2021-02-17 19:59:24 +08:00
next_tick: Option<Instant>,
2021-02-18 00:26:54 +08:00
// The number of elapsed milliseconds recorded.
2021-02-17 19:08:03 +08:00
ticks: u32,
2021-02-18 00:26:54 +08:00
// The increment amount of clock cycles for each elapsed millisecond.
2021-02-17 19:08:03 +08:00
increment: Duration,
}
impl CycleCounter {
2021-02-18 00:26:54 +08:00
/// Construct the cycle counting clock.
///
/// # Args
/// * `dwt` - The debug watch and trace unit of the CPU core.
/// * `cpu_frequency` - The frequency that the cycle counter counts at.
///
/// # Returns
/// A clock that can be used for measuring elapsed milliseconds.
2021-02-17 19:08:03 +08:00
pub fn new(
mut dwt: cortex_m::peripheral::DWT,
cpu_frequency: impl Into<Hertz>,
) -> Self {
dwt.enable_cycle_counter();
let increment =
((cpu_frequency.into().0 as f32 / 1000.0) as u32).cycles();
Self {
increment,
ticks: 0,
2021-02-17 19:59:24 +08:00
next_tick: None,
2021-02-17 19:08:03 +08:00
}
}
2021-02-18 00:26:54 +08:00
/// Get the current number of milliseconds elapsed in the system.
///
/// # Note
/// This function must be called more often than once per 10 seconds to prevent internal
/// wrapping of the cycle counter.
///
/// The internal millisecond accumulator will overflow just shy of every 50 days.
///
/// This function does not start counting milliseconds until the very first invocation.
///
/// # Returns
/// The number of elapsed milliseconds since the system started.
2021-02-17 19:08:03 +08:00
pub fn current_ms(&mut self) -> u32 {
2021-02-17 19:59:24 +08:00
if self.next_tick.is_none() {
self.next_tick = Some(Instant::now() + self.increment);
}
2021-02-17 19:08:03 +08:00
let now = Instant::now();
2021-02-17 19:59:24 +08:00
while now > self.next_tick.unwrap() {
*self.next_tick.as_mut().unwrap() += self.increment;
2021-02-17 19:08:03 +08:00
self.ticks += 1;
}
self.ticks
}
}