1use cortexm4f::support::atomic;
6use kernel::hil::time::{
7 Alarm, AlarmClient, Counter, Freq16KHz, Frequency, 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::clocks::{phclk, Stm32f4Clocks};
17use crate::nvic;
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 CKD OFFSET(8) NUMBITS(2) [],
68 ARPE OFFSET(7) NUMBITS(1) [],
70 CMS OFFSET(5) NUMBITS(2) [],
72 DIR OFFSET(4) NUMBITS(1) [],
74 OPM OFFSET(3) NUMBITS(1) [],
76 URS OFFSET(2) NUMBITS(1) [],
78 UDIS OFFSET(1) NUMBITS(1) [],
80 CEN OFFSET(0) NUMBITS(1) []
82 ],
83 CR2 [
84 TI1S OFFSET(7) NUMBITS(1) [],
86 MMS OFFSET(4) NUMBITS(3) [],
88 CCDS OFFSET(3) NUMBITS(1) []
90 ],
91 SMCR [
92 ETP OFFSET(15) NUMBITS(1) [],
94 ECE OFFSET(14) NUMBITS(1) [],
96 ETPS OFFSET(12) NUMBITS(2) [],
98 ETF OFFSET(8) NUMBITS(4) [],
100 MSM OFFSET(7) NUMBITS(1) [],
102 TS OFFSET(4) NUMBITS(3) [],
104 SMS OFFSET(0) NUMBITS(3) []
106 ],
107 DIER [
108 TDE OFFSET(14) NUMBITS(1) [],
110 CC4DE OFFSET(12) NUMBITS(1) [],
112 CC3DE OFFSET(11) NUMBITS(1) [],
114 CC2DE OFFSET(10) NUMBITS(1) [],
116 CC1DE OFFSET(9) NUMBITS(1) [],
118 UDE OFFSET(8) NUMBITS(1) [],
120 TIE OFFSET(6) NUMBITS(1) [],
122 CC4IE OFFSET(4) NUMBITS(1) [],
124 CC3IE OFFSET(3) NUMBITS(1) [],
126 CC2IE OFFSET(2) NUMBITS(1) [],
128 CC1IE OFFSET(1) NUMBITS(1) [],
130 UIE OFFSET(0) NUMBITS(1) []
132 ],
133 SR [
134 CC4OF OFFSET(12) NUMBITS(1) [],
136 CC3OF OFFSET(11) NUMBITS(1) [],
138 CC2OF OFFSET(10) NUMBITS(1) [],
140 CC1OF OFFSET(9) NUMBITS(1) [],
142 TIF OFFSET(6) NUMBITS(1) [],
144 CC4IF OFFSET(4) NUMBITS(1) [],
146 CC3IF OFFSET(3) NUMBITS(1) [],
148 CC2IF OFFSET(2) NUMBITS(1) [],
150 CC1IF OFFSET(1) NUMBITS(1) [],
152 UIF OFFSET(0) NUMBITS(1) []
154 ],
155 EGR [
156 TG OFFSET(6) NUMBITS(1) [],
158 CC4G OFFSET(4) NUMBITS(1) [],
160 CC3G OFFSET(3) NUMBITS(1) [],
162 CC2G OFFSET(2) NUMBITS(1) [],
164 CC1G OFFSET(1) NUMBITS(1) [],
166 UG OFFSET(0) NUMBITS(1) []
168 ],
169 CCMR1_Output [
170 OC2CE OFFSET(15) NUMBITS(1) [],
172 OC2M OFFSET(12) NUMBITS(3) [],
174 OC2PE OFFSET(11) NUMBITS(1) [],
176 OC2FE OFFSET(10) NUMBITS(1) [],
178 CC2S OFFSET(8) NUMBITS(2) [],
180 OC1CE OFFSET(7) NUMBITS(1) [],
182 OC1M OFFSET(4) NUMBITS(3) [],
184 OC1PE OFFSET(3) NUMBITS(1) [],
186 OC1FE OFFSET(2) NUMBITS(1) [],
188 CC1S OFFSET(0) NUMBITS(2) []
190 ],
191 CCMR1_Input [
192 IC2F OFFSET(12) NUMBITS(4) [],
194 IC2PCS OFFSET(10) NUMBITS(2) [],
196 CC2S OFFSET(8) NUMBITS(2) [],
198 IC1F OFFSET(4) NUMBITS(4) [],
200 ICPCS OFFSET(2) NUMBITS(2) [],
202 CC1S OFFSET(0) NUMBITS(2) []
204 ],
205 CCMR2_Output [
206 O24CE OFFSET(15) NUMBITS(1) [],
208 OC4M OFFSET(12) NUMBITS(3) [],
210 OC4PE OFFSET(11) NUMBITS(1) [],
212 OC4FE OFFSET(10) NUMBITS(1) [],
214 CC4S OFFSET(8) NUMBITS(2) [],
216 OC3CE OFFSET(7) NUMBITS(1) [],
218 OC3M OFFSET(4) NUMBITS(3) [],
220 OC3PE OFFSET(3) NUMBITS(1) [],
222 OC3FE OFFSET(2) NUMBITS(1) [],
224 CC3S OFFSET(0) NUMBITS(2) []
226 ],
227 CCMR2_Input [
228 IC4F OFFSET(12) NUMBITS(4) [],
230 IC4PSC OFFSET(10) NUMBITS(2) [],
232 CC4S OFFSET(8) NUMBITS(2) [],
234 IC3F OFFSET(4) NUMBITS(4) [],
236 IC3PSC OFFSET(2) NUMBITS(2) [],
238 CC3S OFFSET(0) NUMBITS(2) []
240 ],
241 CCER [
242 CC4NP OFFSET(15) NUMBITS(1) [],
244 CC4P OFFSET(13) NUMBITS(1) [],
246 CC4E OFFSET(12) NUMBITS(1) [],
248 CC3NP OFFSET(11) NUMBITS(1) [],
250 CC3P OFFSET(9) NUMBITS(1) [],
252 CC3E OFFSET(8) NUMBITS(1) [],
254 CC2NP OFFSET(7) NUMBITS(1) [],
256 CC2P OFFSET(5) NUMBITS(1) [],
258 CC2E OFFSET(4) NUMBITS(1) [],
260 CC1NP OFFSET(3) NUMBITS(1) [],
262 CC1P OFFSET(1) NUMBITS(1) [],
264 CC1E OFFSET(0) NUMBITS(1) []
266 ],
267 CNT [
268 CNT_H OFFSET(16) NUMBITS(16) [],
270 CNT_L OFFSET(0) NUMBITS(16) []
272 ],
273 ARR [
274 ARR_H OFFSET(16) NUMBITS(16) [],
276 ARR_L OFFSET(0) NUMBITS(16) []
278 ],
279 CCR1 [
280 CCR1_H OFFSET(16) NUMBITS(16) [],
282 CCR1_L OFFSET(0) NUMBITS(16) []
284 ],
285 CCR2 [
286 CCR2_H OFFSET(16) NUMBITS(16) [],
288 CCR2_L OFFSET(0) NUMBITS(16) []
290 ],
291 CCR3 [
292 CCR3_H OFFSET(16) NUMBITS(16) [],
294 CCR3_L OFFSET(0) NUMBITS(16) []
296 ],
297 CCR4 [
298 CCR4_H OFFSET(16) NUMBITS(16) [],
300 CCR4_L OFFSET(0) NUMBITS(16) []
302 ],
303 DCR [
304 DBL OFFSET(8) NUMBITS(5) [],
306 DBA OFFSET(0) NUMBITS(5) []
308 ]
309];
310
311const TIM2_BASE: StaticRef<Tim2Registers> =
312 unsafe { StaticRef::new(0x40000000 as *const Tim2Registers) };
313
314pub struct Tim2<'a> {
315 registers: StaticRef<Tim2Registers>,
316 clock: Tim2Clock<'a>,
317 client: OptionalCell<&'a dyn AlarmClient>,
318 irqn: u32,
319}
320
321impl<'a> Tim2<'a> {
322 pub const fn new(clocks: &'a dyn Stm32f4Clocks) -> Self {
323 Self {
324 registers: TIM2_BASE,
325 clock: Tim2Clock(phclk::PeripheralClock::new(
326 phclk::PeripheralClockType::APB1(phclk::PCLK1::TIM2),
327 clocks,
328 )),
329 client: OptionalCell::empty(),
330 irqn: nvic::TIM2,
331 }
332 }
333
334 pub fn is_enabled_clock(&self) -> bool {
335 self.clock.is_enabled()
336 }
337
338 pub fn enable_clock(&self) {
339 self.clock.enable();
340 }
341
342 pub fn disable_clock(&self) {
343 self.clock.disable();
344 }
345
346 pub fn handle_interrupt(&self) {
347 self.registers.sr.modify(SR::CC1IF::CLEAR);
348
349 self.client.map(|client| client.alarm());
350 }
351
352 pub fn start(&self) {
354 self.registers.arr.set(0xFFFF_FFFF - 1);
358 self.calibrate();
359 }
360
361 pub fn calibrate(&self) {
363 let clk_freq = self.clock.0.get_frequency();
364
365 let psc = clk_freq / Freq16KHz::frequency();
372 self.registers.psc.set(psc - 1);
373
374 self.registers.egr.write(EGR::UG::SET);
376 self.registers.cr1.modify(CR1::CEN::SET);
377 }
378
379 pub fn get_timer_cnt(&self) -> u32 {
381 self.registers.cnt.get()
382 }
383
384 pub fn set_timer_cnt(&self, value: u32) {
386 self.registers.cnt.set(value);
387 }
388}
389
390impl Time for Tim2<'_> {
391 type Frequency = Freq16KHz;
392 type Ticks = Ticks32;
393
394 fn now(&self) -> Ticks32 {
395 Ticks32::from(self.registers.cnt.get())
396 }
397}
398
399impl<'a> Counter<'a> for Tim2<'a> {
400 fn set_overflow_client(&self, _client: &'a dyn OverflowClient) {}
401
402 fn start(&self) -> Result<(), ErrorCode> {
404 self.start();
405 Ok(())
406 }
407
408 fn stop(&self) -> Result<(), ErrorCode> {
409 self.registers.cr1.modify(CR1::CEN::CLEAR);
410 self.registers.sr.modify(SR::CC1IF::CLEAR);
411 Ok(())
412 }
413
414 fn reset(&self) -> Result<(), ErrorCode> {
415 self.registers.cnt.set(0);
416 Ok(())
417 }
418
419 fn is_running(&self) -> bool {
420 self.registers.cr1.is_set(CR1::CEN)
421 }
422}
423
424impl<'a> Alarm<'a> for Tim2<'a> {
425 fn set_alarm_client(&self, client: &'a dyn AlarmClient) {
426 self.client.set(client);
427 }
428
429 fn set_alarm(&self, reference: Self::Ticks, dt: Self::Ticks) {
430 let mut expire = reference.wrapping_add(dt);
431 let now = self.now();
432 if !now.within_range(reference, expire) {
433 expire = now;
434 }
435
436 if expire.wrapping_sub(now) < self.minimum_dt() {
437 expire = now.wrapping_add(self.minimum_dt());
438 }
439
440 let _ = self.disarm();
441 self.registers.ccr1.set(expire.into_u32());
442 self.registers.dier.modify(DIER::CC1IE::SET);
443 }
444
445 fn get_alarm(&self) -> Self::Ticks {
446 Self::Ticks::from(self.registers.ccr1.get())
447 }
448
449 fn disarm(&self) -> Result<(), ErrorCode> {
450 unsafe {
451 atomic(|| {
452 self.registers.dier.modify(DIER::CC1IE::CLEAR);
454 cortexm4f::nvic::Nvic::new(self.irqn).clear_pending();
455 });
456 }
457 Ok(())
458 }
459
460 fn is_armed(&self) -> bool {
461 self.registers.dier.is_set(DIER::CC1IE)
463 }
464
465 fn minimum_dt(&self) -> Self::Ticks {
466 Self::Ticks::from(1)
467 }
468}
469
470struct Tim2Clock<'a>(phclk::PeripheralClock<'a>);
471
472impl ClockInterface for Tim2Clock<'_> {
473 fn is_enabled(&self) -> bool {
474 self.0.is_enabled()
475 }
476
477 fn enable(&self) {
478 self.0.enable();
479 }
480
481 fn disable(&self) {
482 self.0.disable();
483 }
484}