sparreal_kernel/driver/
timer.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
use core::time::Duration;

use alloc::vec::Vec;
pub use driver_interface::timer::*;

use crate::{
    irq::{irq_set_handle, IrqHandle},
    struct_driver,
};

use super::CONTAINER;

struct_driver!(DriverTimer, BoxDriver);

#[allow(unused)]
pub fn list() -> Vec<DriverTimer> {
    let g = CONTAINER.timer.read();
    g.values().map(|one| one.clone()).collect()
}

impl DriverTimer {
    pub fn once_shot(&self, duration: Duration, callback: impl Fn() + 'static) {
        let mut timer = self.spec.write();
        let irq = timer.irq_num() as usize;
        let t = self.clone();

        irq_set_handle(irq, self.desc.id, move |_| {
            let mut timer = t.spec.write();
            if timer.read_irq_status() {
                callback();
                timer.set_irq_enable(false);
                IrqHandle::Handled
            } else {
                IrqHandle::None
            }
        });
        let ticks = timer.tick_hz() as f64 * duration.as_secs_f64();
        timer.set_interval(ticks as _);
        timer.set_enable(true);
        timer.set_irq_enable(true);
    }
}