da14531_hal/
timer.rs

1use crate::{
2    nvic::{Irq, Nvic},
3    pac::{CRG_TOP, TIMER0},
4};
5
6const SYSTEM_CLOCK_FREQ: u32 = 16_000_000;
7const LOW_POWER_CLOCK_FREQ: u32 = 32_000;
8
9/// Extension trait that constrains the `SYS_WDOG` peripheral
10pub trait Timer0Ext {
11    /// Constrains the `SYS_WDOG` peripheral so it plays nicely with the other abstractions
12    fn constrain(self) -> Timer0;
13}
14
15impl Timer0Ext for TIMER0 {
16    fn constrain(self) -> Timer0 {
17        Timer0 { timer: self }
18    }
19}
20
21#[derive(Clone, Copy)]
22#[repr(u8)]
23pub enum BaseClockDiv {
24    Div1 = 0,
25    Div2 = 1,
26    Div4 = 2,
27    Div8 = 3,
28}
29
30#[derive(Clone, Copy)]
31#[repr(u8)]
32pub enum ClockSel {
33    SystemClock = 1,
34    LowPowerClock = 0,
35}
36
37#[derive(Clone, Copy)]
38#[repr(u8)]
39pub enum PwmMode {
40    SystemClock = 1,
41    High = 0,
42}
43
44#[derive(Clone, Copy)]
45#[repr(u8)]
46pub enum TimerClockDiv {
47    Off = 1,
48    Div10 = 0,
49}
50
51pub enum Timer2PwmChannel {
52    Pwm2,
53    Pwm3,
54    Pwm4,
55    Pwm5,
56    Pwm6,
57    Pwm7,
58}
59
60pub struct Timer0 {
61    timer: TIMER0,
62}
63
64impl Timer0 {
65    pub fn start(&mut self) {
66        self.timer
67            .timer0_ctrl_reg
68            .modify(|_, w| w.tim0_ctrl().set_bit());
69    }
70
71    pub fn stop(&mut self) {
72        self.timer
73            .timer0_ctrl_reg
74            .modify(|_, w| w.tim0_ctrl().clear_bit());
75    }
76
77    pub fn enable_clock(&mut self) {
78        let crg_top = unsafe { &*CRG_TOP::ptr() };
79        crg_top.clk_per_reg.modify(|_, w| w.tmr_enable().set_bit());
80    }
81
82    pub fn set_clock_div(&mut self, div: BaseClockDiv) {
83        let crg_top = unsafe { &*CRG_TOP::ptr() };
84        crg_top
85            .clk_per_reg
86            .modify(|_, w| unsafe { w.tmr_div().bits(div as u8) })
87    }
88
89    pub fn init(
90        &mut self,
91        interrupt_controller: &mut Nvic,
92        clk_sel: ClockSel,
93        pwm_mode: PwmMode,
94        clk_div: TimerClockDiv,
95    ) {
96        self.timer.timer0_ctrl_reg.modify(|_, w| {
97            w.tim0_clk_sel().bit(clk_sel as u8 == 1);
98            w.pwm_mode().bit(pwm_mode as u8 == 1);
99            w.tim0_clk_div().bit(clk_div as u8 == 1);
100            w
101        });
102
103        interrupt_controller.set_priority(Irq::SwTim0, 2);
104        interrupt_controller.enable_irq(Irq::SwTim0);
105    }
106
107    pub fn set_pwm(&mut self, pwm_on: u16, pwm_high: u16, pwm_low: u16) {
108        self.timer
109            .timer0_on_reg
110            .modify(|_, w| unsafe { w.tim0_on().bits(pwm_on) });
111        self.timer
112            .timer0_reload_m_reg
113            .modify(|_, w| unsafe { w.tim0_m().bits(pwm_high) });
114        self.timer
115            .timer0_reload_n_reg
116            .modify(|_, w| unsafe { w.tim0_n().bits(pwm_low) });
117    }
118
119    pub fn set_pwm_on(&mut self, pwm_on: u16) {
120        self.timer
121            .timer0_on_reg
122            .modify(|_, w| unsafe { w.tim0_on().bits(pwm_on) });
123    }
124
125    pub fn set_pwm_high(&mut self, pwm_high: u16) {
126        self.timer
127            .timer0_reload_m_reg
128            .modify(|_, w| unsafe { w.tim0_m().bits(pwm_high) });
129    }
130
131    pub fn set_pwm_low(&mut self, pwm_low: u16) {
132        self.timer
133            .timer0_reload_n_reg
134            .modify(|_, w| unsafe { w.tim0_n().bits(pwm_low) });
135    }
136
137    pub fn register_handler(&self, handler: fn()) {
138        unsafe {
139            TIMER0_HANDLER = Some(handler);
140        }
141    }
142
143    pub fn init_triple_pwm(&mut self, clk_sel: ClockSel, freq_hz: u32) {
144        let pwm_freq = match clk_sel {
145            ClockSel::SystemClock => ((SYSTEM_CLOCK_FREQ / freq_hz) - 1) as u16,
146            ClockSel::LowPowerClock => ((LOW_POWER_CLOCK_FREQ / freq_hz) - 1) as u16,
147        };
148
149        self.timer
150            .triple_pwm_ctrl_reg
151            .modify(|_, w| w.triple_pwm_clk_sel().bit(clk_sel as u8 == 1));
152
153        self.timer
154            .triple_pwm_frequency
155            .modify(|_, w| unsafe { w.pwm_freq().bits(pwm_freq) })
156    }
157
158    pub fn start_triple_pwm(&mut self) {
159        self.timer
160            .triple_pwm_ctrl_reg
161            .modify(|_, w| w.triple_pwm_enable().set_bit());
162    }
163
164    pub fn stop_triple_pwm(&mut self) {
165        self.timer
166            .triple_pwm_ctrl_reg
167            .modify(|_, w| w.triple_pwm_enable().clear_bit());
168    }
169
170    pub fn set_triple_pwm_duty_cycle(&mut self, channel: Timer2PwmChannel, start: u16, end: u16) {
171        match channel {
172            Timer2PwmChannel::Pwm2 => {
173                self.timer
174                    .pwm2_start_cycle
175                    .write(|w| unsafe { w.start_cycle().bits(start) });
176                self.timer
177                    .pwm2_end_cycle
178                    .write(|w| unsafe { w.end_cycle().bits(end) });
179            }
180            Timer2PwmChannel::Pwm3 => {
181                self.timer
182                    .pwm3_start_cycle
183                    .write(|w| unsafe { w.start_cycle().bits(start) });
184                self.timer
185                    .pwm3_end_cycle
186                    .write(|w| unsafe { w.end_cycle().bits(end) });
187            }
188            Timer2PwmChannel::Pwm4 => {
189                self.timer
190                    .pwm4_start_cycle
191                    .write(|w| unsafe { w.start_cycle().bits(start) });
192                self.timer
193                    .pwm4_end_cycle
194                    .write(|w| unsafe { w.end_cycle().bits(end) });
195            }
196            Timer2PwmChannel::Pwm5 => {
197                self.timer
198                    .pwm5_start_cycle
199                    .write(|w| unsafe { w.start_cycle().bits(start) });
200                self.timer
201                    .pwm5_end_cycle
202                    .write(|w| unsafe { w.end_cycle().bits(end) });
203            }
204            Timer2PwmChannel::Pwm6 => {
205                self.timer
206                    .pwm6_start_cycle
207                    .write(|w| unsafe { w.start_cycle().bits(start) });
208                self.timer
209                    .pwm6_end_cycle
210                    .write(|w| unsafe { w.end_cycle().bits(end) });
211            }
212            Timer2PwmChannel::Pwm7 => {
213                self.timer
214                    .pwm7_start_cycle
215                    .write(|w| unsafe { w.start_cycle().bits(start) });
216                self.timer
217                    .pwm7_end_cycle
218                    .write(|w| unsafe { w.end_cycle().bits(end) });
219            }
220        }
221    }
222}
223
224#[no_mangle]
225pub unsafe extern "C" fn SWTIM_Handler() {
226    if let Some(handler) = TIMER0_HANDLER {
227        handler();
228    }
229}
230
231static mut TIMER0_HANDLER: Option<fn()> = None;