1use core::marker::PhantomData;
4
5use embassy_hal_internal::PeripheralType;
6use embassy_sync::waitqueue::AtomicWaker;
7
8#[cfg(not(stm32l0))]
9pub mod complementary_pwm;
10pub mod input_capture;
11pub mod low_level;
12pub mod one_pulse;
13pub mod pwm_input;
14pub mod qei;
15pub mod ringbuffered;
16pub mod simple_pwm;
17
18use crate::dma::word::Word;
19use crate::fmt::Debuggable;
20use crate::interrupt;
21use crate::rcc::RccPeripheral;
22
23#[derive(Clone, Copy)]
25pub enum Channel {
26 Ch1,
28 Ch2,
30 Ch3,
32 Ch4,
34}
35
36impl Channel {
37 pub fn index(&self) -> usize {
39 match self {
40 Channel::Ch1 => 0,
41 Channel::Ch2 => 1,
42 Channel::Ch3 => 2,
43 Channel::Ch4 => 3,
44 }
45 }
46}
47
48pub enum Ch1 {}
50pub enum Ch2 {}
52pub enum Ch3 {}
54pub enum Ch4 {}
56
57#[allow(private_bounds)]
59pub trait TimerChannel: SealedTimerChannel {
60 const CHANNEL: Channel;
62}
63
64trait SealedTimerChannel {}
65
66impl TimerChannel for Ch1 {
67 const CHANNEL: Channel = Channel::Ch1;
68}
69
70impl TimerChannel for Ch2 {
71 const CHANNEL: Channel = Channel::Ch2;
72}
73
74impl TimerChannel for Ch3 {
75 const CHANNEL: Channel = Channel::Ch3;
76}
77
78impl TimerChannel for Ch4 {
79 const CHANNEL: Channel = Channel::Ch4;
80}
81
82impl SealedTimerChannel for Ch1 {}
83impl SealedTimerChannel for Ch2 {}
84impl SealedTimerChannel for Ch3 {}
85impl SealedTimerChannel for Ch4 {}
86
87#[derive(Clone, Copy)]
89pub enum BkIn {
90 BkIn1,
92 BkIn2,
94}
95
96impl BkIn {
97 pub fn index(&self) -> usize {
99 match self {
100 BkIn::BkIn1 => 0,
101 BkIn::BkIn2 => 1,
102 }
103 }
104}
105
106pub enum BkIn1 {}
108pub enum BkIn2 {}
110
111#[allow(private_bounds)]
113pub trait BreakInput: SealedBreakInput {
114 const INPUT: BkIn;
116}
117
118trait SealedBreakInput {}
119
120impl BreakInput for BkIn1 {
121 const INPUT: BkIn = BkIn::BkIn1;
122}
123
124impl BreakInput for BkIn2 {
125 const INPUT: BkIn = BkIn::BkIn2;
126}
127
128impl SealedBreakInput for BkIn1 {}
129impl SealedBreakInput for BkIn2 {}
130
131#[derive(Clone, Copy, PartialEq, Eq, Debug)]
133#[cfg_attr(feature = "defmt", derive(defmt::Format))]
134pub enum TimerBits {
135 Bits16,
137 #[cfg(not(stm32l0))]
139 Bits32,
140}
141
142struct State {
143 up_waker: AtomicWaker,
144 cc_waker: [AtomicWaker; 4],
145}
146
147impl State {
148 const fn new() -> Self {
149 Self {
150 up_waker: AtomicWaker::new(),
151 cc_waker: [const { AtomicWaker::new() }; 4],
152 }
153 }
154}
155
156trait SealedInstance: RccPeripheral + PeripheralType {
157 fn state() -> &'static State;
159}
160
161#[allow(private_bounds)]
163pub trait CoreInstance: SealedInstance + 'static {
164 type UpdateInterrupt: interrupt::typelevel::Interrupt;
166
167 type Word: Word
169 + TryInto<u16, Error: Debuggable>
170 + From<u16>
171 + TryFrom<u32, Error: Debuggable>
172 + Into<u32>
173 + TryFrom<u64, Error: Debuggable>;
174
175 fn regs() -> *mut ();
179}
180pub trait BasicNoCr2Instance: CoreInstance {}
182pub trait BasicInstance: BasicNoCr2Instance {}
184
185pub trait GeneralInstance1Channel: CoreInstance {
187 type CaptureCompareInterrupt: interrupt::typelevel::Interrupt;
189}
190
191pub trait GeneralInstance2Channel: GeneralInstance1Channel {
193 type TriggerInterrupt: interrupt::typelevel::Interrupt;
195}
196
197trait General4ChBlankSealed {
203 fn enable_outputs(&self) {}
211}
212
213#[allow(private_bounds)]
215pub trait GeneralInstance4Channel: BasicInstance + GeneralInstance2Channel + General4ChBlankSealed {}
216
217pub trait GeneralInstance32bit4Channel: GeneralInstance4Channel {}
219
220pub trait AdvancedInstance1Channel: BasicNoCr2Instance + GeneralInstance1Channel {
222 type CommunicationInterrupt: interrupt::typelevel::Interrupt;
224 type BreakInputInterrupt: interrupt::typelevel::Interrupt;
226}
227pub trait AdvancedInstance2Channel: BasicInstance + GeneralInstance2Channel + AdvancedInstance1Channel {}
230
231pub trait AdvancedInstance4Channel: AdvancedInstance2Channel + GeneralInstance4Channel {}
233
234pin_trait!(TimerPin, GeneralInstance4Channel, TimerChannel, @A);
235pin_trait!(ExternalTriggerPin, GeneralInstance4Channel, @A);
236
237pin_trait!(TimerComplementaryPin, AdvancedInstance4Channel, TimerChannel, @A);
238
239pin_trait!(BreakInputPin, AdvancedInstance4Channel, BreakInput, @A);
240
241pin_trait!(BreakInputComparator1Pin, AdvancedInstance4Channel, BreakInput, @A);
242pin_trait!(BreakInputComparator2Pin, AdvancedInstance4Channel, BreakInput, @A);
243
244dma_trait!(UpDma, BasicInstance);
246
247dma_trait!(Dma, GeneralInstance4Channel, TimerChannel);
248
249#[allow(unused)]
250macro_rules! impl_core_timer {
251 ($inst:ident, $bits:ident) => {
252 impl SealedInstance for crate::peripherals::$inst {
253 fn state() -> &'static State {
254 static STATE: State = State::new();
255 &STATE
256 }
257 }
258
259 impl CoreInstance for crate::peripherals::$inst {
260 type UpdateInterrupt = crate::_generated::peripheral_interrupts::$inst::UP;
261 type Word = $bits;
262
263 fn regs() -> *mut () {
264 crate::pac::$inst.as_ptr()
265 }
266 }
267 };
268}
269
270#[allow(unused)]
271macro_rules! impl_general_1ch {
272 ($inst:ident) => {
273 impl GeneralInstance1Channel for crate::peripherals::$inst {
274 type CaptureCompareInterrupt = crate::_generated::peripheral_interrupts::$inst::CC;
275 }
276 };
277}
278
279#[allow(unused)]
280macro_rules! impl_general_2ch {
281 ($inst:ident) => {
282 impl GeneralInstance2Channel for crate::peripherals::$inst {
283 type TriggerInterrupt = crate::_generated::peripheral_interrupts::$inst::TRG;
284 }
285 };
286}
287
288#[allow(unused)]
289macro_rules! impl_advanced_1ch {
290 ($inst:ident) => {
291 impl AdvancedInstance1Channel for crate::peripherals::$inst {
292 type CommunicationInterrupt = crate::_generated::peripheral_interrupts::$inst::COM;
293 type BreakInputInterrupt = crate::_generated::peripheral_interrupts::$inst::BRK;
294 }
295 };
296}
297
298#[allow(unused)]
301macro_rules! impl_general_4ch_blank_sealed {
302 ($inst:ident) => {
303 impl General4ChBlankSealed for crate::peripherals::$inst {
304 fn enable_outputs(&self) {
305 unsafe { crate::pac::timer::Tim1chCmp::from_ptr(Self::regs()) }
306 .bdtr()
307 .modify(|w| w.set_moe(true));
308 }
309 }
310 };
311}
312
313foreach_interrupt! {
314 ($inst:ident, timer, TIM_BASIC, UP, $irq:ident) => {
315 impl_core_timer!($inst, u16);
316 impl BasicNoCr2Instance for crate::peripherals::$inst {}
317 impl BasicInstance for crate::peripherals::$inst {}
318 };
319
320 ($inst:ident, timer, TIM_1CH, UP, $irq:ident) => {
321 impl_core_timer!($inst, u16);
322 impl BasicNoCr2Instance for crate::peripherals::$inst {}
323 impl BasicInstance for crate::peripherals::$inst {}
324 impl_general_1ch!($inst);
325 impl_general_2ch!($inst);
326 impl GeneralInstance4Channel for crate::peripherals::$inst {}
327 impl General4ChBlankSealed for crate::peripherals::$inst {}
328 };
329
330 ($inst:ident, timer, TIM_2CH, UP, $irq:ident) => {
331 impl_core_timer!($inst, u16);
332 impl BasicNoCr2Instance for crate::peripherals::$inst {}
333 impl BasicInstance for crate::peripherals::$inst {}
334 impl_general_1ch!($inst);
335 impl_general_2ch!($inst);
336 impl GeneralInstance4Channel for crate::peripherals::$inst {}
337 impl General4ChBlankSealed for crate::peripherals::$inst {}
338 };
339
340 ($inst:ident, timer, TIM_GP16, UP, $irq:ident) => {
341 impl_core_timer!($inst, u16);
342 impl BasicNoCr2Instance for crate::peripherals::$inst {}
343 impl BasicInstance for crate::peripherals::$inst {}
344 impl_general_1ch!($inst);
345 impl_general_2ch!($inst);
346 impl GeneralInstance4Channel for crate::peripherals::$inst {}
347 impl General4ChBlankSealed for crate::peripherals::$inst {}
348 };
349
350 ($inst:ident, timer, TIM_GP32, UP, $irq:ident) => {
351 impl_core_timer!($inst, u32);
352 impl BasicNoCr2Instance for crate::peripherals::$inst {}
353 impl BasicInstance for crate::peripherals::$inst {}
354 impl_general_1ch!($inst);
355 impl_general_2ch!($inst);
356 impl GeneralInstance4Channel for crate::peripherals::$inst {}
357 impl GeneralInstance32bit4Channel for crate::peripherals::$inst {}
358 impl General4ChBlankSealed for crate::peripherals::$inst {}
359 };
360
361 ($inst:ident, timer, TIM_1CH_CMP, UP, $irq:ident) => {
362 impl_core_timer!($inst, u16);
363 impl BasicNoCr2Instance for crate::peripherals::$inst {}
364 impl BasicInstance for crate::peripherals::$inst {}
365 impl_general_1ch!($inst);
366 impl_general_2ch!($inst);
367 impl GeneralInstance4Channel for crate::peripherals::$inst {}
368 impl_general_4ch_blank_sealed!($inst);
369 impl_advanced_1ch!($inst);
370 impl AdvancedInstance2Channel for crate::peripherals::$inst {}
371 impl AdvancedInstance4Channel for crate::peripherals::$inst {}
372 };
373
374 ($inst:ident, timer, TIM_2CH_CMP, UP, $irq:ident) => {
375 impl_core_timer!($inst, u16);
376 impl BasicNoCr2Instance for crate::peripherals::$inst {}
377 impl BasicInstance for crate::peripherals::$inst {}
378 impl_general_1ch!($inst);
379 impl_general_2ch!($inst);
380 impl GeneralInstance4Channel for crate::peripherals::$inst {}
381 impl_general_4ch_blank_sealed!($inst);
382 impl_advanced_1ch!($inst);
383 impl AdvancedInstance2Channel for crate::peripherals::$inst {}
384 impl AdvancedInstance4Channel for crate::peripherals::$inst {}
385 };
386
387 ($inst:ident, timer, TIM_ADV, UP, $irq:ident) => {
388 impl_core_timer!($inst, u16);
389 impl BasicNoCr2Instance for crate::peripherals::$inst {}
390 impl BasicInstance for crate::peripherals::$inst {}
391 impl_general_1ch!($inst);
392 impl_general_2ch!($inst);
393 impl GeneralInstance4Channel for crate::peripherals::$inst {}
394 impl_general_4ch_blank_sealed!($inst);
395 impl_advanced_1ch!($inst);
396 impl AdvancedInstance2Channel for crate::peripherals::$inst {}
397 impl AdvancedInstance4Channel for crate::peripherals::$inst {}
398 };
399}
400
401pub struct UpdateInterruptHandler<T: CoreInstance> {
403 _phantom: PhantomData<T>,
404}
405
406impl<T: CoreInstance> interrupt::typelevel::Handler<T::UpdateInterrupt> for UpdateInterruptHandler<T> {
407 unsafe fn on_interrupt() {
408 let regs = crate::pac::timer::TimCore::from_ptr(T::regs());
409
410 let sr = regs.sr().read();
412
413 let bits = sr.0 & 0x00000001;
415
416 regs.dier().modify(|w| w.0 &= !bits);
418
419 if sr.uif() {
421 T::state().up_waker.wake();
422 }
423 }
424}
425
426pub struct CaptureCompareInterruptHandler<T: GeneralInstance1Channel> {
428 _phantom: PhantomData<T>,
429}
430
431impl<T: GeneralInstance1Channel> interrupt::typelevel::Handler<T::CaptureCompareInterrupt>
432 for CaptureCompareInterruptHandler<T>
433{
434 unsafe fn on_interrupt() {
435 let regs = crate::pac::timer::TimGp16::from_ptr(T::regs());
436
437 let sr = regs.sr().read();
439
440 let bits = sr.0 & 0x0000001E;
442
443 regs.dier().modify(|w| w.0 &= !bits);
445
446 for ch in 0..4 {
448 if sr.ccif(ch) {
449 T::state().cc_waker[ch].wake();
450 }
451 }
452 }
453}