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
|
|
|
|
}
|
|
|
|
}
|