pic32_hal/timer/
timer_a.rs

1//! Timer type A
2
3use super::Clocking;
4use crate::pac::TMR1;
5use core::marker::PhantomData;
6
7/// Clock pre scaler configuration for timer type A
8#[derive(Clone, Copy, Debug)]
9#[repr(u8)]
10pub enum ClockPrescale {
11    /// 1:1 prescale value
12    Prescale1 = 0,
13
14    /// 1:8 prescale value
15    Prescale8 = 1,
16
17    /// 1:64 prescale value
18    Prescale64 = 2,
19
20    /// 1:256 prescale value
21    Prescale256 = 3,
22}
23
24/// Marker for Synchronous operation
25pub struct TimerSynchronous;
26
27/// Marker for Asynchronous operation
28pub struct TimerAsynchronous;
29
30/// HAL struct for Timer1 (timer type A)
31pub struct Timer<MODE> {
32    timer: TMR1,
33    _marker: PhantomData<MODE>,
34}
35
36impl<MODE> Timer<MODE> {
37    /// Initalize the timer for synchronous operation
38    ///
39    /// The timer peripheral is running synchronously with the PBCLOCK and
40    /// cannot count external pulses when the PBCLOCK is gated.
41    pub fn timer1_synchronous(
42        timer: TMR1,
43        clocking: Clocking,
44        prescale: ClockPrescale,
45        period: u16,
46        stop_in_idle_mode: bool,
47    ) -> Timer<TimerSynchronous> {
48        timer.cont.write(|w| unsafe { w
49            .sidl().bit(stop_in_idle_mode)
50            .tgate().bit(clocking == Clocking::PbclockGated)
51            .tckps().bits(prescale as u8)
52            .tsync().set_bit()
53            .tcs().bit(clocking == Clocking::External)
54        });
55        timer.tmr.write(|w| unsafe { w.tmr().bits(0) });
56        timer.pr.write(|w| unsafe { w.pr().bits(period as u32) });
57        timer.contset.write(|w| w.on().set_bit());
58
59        Timer { timer, _marker: PhantomData }
60    }
61
62    /// Initialize the timer for asynchronous operation
63    ///
64    /// The timer will operate asynchronously with respect and independently
65    /// from to the PBCLOCK When operating asynchronously, the timer is always
66    /// external clocked, e.g. by a 32 kHz clock source or the like.
67    pub fn timer1_asynchronous(
68        timer: TMR1,
69        prescale: ClockPrescale,
70        period: u16,
71        stop_in_idle_mode: bool,
72    ) -> Timer<TimerAsynchronous> {
73        timer.tmr.write(|w| unsafe { w.tmr().bits(0) });
74        timer.pr.write(|w| unsafe { w.pr().bits(period as u32) });
75        timer.cont.write(|w| unsafe { w
76            .sidl().bit(stop_in_idle_mode)
77            .twdis().clear_bit()
78            .tgate().clear_bit()
79            .tckps().bits(prescale as u8)
80            .tsync().clear_bit()
81            .tcs().set_bit()
82        });
83        timer.contset.write(|w| w.on().set_bit());
84
85        Timer { timer, _marker: PhantomData }
86    }
87
88    /// Turn the timer off
89    pub fn free(self) -> TMR1 {
90        self.timer.contclr.write(|w| w.on().set_bit());
91        self.timer
92    }
93
94    /// Read the current timer count value
95    pub fn tmr(&self) -> u16 {
96        self.timer.tmr.read().tmr().bits() as u16
97    }
98
99    /// Read the period (PR register)
100    pub fn period(&self) -> u16 {
101        self.timer.pr.read().pr().bits() as u16
102    }
103
104    /// Write to the period (PR register)
105    pub fn set_period(&mut self, period: u16) {
106        self.timer.pr.write(|w| unsafe { w.pr().bits(period as u32) });
107    }
108}
109
110impl Timer<TimerSynchronous> {
111    /// Set the current timer count value
112    pub fn set_tmr(&mut self, tmr: u16) {
113        self.timer.tmr.write(|w| unsafe { w.tmr().bits(tmr as u32) });
114    }
115}
116
117impl Timer<TimerAsynchronous> {
118    /// Set the current timer count value
119    pub fn set_tmr(&mut self, tmr: u16) {
120        while self.timer.cont.read().twip().bit_is_set() {}
121        self.timer.tmr.write(|w| unsafe { w.tmr().bits(tmr as u32) });
122    }
123}