1use core::marker::PhantomData;
8
9use embassy_hal_internal::Peripheral;
10use embassy_sync::waitqueue::AtomicWaker;
11
12pub mod complementary_pwm;
13pub mod input_capture;
14pub mod low_level;
15pub mod pwm_input;
16pub mod qei;
17pub mod simple_pwm;
18
19use crate::interrupt;
20use crate::rcc::RccPeripheral;
21
22#[derive(Clone, Copy)]
24pub enum Channel {
25 Ch1,
27 Ch2,
29 Ch3,
31 Ch4,
33}
34
35impl Channel {
36 pub fn index(&self) -> usize {
38 match self {
39 Channel::Ch1 => 0,
40 Channel::Ch2 => 1,
41 Channel::Ch3 => 2,
42 Channel::Ch4 => 3,
43 }
44 }
45}
46
47#[derive(Clone, Copy, PartialEq, Eq, Debug)]
49#[cfg_attr(feature = "defmt", derive(defmt::Format))]
50pub enum TimerBits {
51 Bits16,
53 #[cfg(py32f072)]
54 Bits32,
56}
57
58struct State {
59 up_waker: AtomicWaker,
60 cc_waker: [AtomicWaker; 4],
61}
62
63impl State {
64 const fn new() -> Self {
65 const NEW_AW: AtomicWaker = AtomicWaker::new();
66 Self {
67 up_waker: NEW_AW,
68 cc_waker: [NEW_AW; 4],
69 }
70 }
71}
72
73trait SealedInstance: RccPeripheral + Peripheral<P = Self> {
74 fn state() -> &'static State;
76}
77
78#[allow(private_bounds)]
80pub trait CoreInstance: SealedInstance + 'static {
81 type UpdateInterrupt: interrupt::typelevel::Interrupt;
83
84 const BITS: TimerBits;
86
87 fn regs() -> *mut ();
91}
92pub trait BasicNoCr2Instance: CoreInstance {}
94pub trait BasicInstance: BasicNoCr2Instance {}
96
97pub trait GeneralInstance1Channel: CoreInstance {
99 type CaptureCompareInterrupt: interrupt::typelevel::Interrupt;
101}
102
103pub trait GeneralInstance2Channel: GeneralInstance1Channel {
105 type TriggerInterrupt: interrupt::typelevel::Interrupt;
107}
108
109trait General4ChBlankSealed {
115 fn enable_outputs(&self) {}
123}
124
125#[allow(private_bounds)]
127pub trait GeneralInstance4Channel:
128 BasicInstance + GeneralInstance2Channel + General4ChBlankSealed
129{
130}
131
132pub trait GeneralInstance32bit4Channel: GeneralInstance4Channel {}
134
135pub trait AdvancedInstance1Channel: BasicNoCr2Instance + GeneralInstance1Channel {
137 type CommunicationInterrupt: interrupt::typelevel::Interrupt;
139 type BreakInputInterrupt: interrupt::typelevel::Interrupt;
141}
142pub trait AdvancedInstance2Channel:
145 BasicInstance + GeneralInstance2Channel + AdvancedInstance1Channel
146{
147}
148
149pub trait AdvancedInstance4Channel: AdvancedInstance2Channel + GeneralInstance4Channel {}
151
152pin_trait!(Channel1Pin, GeneralInstance4Channel);
153pin_trait!(Channel2Pin, GeneralInstance4Channel);
154pin_trait!(Channel3Pin, GeneralInstance4Channel);
155pin_trait!(Channel4Pin, GeneralInstance4Channel);
156pin_trait!(ExternalTriggerPin, GeneralInstance4Channel);
157
158pin_trait!(Channel1ComplementaryPin, AdvancedInstance4Channel);
159pin_trait!(Channel2ComplementaryPin, AdvancedInstance4Channel);
160pin_trait!(Channel3ComplementaryPin, AdvancedInstance4Channel);
161pin_trait!(Channel4ComplementaryPin, AdvancedInstance4Channel);
162
163pin_trait!(BreakInputPin, AdvancedInstance4Channel);
164pin_trait!(BreakInput2Pin, AdvancedInstance4Channel);
165
166pin_trait!(BreakInputComparator1Pin, AdvancedInstance4Channel);
167pin_trait!(BreakInputComparator2Pin, AdvancedInstance4Channel);
168
169pin_trait!(BreakInput2Comparator1Pin, AdvancedInstance4Channel);
170pin_trait!(BreakInput2Comparator2Pin, AdvancedInstance4Channel);
171
172#[allow(unused)]
181macro_rules! impl_core_timer {
182 ($inst:ident, $bits:expr) => {
183 impl SealedInstance for crate::peripherals::$inst {
184 fn state() -> &'static State {
185 static STATE: State = State::new();
186 &STATE
187 }
188 }
189
190 impl CoreInstance for crate::peripherals::$inst {
191 type UpdateInterrupt = crate::_generated::peripheral_interrupts::$inst::UP;
192
193 const BITS: TimerBits = $bits;
194
195 fn regs() -> *mut () {
196 crate::pac::$inst.as_ptr()
197 }
198 }
199 };
200}
201
202#[allow(unused)]
203macro_rules! impl_general_1ch {
204 ($inst:ident) => {
205 impl GeneralInstance1Channel for crate::peripherals::$inst {
206 type CaptureCompareInterrupt = crate::_generated::peripheral_interrupts::$inst::CC;
207 }
208 };
209}
210
211#[allow(unused)]
212macro_rules! impl_general_2ch {
213 ($inst:ident) => {
214 impl GeneralInstance2Channel for crate::peripherals::$inst {
215 type TriggerInterrupt = crate::_generated::peripheral_interrupts::$inst::TRG;
216 }
217 };
218}
219
220#[allow(unused)]
221macro_rules! impl_advanced_1ch {
222 ($inst:ident) => {
223 impl AdvancedInstance1Channel for crate::peripherals::$inst {
224 type CommunicationInterrupt = crate::_generated::peripheral_interrupts::$inst::COM;
225 type BreakInputInterrupt = crate::_generated::peripheral_interrupts::$inst::BRK;
226 }
227 };
228}
229
230#[allow(unused)]
233macro_rules! impl_general_4ch_blank_sealed {
234 ($inst:ident) => {
235 impl General4ChBlankSealed for crate::peripherals::$inst {
236 fn enable_outputs(&self) {
237 unsafe { crate::pac::timer::Tim1chCmp::from_ptr(Self::regs()) }
238 .bdtr()
239 .modify(|w| w.set_moe(true));
240 }
241 }
242 };
243}
244
245foreach_interrupt! {
246 ($inst:ident, timer, TIM_BASIC, UP, $irq:ident) => {
247 impl_core_timer!($inst, TimerBits::Bits16);
248 impl BasicNoCr2Instance for crate::peripherals::$inst {}
249 impl BasicInstance for crate::peripherals::$inst {}
250 };
251
252 ($inst:ident, timer, TIM_1CH, UP, $irq:ident) => {
253 impl_core_timer!($inst, TimerBits::Bits16);
254 impl BasicNoCr2Instance for crate::peripherals::$inst {}
255 impl BasicInstance for crate::peripherals::$inst {}
256 impl_general_1ch!($inst);
257 impl_general_2ch!($inst);
258 impl GeneralInstance4Channel for crate::peripherals::$inst {}
259 impl General4ChBlankSealed for crate::peripherals::$inst {}
260 };
261
262 ($inst:ident, timer, TIM_2CH, UP, $irq:ident) => {
263 impl_core_timer!($inst, TimerBits::Bits16);
264 impl BasicNoCr2Instance for crate::peripherals::$inst {}
265 impl BasicInstance for crate::peripherals::$inst {}
266 impl_general_1ch!($inst);
267 impl_general_2ch!($inst);
268 impl GeneralInstance4Channel for crate::peripherals::$inst {}
269 impl General4ChBlankSealed for crate::peripherals::$inst {}
270 };
271
272 ($inst:ident, timer, TIM_GP16, UP, $irq:ident) => {
273 impl_core_timer!($inst, TimerBits::Bits16);
274 impl BasicNoCr2Instance for crate::peripherals::$inst {}
275 impl BasicInstance for crate::peripherals::$inst {}
276 impl_general_1ch!($inst);
277 impl_general_2ch!($inst);
278 impl GeneralInstance4Channel for crate::peripherals::$inst {}
279 impl General4ChBlankSealed for crate::peripherals::$inst {}
280 };
281
282 ($inst:ident, timer, TIM_GP32, UP, $irq:ident) => {
283 impl_core_timer!($inst, TimerBits::Bits32);
284 impl BasicNoCr2Instance for crate::peripherals::$inst {}
285 impl BasicInstance for crate::peripherals::$inst {}
286 impl_general_1ch!($inst);
287 impl_general_2ch!($inst);
288 impl GeneralInstance4Channel for crate::peripherals::$inst {}
289 impl GeneralInstance32bit4Channel for crate::peripherals::$inst {}
290 impl General4ChBlankSealed for crate::peripherals::$inst {}
291 };
292
293 ($inst:ident, timer, TIM_1CH_CMP, UP, $irq:ident) => {
294 impl_core_timer!($inst, TimerBits::Bits16);
295 impl BasicNoCr2Instance for crate::peripherals::$inst {}
296 impl BasicInstance for crate::peripherals::$inst {}
297 impl_general_1ch!($inst);
298 impl_general_2ch!($inst);
299 impl GeneralInstance4Channel for crate::peripherals::$inst {}
300 impl_general_4ch_blank_sealed!($inst);
301 impl_advanced_1ch!($inst);
302 impl AdvancedInstance2Channel for crate::peripherals::$inst {}
303 impl AdvancedInstance4Channel for crate::peripherals::$inst {}
304 };
305
306 ($inst:ident, timer, TIM_2CH_CMP, UP, $irq:ident) => {
307 impl_core_timer!($inst, TimerBits::Bits16);
308 impl BasicNoCr2Instance for crate::peripherals::$inst {}
309 impl BasicInstance for crate::peripherals::$inst {}
310 impl_general_1ch!($inst);
311 impl_general_2ch!($inst);
312 impl GeneralInstance4Channel for crate::peripherals::$inst {}
313 impl_general_4ch_blank_sealed!($inst);
314 impl_advanced_1ch!($inst);
315 impl AdvancedInstance2Channel for crate::peripherals::$inst {}
316 impl AdvancedInstance4Channel for crate::peripherals::$inst {}
317 };
318
319 ($inst:ident, timer, TIM_ADV, UP, $irq:ident) => {
320 impl_core_timer!($inst, TimerBits::Bits16);
321 impl BasicNoCr2Instance for crate::peripherals::$inst {}
322 impl BasicInstance for crate::peripherals::$inst {}
323 impl_general_1ch!($inst);
324 impl_general_2ch!($inst);
325 impl GeneralInstance4Channel for crate::peripherals::$inst {}
326 impl_general_4ch_blank_sealed!($inst);
327 impl_advanced_1ch!($inst);
328 impl AdvancedInstance2Channel for crate::peripherals::$inst {}
329 impl AdvancedInstance4Channel for crate::peripherals::$inst {}
330 };
331}
332
333pub struct UpdateInterruptHandler<T: CoreInstance> {
335 _phantom: PhantomData<T>,
336}
337
338impl<T: CoreInstance> interrupt::typelevel::Handler<T::UpdateInterrupt>
339 for UpdateInterruptHandler<T>
340{
341 unsafe fn on_interrupt() {
342 let regs = crate::pac::timer::TimCore::from_ptr(T::regs());
346
347 let sr = regs.sr().read();
349
350 let bits = sr.0 & 0x00000001;
352
353 regs.dier().modify(|w| w.0 &= !bits);
355
356 if sr.uif() {
358 T::state().up_waker.wake();
359 }
360 }
361}
362
363pub struct CaptureCompareInterruptHandler<T: GeneralInstance1Channel> {
365 _phantom: PhantomData<T>,
366}
367
368impl<T: GeneralInstance1Channel> interrupt::typelevel::Handler<T::CaptureCompareInterrupt>
369 for CaptureCompareInterruptHandler<T>
370{
371 unsafe fn on_interrupt() {
372 let regs = crate::pac::timer::TimGp16::from_ptr(T::regs());
376
377 let sr = regs.sr().read();
379
380 let bits = sr.0 & 0x0000001E;
382
383 regs.dier().modify(|w| w.0 &= !bits);
385
386 for ch in 0..4 {
388 if sr.ccif(ch) {
389 T::state().cc_waker[ch].wake();
390 }
391 }
392 }
393}