1#![doc = crate::before_snippet!()]
29#![doc = crate::before_snippet!()]
54use core::marker::PhantomData;
70
71use super::Error;
72#[cfg(timg1)]
73use crate::peripherals::TIMG1;
74#[cfg(any(esp32c6, esp32h2))]
75use crate::soc::constants::TIMG_DEFAULT_CLK_SRC;
76use crate::{
77 asynch::AtomicWaker,
78 clock::Clocks,
79 interrupt::{self, InterruptConfigurable, InterruptHandler},
80 pac::timg0::RegisterBlock,
81 peripherals::{Interrupt, TIMG0},
82 private::Sealed,
83 system::PeripheralClockControl,
84 time::{Duration, Instant, Rate},
85};
86
87const NUM_TIMG: usize = 1 + cfg!(timg1) as usize;
88
89cfg_if::cfg_if! {
90 if #[cfg(all(timg_timer1, not(any(esp32, esp32s2))))] {
94 use crate::sync::{lock, RawMutex};
95 static INT_ENA_LOCK: [RawMutex; NUM_TIMG] = [const { RawMutex::new() }; NUM_TIMG];
96 }
97}
98
99#[cfg_attr(not(timg_timer1), doc = "a general purpose timer")]
101#[cfg_attr(timg_timer1, doc = "2 timers")]
102pub struct TimerGroup<'d, T>
104where
105 T: TimerGroupInstance + 'd,
106{
107 _timer_group: PhantomData<T>,
108 pub timer0: Timer<'d>,
110 #[cfg(timg_timer1)]
112 pub timer1: Timer<'d>,
113 pub wdt: Wdt<T>,
115}
116
117#[doc(hidden)]
118pub trait TimerGroupInstance {
119 fn id() -> u8;
120 fn register_block() -> *const RegisterBlock;
121 fn configure_src_clk();
122 fn enable_peripheral();
123 fn reset_peripheral();
124 fn configure_wdt_src_clk();
125 fn wdt_interrupt() -> Interrupt;
126}
127
128impl TimerGroupInstance for TIMG0<'_> {
129 fn id() -> u8 {
130 0
131 }
132
133 #[inline(always)]
134 fn register_block() -> *const RegisterBlock {
135 Self::regs()
136 }
137
138 fn configure_src_clk() {
139 cfg_if::cfg_if! {
140 if #[cfg(esp32)] {
141 } else if #[cfg(any(esp32c2, esp32c3, esp32s2, esp32s3))] {
143 unsafe {
144 (*<Self as TimerGroupInstance>::register_block())
145 .t(0)
146 .config()
147 .modify(|_, w| w.use_xtal().clear_bit());
148 }
149 } else if #[cfg(any(esp32c6, esp32h2))] {
150 crate::peripherals::PCR::regs()
151 .timergroup0_timer_clk_conf()
152 .modify(|_, w| unsafe { w.tg0_timer_clk_sel().bits(TIMG_DEFAULT_CLK_SRC) });
153 }
154 }
155 }
156
157 fn enable_peripheral() {
158 PeripheralClockControl::enable(crate::system::Peripheral::Timg0);
159 }
160
161 fn reset_peripheral() {
162 }
165
166 fn configure_wdt_src_clk() {
167 cfg_if::cfg_if! {
168 if #[cfg(any(esp32, esp32s2, esp32s3))] {
169 } else if #[cfg(any(esp32c2, esp32c3))] {
171 unsafe {
172 (*<Self as TimerGroupInstance>::register_block())
173 .wdtconfig0()
174 .modify(|_, w| w.wdt_use_xtal().clear_bit());
175 }
176 } else if #[cfg(any(esp32c6, esp32h2))] {
177 crate::peripherals::PCR::regs()
178 .timergroup0_wdt_clk_conf()
179 .modify(|_, w| unsafe { w.tg0_wdt_clk_sel().bits(1) });
180 }
181 }
182 }
183
184 fn wdt_interrupt() -> Interrupt {
185 Interrupt::TG0_WDT_LEVEL
186 }
187}
188
189#[cfg(timg1)]
190impl TimerGroupInstance for crate::peripherals::TIMG1<'_> {
191 fn id() -> u8 {
192 1
193 }
194
195 #[inline(always)]
196 fn register_block() -> *const RegisterBlock {
197 Self::regs()
198 }
199
200 fn configure_src_clk() {
201 cfg_if::cfg_if! {
202 if #[cfg(any(esp32, esp32c2, esp32c3))] {
203 } else if #[cfg(any(esp32c6, esp32h2))] {
206 crate::peripherals::PCR::regs()
207 .timergroup1_timer_clk_conf()
208 .modify(|_, w| unsafe { w.tg1_timer_clk_sel().bits(TIMG_DEFAULT_CLK_SRC) });
209 } else if #[cfg(any(esp32s2, esp32s3))] {
210 unsafe {
211 (*<Self as TimerGroupInstance>::register_block())
212 .t(1)
213 .config()
214 .modify(|_, w| w.use_xtal().clear_bit());
215 }
216 }
217 }
218 }
219
220 fn enable_peripheral() {
221 PeripheralClockControl::enable(crate::system::Peripheral::Timg1);
222 }
223
224 fn reset_peripheral() {
225 PeripheralClockControl::reset(crate::system::Peripheral::Timg1)
226 }
227
228 fn configure_wdt_src_clk() {
229 cfg_if::cfg_if! {
230 if #[cfg(any(esp32, esp32s2, esp32s3, esp32c2, esp32c3))] {
231 } else if #[cfg(any(esp32c6, esp32h2))] {
234 crate::peripherals::PCR::regs()
235 .timergroup1_wdt_clk_conf()
236 .modify(|_, w| unsafe { w.tg1_wdt_clk_sel().bits(TIMG_DEFAULT_CLK_SRC) });
237 }
238 }
239 }
240
241 fn wdt_interrupt() -> Interrupt {
242 Interrupt::TG1_WDT_LEVEL
243 }
244}
245
246impl<'d, T> TimerGroup<'d, T>
247where
248 T: TimerGroupInstance + 'd,
249{
250 pub fn new(_timer_group: T) -> Self {
252 T::reset_peripheral();
253 T::enable_peripheral();
254
255 T::configure_src_clk();
256
257 Self {
258 _timer_group: PhantomData,
259 timer0: Timer {
260 timer: 0,
261 tg: T::id(),
262 register_block: T::register_block(),
263 _lifetime: PhantomData,
264 },
265 #[cfg(timg_timer1)]
266 timer1: Timer {
267 timer: 1,
268 tg: T::id(),
269 register_block: T::register_block(),
270 _lifetime: PhantomData,
271 },
272 wdt: Wdt::new(),
273 }
274 }
275}
276
277impl super::Timer for Timer<'_> {
278 fn start(&self) {
279 self.set_counter_active(false);
280 self.set_alarm_active(false);
281
282 self.reset_counter();
283 self.set_counter_decrementing(false);
284
285 self.set_counter_active(true);
286 self.set_alarm_active(true);
287 }
288
289 fn stop(&self) {
290 self.set_counter_active(false);
291 }
292
293 fn reset(&self) {
294 self.reset_counter()
295 }
296
297 fn is_running(&self) -> bool {
298 self.is_counter_active()
299 }
300
301 fn now(&self) -> Instant {
302 self.now()
303 }
304
305 fn load_value(&self, value: Duration) -> Result<(), Error> {
306 self.load_value(value)
307 }
308
309 fn enable_auto_reload(&self, auto_reload: bool) {
310 self.set_auto_reload(auto_reload)
311 }
312
313 fn enable_interrupt(&self, state: bool) {
314 self.set_interrupt_enabled(state);
315 }
316
317 fn clear_interrupt(&self) {
318 self.clear_interrupt()
319 }
320
321 fn is_interrupt_set(&self) -> bool {
322 self.is_interrupt_set()
323 }
324
325 fn async_interrupt_handler(&self) -> InterruptHandler {
326 match (self.timer_group(), self.timer_number()) {
327 (0, 0) => asynch::timg0_timer0_handler,
328 #[cfg(timg_timer1)]
329 (0, 1) => asynch::timg0_timer1_handler,
330 #[cfg(timg1)]
331 (1, 0) => asynch::timg1_timer0_handler,
332 #[cfg(all(timg_timer1, timg1))]
333 (1, 1) => asynch::timg1_timer1_handler,
334 _ => unreachable!(),
335 }
336 }
337
338 fn peripheral_interrupt(&self) -> Interrupt {
339 match (self.timer_group(), self.timer_number()) {
340 (0, 0) => Interrupt::TG0_T0_LEVEL,
341 #[cfg(timg_timer1)]
342 (0, 1) => Interrupt::TG0_T1_LEVEL,
343 #[cfg(timg1)]
344 (1, 0) => Interrupt::TG1_T0_LEVEL,
345 #[cfg(all(timg_timer1, timg1))]
346 (1, 1) => Interrupt::TG1_T1_LEVEL,
347 _ => unreachable!(),
348 }
349 }
350
351 fn set_interrupt_handler(&self, handler: InterruptHandler) {
352 self.set_interrupt_handler(handler)
353 }
354
355 fn waker(&self) -> &AtomicWaker {
356 asynch::waker(self)
357 }
358}
359
360#[derive(Debug)]
362#[cfg_attr(feature = "defmt", derive(defmt::Format))]
363pub struct Timer<'d> {
364 register_block: *const RegisterBlock,
365 _lifetime: PhantomData<&'d mut ()>,
366 timer: u8,
367 tg: u8,
368}
369
370impl Sealed for Timer<'_> {}
371unsafe impl Send for Timer<'_> {}
372
373impl Timer<'_> {
375 pub unsafe fn clone_unchecked(&self) -> Self {
382 Self {
383 register_block: self.register_block,
384 timer: self.timer,
385 tg: self.tg,
386 _lifetime: PhantomData,
387 }
388 }
389
390 pub fn reborrow(&mut self) -> Timer<'_> {
395 unsafe { self.clone_unchecked() }
396 }
397
398 pub(crate) fn set_interrupt_handler(&self, handler: InterruptHandler) {
399 let interrupt = match (self.timer_group(), self.timer_number()) {
400 (0, 0) => Interrupt::TG0_T0_LEVEL,
401 #[cfg(timg_timer1)]
402 (0, 1) => Interrupt::TG0_T1_LEVEL,
403 #[cfg(timg1)]
404 (1, 0) => Interrupt::TG1_T0_LEVEL,
405 #[cfg(all(timg_timer1, timg1))]
406 (1, 1) => Interrupt::TG1_T1_LEVEL,
407 _ => unreachable!(),
408 };
409
410 for core in crate::system::Cpu::other() {
411 crate::interrupt::disable(core, interrupt);
412 }
413 unsafe { interrupt::bind_interrupt(interrupt, handler.handler()) };
414 unwrap!(interrupt::enable(interrupt, handler.priority()));
415 }
416
417 fn register_block(&self) -> &RegisterBlock {
418 unsafe { &*self.register_block }
419 }
420
421 fn timer_group(&self) -> u8 {
422 self.tg
423 }
424
425 fn timer_number(&self) -> u8 {
426 self.timer
427 }
428
429 fn t(&self) -> &crate::pac::timg0::T {
430 self.register_block().t(self.timer_number().into())
431 }
432
433 fn reset_counter(&self) {
434 let t = self.t();
435
436 t.loadlo().write(|w| unsafe { w.load_lo().bits(0) });
437 t.loadhi().write(|w| unsafe { w.load_hi().bits(0) });
438
439 t.load().write(|w| unsafe { w.load().bits(1) });
440 }
441
442 fn set_counter_active(&self, state: bool) {
443 self.t().config().modify(|_, w| w.en().bit(state));
444 }
445
446 fn is_counter_active(&self) -> bool {
447 self.t().config().read().en().bit_is_set()
448 }
449
450 fn set_counter_decrementing(&self, decrementing: bool) {
451 self.t()
452 .config()
453 .modify(|_, w| w.increase().bit(!decrementing));
454 }
455
456 fn set_auto_reload(&self, auto_reload: bool) {
457 self.t()
458 .config()
459 .modify(|_, w| w.autoreload().bit(auto_reload));
460 }
461
462 fn set_alarm_active(&self, state: bool) {
463 self.t().config().modify(|_, w| w.alarm_en().bit(state));
464 }
465
466 fn load_value(&self, value: Duration) -> Result<(), Error> {
467 cfg_if::cfg_if! {
468 if #[cfg(esp32h2)] {
469 let clk_src = Clocks::get().pll_48m_clock;
471 } else {
472 let clk_src = Clocks::get().apb_clock;
473 }
474 }
475 let Some(ticks) = timeout_to_ticks(value, clk_src, self.divider()) else {
476 return Err(Error::InvalidTimeout);
477 };
478
479 if (ticks & !0x3F_FFFF_FFFF_FFFF) != 0 {
482 return Err(Error::InvalidTimeout);
483 }
484
485 let high = (ticks >> 32) as u32;
486 let low = (ticks & 0xFFFF_FFFF) as u32;
487
488 let t = self.t();
489
490 t.alarmlo().write(|w| unsafe { w.alarm_lo().bits(low) });
491 t.alarmhi().write(|w| unsafe { w.alarm_hi().bits(high) });
492
493 Ok(())
494 }
495
496 fn clear_interrupt(&self) {
497 self.register_block()
498 .int_clr()
499 .write(|w| w.t(self.timer).clear_bit_by_one());
500 let periodic = self.t().config().read().autoreload().bit_is_set();
501 self.set_alarm_active(periodic);
502 }
503
504 fn now(&self) -> Instant {
505 let t = self.t();
506
507 t.update().write(|w| w.update().set_bit());
508 while t.update().read().update().bit_is_set() {
509 }
511
512 let value_lo = t.lo().read().bits() as u64;
513 let value_hi = t.hi().read().bits() as u64;
514
515 let ticks = (value_hi << 32) | value_lo;
516 cfg_if::cfg_if! {
517 if #[cfg(esp32h2)] {
518 let clk_src = Clocks::get().pll_48m_clock;
520 } else {
521 let clk_src = Clocks::get().apb_clock;
522 }
523 }
524 let micros = ticks_to_timeout(ticks, clk_src, self.divider());
525
526 Instant::from_ticks(micros)
527 }
528
529 fn divider(&self) -> u32 {
530 let t = self.t();
531
532 match t.config().read().divider().bits() {
539 0 => 65536,
540 1 | 2 => 2,
541 n => n as u32,
542 }
543 }
544
545 fn is_interrupt_set(&self) -> bool {
546 self.register_block()
547 .int_raw()
548 .read()
549 .t(self.timer)
550 .bit_is_set()
551 }
552
553 fn set_interrupt_enabled(&self, state: bool) {
554 cfg_if::cfg_if! {
555 if #[cfg(any(esp32, esp32s2))] {
556 self.register_block()
560 .t(self.timer as usize)
561 .config()
562 .modify(|_, w| w.level_int_en().bit(state));
563 } else if #[cfg(timg_timer1)] {
564 lock(&INT_ENA_LOCK[self.timer_group() as usize], || {
565 self.register_block()
566 .int_ena()
567 .modify(|_, w| w.t(self.timer_number()).bit(state));
568 });
569 } else {
570 self.register_block()
571 .int_ena()
572 .modify(|_, w| w.t(0).bit(state));
573 }
574 }
575 }
576}
577
578fn ticks_to_timeout(ticks: u64, clock: Rate, divider: u32) -> u64 {
579 let period: u64 = 1_000_000 * 1_000_000 / (clock.as_hz() as u64 / divider as u64);
581
582 ticks * period / 1_000_000
583}
584
585fn timeout_to_ticks(timeout: Duration, clock: Rate, divider: u32) -> Option<u64> {
586 let micros = timeout.as_micros();
587 let ticks_per_sec = (clock.as_hz() / divider) as u64;
588
589 micros.checked_mul(ticks_per_sec).map(|n| n / 1_000_000)
590}
591
592#[allow(unused)]
594#[derive(Debug, Clone, Copy)]
595pub enum MwdtStageAction {
596 Off = 0,
598 Interrupt = 1,
600 ResetCpu = 2,
602 ResetSystem = 3,
604}
605
606#[derive(Debug, Clone, Copy)]
611pub enum MwdtStage {
612 Stage0,
614 Stage1,
616 Stage2,
618 Stage3,
620}
621
622pub struct Wdt<TG> {
624 phantom: PhantomData<TG>,
625}
626
627impl<TG> Wdt<TG>
629where
630 TG: TimerGroupInstance,
631{
632 pub fn new() -> Self {
634 TG::configure_wdt_src_clk();
635
636 Self {
637 phantom: PhantomData,
638 }
639 }
640
641 pub fn enable(&mut self) {
643 unsafe { self.set_wdt_enabled(true) };
646 }
647
648 pub fn disable(&mut self) {
650 unsafe { self.set_wdt_enabled(false) };
653 }
654
655 pub unsafe fn set_wdt_enabled(&mut self, enabled: bool) {
663 let reg_block = unsafe { &*TG::register_block() };
664
665 self.set_write_protection(false);
666
667 if !enabled {
668 reg_block.wdtconfig0().write(|w| unsafe { w.bits(0) });
669 } else {
670 reg_block.wdtconfig0().write(|w| w.wdt_en().bit(true));
671
672 reg_block
673 .wdtconfig0()
674 .write(|w| w.wdt_flashboot_mod_en().bit(false));
675
676 #[cfg_attr(esp32, allow(unused_unsafe))]
677 reg_block.wdtconfig0().write(|w| unsafe {
678 w.wdt_en()
679 .bit(true)
680 .wdt_stg0()
681 .bits(MwdtStageAction::ResetSystem as u8)
682 .wdt_cpu_reset_length()
683 .bits(7)
684 .wdt_sys_reset_length()
685 .bits(7)
686 .wdt_stg1()
687 .bits(MwdtStageAction::Off as u8)
688 .wdt_stg2()
689 .bits(MwdtStageAction::Off as u8)
690 .wdt_stg3()
691 .bits(MwdtStageAction::Off as u8)
692 });
693
694 #[cfg(any(esp32c2, esp32c3, esp32c6))]
695 reg_block
696 .wdtconfig0()
697 .modify(|_, w| w.wdt_conf_update_en().set_bit());
698 }
699
700 self.set_write_protection(true);
701 }
702
703 pub fn feed(&mut self) {
705 let reg_block = unsafe { &*TG::register_block() };
706
707 self.set_write_protection(false);
708
709 reg_block.wdtfeed().write(|w| unsafe { w.bits(1) });
710
711 self.set_write_protection(true);
712 }
713
714 fn set_write_protection(&mut self, enable: bool) {
715 let reg_block = unsafe { &*TG::register_block() };
716
717 let wkey = if enable { 0u32 } else { 0x50D8_3AA1u32 };
718
719 reg_block
720 .wdtwprotect()
721 .write(|w| unsafe { w.wdt_wkey().bits(wkey) });
722 }
723
724 pub fn set_timeout(&mut self, stage: MwdtStage, timeout: Duration) {
726 let timeout_raw = (timeout.as_micros() * 10_000 / 125) as u32;
727
728 let reg_block = unsafe { &*TG::register_block() };
729
730 self.set_write_protection(false);
731
732 reg_block
733 .wdtconfig1()
734 .write(|w| unsafe { w.wdt_clk_prescale().bits(1) });
735
736 unsafe {
737 match stage {
738 MwdtStage::Stage0 => reg_block
739 .wdtconfig2()
740 .write(|w| w.wdt_stg0_hold().bits(timeout_raw)),
741 MwdtStage::Stage1 => reg_block
742 .wdtconfig3()
743 .write(|w| w.wdt_stg1_hold().bits(timeout_raw)),
744 MwdtStage::Stage2 => reg_block
745 .wdtconfig4()
746 .write(|w| w.wdt_stg2_hold().bits(timeout_raw)),
747 MwdtStage::Stage3 => reg_block
748 .wdtconfig5()
749 .write(|w| w.wdt_stg3_hold().bits(timeout_raw)),
750 };
751 }
752
753 #[cfg(any(esp32c2, esp32c3, esp32c6))]
754 reg_block
755 .wdtconfig0()
756 .modify(|_, w| w.wdt_conf_update_en().set_bit());
757
758 self.set_write_protection(true);
759 }
760
761 pub fn set_stage_action(&mut self, stage: MwdtStage, action: MwdtStageAction) {
768 let reg_block = unsafe { &*TG::register_block() };
769
770 self.set_write_protection(false);
771
772 match stage {
773 MwdtStage::Stage0 => {
774 reg_block
775 .wdtconfig0()
776 .modify(|_, w| unsafe { w.wdt_stg0().bits(action as u8) });
777 }
778 MwdtStage::Stage1 => {
779 reg_block
780 .wdtconfig0()
781 .modify(|_, w| unsafe { w.wdt_stg1().bits(action as u8) });
782 }
783 MwdtStage::Stage2 => {
784 reg_block
785 .wdtconfig0()
786 .modify(|_, w| unsafe { w.wdt_stg2().bits(action as u8) });
787 }
788 MwdtStage::Stage3 => {
789 reg_block
790 .wdtconfig0()
791 .modify(|_, w| unsafe { w.wdt_stg3().bits(action as u8) });
792 }
793 }
794
795 self.set_write_protection(true);
796 }
797}
798
799impl<TG> crate::private::Sealed for Wdt<TG> where TG: TimerGroupInstance {}
800
801impl<TG> InterruptConfigurable for Wdt<TG>
802where
803 TG: TimerGroupInstance,
804{
805 fn set_interrupt_handler(&mut self, handler: interrupt::InterruptHandler) {
806 let interrupt = TG::wdt_interrupt();
807 unsafe {
808 interrupt::bind_interrupt(interrupt, handler.handler());
809 interrupt::enable(interrupt, handler.priority()).unwrap();
810 }
811 }
812}
813
814impl<TG> Default for Wdt<TG>
815where
816 TG: TimerGroupInstance,
817{
818 fn default() -> Self {
819 Self::new()
820 }
821}
822
823mod asynch {
825 use procmacros::handler;
826
827 use super::*;
828 use crate::asynch::AtomicWaker;
829
830 const NUM_WAKERS: usize = {
831 let timer_per_group = 1 + cfg!(timg_timer1) as usize;
832 NUM_TIMG * timer_per_group
833 };
834
835 static WAKERS: [AtomicWaker; NUM_WAKERS] = [const { AtomicWaker::new() }; NUM_WAKERS];
836
837 pub(super) fn waker(timer: &Timer<'_>) -> &'static AtomicWaker {
838 let index = (timer.timer_number() << 1) | timer.timer_group();
839 &WAKERS[index as usize]
840 }
841
842 #[inline]
843 fn handle_irq(timer: Timer<'_>) {
844 timer.set_interrupt_enabled(false);
845 waker(&timer).wake();
846 }
847
848 #[handler]
853 pub(crate) fn timg0_timer0_handler() {
854 handle_irq(Timer {
855 register_block: TIMG0::regs(),
856 _lifetime: PhantomData,
857 timer: 0,
858 tg: 0,
859 });
860 }
861
862 #[cfg(timg1)]
863 #[handler]
864 pub(crate) fn timg1_timer0_handler() {
865 handle_irq(Timer {
866 register_block: TIMG1::regs(),
867 _lifetime: PhantomData,
868 timer: 0,
869 tg: 1,
870 });
871 }
872
873 #[cfg(timg_timer1)]
874 #[handler]
875 pub(crate) fn timg0_timer1_handler() {
876 handle_irq(Timer {
877 register_block: TIMG0::regs(),
878 _lifetime: PhantomData,
879 timer: 1,
880 tg: 0,
881 });
882 }
883
884 #[cfg(all(timg1, timg_timer1))]
885 #[handler]
886 pub(crate) fn timg1_timer1_handler() {
887 handle_irq(Timer {
888 register_block: TIMG1::regs(),
889 _lifetime: PhantomData,
890 timer: 1,
891 tg: 1,
892 });
893 }
894}
895
896#[cfg(soc_etm)]
898pub mod etm {
899 use super::*;
900 use crate::etm::{EtmEvent, EtmTask};
901
902 pub struct Event {
904 id: u8,
905 }
906
907 pub struct Task {
909 id: u8,
910 }
911
912 impl EtmEvent for Event {
913 fn id(&self) -> u8 {
914 self.id
915 }
916 }
917
918 impl Sealed for Event {}
919
920 impl EtmTask for Task {
921 fn id(&self) -> u8 {
922 self.id
923 }
924 }
925
926 impl Sealed for Task {}
927
928 pub trait Events {
930 fn on_alarm(&self) -> Event;
932 }
933
934 pub trait Tasks {
936 fn cnt_start(&self) -> Task;
938
939 fn cnt_stop(&self) -> Task;
941
942 fn cnt_reload(&self) -> Task;
944
945 fn cnt_cap(&self) -> Task;
947
948 fn alarm_start(&self) -> Task;
951 }
952
953 impl Events for Timer<'_> {
954 fn on_alarm(&self) -> Event {
955 Event {
956 id: 48 + self.timer_group(),
957 }
958 }
959 }
960
961 impl Tasks for Timer<'_> {
962 fn cnt_start(&self) -> Task {
963 Task {
964 id: 88 + self.timer_group(),
965 }
966 }
967
968 fn alarm_start(&self) -> Task {
969 Task {
970 id: 90 + self.timer_group(),
971 }
972 }
973
974 fn cnt_stop(&self) -> Task {
975 Task {
976 id: 92 + self.timer_group(),
977 }
978 }
979
980 fn cnt_reload(&self) -> Task {
981 Task {
982 id: 94 + self.timer_group(),
983 }
984 }
985
986 fn cnt_cap(&self) -> Task {
987 Task {
988 id: 96 + self.timer_group(),
989 }
990 }
991 }
992}