1use crate::clock::Clocks;
4use e310x::CLINT;
5use embedded_hal::delay::DelayNs;
6use riscv::register::mip;
7
8#[derive(Default)]
10pub struct Delay;
11
12const TICKS_PER_SECOND: u64 = 32768;
13
14impl Delay {
15 pub fn new() -> Self {
17 Delay
18 }
19}
20
21impl DelayNs for Delay {
22 fn delay_ns(&mut self, ns: u32) {
23 let ticks = (ns as u64) * TICKS_PER_SECOND / 1_000_000_000;
24
25 let mtime = CLINT::mtimer().mtime;
26 let t = mtime.read() + ticks;
27 while mtime.read() < t {}
28 }
29}
30
31pub struct Sleep {
33 clock_freq: u32,
34}
35
36impl Sleep {
37 pub fn new(clocks: Clocks) -> Self {
39 Sleep {
40 clock_freq: clocks.lfclk().0,
41 }
42 }
43}
44
45impl DelayNs for Sleep {
46 fn delay_ns(&mut self, ns: u32) {
47 let ticks = (ns as u64) * u64::from(self.clock_freq) / 1_000_000_000;
48 let t = CLINT::mtimer().mtime.read() + ticks;
49
50 CLINT::mtimecmp0().write(t);
51
52 unsafe { CLINT::mtimer_enable() };
54
55 loop {
60 riscv::asm::wfi();
61
62 if mip::read().mtimer() {
64 break;
65 }
66 }
67
68 CLINT::mtimer_disable();
70 }
71}