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
9pub trait Timer0Ext {
11 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;