1use crate::{
27 pio::{
28 interrupt::InterruptCfg,
29 peripheral::PioControlCfg,
30 pin::{MultiDriverCfg, PadResistorCfg, Pin, PinId, Unconfigured},
31 PioRegisters,
32 },
33 structure::*,
34};
35use core::marker::PhantomData;
36
37#[allow(clippy::module_name_repetitions)]
38pub trait InputFilterCfg {}
40
41impl InputFilterCfg for Unconfigured {}
42
43#[allow(clippy::module_name_repetitions)]
44pub struct InputFilterDisabled;
46
47impl InputFilterCfg for InputFilterDisabled {}
48
49#[allow(clippy::module_name_repetitions)]
50pub struct InputFilterEnabled<Flck: InputFilterClockCfg> {
52 _flck: PhantomData<Flck>,
53}
54
55impl<Flck: InputFilterClockCfg> InputFilterCfg for InputFilterEnabled<Flck> {}
56
57pub trait ConfigureInputFilter {
62 type Disabled: ConfigureInputFilter;
63 type Enabled: ConfigureInputFilter;
64
65 fn disable_input_filter(self) -> Self::Disabled;
67 unsafe fn disable_input_filter_unchecked(self) -> Self::Disabled;
74 fn enable_input_filter(self) -> Self::Enabled;
76 unsafe fn enable_input_filter_unchecked(self) -> Self::Enabled;
83}
84
85#[allow(clippy::module_name_repetitions)]
86pub trait InputFilterClockCfg {}
88
89impl InputFilterClockCfg for Unconfigured {}
90
91#[allow(clippy::module_name_repetitions)]
92pub struct SlowClock;
94
95impl InputFilterClockCfg for SlowClock {}
96
97#[allow(clippy::module_name_repetitions)]
98pub struct Debouncing;
100
101impl InputFilterClockCfg for Debouncing {}
102
103pub trait ConfigureInputFilterClock {
108 type Debouncing: ConfigureInputFilterClock;
109 type SlowClock: ConfigureInputFilterClock;
110
111 fn debouncing_filter(self) -> Self::Debouncing;
113 #[cfg_attr(
120 any(feature = "sam3a", feature = "sam3u", feature = "sam3x"),
121 doc = "PIO_IFDGSR"
122 )]
123 #[cfg_attr(
124 any(feature = "sam3n", feature = "sam3s", feature = "sam3s8"),
125 doc = "PIO_IFSCSR"
126 )]
127 unsafe fn debouncing_filter_unchecked(self) -> Self::Debouncing;
129 fn slow_clock_filter(self) -> Self::SlowClock;
131 #[cfg_attr(
138 any(feature = "sam3a", feature = "sam3u", feature = "sam3x"),
139 doc = "PIO_IFDGSR"
140 )]
141 #[cfg_attr(
142 any(feature = "sam3n", feature = "sam3s", feature = "sam3s8"),
143 doc = "PIO_IFSCSR"
144 )]
145 unsafe fn slow_clock_filter_unchecked(self) -> Self::SlowClock;
147}
148
149impl<Pio, Pid, Mdvr, Pioc, Padr, Irpt> ConfigureInputFilter
150 for Pin<Pio, Pid, Mdvr, Pioc, Padr, Irpt, Unconfigured>
151where
152 Pio: PioRegisters,
153 Pid: PinId<Controller = Pio>,
154 Mdvr: MultiDriverCfg,
155 Pioc: PioControlCfg,
156 Padr: PadResistorCfg,
157 Irpt: InterruptCfg,
158{
159 type Disabled = Pin<Pio, Pid, Mdvr, Pioc, Padr, Irpt, InputFilterDisabled>;
160 type Enabled = Pin<Pio, Pid, Mdvr, Pioc, Padr, Irpt, InputFilterEnabled<Unconfigured>>;
161
162 fn disable_input_filter(self) -> Self::Disabled {
163 unsafe {
164 let pioreg = &*Pio::PTR;
165 if pioreg._ifsr().read().bits() & Pid::MASK != 0 {
166 let _ = self.disable_input_filter_unchecked();
167 while pioreg._ifsr().read().bits() & Pid::MASK != 0 {}
168 }
169 Pin::new()
170 }
171 }
172
173 unsafe fn disable_input_filter_unchecked(self) -> Self::Disabled {
174 let pioreg = &*Pio::PTR;
175 pioreg._ifdr().write_with_zero(|w| w.bits(Pid::MASK));
176 Pin::new()
177 }
178
179 fn enable_input_filter(self) -> Self::Enabled {
180 unsafe {
181 let pioreg = &*Pio::PTR;
182 if pioreg._ifsr().read().bits() & Pid::MASK == 0 {
183 let _ = self.enable_input_filter_unchecked();
184 while pioreg._ifsr().read().bits() & Pid::MASK == 0 {}
185 }
186 Pin::new()
187 }
188 }
189
190 unsafe fn enable_input_filter_unchecked(self) -> Self::Enabled {
191 let pioreg = &*Pio::PTR;
192 pioreg._ifer().write_with_zero(|w| w.bits(Pid::MASK));
193 Pin::new()
194 }
195}
196
197impl<Pio, Pid, Mdvr, Pioc, Padr, Irpt> ConfigureInputFilter
198 for Pin<Pio, Pid, Mdvr, Pioc, Padr, Irpt, InputFilterDisabled>
199where
200 Pio: PioRegisters,
201 Pid: PinId<Controller = Pio>,
202 Mdvr: MultiDriverCfg,
203 Pioc: PioControlCfg,
204 Padr: PadResistorCfg,
205 Irpt: InterruptCfg,
206{
207 type Disabled = Self;
208 type Enabled = Pin<Pio, Pid, Mdvr, Pioc, Padr, Irpt, InputFilterEnabled<Unconfigured>>;
209
210 fn disable_input_filter(self) -> Self::Disabled {
211 self
212 }
213
214 unsafe fn disable_input_filter_unchecked(self) -> Self::Disabled {
215 self
216 }
217
218 fn enable_input_filter(self) -> Self::Enabled {
219 unsafe {
220 let pioreg = &*Pio::PTR;
221 let _ = self.enable_input_filter_unchecked();
222 while pioreg._ifsr().read().bits() & Pid::MASK == 0 {}
223 Pin::new()
224 }
225 }
226
227 unsafe fn enable_input_filter_unchecked(self) -> Self::Enabled {
228 let pioreg = &*Pio::PTR;
229 pioreg._ifer().write_with_zero(|w| w.bits(Pid::MASK));
230 Pin::new()
231 }
232}
233
234impl<Pio, Pid, Mdvr, Pioc, Padr, Irpt, Flck> ConfigureInputFilter
235 for Pin<Pio, Pid, Mdvr, Pioc, Padr, Irpt, InputFilterEnabled<Flck>>
236where
237 Pio: PioRegisters,
238 Pid: PinId<Controller = Pio>,
239 Mdvr: MultiDriverCfg,
240 Pioc: PioControlCfg,
241 Padr: PadResistorCfg,
242 Irpt: InterruptCfg,
243 Flck: InputFilterClockCfg,
244{
245 type Disabled = Pin<Pio, Pid, Mdvr, Pioc, Padr, Irpt, InputFilterDisabled>;
246 type Enabled = Self;
247
248 fn disable_input_filter(self) -> Self::Disabled {
249 unsafe {
250 let pioreg = &*Pio::PTR;
251 let _ = self.disable_input_filter_unchecked();
252 while pioreg._ifsr().read().bits() & Pid::MASK != 0 {}
253 Pin::new()
254 }
255 }
256
257 unsafe fn disable_input_filter_unchecked(self) -> Self::Disabled {
258 let pioreg = &*Pio::PTR;
259 pioreg._ifdr().write_with_zero(|w| w.bits(Pid::MASK));
260 Pin::new()
261 }
262
263 fn enable_input_filter(self) -> Self::Enabled {
264 self
265 }
266
267 unsafe fn enable_input_filter_unchecked(self) -> Self::Enabled {
268 self
269 }
270}
271
272#[cfg(any(feature = "sam3a", feature = "sam3u", feature = "sam3x"))]
273const _: () = {
274 impl<Pio, Pid, Mdvr, Pioc, Padr, Irpt> ConfigureInputFilterClock
275 for Pin<Pio, Pid, Mdvr, Pioc, Padr, Irpt, InputFilterEnabled<Unconfigured>>
276 where
277 Pio: PioRegisters,
278 Pid: PinId<Controller = Pio>,
279 Mdvr: MultiDriverCfg,
280 Pioc: PioControlCfg,
281 Padr: PadResistorCfg,
282 Irpt: InterruptCfg,
283 {
284 type Debouncing = Pin<Pio, Pid, Mdvr, Pioc, Padr, Irpt, InputFilterEnabled<Debouncing>>;
285 type SlowClock = Pin<Pio, Pid, Mdvr, Pioc, Padr, Irpt, InputFilterEnabled<SlowClock>>;
286
287 fn debouncing_filter(self) -> Self::Debouncing {
288 unsafe {
289 let pioreg = &*Pio::PTR;
290 if pioreg._ifdgsr().read().bits() & Pid::MASK != 0 {
291 let _ = self.debouncing_filter_unchecked();
292 while pioreg._ifdgsr().read().bits() & Pid::MASK != 0 {}
293 }
294 Pin::new()
295 }
296 }
297
298 unsafe fn debouncing_filter_unchecked(self) -> Self::Debouncing {
299 let pioreg = &*Pio::PTR;
300 pioreg._difsr().write_with_zero(|w| w.bits(Pid::MASK));
301 Pin::new()
302 }
303
304 fn slow_clock_filter(self) -> Self::SlowClock {
305 unsafe {
306 let pioreg = &*Pio::PTR;
307 if pioreg._ifdgsr().read().bits() & Pid::MASK == 0 {
308 let _ = self.slow_clock_filter_unchecked();
309 while pioreg._ifdgsr().read().bits() & Pid::MASK == 0 {}
310 }
311 Pin::new()
312 }
313 }
314
315 unsafe fn slow_clock_filter_unchecked(self) -> Self::SlowClock {
316 let pioreg = &*Pio::PTR;
317 pioreg._scifsr().write_with_zero(|w| w.bits(Pid::MASK));
318 Pin::new()
319 }
320 }
321
322 impl<Pio, Pid, Mdvr, Pioc, Padr, Irpt> ConfigureInputFilterClock
323 for Pin<Pio, Pid, Mdvr, Pioc, Padr, Irpt, InputFilterEnabled<Debouncing>>
324 where
325 Pio: PioRegisters,
326 Pid: PinId<Controller = Pio>,
327 Mdvr: MultiDriverCfg,
328 Pioc: PioControlCfg,
329 Padr: PadResistorCfg,
330 Irpt: InterruptCfg,
331 {
332 type Debouncing = Self;
333 type SlowClock = Pin<Pio, Pid, Mdvr, Pioc, Padr, Irpt, InputFilterEnabled<SlowClock>>;
334
335 fn debouncing_filter(self) -> Self::Debouncing {
336 self
337 }
338
339 unsafe fn debouncing_filter_unchecked(self) -> Self::Debouncing {
340 self
341 }
342
343 fn slow_clock_filter(self) -> Self::SlowClock {
344 unsafe {
345 let pioreg = &*Pio::PTR;
346 let _ = self.slow_clock_filter_unchecked();
347 while pioreg._ifdgsr().read().bits() & Pid::MASK == 0 {}
348 Pin::new()
349 }
350 }
351
352 unsafe fn slow_clock_filter_unchecked(self) -> Self::SlowClock {
353 let pioreg = &*Pio::PTR;
354 pioreg._scifsr().write_with_zero(|w| w.bits(Pid::MASK));
355 Pin::new()
356 }
357 }
358
359 impl<Pio, Pid, Mdvr, Pioc, Padr, Irpt> ConfigureInputFilterClock
360 for Pin<Pio, Pid, Mdvr, Pioc, Padr, Irpt, InputFilterEnabled<SlowClock>>
361 where
362 Pio: PioRegisters,
363 Pid: PinId<Controller = Pio>,
364 Mdvr: MultiDriverCfg,
365 Pioc: PioControlCfg,
366 Padr: PadResistorCfg,
367 Irpt: InterruptCfg,
368 {
369 type Debouncing = Pin<Pio, Pid, Mdvr, Pioc, Padr, Irpt, InputFilterEnabled<Debouncing>>;
370 type SlowClock = Self;
371
372 fn debouncing_filter(self) -> Self::Debouncing {
373 unsafe {
374 let pioreg = &*Pio::PTR;
375 let _ = self.debouncing_filter_unchecked();
376 while pioreg._ifdgsr().read().bits() & Pid::MASK != 0 {}
377 Pin::new()
378 }
379 }
380
381 unsafe fn debouncing_filter_unchecked(self) -> Self::Debouncing {
382 let pioreg = &*Pio::PTR;
383 pioreg._difsr().write_with_zero(|w| w.bits(Pid::MASK));
384 Pin::new()
385 }
386
387 fn slow_clock_filter(self) -> Self::SlowClock {
388 self
389 }
390
391 unsafe fn slow_clock_filter_unchecked(self) -> Self::SlowClock {
392 self
393 }
394 }
395};
396
397#[cfg(any(feature = "sam3n", feature = "sam3s", feature = "sam3s8"))]
398const _: () = {
399 impl<Pio, Pid, Mdvr, Pioc, Padr, Irpt> ConfigureInputFilterClock
400 for Pin<Pio, Pid, Mdvr, Pioc, Padr, Irpt, InputFilterEnabled<Unconfigured>>
401 where
402 Pio: PioRegisters,
403 Pid: PinId<Controller = Pio>,
404 Mdvr: MultiDriverCfg,
405 Pioc: PioControlCfg,
406 Padr: PadResistorCfg,
407 Irpt: InterruptCfg,
408 {
409 type Debouncing = Pin<Pio, Pid, Mdvr, Pioc, Padr, Irpt, InputFilterEnabled<Debouncing>>;
410 type SlowClock = Pin<Pio, Pid, Mdvr, Pioc, Padr, Irpt, InputFilterEnabled<SlowClock>>;
411
412 fn debouncing_filter(self) -> Self::Debouncing {
413 unsafe {
414 let pioreg = &*Pio::PTR;
415 if pioreg._ifscsr().read().bits() & Pid::MASK != 0 {
416 let _ = self.debouncing_filter_unchecked();
417 while pioreg._ifscsr().read().bits() & Pid::MASK != 0 {}
418 }
419 Pin::new()
420 }
421 }
422
423 unsafe fn debouncing_filter_unchecked(self) -> Self::Debouncing {
424 let pioreg = &*Pio::PTR;
425 pioreg._ifscdr().write_with_zero(|w| w.bits(Pid::MASK));
426 Pin::new()
427 }
428
429 fn slow_clock_filter(self) -> Self::SlowClock {
430 unsafe {
431 let pioreg = &*Pio::PTR;
432 if pioreg._ifscsr().read().bits() & Pid::MASK == 0 {
433 let _ = self.slow_clock_filter_unchecked();
434 while pioreg._ifscsr().read().bits() & Pid::MASK == 0 {}
435 }
436 Pin::new()
437 }
438 }
439
440 unsafe fn slow_clock_filter_unchecked(self) -> Self::SlowClock {
441 let pioreg = &*Pio::PTR;
442 pioreg._ifscer().write_with_zero(|w| w.bits(Pid::MASK));
443 Pin::new()
444 }
445 }
446
447 impl<Pio, Pid, Mdvr, Pioc, Padr, Irpt> ConfigureInputFilterClock
448 for Pin<Pio, Pid, Mdvr, Pioc, Padr, Irpt, InputFilterEnabled<Debouncing>>
449 where
450 Pio: PioRegisters,
451 Pid: PinId<Controller = Pio>,
452 Mdvr: MultiDriverCfg,
453 Pioc: PioControlCfg,
454 Padr: PadResistorCfg,
455 Irpt: InterruptCfg,
456 {
457 type Debouncing = Self;
458 type SlowClock = Pin<Pio, Pid, Mdvr, Pioc, Padr, Irpt, InputFilterEnabled<SlowClock>>;
459
460 fn debouncing_filter(self) -> Self::Debouncing {
461 self
462 }
463
464 unsafe fn debouncing_filter_unchecked(self) -> Self::Debouncing {
465 self
466 }
467
468 fn slow_clock_filter(self) -> Self::SlowClock {
469 unsafe {
470 let pioreg = &*Pio::PTR;
471 let _ = self.slow_clock_filter_unchecked();
472 while pioreg._ifscsr().read().bits() & Pid::MASK == 0 {}
473 Pin::new()
474 }
475 }
476
477 unsafe fn slow_clock_filter_unchecked(self) -> Self::SlowClock {
478 let pioreg = &*Pio::PTR;
479 pioreg._ifscer().write_with_zero(|w| w.bits(Pid::MASK));
480 Pin::new()
481 }
482 }
483
484 impl<Pio, Pid, Mdvr, Pioc, Padr, Irpt> ConfigureInputFilterClock
485 for Pin<Pio, Pid, Mdvr, Pioc, Padr, Irpt, InputFilterEnabled<SlowClock>>
486 where
487 Pio: PioRegisters,
488 Pid: PinId<Controller = Pio>,
489 Mdvr: MultiDriverCfg,
490 Pioc: PioControlCfg,
491 Padr: PadResistorCfg,
492 Irpt: InterruptCfg,
493 {
494 type Debouncing = Pin<Pio, Pid, Mdvr, Pioc, Padr, Irpt, InputFilterEnabled<Debouncing>>;
495 type SlowClock = Self;
496
497 fn debouncing_filter(self) -> Self::Debouncing {
498 unsafe {
499 let pioreg = &*Pio::PTR;
500 let _ = self.debouncing_filter_unchecked();
501 while pioreg._ifscsr().read().bits() & Pid::MASK != 0 {}
502 Pin::new()
503 }
504 }
505
506 unsafe fn debouncing_filter_unchecked(self) -> Self::Debouncing {
507 let pioreg = &*Pio::PTR;
508 pioreg._ifscdr().write_with_zero(|w| w.bits(Pid::MASK));
509 Pin::new()
510 }
511
512 fn slow_clock_filter(self) -> Self::SlowClock {
513 self
514 }
515
516 unsafe fn slow_clock_filter_unchecked(self) -> Self::SlowClock {
517 self
518 }
519 }
520};