1use crate::pm::{self, PBDClock};
12use kernel::hil::time::{self, Ticks};
13use kernel::hil::Controller;
14use kernel::utilities::cells::OptionalCell;
15use kernel::utilities::registers::interfaces::{ReadWriteable, Readable, Writeable};
16use kernel::utilities::registers::{register_bitfields, ReadOnly, ReadWrite, WriteOnly};
17use kernel::utilities::StaticRef;
18use kernel::ErrorCode;
19
20const ALARM0_SYNC_TICS: u32 = 8;
35
36#[repr(C)]
37struct AstRegisters {
38 cr: ReadWrite<u32, Control::Register>,
39 cv: ReadWrite<u32, Value::Register>,
40 sr: ReadOnly<u32, Status::Register>,
41 scr: WriteOnly<u32, Interrupt::Register>,
42 ier: WriteOnly<u32, Interrupt::Register>,
43 idr: WriteOnly<u32, Interrupt::Register>,
44 imr: ReadOnly<u32, Interrupt::Register>,
45 wer: ReadWrite<u32, Event::Register>,
46 ar0: ReadWrite<u32, Value::Register>,
48 ar1: ReadWrite<u32, Value::Register>,
49 _reserved0: [u32; 2],
50 pir0: ReadWrite<u32, PeriodicInterval::Register>,
51 pir1: ReadWrite<u32, PeriodicInterval::Register>,
52 _reserved1: [u32; 2],
53 clock: ReadWrite<u32, ClockControl::Register>,
55 dtr: ReadWrite<u32, DigitalTuner::Register>,
56 eve: WriteOnly<u32, Event::Register>,
57 evd: WriteOnly<u32, Event::Register>,
58 evm: ReadOnly<u32, Event::Register>,
59 calv: ReadWrite<u32, Calendar::Register>, }
61
62register_bitfields![u32,
63 Control [
64 PSEL OFFSET(16) NUMBITS(5) [],
66 CA1 OFFSET(9) NUMBITS(1) [
68 NoClearCounter = 0,
69 ClearCounter = 1
70 ],
71 CA0 OFFSET(8) NUMBITS(1) [
73 NoClearCounter = 0,
74 ClearCounter = 1
75 ],
76 CAL OFFSET(2) NUMBITS(1) [
78 CounterMode = 0,
79 CalendarMode = 1
80 ],
81 PCLR OFFSET(1) NUMBITS(1) [],
83 EN OFFSET(0) NUMBITS(1) [
85 Disable = 0,
86 Enable = 1
87 ]
88 ],
89
90 Value [
91 VALUE OFFSET(0) NUMBITS(32) []
92 ],
93
94 Status [
95 CLKRDY 29,
97 CLKBUSY 28,
99 READY 25,
101 BUSY 24,
103 PER0 16,
105 ALARM0 8,
107 OVF 0
109 ],
110
111 Interrupt [
112 CLKRDY 29,
114 READY 25,
116 PER0 16,
118 ALARM0 8,
120 OVF 0
122 ],
123
124 Event [
125 PER0 16,
127 ALARM0 8,
129 OVF 0
131 ],
132
133 PeriodicInterval [
134 INSEL OFFSET(0) NUMBITS(5) []
136 ],
137
138 ClockControl [
139 CSSEL OFFSET(8) NUMBITS(3) [
141 RCSYS = 0,
142 OSC32 = 1,
143 APBClock = 2,
144 GCLK = 3,
145 Clk1k = 4
146 ],
147 CEN OFFSET(0) NUMBITS(1) [
149 Disable = 0,
150 Enable = 1
151 ]
152 ],
153
154 DigitalTuner [
155 VALUE OFFSET(8) NUMBITS(8) [],
156 ADD OFFSET(5) NUMBITS(1) [],
157 EXP OFFSET(0) NUMBITS(5) []
158 ],
159
160 Calendar [
161 YEAR OFFSET(26) NUMBITS(6) [],
162 MONTH OFFSET(22) NUMBITS(4) [],
163 DAY OFFSET(17) NUMBITS(5) [],
164 HOUR OFFSET(12) NUMBITS(5) [],
165 MIN OFFSET( 6) NUMBITS(6) [],
166 SEC OFFSET( 0) NUMBITS(6) []
167 ]
168];
169
170const AST_ADDRESS: StaticRef<AstRegisters> =
171 unsafe { StaticRef::new(0x400F0800 as *const AstRegisters) };
172
173pub struct Ast<'a> {
174 registers: StaticRef<AstRegisters>,
175 callback: OptionalCell<&'a dyn time::AlarmClient>,
176}
177
178impl Ast<'_> {
179 pub const fn new() -> Self {
180 Self {
181 registers: AST_ADDRESS,
182 callback: OptionalCell::empty(),
183 }
184 }
185}
186
187impl Controller for Ast<'_> {
188 type Config = &'static dyn time::AlarmClient;
189
190 fn configure(&self, client: Self::Config) {
191 self.callback.set(client);
192
193 pm::enable_clock(pm::Clock::PBD(PBDClock::AST));
194 self.select_clock(Clock::ClockOsc32);
195 self.disable();
196 self.disable_alarm_irq();
197 self.set_prescalar(0); self.enable_alarm_wake();
199
200 self.clear_alarm();
201 }
202}
203
204#[repr(usize)]
205#[allow(dead_code)]
206enum Clock {
207 ClockRCSys = 0,
208 ClockOsc32 = 1,
209 ClockAPB = 2,
210 ClockGclk2 = 3,
211 Clock1K = 4,
212}
213
214impl Ast<'_> {
215 fn clock_busy(&self) -> bool {
216 self.registers.sr.is_set(Status::CLKBUSY)
217 }
218
219 fn busy(&self) -> bool {
220 self.registers.sr.is_set(Status::BUSY)
221 }
222
223 fn clear_alarm(&self) {
226 while self.busy() {}
227 self.registers.scr.write(Interrupt::ALARM0::SET);
228 while self.busy() {}
229 }
230
231 fn select_clock(&self, clock: Clock) {
233 while self.clock_busy() {}
235 self.registers.clock.modify(ClockControl::CEN::CLEAR);
236 while self.clock_busy() {}
237
238 self.registers
240 .clock
241 .write(ClockControl::CSSEL.val(clock as u32));
242 while self.clock_busy() {}
243
244 self.registers.clock.modify(ClockControl::CEN::SET);
246 while self.clock_busy() {}
247 }
248
249 fn enable(&self) {
251 while self.busy() {}
252 self.registers.cr.modify(Control::EN::SET);
253 while self.busy() {}
254 }
255
256 fn disable(&self) {
258 while self.busy() {}
259 self.registers.cr.modify(Control::EN::CLEAR);
260 while self.busy() {}
261 }
262
263 fn is_enabled(&self) -> bool {
264 let regs: &AstRegisters = &self.registers;
265 while self.busy() {}
266 regs.cr.is_set(Control::EN)
267 }
268
269 fn is_alarm_enabled(&self) -> bool {
271 while self.busy() {}
272 self.registers.sr.is_set(Status::ALARM0)
273 }
274
275 fn set_prescalar(&self, val: u8) {
276 while self.busy() {}
277 self.registers.cr.modify(Control::PSEL.val(val as u32));
278 while self.busy() {}
279 }
280
281 fn enable_alarm_irq(&self) {
282 self.registers.ier.write(Interrupt::ALARM0::SET);
283 }
284
285 fn disable_alarm_irq(&self) {
286 self.registers.idr.write(Interrupt::ALARM0::SET);
287 }
288
289 fn enable_alarm_wake(&self) {
290 while self.busy() {}
291 self.registers.wer.modify(Event::ALARM0::SET);
292 while self.busy() {}
293 }
294
295 fn get_counter(&self) -> u32 {
296 while self.busy() {}
297 self.registers.cv.read(Value::VALUE)
298 }
299
300 fn set_counter(&self, val: u32) {
301 let regs: &AstRegisters = &self.registers;
302 while self.busy() {}
303 regs.cv.set(val);
304 }
305
306 pub fn handle_interrupt(&self) {
307 self.clear_alarm();
308 self.callback.map(|cb| {
309 cb.alarm();
310 });
311 }
312}
313
314impl time::Time for Ast<'_> {
315 type Frequency = time::Freq16KHz;
316 type Ticks = time::Ticks32;
317
318 fn now(&self) -> Self::Ticks {
319 Self::Ticks::from(self.get_counter())
320 }
321}
322
323impl<'a> time::Counter<'a> for Ast<'a> {
324 fn set_overflow_client(&self, _client: &'a dyn time::OverflowClient) {}
325
326 fn start(&self) -> Result<(), ErrorCode> {
327 self.enable();
328 Ok(())
329 }
330
331 fn stop(&self) -> Result<(), ErrorCode> {
332 self.disable();
333 Ok(())
334 }
335
336 fn reset(&self) -> Result<(), ErrorCode> {
337 self.set_counter(0);
338 Ok(())
339 }
340
341 fn is_running(&self) -> bool {
342 self.is_enabled()
343 }
344}
345
346impl<'a> time::Alarm<'a> for Ast<'a> {
347 fn set_alarm_client(&self, client: &'a dyn time::AlarmClient) {
348 self.callback.set(client);
349 }
350
351 fn set_alarm(&self, reference: Self::Ticks, dt: Self::Ticks) {
352 let now = Self::Ticks::from(self.get_counter());
353 let mut expire = reference.wrapping_add(dt);
354 if !now.within_range(reference, expire) {
355 expire = now;
358 }
359
360 if expire.wrapping_sub(now).into_u32() <= ALARM0_SYNC_TICS {
363 expire = now.wrapping_add(Self::Ticks::from(ALARM0_SYNC_TICS));
364 }
365
366 self.clear_alarm();
368
369 while self.busy() {}
370 self.registers
371 .ar0
372 .write(Value::VALUE.val(expire.into_u32()));
373
374 while self.busy() {}
375 self.enable_alarm_irq();
376 self.enable();
377 }
378
379 fn get_alarm(&self) -> Self::Ticks {
380 while self.busy() {}
381 Self::Ticks::from(self.registers.ar0.read(Value::VALUE))
382 }
383
384 fn disarm(&self) -> Result<(), ErrorCode> {
385 self.disable_alarm_irq();
388 self.clear_alarm();
389 Ok(())
390 }
391
392 fn is_armed(&self) -> bool {
393 self.is_alarm_enabled()
394 }
395
396 fn minimum_dt(&self) -> Self::Ticks {
397 Self::Ticks::from(ALARM0_SYNC_TICS)
398 }
399}