1use crate::pac::{DCB, DWT};
14#[cfg(feature = "enumset")]
15use enumset::{EnumSet, EnumSetType};
16use void::Void;
17
18use crate::hal::timer::{Cancel, CountDown, Periodic};
19#[allow(unused)]
20use crate::pac::{self, RCC};
21use crate::rcc::{self, Clocks};
22use crate::time::{duration, fixed_point::FixedPoint, rate::Hertz};
23
24mod interrupts;
25
26#[allow(clippy::module_name_repetitions)]
28#[derive(Debug, Clone, Copy)]
29pub struct MonoTimer {
30 frequency: Hertz,
31}
32
33#[cfg(feature = "defmt")]
34impl defmt::Format for MonoTimer {
35 fn format(&self, f: defmt::Formatter) {
36 defmt::write!(
37 f,
38 "MonoTimer {{ frequency: {} Hz }}",
39 self.frequency.integer(),
40 );
41 }
42}
43
44impl MonoTimer {
45 pub fn new(mut dwt: DWT, clocks: Clocks, dcb: &mut DCB) -> Self {
47 dcb.enable_trace();
51 dwt.enable_cycle_counter();
52
53 MonoTimer {
54 frequency: clocks.hclk(),
55 }
56 }
57
58 #[must_use]
60 pub fn frequency(&self) -> Hertz {
61 self.frequency
62 }
63
64 #[must_use]
66 pub fn now(&self) -> Instant {
67 Instant {
68 now: DWT::cycle_count(),
69 }
70 }
71}
72
73#[derive(Debug, Clone, Copy)]
75#[cfg_attr(feature = "defmt", derive(defmt::Format))]
76pub struct Instant {
77 now: u32,
78}
79
80impl Instant {
81 #[must_use]
83 pub fn elapsed(self) -> u32 {
84 DWT::cycle_count().wrapping_sub(self.now)
85 }
86}
87
88#[derive(Debug)]
90#[cfg_attr(feature = "defmt", derive(defmt::Format))]
91pub struct Timer<TIM> {
92 tim: TIM,
93 clocks: Clocks,
94}
95
96#[derive(Debug)]
98#[cfg_attr(feature = "defmt", derive(defmt::Format))]
99#[cfg_attr(feature = "enumset", derive(EnumSetType))]
100#[cfg_attr(not(feature = "enumset"), derive(Copy, Clone, PartialEq, Eq))]
101#[non_exhaustive]
102pub enum Event {
104 Update,
106}
107
108impl<TIM> Timer<TIM>
109where
110 TIM: Instance,
111{
112 pub fn new(tim: TIM, clocks: Clocks, apb: &mut <TIM as rcc::RccBus>::Bus) -> Self {
114 TIM::enable(apb);
115 TIM::reset(apb);
116
117 Timer { tim, clocks }
118 }
119
120 #[inline]
122 pub fn stop(&mut self) {
123 self.tim.set_cr1_cen(false);
124 }
125
126 #[inline]
128 pub fn enable_interrupt(&mut self, event: Event) {
129 self.configure_interrupt(event, true);
130 }
131
132 #[inline]
134 pub fn disable_interrupt(&mut self, event: Event) {
135 self.configure_interrupt(event, false);
136 }
137
138 #[doc(alias = "unmask")]
157 pub fn interrupt(&self) -> <TIM as crate::interrupts::InterruptNumber>::Interrupt {
158 <TIM as crate::interrupts::InterruptNumber>::INTERRUPT
159 }
160
161 #[inline]
163 pub fn configure_interrupt(&mut self, event: Event, enable: bool) {
164 match event {
165 Event::Update => self.tim.set_dier_uie(enable),
166 }
167 }
168
169 #[cfg(feature = "enumset")]
175 #[cfg_attr(docsrs, doc(cfg(feature = "enumset")))]
176 pub fn configure_interrupts(&mut self, events: EnumSet<Event>) {
177 for event in events.complement().iter() {
178 self.configure_interrupt(event, false);
179 }
180 for event in events.iter() {
181 self.configure_interrupt(event, true);
182 }
183 }
184
185 #[inline]
187 pub fn is_interrupt_configured(&self, event: Event) -> bool {
188 match event {
189 Event::Update => self.tim.is_dier_uie_set(),
190 }
191 }
192
193 #[cfg(feature = "enumset")]
196 #[cfg_attr(docsrs, doc(cfg(feature = "enumset")))]
197 #[inline]
198 pub fn configured_interrupts(&mut self) -> EnumSet<Event> {
199 let mut events = EnumSet::new();
200
201 for event in EnumSet::<Event>::all().iter() {
202 if self.is_interrupt_configured(event) {
203 events |= event;
204 }
205 }
206
207 events
208 }
209
210 pub fn is_event_triggered(&self, event: Event) -> bool {
212 match event {
213 Event::Update => self.tim.is_sr_uief_set(),
214 }
215 }
216
217 #[cfg(feature = "enumset")]
219 #[cfg_attr(docsrs, doc(cfg(feature = "enumset")))]
220 pub fn triggered_events(&self) -> EnumSet<Event> {
221 let mut events = EnumSet::new();
222
223 for event in EnumSet::<Event>::all().iter() {
224 if self.is_event_triggered(event) {
225 events |= event;
226 }
227 }
228
229 events
230 }
231
232 #[inline]
234 pub fn clear_event(&mut self, event: Event) {
235 match event {
236 Event::Update => self.tim.clear_sr_uief(),
237 }
238 }
239
240 #[inline]
242 pub fn clear_events(&mut self) {
243 self.tim.clear_sr();
244 }
245
246 pub unsafe fn peripheral(&mut self) -> &mut TIM {
256 &mut self.tim
257 }
258
259 #[inline]
261 pub fn free(mut self) -> TIM {
262 self.stop();
263 self.tim
264 }
265}
266
267impl<TIM> Periodic for Timer<TIM> where TIM: Instance {}
268
269impl<TIM> CountDown for Timer<TIM>
270where
271 TIM: Instance,
272{
273 type Time = duration::Generic<u32>;
274
275 fn start<T>(&mut self, timeout: T)
276 where
277 T: Into<Self::Time>,
278 {
279 self.stop();
280
281 let timeout: Self::Time = timeout.into();
282 let clock = TIM::clock(&self.clocks);
283
284 let ticks = u64::from(clock.integer()).saturating_mul(u64::from(timeout.integer()))
285 * *timeout.scaling_factor();
286
287 let psc = ticks.saturating_sub(1) / (1 << 16);
288 self.tim.set_psc(crate::unwrap!(u16::try_from(psc).ok()));
289
290 let mut arr = ticks / psc.saturating_add(1);
291 if psc == 0 && arr == 0 {
295 arr = 1;
296 }
297 self.tim.set_arr(crate::unwrap!(u16::try_from(arr).ok()));
298
299 let is_update_interrupt_active = self.is_interrupt_configured(Event::Update);
301 if is_update_interrupt_active {
302 self.configure_interrupt(Event::Update, false);
303 }
304
305 self.tim.set_egr_ug();
308 self.clear_event(Event::Update);
310
311 if is_update_interrupt_active {
312 self.configure_interrupt(Event::Update, true);
313 }
314
315 self.tim.set_cr1_cen(true);
317 }
318
319 fn wait(&mut self) -> nb::Result<(), Void> {
322 if self.tim.is_sr_uief_set() {
323 self.clear_event(Event::Update);
324 Ok(())
325 } else {
326 Err(nb::Error::WouldBlock)
327 }
328 }
329}
330
331#[derive(Debug, Copy, Clone, PartialEq, Eq)]
333#[cfg_attr(feature = "defmt", derive(defmt::Format))]
334pub struct AlreadyCancled;
335
336impl<TIM> Cancel for Timer<TIM>
337where
338 TIM: Instance,
339{
340 type Error = AlreadyCancled;
341 fn cancel(&mut self) -> Result<(), Self::Error> {
342 if !self.tim.is_cr1_cen_set() {
344 return Err(AlreadyCancled);
345 }
346 self.stop();
347 Ok(())
348 }
349}
350
351pub trait CommonRegisterBlock: crate::private::Sealed {
356 #[doc(hidden)]
357 fn set_cr1_cen(&mut self, enable: bool);
358 #[doc(hidden)]
359 fn is_cr1_cen_set(&mut self) -> bool;
360 #[doc(hidden)]
361 fn set_dier_uie(&mut self, enable: bool);
362 #[doc(hidden)]
363 fn is_dier_uie_set(&self) -> bool;
364 #[doc(hidden)]
365 fn clear_sr_uief(&mut self);
366 #[doc(hidden)]
367 fn clear_sr(&mut self);
368 #[doc(hidden)]
369 fn is_sr_uief_set(&self) -> bool;
370 #[doc(hidden)]
371 fn set_egr_ug(&mut self);
372 #[doc(hidden)]
373 fn set_psc(&mut self, psc: u16);
374 #[doc(hidden)]
375 fn set_arr(&mut self, arr: u16);
376}
377
378pub trait Instance:
380 CommonRegisterBlock
381 + crate::interrupts::InterruptNumber
382 + crate::private::Sealed
383 + rcc::Enable
384 + rcc::Reset
385{
386 #[doc(hidden)]
387 fn clock(clocks: &Clocks) -> Hertz;
388}
389
390macro_rules! timer {
391 ($TIMX:ident) => {
392 impl CommonRegisterBlock for crate::pac::$TIMX {
393 #[inline]
394 fn set_cr1_cen(&mut self, enable: bool) {
395 self.cr1.modify(|_, w| w.cen().bit(enable));
396 }
397
398 #[inline]
399 fn is_cr1_cen_set(&mut self) -> bool {
400 self.cr1.read().cen().bit()
401 }
402
403 #[inline]
404 fn set_dier_uie(&mut self, enable: bool) {
405 self.dier.modify(|_, w| w.uie().bit(enable));
406 }
407
408 #[inline]
409 fn is_dier_uie_set(&self) -> bool {
410 self.dier.read().uie().bit()
411 }
412
413 #[inline]
414 fn clear_sr_uief(&mut self) {
415 self.sr.modify(|_, w| w.uif().clear())
416 }
417
418 #[inline]
419 fn clear_sr(&mut self) {
420 self.sr.write(|w| unsafe { w.bits(0) });
422 }
423
424 #[inline]
425 fn is_sr_uief_set(&self) -> bool {
426 self.sr.read().uif().is_update_pending()
427 }
428
429 #[inline]
430 fn set_egr_ug(&mut self) {
431 self.egr.write(|w| w.ug().update());
433 }
434
435 #[inline]
436 fn set_psc(&mut self, psc: u16) {
437 self.psc.write(|w| w.psc().bits(psc));
439 }
440
441 #[inline]
442 fn set_arr(&mut self, arr: u16) {
443 #[allow(unused_unsafe)]
444 self.arr.write(|w| unsafe { w.arr().bits(arr.into()) });
446 }
447 }
448 };
449}
450
451#[allow(unused)]
452macro_rules! timer_var_clock {
453 ($($TIMX:ident, $timXsw:ident),+) => {
454 $(
455 impl Instance for crate::pac::$TIMX {
456 #[inline]
457 fn clock(clocks: &Clocks) -> Hertz {
458 match unsafe {(*RCC::ptr()).cfgr3.read().$timXsw().variant()} {
460 crate::pac::rcc::cfgr3::TIM1SW_A::Pclk2 => {
463 <pac::$TIMX as rcc::BusTimerClock>::timer_clock(clocks)
466 }
467 crate::pac::rcc::cfgr3::TIM1SW_A::Pll => {
468 if let Some(pllclk) = clocks.pllclk() {
469 pllclk * 2
470 } else {
471 crate::panic!("Invalid timer clock source.");
474 }
475 }
476 }
477 }
478 }
479
480 timer!($TIMX);
481 )+
482 };
483 ($(($X:literal: $Y:literal)),+) => {
484 paste::paste! {
485 timer_var_clock!(
486 $([<TIM $X>], [<tim $Y sw>]),+
487 );
488
489 }
490 };
491 ($($X:literal),+) => {
492 timer_var_clock!($(($X: $X)),+);
493 };
494}
495
496macro_rules! timer_static_clock {
497 ($($TIMX:ident),+) => {
498 $(
499 impl Instance for crate::pac::$TIMX {
500 #[inline]
501 fn clock(clocks: &Clocks) -> Hertz {
502 <pac::$TIMX as rcc::BusTimerClock>::timer_clock(clocks)
503 }
504 }
505
506 timer!($TIMX);
507 )+
508 };
509 ($($X:literal),+) => {
510 paste::paste! {
511 timer_static_clock!(
512 $([<TIM $X>]),+
513 );
514 }
515 };
516}
517
518cfg_if::cfg_if! {
524 if #[cfg(feature = "svd-f301")] {
530 timer_static_clock!(2, 6);
531 timer_var_clock!(1, 15, 16, 17);
532 }
533}
534
535cfg_if::cfg_if! {
536 if #[cfg(all(feature = "svd-f302", feature = "gpio-f303"))] {
538 timer_static_clock!(2, 3, 4, 6, 15, 16, 17);
539 timer_var_clock!(1);
540 }
541
542 else if #[cfg(all(feature = "svd-f302", feature = "gpio-f303e"))] {
544 timer_static_clock!(6);
545 timer_var_clock!(1, 2, 15, 16, 17);
546 timer_var_clock!((3: 34), (4: 34));
547 }
548
549 else if #[cfg(all(feature = "svd-f302", feature = "gpio-f302"))] {
555 timer_static_clock!(2, 6);
556 timer_var_clock!(1, 15, 16, 17);
557 }
558
559 else if #[cfg(all(feature = "svd-f303", feature = "gpio-f303"))] {
561 timer_static_clock!(2, 3, 4, 6, 7, 15, 16, 17);
562 timer_var_clock!(1, 8);
563 }
564
565 else if #[cfg(all(feature = "svd-f303", feature = "gpio-f303e"))] {
567 timer_static_clock!(6, 7);
568 timer_var_clock!(1, 2, 8, 15, 16, 17, 20);
569 timer_var_clock!((3: 34), (4: 34));
570 }
571
572 else if #[cfg(all(feature = "svd-f303", feature = "gpio-f333"))] {
574 timer_static_clock!(2, 3, 6, 7, 15, 16, 17);
575 timer_var_clock!(1);
576 }
577
578 else if #[cfg(feature = "gpio-f373")] {
584 timer_static_clock!(2, 3, 4, 5, 6, 7, 12, 13, 14, 15, 16, 17, 18, 19);
585 }
586
587 else if #[cfg(all(feature = "svd-f3x4", feature = "gpio-f333"))] {
589 timer_static_clock!(2, 3, 6, 7, 15, 16, 17);
590 timer_var_clock!(1);
591 }
592}