1use core::cell::Cell;
8use kernel::hil::time::{self, Alarm, Ticks, Time};
9use kernel::utilities::cells::OptionalCell;
10use kernel::utilities::registers::interfaces::{Readable, Writeable};
11use kernel::utilities::registers::{register_bitfields, ReadOnly, ReadWrite, WriteOnly};
12use kernel::utilities::StaticRef;
13use kernel::ErrorCode;
14
15const RTC1_BASE: StaticRef<RtcRegisters> =
16 unsafe { StaticRef::new(0x40011000 as *const RtcRegisters) };
17
18#[repr(C)]
19struct RtcRegisters {
20 tasks_start: WriteOnly<u32, Task::Register>,
22 tasks_stop: WriteOnly<u32, Task::Register>,
24 tasks_clear: WriteOnly<u32, Task::Register>,
26 tasks_trigovrflw: WriteOnly<u32, Task::Register>,
28 _reserved0: [u8; 240],
29 events_tick: ReadWrite<u32, Event::Register>,
31 events_ovrflw: ReadWrite<u32, Event::Register>,
33 _reserved1: [u8; 56],
34 events_compare: [ReadWrite<u32, Event::Register>; 4],
36 _reserved2: [u8; 436],
37 intenset: ReadWrite<u32, Inte::Register>,
39 intenclr: ReadWrite<u32, Inte::Register>,
41 _reserved3: [u8; 52],
42 evten: ReadWrite<u32, Inte::Register>,
44 evtenset: ReadWrite<u32, Inte::Register>,
46 evtenclr: ReadWrite<u32, Inte::Register>,
48 _reserved4: [u8; 440],
49 counter: ReadOnly<u32, Counter::Register>,
51 prescaler: ReadWrite<u32, Prescaler::Register>,
54 _reserved5: [u8; 52],
55 cc: [ReadWrite<u32, Counter::Register>; 4],
57 _reserved6: [u8; 2732],
58 power: ReadWrite<u32>,
60}
61
62register_bitfields![u32,
63 Inte [
64 TICK 0,
66 OVRFLW 1,
68 COMPARE0 16,
70 COMPARE1 17,
72 COMPARE2 18,
74 COMPARE3 19
76 ],
77 Prescaler [
78 PRESCALER OFFSET(0) NUMBITS(12)
79 ],
80 Task [
81 ENABLE 0
82 ],
83 Event [
84 READY 0
85 ],
86 Counter [
87 VALUE OFFSET(0) NUMBITS(24)
88 ]
89];
90
91pub struct Rtc<'a> {
92 registers: StaticRef<RtcRegisters>,
93 overflow_client: OptionalCell<&'a dyn time::OverflowClient>,
94 alarm_client: OptionalCell<&'a dyn time::AlarmClient>,
95 enabled: Cell<bool>,
96}
97
98impl Rtc<'_> {
99 pub const fn new() -> Self {
100 Self {
101 registers: RTC1_BASE,
102 overflow_client: OptionalCell::empty(),
103 alarm_client: OptionalCell::empty(),
104 enabled: Cell::new(false),
105 }
106 }
107
108 pub fn handle_interrupt(&self) {
109 if self.registers.events_ovrflw.is_set(Event::READY) {
110 self.registers.events_ovrflw.write(Event::READY::CLEAR);
111 self.overflow_client.map(|client| client.overflow());
112 }
113 if self.registers.events_compare[0].is_set(Event::READY) {
114 self.registers.intenclr.write(Inte::COMPARE0::SET);
115 self.registers.events_compare[0].write(Event::READY::CLEAR);
116 self.alarm_client.map(|client| {
117 client.alarm();
118 });
119 }
120 }
121}
122
123impl Time for Rtc<'_> {
124 type Frequency = time::Freq32KHz;
125 type Ticks = time::Ticks24;
126
127 fn now(&self) -> Self::Ticks {
128 Self::Ticks::from(self.registers.counter.read(Counter::VALUE))
129 }
130}
131
132impl<'a> time::Counter<'a> for Rtc<'a> {
133 fn set_overflow_client(&self, client: &'a dyn time::OverflowClient) {
134 self.overflow_client.set(client);
135 self.registers.intenset.write(Inte::OVRFLW::SET);
136 }
137
138 fn start(&self) -> Result<(), ErrorCode> {
139 self.registers.prescaler.write(Prescaler::PRESCALER.val(0));
140 self.registers.tasks_start.write(Task::ENABLE::SET);
141 self.enabled.set(true);
142 Ok(())
143 }
144
145 fn stop(&self) -> Result<(), ErrorCode> {
146 self.registers.tasks_stop.write(Task::ENABLE::SET);
148 self.enabled.set(false);
149 Ok(())
150 }
151
152 fn reset(&self) -> Result<(), ErrorCode> {
153 self.registers.tasks_clear.write(Task::ENABLE::SET);
154 Ok(())
155 }
156
157 fn is_running(&self) -> bool {
158 self.enabled.get()
159 }
160}
161
162impl<'a> Alarm<'a> for Rtc<'a> {
163 fn set_alarm_client(&self, client: &'a dyn time::AlarmClient) {
164 self.alarm_client.set(client);
165 }
166
167 fn set_alarm(&self, reference: Self::Ticks, dt: Self::Ticks) {
168 const SYNC_TICS: u32 = 2;
169 let regs = &*self.registers;
170
171 let mut expire = reference.wrapping_add(dt);
172
173 let now = self.now();
174 let earliest_possible = now.wrapping_add(Self::Ticks::from(SYNC_TICS));
175
176 if !now.within_range(reference, expire) || expire.wrapping_sub(now).into_u32() <= SYNC_TICS
177 {
178 expire = earliest_possible;
179 }
180
181 regs.cc[0].write(Counter::VALUE.val(expire.into_u32()));
182 regs.events_compare[0].write(Event::READY::CLEAR);
183 regs.intenset.write(Inte::COMPARE0::SET);
184 }
185
186 fn get_alarm(&self) -> Self::Ticks {
187 Self::Ticks::from(self.registers.cc[0].read(Counter::VALUE))
188 }
189
190 fn disarm(&self) -> Result<(), ErrorCode> {
191 let regs = &*self.registers;
192 regs.intenclr.write(Inte::COMPARE0::SET);
193 regs.events_compare[0].write(Event::READY::CLEAR);
194 Ok(())
195 }
196
197 fn is_armed(&self) -> bool {
198 self.registers.evten.is_set(Inte::COMPARE0)
199 }
200
201 fn minimum_dt(&self) -> Self::Ticks {
202 Self::Ticks::from(10)
204 }
205}