mod el2;
pub use el2::{El2HypPhysicalTimer, El2PhysicalTimer, El2VirtualTimer};
mod el1;
pub use el1::{El1PhysicalTimer, El1VirtualTimer};
mod el0;
pub use el0::{El0PhysicalTimer, El0VirtualTimer};
pub trait GenericTimer {
fn frequency_hz(&self) -> u32;
fn counter(&self) -> u64;
fn counter_compare(&self) -> u64;
fn counter_compare_set(&mut self, value: u64);
fn countdown(&self) -> u32;
fn countdown_set(&mut self, duration_ticks: u32);
fn enabled(&self) -> bool;
fn enable(&self, enabled: bool);
fn interrupt_masked(&self) -> bool;
fn interrupt_mask(&mut self, mask: bool);
fn interrupt_status(&self) -> bool;
fn delay_ticks(&mut self, ticks: u32) {
let enabled = self.enabled();
self.enable(true);
self.countdown_set(ticks);
while !self.interrupt_status() {
core::hint::spin_loop();
}
if !enabled {
self.enable(false);
}
}
fn delay_ms(&mut self, ms: u32) {
let mut ticks: u64 = u64::from(self.frequency_hz()).wrapping_mul(u64::from(ms)) / 1000;
while ticks >= 0xFFFF_FFFF {
self.delay_ticks(0xFFFF_FFFF);
ticks -= 0xFFFF_FFFF;
}
self.delay_ticks(ticks as u32);
}
fn delay_us(&mut self, us: u32) {
let mut ticks: u64 = u64::from(self.frequency_hz()).wrapping_mul(u64::from(us)) / 1_000_000;
while ticks >= 0xFFFF_FFFF {
self.delay_ticks(0xFFFF_FFFF);
ticks -= 0xFFFF_FFFF;
}
self.delay_ticks(ticks as u32);
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct EventConfig {
pub evntdir: EventDir,
pub rate: EventRate,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum EventDir {
HighLow,
LowHigh,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[repr(u8)]
pub enum EventRate {
_1 = 0,
_2 = 1,
_4 = 2,
_8 = 3,
_16 = 4,
_32 = 5,
_64 = 6,
_128 = 7,
_256 = 8,
_512 = 9,
_1024 = 10,
_2048 = 11,
_4096 = 12,
_8192 = 13,
_16384 = 14,
_32768 = 15,
}