1use core::convert::Infallible;
4use embedded_hal::delay::blocking::{DelayMs, DelayUs};
5
6#[derive(Copy, Clone)]
11pub struct McycleDelay {
12 core_frequency: u32,
13}
14
15impl McycleDelay {
16 pub fn new(freq: u32) -> Self {
18 Self {
19 core_frequency: freq,
22 }
23 }
24
25 #[inline]
27 pub fn get_cycle_count() -> u64 {
28 riscv::register::mcycle::read64()
29 }
30
31 #[inline]
33 pub fn cycles_since(previous_cycle_count: u64) -> u64 {
34 riscv::register::mcycle::read64().wrapping_sub(previous_cycle_count)
35 }
36
37 #[inline]
39 pub fn delay_cycles(cycle_count: u64) {
40 let start_cycle_count = McycleDelay::get_cycle_count();
41
42 while McycleDelay::cycles_since(start_cycle_count) <= cycle_count {}
43 }
44}
45
46impl DelayUs<u64> for McycleDelay {
47 type Error = Infallible;
48
49 #[inline]
51 fn delay_us(&mut self, us: u64) -> Result<(), Infallible> {
52 McycleDelay::delay_cycles((us * (self.core_frequency as u64)) / 1_000_000);
53
54 Ok(())
55 }
56}
57
58impl DelayMs<u64> for McycleDelay {
59 type Error = Infallible;
60
61 #[inline]
63 fn delay_ms(&mut self, ms: u64) -> Result<(), Infallible> {
64 McycleDelay::delay_cycles((ms * (self.core_frequency as u64)) / 1000);
65
66 Ok(())
67 }
68}