1use cortexm33::support::with_interrupts_disabled;
6use kernel::hil;
7use kernel::hil::time::{Alarm, Ticks, Ticks32, Time};
8use kernel::utilities::cells::OptionalCell;
9use kernel::utilities::registers::interfaces::{ReadWriteable, Readable, Writeable};
10use kernel::utilities::registers::{register_bitfields, register_structs, ReadWrite};
11use kernel::utilities::StaticRef;
12use kernel::ErrorCode;
13
14use crate::interrupts::TIMER0_IRQ_0;
15
16register_structs! {
17 TimerRegisters {
19 (0x000 => timehw: ReadWrite<u32>),
21 (0x004 => timelw: ReadWrite<u32>),
23 (0x008 => timehr: ReadWrite<u32>),
25 (0x00C => timelr: ReadWrite<u32>),
27 (0x010 => alarm0: ReadWrite<u32>),
29 (0x014 => alarm1: ReadWrite<u32>),
31 (0x018 => alarm2: ReadWrite<u32>),
33 (0x01C => alarm3: ReadWrite<u32>),
35 (0x020 => armed: ReadWrite<u32>),
37 (0x024 => timerawh: ReadWrite<u32>),
39 (0x028 => timerawl: ReadWrite<u32>),
41 (0x02C => dbgpause: ReadWrite<u32, DBGPAUSE::Register>),
43 (0x030 => pause: ReadWrite<u32>),
45 (0x034 => locked: ReadWrite<u32>),
47 (0x038 => source: ReadWrite<u32>),
49 (0x03C => intr: ReadWrite<u32, INTR::Register>),
51 (0x040 => inte: ReadWrite<u32, INTE::Register>),
53 (0x044 => intf: ReadWrite<u32, INTF::Register>),
55 (0x048 => ints: ReadWrite<u32, INTS::Register>),
57 (0x04C => @END),
58 }
59}
60register_bitfields![u32,
61TIMEHW [
62
63 TIMEHW OFFSET(0) NUMBITS(32) []
64],
65TIMELW [
66
67 TIMELW OFFSET(0) NUMBITS(32) []
68],
69TIMEHR [
70
71 TIMEHR OFFSET(0) NUMBITS(32) []
72],
73TIMELR [
74
75 TIMELR OFFSET(0) NUMBITS(32) []
76],
77ALARM0 [
78
79 ALARM0 OFFSET(0) NUMBITS(32) []
80],
81ALARM1 [
82
83 ALARM1 OFFSET(0) NUMBITS(32) []
84],
85ALARM2 [
86
87 ALARM2 OFFSET(0) NUMBITS(32) []
88],
89ALARM3 [
90
91 ALARM3 OFFSET(0) NUMBITS(32) []
92],
93ARMED [
94
95 ARMED OFFSET(0) NUMBITS(4) []
96],
97TIMERAWH [
98
99 TIMERAWH OFFSET(0) NUMBITS(32) []
100],
101TIMERAWL [
102
103 TIMERAWL OFFSET(0) NUMBITS(32) []
104],
105DBGPAUSE [
106 DBG1 OFFSET(2) NUMBITS(1) [],
108 DBG0 OFFSET(1) NUMBITS(1) []
110],
111PAUSE [
112
113 PAUSE OFFSET(0) NUMBITS(1) []
114],
115LOCKED [
116
117 LOCKED OFFSET(0) NUMBITS(1) []
118],
119SOURCE [
120
121 CLK_SYS OFFSET(0) NUMBITS(1) [
122
123 TICK = 0
124 ]
125],
126INTR [
127
128 ALARM_3 OFFSET(3) NUMBITS(1) [],
129
130 ALARM_2 OFFSET(2) NUMBITS(1) [],
131
132 ALARM_1 OFFSET(1) NUMBITS(1) [],
133
134 ALARM_0 OFFSET(0) NUMBITS(1) []
135],
136INTE [
137
138 ALARM_3 OFFSET(3) NUMBITS(1) [],
139
140 ALARM_2 OFFSET(2) NUMBITS(1) [],
141
142 ALARM_1 OFFSET(1) NUMBITS(1) [],
143
144 ALARM_0 OFFSET(0) NUMBITS(1) []
145],
146INTF [
147
148 ALARM_3 OFFSET(3) NUMBITS(1) [],
149
150 ALARM_2 OFFSET(2) NUMBITS(1) [],
151
152 ALARM_1 OFFSET(1) NUMBITS(1) [],
153
154 ALARM_0 OFFSET(0) NUMBITS(1) []
155],
156INTS [
157
158 ALARM_3 OFFSET(3) NUMBITS(1) [],
159
160 ALARM_2 OFFSET(2) NUMBITS(1) [],
161
162 ALARM_1 OFFSET(1) NUMBITS(1) [],
163
164 ALARM_0 OFFSET(0) NUMBITS(1) []
165]
166];
167
168const TIMER0_BASE: StaticRef<TimerRegisters> =
169 unsafe { StaticRef::new(0x400B0000 as *const TimerRegisters) };
170
171pub struct RPTimer<'a> {
172 registers: StaticRef<TimerRegisters>,
173 client: OptionalCell<&'a dyn hil::time::AlarmClient>,
174}
175
176impl<'a> RPTimer<'a> {
177 pub const fn new_timer0() -> RPTimer<'a> {
178 RPTimer {
179 registers: TIMER0_BASE,
180 client: OptionalCell::empty(),
181 }
182 }
183
184 fn enable_interrupt0(&self) {
185 self.registers.inte.modify(INTE::ALARM_0::SET);
186 }
187
188 fn disable_interrupt0(&self) {
189 self.registers.inte.modify(INTE::ALARM_0::CLEAR);
190 }
191
192 fn enable_timer_interrupt0(&self) {
193 unsafe {
201 with_interrupts_disabled(|| {
202 cortexm33::nvic::Nvic::new(TIMER0_IRQ_0).enable();
203 })
204 }
205 }
206
207 fn disable_timer_interrupt0(&self) {
208 unsafe {
212 cortexm33::nvic::Nvic::new(TIMER0_IRQ_0).disable();
213 }
214 }
215
216 pub fn handle_interrupt(&self) {
217 self.registers.intr.modify(INTR::ALARM_0::SET);
218 self.client.map(|client| client.alarm());
219 }
220}
221
222impl Time for RPTimer<'_> {
223 type Frequency = hil::time::Freq1MHz;
224 type Ticks = Ticks32;
225
226 fn now(&self) -> Self::Ticks {
227 Self::Ticks::from(self.registers.timerawl.get())
228 }
229}
230
231impl<'a> Alarm<'a> for RPTimer<'a> {
232 fn set_alarm_client(&self, client: &'a dyn hil::time::AlarmClient) {
233 self.client.set(client);
234 }
235
236 fn set_alarm(&self, reference: Self::Ticks, dt: Self::Ticks) {
237 let mut expire = reference.wrapping_add(dt);
238 let now = self.now();
239 if !now.within_range(reference, expire) {
240 expire = now;
241 }
242
243 if expire.wrapping_sub(now) < self.minimum_dt() {
244 expire = now.wrapping_add(self.minimum_dt());
245 }
246
247 self.registers.alarm0.set(expire.into_u32());
248 self.enable_timer_interrupt0();
249 self.enable_interrupt0();
250 }
251
252 fn get_alarm(&self) -> Self::Ticks {
253 Self::Ticks::from(self.registers.alarm0.get())
254 }
255
256 fn disarm(&self) -> Result<(), ErrorCode> {
257 self.registers.armed.set(1);
258 unsafe {
259 with_interrupts_disabled(|| {
260 cortexm33::nvic::Nvic::new(TIMER0_IRQ_0).clear_pending();
262 });
263 }
264 self.disable_interrupt0();
265 self.disable_timer_interrupt0();
266 Ok(())
267 }
268
269 fn is_armed(&self) -> bool {
270 let armed = self.registers.armed.get() & 0b0001;
271 if armed == 1 {
272 return true;
273 }
274 false
275 }
276
277 fn minimum_dt(&self) -> Self::Ticks {
278 Self::Ticks::from(50)
279 }
280}