1use cortexm4f::support::atomic;
6use kernel::hil::time::{
7 Alarm, AlarmClient, Counter, Freq16KHz, OverflowClient, Ticks, Ticks32, Time,
8};
9use kernel::platform::chip::ClockInterface;
10use kernel::utilities::cells::OptionalCell;
11use kernel::utilities::registers::interfaces::{ReadWriteable, Readable, Writeable};
12use kernel::utilities::registers::{register_bitfields, ReadWrite, WriteOnly};
13use kernel::utilities::StaticRef;
14use kernel::ErrorCode;
15
16use crate::nvic;
17use crate::rcc;
18
19#[repr(C)]
21struct Tim2Registers {
22 cr1: ReadWrite<u32, CR1::Register>,
24 cr2: ReadWrite<u32, CR2::Register>,
26 smcr: ReadWrite<u32, SMCR::Register>,
28 dier: ReadWrite<u32, DIER::Register>,
30 sr: ReadWrite<u32, SR::Register>,
32 egr: WriteOnly<u32, EGR::Register>,
34 ccmr1_output: ReadWrite<u32, CCMR1_Output::Register>,
36 ccmr2_output: ReadWrite<u32, CCMR2_Output::Register>,
38 ccer: ReadWrite<u32, CCER::Register>,
40 cnt: ReadWrite<u32, CNT::Register>,
42 psc: ReadWrite<u32>,
44 arr: ReadWrite<u32, ARR::Register>,
46 _reserved0: [u8; 4],
47 ccr1: ReadWrite<u32, CCR1::Register>,
49 ccr2: ReadWrite<u32, CCR2::Register>,
51 ccr3: ReadWrite<u32, CCR3::Register>,
53 ccr4: ReadWrite<u32, CCR4::Register>,
55 _reserved1: [u8; 4],
56 dcr: ReadWrite<u32, DCR::Register>,
58 dmar: ReadWrite<u32>,
60 or_: ReadWrite<u32>,
62}
63
64register_bitfields![u32,
65 CR1 [
66 UIFREMAP OFFSET(11) NUMBITS(1) [],
68 CKD OFFSET(8) NUMBITS(2) [],
70 ARPE OFFSET(7) NUMBITS(1) [],
72 CMS OFFSET(5) NUMBITS(2) [],
74 DIR OFFSET(4) NUMBITS(1) [],
76 OPM OFFSET(3) NUMBITS(1) [],
78 URS OFFSET(2) NUMBITS(1) [],
80 UDIS OFFSET(1) NUMBITS(1) [],
82 CEN OFFSET(0) NUMBITS(1) []
84 ],
85 CR2 [
86 TI1S OFFSET(7) NUMBITS(1) [],
88 MMS OFFSET(4) NUMBITS(3) [],
90 CCDS OFFSET(3) NUMBITS(1) []
92 ],
93 SMCR [
94 ETP OFFSET(15) NUMBITS(1) [],
96 ECE OFFSET(14) NUMBITS(1) [],
98 ETPS OFFSET(12) NUMBITS(2) [],
100 ETF OFFSET(8) NUMBITS(4) [],
102 MSM OFFSET(7) NUMBITS(1) [],
104 TS OFFSET(4) NUMBITS(3) [],
106 SMS OFFSET(0) NUMBITS(3) []
108 ],
109 DIER [
110 TDE OFFSET(14) NUMBITS(1) [],
112 CC4DE OFFSET(12) NUMBITS(1) [],
114 CC3DE OFFSET(11) NUMBITS(1) [],
116 CC2DE OFFSET(10) NUMBITS(1) [],
118 CC1DE OFFSET(9) NUMBITS(1) [],
120 UDE OFFSET(8) NUMBITS(1) [],
122 TIE OFFSET(6) NUMBITS(1) [],
124 CC4IE OFFSET(4) NUMBITS(1) [],
126 CC3IE OFFSET(3) NUMBITS(1) [],
128 CC2IE OFFSET(2) NUMBITS(1) [],
130 CC1IE OFFSET(1) NUMBITS(1) [],
132 UIE OFFSET(0) NUMBITS(1) []
134 ],
135 SR [
136 CC4OF OFFSET(12) NUMBITS(1) [],
138 CC3OF OFFSET(11) NUMBITS(1) [],
140 CC2OF OFFSET(10) NUMBITS(1) [],
142 CC1OF OFFSET(9) NUMBITS(1) [],
144 TIF OFFSET(6) NUMBITS(1) [],
146 CC4IF OFFSET(4) NUMBITS(1) [],
148 CC3IF OFFSET(3) NUMBITS(1) [],
150 CC2IF OFFSET(2) NUMBITS(1) [],
152 CC1IF OFFSET(1) NUMBITS(1) [],
154 UIF OFFSET(0) NUMBITS(1) []
156 ],
157 EGR [
158 TG OFFSET(6) NUMBITS(1) [],
160 CC4G OFFSET(4) NUMBITS(1) [],
162 CC3G OFFSET(3) NUMBITS(1) [],
164 CC2G OFFSET(2) NUMBITS(1) [],
166 CC1G OFFSET(1) NUMBITS(1) [],
168 UG OFFSET(0) NUMBITS(1) []
170 ],
171 CCMR1_Output [
172 OC2CE OFFSET(15) NUMBITS(1) [],
174 OC2M OFFSET(12) NUMBITS(3) [],
176 OC2PE OFFSET(11) NUMBITS(1) [],
178 OC2FE OFFSET(10) NUMBITS(1) [],
180 CC2S OFFSET(8) NUMBITS(2) [],
182 OC1CE OFFSET(7) NUMBITS(1) [],
184 OC1M OFFSET(4) NUMBITS(3) [],
186 OC1PE OFFSET(3) NUMBITS(1) [],
188 OC1FE OFFSET(2) NUMBITS(1) [],
190 CC1S OFFSET(0) NUMBITS(2) []
192 ],
193 CCMR1_Input [
194 IC2F OFFSET(12) NUMBITS(4) [],
196 IC2PCS OFFSET(10) NUMBITS(2) [],
198 CC2S OFFSET(8) NUMBITS(2) [],
200 IC1F OFFSET(4) NUMBITS(4) [],
202 ICPCS OFFSET(2) NUMBITS(2) [],
204 CC1S OFFSET(0) NUMBITS(2) []
206 ],
207 CCMR2_Output [
208 O24CE OFFSET(15) NUMBITS(1) [],
210 OC4M OFFSET(12) NUMBITS(3) [],
212 OC4PE OFFSET(11) NUMBITS(1) [],
214 OC4FE OFFSET(10) NUMBITS(1) [],
216 CC4S OFFSET(8) NUMBITS(2) [],
218 OC3CE OFFSET(7) NUMBITS(1) [],
220 OC3M OFFSET(4) NUMBITS(3) [],
222 OC3PE OFFSET(3) NUMBITS(1) [],
224 OC3FE OFFSET(2) NUMBITS(1) [],
226 CC3S OFFSET(0) NUMBITS(2) []
228 ],
229 CCMR2_Input [
230 IC4F OFFSET(12) NUMBITS(4) [],
232 IC4PSC OFFSET(10) NUMBITS(2) [],
234 CC4S OFFSET(8) NUMBITS(2) [],
236 IC3F OFFSET(4) NUMBITS(4) [],
238 IC3PSC OFFSET(2) NUMBITS(2) [],
240 CC3S OFFSET(0) NUMBITS(2) []
242 ],
243 CCER [
244 CC4NP OFFSET(15) NUMBITS(1) [],
246 CC4P OFFSET(13) NUMBITS(1) [],
248 CC4E OFFSET(12) NUMBITS(1) [],
250 CC3NP OFFSET(11) NUMBITS(1) [],
252 CC3P OFFSET(9) NUMBITS(1) [],
254 CC3E OFFSET(8) NUMBITS(1) [],
256 CC2NP OFFSET(7) NUMBITS(1) [],
258 CC2P OFFSET(5) NUMBITS(1) [],
260 CC2E OFFSET(4) NUMBITS(1) [],
262 CC1NP OFFSET(3) NUMBITS(1) [],
264 CC1P OFFSET(1) NUMBITS(1) [],
266 CC1E OFFSET(0) NUMBITS(1) []
268 ],
269 CNT [
270 CNT_H OFFSET(16) NUMBITS(16) [],
272 CNT_L OFFSET(0) NUMBITS(16) []
274 ],
275 ARR [
276 ARR_H OFFSET(16) NUMBITS(16) [],
278 ARR_L OFFSET(0) NUMBITS(16) []
280 ],
281 CCR1 [
282 CCR1_H OFFSET(16) NUMBITS(16) [],
284 CCR1_L OFFSET(0) NUMBITS(16) []
286 ],
287 CCR2 [
288 CCR2_H OFFSET(16) NUMBITS(16) [],
290 CCR2_L OFFSET(0) NUMBITS(16) []
292 ],
293 CCR3 [
294 CCR3_H OFFSET(16) NUMBITS(16) [],
296 CCR3_L OFFSET(0) NUMBITS(16) []
298 ],
299 CCR4 [
300 CCR4_H OFFSET(16) NUMBITS(16) [],
302 CCR4_L OFFSET(0) NUMBITS(16) []
304 ],
305 DCR [
306 DBL OFFSET(8) NUMBITS(5) [],
308 DBA OFFSET(0) NUMBITS(5) []
310 ]
311];
312
313const TIM2_BASE: StaticRef<Tim2Registers> =
314 unsafe { StaticRef::new(0x40000000 as *const Tim2Registers) };
315
316pub struct Tim2<'a> {
317 registers: StaticRef<Tim2Registers>,
318 clock: Tim2Clock<'a>,
319 client: OptionalCell<&'a dyn AlarmClient>,
320 irqn: u32,
321}
322
323impl<'a> Tim2<'a> {
324 pub const fn new(rcc: &'a rcc::Rcc) -> Self {
325 Self {
326 registers: TIM2_BASE,
327 clock: Tim2Clock(rcc::PeripheralClock::new(
328 rcc::PeripheralClockType::APB1(rcc::PCLK1::TIM2),
329 rcc,
330 )),
331 client: OptionalCell::empty(),
332 irqn: nvic::TIM2,
333 }
334 }
335
336 fn start_counter(&self) {
338 self.registers.arr.set(0xFFFF_FFFF - 1);
343 self.registers.psc.set((499 - 1) as u32);
346 self.registers.egr.write(EGR::UG::SET);
347 self.registers.cr1.modify(CR1::CEN::SET);
348 }
349
350 pub fn is_enabled_clock(&self) -> bool {
351 self.clock.is_enabled()
352 }
353
354 pub fn enable_clock(&self) {
355 self.clock.enable();
356 }
357
358 pub fn disable_clock(&self) {
359 self.clock.disable();
360 }
361
362 pub fn handle_interrupt(&self) {
363 self.registers.sr.modify(SR::CC1IF::CLEAR);
364
365 self.client.map(|client| client.alarm());
366 }
367}
368
369impl Time for Tim2<'_> {
370 type Frequency = Freq16KHz;
371 type Ticks = Ticks32;
372
373 fn now(&self) -> Self::Ticks {
374 Self::Ticks::from(self.registers.cnt.get())
375 }
376}
377
378impl<'a> Counter<'a> for Tim2<'a> {
379 fn set_overflow_client(&self, _client: &'a dyn OverflowClient) {}
380
381 fn start(&self) -> Result<(), ErrorCode> {
383 self.start_counter();
384
385 Ok(())
386 }
387
388 fn stop(&self) -> Result<(), ErrorCode> {
389 self.registers.cr1.modify(CR1::CEN::CLEAR);
390 self.registers.sr.modify(SR::CC1IF::CLEAR);
391 Ok(())
392 }
393
394 fn reset(&self) -> Result<(), ErrorCode> {
395 self.registers.cnt.set(0);
396 Ok(())
397 }
398
399 fn is_running(&self) -> bool {
400 self.registers.cr1.is_set(CR1::CEN)
401 }
402}
403
404impl<'a> Alarm<'a> for Tim2<'a> {
405 fn set_alarm_client(&self, client: &'a dyn AlarmClient) {
406 self.client.set(client);
407 }
408
409 fn set_alarm(&self, reference: Self::Ticks, dt: Self::Ticks) {
410 let mut expire = reference.wrapping_add(dt);
411 let now = self.now();
412 if !now.within_range(reference, expire) {
413 expire = now;
414 }
415
416 if expire.wrapping_sub(now) <= self.minimum_dt() {
417 expire = now.wrapping_add(self.minimum_dt());
418 }
419
420 let _ = self.disarm();
421 self.registers.ccr1.set(expire.into_u32());
422 self.registers.dier.modify(DIER::CC1IE::SET);
423 }
424
425 fn get_alarm(&self) -> Self::Ticks {
426 Self::Ticks::from(self.registers.ccr1.get())
427 }
428
429 fn disarm(&self) -> Result<(), ErrorCode> {
430 unsafe {
431 atomic(|| {
432 self.registers.dier.modify(DIER::CC1IE::CLEAR);
434 cortexm4f::nvic::Nvic::new(self.irqn).clear_pending();
435 });
436 }
437 Ok(())
438 }
439
440 fn is_armed(&self) -> bool {
441 self.registers.dier.is_set(DIER::CC1IE)
443 }
444
445 fn minimum_dt(&self) -> Self::Ticks {
446 Self::Ticks::from(1)
447 }
448}
449
450struct Tim2Clock<'a>(rcc::PeripheralClock<'a>);
451
452impl ClockInterface for Tim2Clock<'_> {
453 fn is_enabled(&self) -> bool {
454 self.0.is_enabled()
455 }
456
457 fn enable(&self) {
458 self.0.enable();
459 }
460
461 fn disable(&self) {
462 self.0.disable();
463 }
464}