cortex_ar/generic_timer/mod.rs
1//! Support for Arm Generic Timer
2//!
3//! See Chapter G6: The Generic Timer in AArch32 State in [ARM Architecture
4//! Reference Manual v8][armv8].
5//!
6//! The Generic Timer existed in Armv7-A as well, but not in Armv7-R.
7//!
8//! [armv8]: https://developer.arm.com/documentation/ddi0487/latest/
9
10mod el2;
11pub use el2::{El2HypPhysicalTimer, El2PhysicalTimer, El2VirtualTimer};
12
13mod el1;
14pub use el1::{El1PhysicalTimer, El1VirtualTimer};
15
16mod el0;
17pub use el0::{El0PhysicalTimer, El0VirtualTimer};
18
19/// Describes either a Physical or Virtual timer
20pub trait GenericTimer {
21 /// Get the timer frequency
22 fn frequency_hz(&self) -> u32;
23
24 /// Get the current counter value.
25 ///
26 /// This is a 64-bit value that goes up. It can be used to measure the
27 /// passing of time.
28 ///
29 /// Note that speculative reads are allowed and reads may occur out of
30 /// order. Add ISB and DSB fences before/after this call as required.
31 fn counter(&self) -> u64;
32
33 /// Get the counter compare value.
34 fn counter_compare(&self) -> u64;
35
36 /// Set the counter compare value.
37 ///
38 /// The timer condition is met when the `counter - compare_value >= 0`. This
39 /// therefore operates as a *count-up* timer.
40 fn counter_compare_set(&mut self, value: u64);
41
42 /// Get the current value of the countdown timer.
43 fn countdown(&self) -> u32;
44
45 /// Set the value of the count-down timer.
46 ///
47 /// Sets a value which is decremented on every counter tick. When it reaches
48 /// zero, the timer fires.
49 fn countdown_set(&mut self, duration_ticks: u32);
50
51 /// This is timer enabled?
52 fn enabled(&self) -> bool;
53
54 /// Enable/disable this timer
55 fn enable(&self, enabled: bool);
56
57 /// Is this timer's interrupt masked?
58 fn interrupt_masked(&self) -> bool;
59
60 /// Mask (or unmask) this timer's interrupt.
61 fn interrupt_mask(&mut self, mask: bool);
62
63 /// Has this timer's interrupt fired?
64 fn interrupt_status(&self) -> bool;
65
66 /// Wait for some number of clock ticks
67 fn delay_ticks(&mut self, ticks: u32) {
68 let enabled = self.enabled();
69 self.enable(true);
70 self.countdown_set(ticks);
71 while !self.interrupt_status() {
72 core::hint::spin_loop();
73 }
74 if !enabled {
75 self.enable(false);
76 }
77 }
78
79 /// Delay for some number of milliseconds
80 fn delay_ms(&mut self, ms: u32) {
81 // can't overflow a u64 if you multiply two u32s together
82 let mut ticks: u64 = u64::from(self.frequency_hz()).wrapping_mul(u64::from(ms)) / 1000;
83 while ticks >= 0xFFFF_FFFF {
84 self.delay_ticks(0xFFFF_FFFF);
85 ticks -= 0xFFFF_FFFF;
86 }
87 self.delay_ticks(ticks as u32);
88 }
89
90 /// Delay for some number of microseconds
91 fn delay_us(&mut self, us: u32) {
92 // can't overflow a u64 if you multiply two u32s together
93 let mut ticks: u64 = u64::from(self.frequency_hz()).wrapping_mul(u64::from(us)) / 1_000_000;
94 while ticks >= 0xFFFF_FFFF {
95 self.delay_ticks(0xFFFF_FFFF);
96 ticks -= 0xFFFF_FFFF;
97 }
98 self.delay_ticks(ticks as u32);
99 }
100}
101
102/// Describes the configuration for an Edvent
103#[derive(Debug, Clone, PartialEq, Eq)]
104pub struct EventConfig {
105 /// Controls which transition of the CNTVCT trigger bit, defined by EVNTI,
106 /// generates an event, when the event stream is enabled.
107 pub evntdir: EventDir,
108 /// How often does the event fire
109 pub rate: EventRate,
110}
111
112/// Describes the direction of an Event
113#[derive(Debug, Copy, Clone, PartialEq, Eq)]
114pub enum EventDir {
115 /// Event fires on a 1 -> 0 transition
116 HighLow,
117 /// Event fires on a 0 -> 1 transition
118 LowHigh,
119}
120
121/// How often does the event fire?
122#[derive(Debug, Copy, Clone, PartialEq, Eq)]
123#[repr(u8)]
124pub enum EventRate {
125 /// Fire every 1 ticks
126 _1 = 0,
127 /// Fire every 2 ticks
128 _2 = 1,
129 /// Fire every 4 ticks
130 _4 = 2,
131 /// Fire every 8 ticks
132 _8 = 3,
133 /// Fire every 16 ticks
134 _16 = 4,
135 /// Fire every 32 ticks
136 _32 = 5,
137 /// Fire every 64 ticks
138 _64 = 6,
139 /// Fire every 128 ticks
140 _128 = 7,
141 /// Fire every 256 ticks
142 _256 = 8,
143 /// Fire every 512 ticks
144 _512 = 9,
145 /// Fire every 1024 ticks
146 _1024 = 10,
147 /// Fire every 2048 ticks
148 _2048 = 11,
149 /// Fire every 4096 ticks
150 _4096 = 12,
151 /// Fire every 8192 ticks
152 _8192 = 13,
153 /// Fire every 16384 ticks
154 _16384 = 14,
155 /// Fire every 32768 ticks
156 _32768 = 15,
157}