1use cortexm0p::support::atomic;
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::{
11 register_bitfields, register_structs, ReadOnly, ReadWrite, WriteOnly,
12};
13use kernel::utilities::StaticRef;
14use kernel::ErrorCode;
15
16use crate::interrupts::TIMER_IRQ_0;
17
18register_structs! {
19 TimerRegisters {
30 (0x000 => timehw: WriteOnly<u32, TIMEHW::Register>),
33 (0x004 => timelw: WriteOnly<u32, TIMELW::Register>),
36 (0x008 => timehr: ReadOnly<u32, TIMEHR::Register>),
39 (0x00C => timelr: ReadOnly<u32, TIMELR::Register>),
41 (0x010 => alarm0: ReadWrite<u32, ALARM0::Register>),
46 (0x014 => alarm1: ReadWrite<u32, ALARM1::Register>),
51 (0x018 => alarm2: ReadWrite<u32, ALARM2::Register>),
56 (0x01C => alarm3: ReadWrite<u32, ALARM3::Register>),
61 (0x020 => armed: ReadWrite<u32>),
66 (0x024 => timerawh: ReadOnly<u32, TIMERAWH::Register>),
68 (0x028 => timerawl: ReadOnly<u32, TIMERAWL::Register>),
70 (0x02C => dbgpause: ReadWrite<u32, DBGPAUSE::Register>),
72 (0x030 => pause: ReadWrite<u32>),
74 (0x034 => intr: ReadWrite<u32, INTR::Register>),
76 (0x038 => inte: ReadWrite<u32, INTE::Register>),
78 (0x03C => intf: ReadWrite<u32, INTF::Register>),
80 (0x040 => ints: ReadWrite<u32, INTS::Register>),
82 (0x044 => @END),
83 }
84}
85register_bitfields![u32,
86TIMEHW [
87 VALUE OFFSET (0) NUMBITS (32) []
88],
89TIMELW [
90 VALUE OFFSET (0) NUMBITS (32) []
91],
92TIMEHR [
93 VALUE OFFSET (0) NUMBITS (32) []
94],
95TIMELR [
96 VALUE OFFSET (0) NUMBITS (32) []
97],
98ALARM0 [
99 VALUE OFFSET (0) NUMBITS (32) []
100],
101ALARM1 [
102 VALUE OFFSET (0) NUMBITS (32) []
103],
104ALARM2 [
105 VALUE OFFSET (0) NUMBITS (32) []
106],
107ALARM3 [
108 VALUE OFFSET (0) NUMBITS (32) []
109],
110ARMED [
111 ARMED OFFSET(0) NUMBITS(4) []
112],
113TIMERAWH [
114 VALUE OFFSET (0) NUMBITS (32) []
115],
116TIMERAWL [
117 VALUE OFFSET (0) NUMBITS (32) []
118],
119DBGPAUSE [
120 DBG1 OFFSET(2) NUMBITS(1) [],
122 DBG0 OFFSET(1) NUMBITS(1) []
124],
125PAUSE [
126
127 PAUSE OFFSET(0) NUMBITS(1) []
128],
129INTR [
130
131 ALARM_3 OFFSET(3) NUMBITS(1) [],
132
133 ALARM_2 OFFSET(2) NUMBITS(1) [],
134
135 ALARM_1 OFFSET(1) NUMBITS(1) [],
136
137 ALARM_0 OFFSET(0) NUMBITS(1) []
138],
139INTE [
140
141 ALARM_3 OFFSET(3) NUMBITS(1) [],
142
143 ALARM_2 OFFSET(2) NUMBITS(1) [],
144
145 ALARM_1 OFFSET(1) NUMBITS(1) [],
146
147 ALARM_0 OFFSET(0) NUMBITS(1) []
148],
149INTF [
150
151 ALARM_3 OFFSET(3) NUMBITS(1) [],
152
153 ALARM_2 OFFSET(2) NUMBITS(1) [],
154
155 ALARM_1 OFFSET(1) NUMBITS(1) [],
156
157 ALARM_0 OFFSET(0) NUMBITS(1) []
158],
159INTS [
160
161 ALARM_3 OFFSET(3) NUMBITS(1) [],
162
163 ALARM_2 OFFSET(2) NUMBITS(1) [],
164
165 ALARM_1 OFFSET(1) NUMBITS(1) [],
166
167 ALARM_0 OFFSET(0) NUMBITS(1) []
168]
169];
170const TIMER_BASE: StaticRef<TimerRegisters> =
171 unsafe { StaticRef::new(0x40054000 as *const TimerRegisters) };
172
173pub struct RPTimer<'a> {
174 registers: StaticRef<TimerRegisters>,
175 client: OptionalCell<&'a dyn hil::time::AlarmClient>,
176}
177
178impl<'a> RPTimer<'a> {
179 pub const fn new() -> RPTimer<'a> {
180 RPTimer {
181 registers: TIMER_BASE,
182 client: OptionalCell::empty(),
183 }
184 }
185
186 fn enable_interrupt(&self) {
187 self.registers.inte.modify(INTE::ALARM_0::SET);
188 }
189
190 fn disable_interrupt(&self) {
191 self.registers.inte.modify(INTE::ALARM_0::CLEAR);
192 }
193
194 fn enable_timer_interrupt(&self) {
195 unsafe {
203 atomic(|| {
204 let n = cortexm0p::nvic::Nvic::new(TIMER_IRQ_0);
205 n.enable();
206 })
207 }
208 }
209
210 fn disable_timer_interrupt(&self) {
211 unsafe {
215 cortexm0p::nvic::Nvic::new(TIMER_IRQ_0).disable();
216 }
217 }
218
219 pub fn handle_interrupt(&self) {
220 self.registers.intr.modify(INTR::ALARM_0::SET);
221 self.client.map(|client| client.alarm());
222 }
223}
224
225impl Time for RPTimer<'_> {
226 type Frequency = hil::time::Freq1MHz;
227 type Ticks = Ticks32;
228
229 fn now(&self) -> Self::Ticks {
230 Self::Ticks::from(self.registers.timerawl.get())
231 }
232}
233
234impl<'a> Alarm<'a> for RPTimer<'a> {
235 fn set_alarm_client(&self, client: &'a dyn hil::time::AlarmClient) {
236 self.client.set(client);
237 }
238
239 fn set_alarm(&self, reference: Self::Ticks, dt: Self::Ticks) {
240 let mut expire = reference.wrapping_add(dt);
241 let now = self.now();
242 if !now.within_range(reference, expire) {
243 expire = now;
244 }
245
246 if expire.wrapping_sub(now) < self.minimum_dt() {
247 expire = now.wrapping_add(self.minimum_dt());
248 }
249
250 self.registers.alarm0.set(expire.into_u32());
251 self.enable_timer_interrupt();
252 self.enable_interrupt();
253 }
254
255 fn get_alarm(&self) -> Self::Ticks {
256 Self::Ticks::from(self.registers.alarm0.get())
257 }
258
259 fn disarm(&self) -> Result<(), ErrorCode> {
260 self.registers.armed.set(1);
261 unsafe {
262 atomic(|| {
263 cortexm0p::nvic::Nvic::new(TIMER_IRQ_0).clear_pending();
265 });
266 }
267 self.disable_interrupt();
268 self.disable_timer_interrupt();
269 Ok(())
270 }
271
272 fn is_armed(&self) -> bool {
273 let armed = self.registers.armed.get() & 0b0001;
274 if armed == 1 {
275 return true;
276 }
277 false
278 }
279
280 fn minimum_dt(&self) -> Self::Ticks {
281 Self::Ticks::from(50)
282 }
283}