1use crate::clock::{Aclk, Smclk};
11use crate::hw_traits::timer_base::{CCRn, RunningMode, Tbssel, TimerBase};
12use core::convert::Infallible;
13use core::marker::PhantomData;
14
15pub use crate::hw_traits::timer_base::{
16 TimerDiv, TimerExDiv, CCR0, CCR1, CCR2, CCR3, CCR4, CCR5, CCR6,
17};
18
19pub trait CapCmp<C>: CCRn<C> {}
22impl<T: CCRn<C>, C> CapCmp<C> for T {}
23
24pub trait TimerPeriph: TimerBase + CapCmp<CCR0> {
27 type Tbxclk;
29}
30
31pub trait CapCmpTimer3: TimerPeriph + CapCmp<CCR1> + CapCmp<CCR2> {}
34pub trait CapCmpTimer7:
36 TimerPeriph
37 + CapCmp<CCR1>
38 + CapCmp<CCR2>
39 + CapCmp<CCR3>
40 + CapCmp<CCR4>
41 + CapCmp<CCR5>
42 + CapCmp<CCR6>
43{
44}
45
46pub struct TimerConfig<T: TimerPeriph> {
50 _timer: PhantomData<T>,
51 sel: Tbssel,
52 div: TimerDiv,
53 ex_div: TimerExDiv,
54}
55
56impl<T: TimerPeriph> TimerConfig<T> {
57 #[inline]
59 pub fn aclk(_aclk: &Aclk) -> Self {
60 TimerConfig {
61 _timer: PhantomData,
62 sel: Tbssel::Aclk,
63 div: TimerDiv::_1,
64 ex_div: TimerExDiv::_1,
65 }
66 }
67
68 #[inline]
70 pub fn smclk(_smclk: &Smclk) -> Self {
71 TimerConfig {
72 _timer: PhantomData,
73 sel: Tbssel::Smclk,
74 div: TimerDiv::_1,
75 ex_div: TimerExDiv::_1,
76 }
77 }
78
79 #[inline]
81 pub fn tbclk(_pin: T::Tbxclk) -> Self {
82 TimerConfig {
83 _timer: PhantomData,
84 sel: Tbssel::Tbxclk,
85 div: TimerDiv::_1,
86 ex_div: TimerExDiv::_1,
87 }
88 }
89
90 #[inline]
92 pub fn clk_div(self, div: TimerDiv, ex_div: TimerExDiv) -> Self {
93 TimerConfig {
94 _timer: PhantomData,
95 sel: self.sel,
96 div,
97 ex_div,
98 }
99 }
100
101 #[inline]
102 pub(crate) fn write_regs(self, timer: &T) {
103 timer.reset();
104 timer.set_tbidex(self.ex_div);
105 timer.config_clock(self.sel, self.div);
106 }
107}
108
109pub struct TimerParts3<T: CapCmpTimer3> {
111 pub timer: Timer<T>,
113 pub tbxiv: TBxIV<T>,
115 pub subtimer1: SubTimer<T, CCR1>,
117 pub subtimer2: SubTimer<T, CCR2>,
119}
120
121impl<T: CapCmpTimer3> TimerParts3<T> {
122 #[inline(always)]
124 pub fn new(_timer: T, config: TimerConfig<T>) -> Self {
125 config.write_regs(unsafe { &T::steal() });
126 Self {
127 timer: Timer::new(),
128 tbxiv: TBxIV(PhantomData),
129 subtimer1: SubTimer::new(),
130 subtimer2: SubTimer::new(),
131 }
132 }
133}
134
135pub struct TimerParts7<T: CapCmpTimer7> {
137 pub timer: Timer<T>,
139 pub tbxiv: TBxIV<T>,
141 pub subtimer1: SubTimer<T, CCR1>,
143 pub subtimer2: SubTimer<T, CCR2>,
145 pub subtimer3: SubTimer<T, CCR3>,
147 pub subtimer4: SubTimer<T, CCR4>,
149 pub subtimer5: SubTimer<T, CCR5>,
151 pub subtimer6: SubTimer<T, CCR6>,
153}
154
155impl<T: CapCmpTimer7> TimerParts7<T> {
156 #[inline(always)]
158 pub fn new(_timer: T, config: TimerConfig<T>) -> Self {
159 config.write_regs(unsafe { &T::steal() });
160 Self {
161 timer: Timer::new(),
162 tbxiv: TBxIV(PhantomData),
163 subtimer1: SubTimer::new(),
164 subtimer2: SubTimer::new(),
165 subtimer3: SubTimer::new(),
166 subtimer4: SubTimer::new(),
167 subtimer5: SubTimer::new(),
168 subtimer6: SubTimer::new(),
169 }
170 }
171}
172
173pub struct Timer<T: TimerPeriph>(PhantomData<T>);
175
176impl<T: TimerPeriph> Timer<T> {
177 fn new() -> Self {
178 Self(PhantomData)
179 }
180}
181
182pub struct SubTimer<T: CapCmp<C>, C>(PhantomData<T>, PhantomData<C>);
187
188impl<T: CapCmp<C>, C> SubTimer<T, C> {
189 fn new() -> Self {
190 Self(PhantomData, PhantomData)
191 }
192}
193
194pub enum TimerVector {
196 NoInterrupt,
198 SubTimer1,
200 SubTimer2,
202 SubTimer3,
204 SubTimer4,
206 SubTimer5,
208 SubTimer6,
210 MainTimer,
212}
213
214#[inline]
215pub(crate) fn read_tbxiv<T: TimerBase>(timer: &T) -> TimerVector {
216 match timer.tbxiv_rd() {
217 0 => TimerVector::NoInterrupt,
218 2 => TimerVector::SubTimer1,
219 4 => TimerVector::SubTimer2,
220 6 => TimerVector::SubTimer3,
221 8 => TimerVector::SubTimer4,
222 10 => TimerVector::SubTimer5,
223 12 => TimerVector::SubTimer6,
224 14 => TimerVector::MainTimer,
225 _ => unsafe { core::hint::unreachable_unchecked() },
226 }
227}
228
229pub struct TBxIV<T>(PhantomData<T>);
231
232impl<T: TimerBase> TBxIV<T> {
233 #[inline]
234 pub fn interrupt_vector(&mut self) -> TimerVector {
236 let timer = unsafe { T::steal() };
237 read_tbxiv(&timer)
238 }
239}
240
241impl<T: TimerPeriph> Timer<T> {
242 #[inline(always)]
244 pub fn enable_interrupts(&mut self) {
245 let timer = unsafe { T::steal() };
246 timer.tbie_set();
247 }
248
249 #[inline(always)]
251 pub fn disable_interrupts(&mut self) {
252 let timer = unsafe { T::steal() };
253 timer.tbie_clr();
254 }
255
256 #[inline]
257 pub fn start(&mut self, count: u16) {
259 let timer = unsafe { T::steal() };
260 timer.stop();
261 timer.set_ccrn(count);
262 timer.upmode();
263 }
264
265 #[inline]
266 pub fn wait(&mut self) -> nb::Result<(), Infallible> {
268 let timer = unsafe { T::steal() };
269 if timer.tbifg_rd() {
270 timer.tbifg_clr();
271 Ok(())
272 } else {
273 Err(nb::Error::WouldBlock)
274 }
275 }
276
277 #[inline]
278 pub fn pause(&mut self) {
280 let timer = unsafe { T::steal() };
281 timer.stop();
282 }
283
284 #[inline]
285 pub fn resume(&mut self) {
287 let timer = unsafe { T::steal() };
288 timer.resume(RunningMode::Up);
289 }
290
291 #[inline]
292 pub fn count(&mut self) -> u16 {
294 let timer = unsafe { T::steal() };
295 timer.get_tbxr()
296 }
297}
298
299impl<T: CapCmp<C>, C> SubTimer<T, C> {
300 #[inline]
301 pub fn set_count(&mut self, count: u16) {
306 let timer = unsafe { T::steal() };
307 timer.set_ccrn(count);
308 timer.ccifg_clr();
309 }
310
311 #[inline]
312 pub fn wait(&mut self) -> nb::Result<(), Infallible> {
314 let timer = unsafe { T::steal() };
315 if timer.ccifg_rd() {
316 timer.ccifg_clr();
317 Ok(())
318 } else {
319 Err(nb::Error::WouldBlock)
320 }
321 }
322
323 #[inline(always)]
324 pub fn enable_interrupts(&mut self) {
326 let timer = unsafe { T::steal() };
327 timer.ccie_set();
328 }
329
330 #[inline(always)]
331 pub fn disable_interrupts(&mut self) {
333 let timer = unsafe { T::steal() };
334 timer.ccie_clr();
335 }
336}
337
338#[cfg(feature = "embedded-hal-02")]
339mod ehal02 {
340 use super::*;
341 use embedded_hal_02::timer::{Cancel, CountDown, Periodic};
342
343 impl<T: TimerPeriph + CapCmp<CCR0>> CountDown for Timer<T> {
344 type Time = u16;
345
346 #[inline]
347 fn start<U: Into<Self::Time>>(&mut self, count: U) {
348 self.start(count.into())
349 }
350
351 #[inline]
352 fn wait(&mut self) -> nb::Result<(), void::Void> {
353 self.wait().map_err(|_| nb::Error::WouldBlock)
354 }
355 }
356
357 impl<T: TimerPeriph + CapCmp<CCR0>> Cancel for Timer<T> {
358 type Error = void::Void;
359
360 #[inline(always)]
361 fn cancel(&mut self) -> Result<(), Self::Error> {
362 self.pause();
363 Ok(())
364 }
365 }
366
367 impl<T: TimerPeriph> Periodic for Timer<T> {}
368}