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