Skip to main content

pic32_hal/timer/
timer_b.rs

1//! Timer type B
2
3use super::Clocking;
4use crate::pac::{TMR2, TMR3, TMR4, TMR5};
5
6/// Clock pre scaler configuration for timer type B
7#[derive(Clone, Copy, Debug)]
8#[repr(u8)]
9pub enum ClockPrescale {
10    /// 1:1 prescale value
11    Prescale1 = 0,
12
13    /// 1:2 prescale value
14    Prescale2 = 1,
15
16    /// 1:4 prescale value
17    Prescale4 = 2,
18
19    /// 1:8 prescale value
20    Prescale8 = 3,
21
22    /// 1:16 prescale value
23    Prescale16 = 4,
24
25    /// 1:32 prescale value
26    Prescale32 = 5,
27
28    /// 1:64 prescale value
29    Prescale64 = 6,
30
31    /// 1:256 prescale value
32    Prescale256 = 7,
33}
34
35/// HAL struct of timer type B
36pub struct Timer<TIMER> {
37    timer: TIMER,
38}
39
40macro_rules! timerb_impl {
41    ($constructor: ident, $timer: ty) => {
42        impl Timer<$timer> {
43            /// Initialize the timer
44            pub fn $constructor(
45                timer: $timer,
46                clocking: Clocking,
47                prescale: ClockPrescale,
48                period: u16,
49                stop_in_idle_mode: bool,
50            ) -> Self {
51                timer.cont.write(|w| unsafe { w
52                    .sidl().bit(stop_in_idle_mode)
53                    .tgate().bit(clocking == Clocking::PbclockGated)
54                    .tckps().bits(prescale as u8)
55                    .tcs().bit(clocking == Clocking::External)
56                });
57                timer.tmr.write(|w| unsafe { w.tmr().bits(0) });
58                timer.pr.write(|w| unsafe { w.pr().bits(period as u32) });
59                timer.contset.write(|w| w.on().set_bit());
60
61                Self { timer }
62            }
63
64            /// Turn the timer off
65            pub fn free(self) -> $timer {
66                self.timer.contclr.write(|w| w.on().set_bit());
67                self.timer
68            }
69
70            /// Read the current timer count value (TMR register)
71            pub fn tmr(&self) -> u16 {
72                self.timer.tmr.read().tmr().bits() as u16
73            }
74
75            /// Set the current timer count value (TMR register)
76            pub fn set_tmr(&mut self, tmr: u16) {
77                self.timer.tmr.write(|w| unsafe { w.tmr().bits(tmr as u32) });
78            }
79
80            /// Read the maximum value (PR register)
81            pub fn pr(&self) -> u16 {
82                self.timer.pr.read().pr().bits() as u16
83            }
84
85            /// Set the maximum value (PR register)
86            pub fn set_pr(&mut self, period: u16) {
87                self.timer.pr.write(|w| unsafe { w.pr().bits(period as u32) });
88            }
89        }
90    };
91}
92
93timerb_impl!(timer2, TMR2);
94timerb_impl!(timer3, TMR3);
95timerb_impl!(timer4, TMR4);
96timerb_impl!(timer5, TMR5);
97
98/// HAL struct for a pair of timers of type B (32-bit mode)
99pub struct Timer32<TIMERL, TIMERH> {
100    timer_low: TIMERL,
101    timer_high: TIMERH,
102}
103
104macro_rules! timer32_impl {
105    ($constructor: ident, $timer_low: ty, $timer_high: ty) => {
106        impl Timer32<$timer_low, $timer_high> {
107            /// Initialize the timer
108            pub fn $constructor(
109                timer_low: $timer_low,
110                timer_high: $timer_high,
111                clocking: Clocking,
112                prescale: ClockPrescale,
113                period: u32,
114                stop_in_idle_mode: bool,
115            ) -> Self {
116                timer_low.cont.write(|w| unsafe { w
117                    .sidl().bit(stop_in_idle_mode)
118                    .tgate().bit(clocking == Clocking::PbclockGated)
119                    .tckps().bits(prescale as u8)
120                    .t32().set_bit()
121                    .tcs().bit(clocking == Clocking::External)
122                });
123                timer_high.cont.write(|w| w.sidl().bit(stop_in_idle_mode));
124
125                timer_low.tmr.write(|w| unsafe { w.tmr().bits(0) });
126                timer_low.pr.write(|w| unsafe { w.pr().bits(period) });
127                timer_low.contset.write(|w| w.on().set_bit());
128
129                Self { timer_low, timer_high }
130            }
131
132            /// Turn the timer off
133            pub fn free(self) -> ($timer_low, $timer_high) {
134                self.timer_low.contclr.write(|w| w.on().set_bit());
135                self.timer_high.contclr.write(|w| w.on().set_bit());
136                (self.timer_low, self.timer_high)
137            }
138
139            /// Read the current timer count value (TMR register)
140            pub fn tmr(&self) -> u32 {
141                self.timer_low.tmr.read().tmr().bits()
142            }
143
144            /// Set the current timer count value (TMR register)
145            pub fn set_tmr(&mut self, tmr: u32) {
146                self.timer_low.tmr.write(|w| unsafe { w.tmr().bits(tmr) });
147            }
148
149            /// Read the maximum value (PR register)
150            pub fn pr(&self) -> u32 {
151                self.timer_low.pr.read().pr().bits()
152            }
153
154            /// Set the maximum value (PR register)
155            pub fn set_pr(&mut self, period: u32) {
156                self.timer_low.pr.write(|w| unsafe { w.pr().bits(period) });
157            }
158        }
159    };
160}
161
162timer32_impl!(timer2_3, TMR2, TMR3);
163timer32_impl!(timer4_5, TMR4, TMR5);