1use cortexm4f::support::with_interrupts_disabled;
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            with_interrupts_disabled(|| {
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}