1use {
3 core::convert::Infallible,
4 core::marker::PhantomData,
5 hal::digital::v2::{toggleable, InputPin, IoPin, OutputPin, PinState, StatefulOutputPin},
6 paste::paste,
7};
8
9#[cfg(feature = "atsam4e")]
10use {
11 crate::clock::PioDClock,
12 crate::pac::{piod, PIOD},
13};
14
15#[cfg(feature = "atsam4e_e")]
16use {
17 crate::clock::{PioCClock, PioEClock},
18 crate::pac::{pioc, pioe, PIOC, PIOE},
19};
20
21#[cfg(any(feature = "atsam4e", feature = "atsam4n", feature = "atsam4s"))]
22use {
23 crate::clock::{Enabled, PioAClock, PioBClock},
24 crate::pac::MATRIX,
25 crate::pac::{pioa, piob, PIOA, PIOB},
26};
27
28#[cfg(any(feature = "atsam4n_c", feature = "atsam4s_c"))]
29use {
30 crate::clock::PioCClock,
31 crate::pac::{pioc, PIOC},
32};
33
34pub trait GpioExt {
37 type Parts;
38
39 fn split(self) -> Self::Parts;
41}
42pub struct Ports {
43 pioa: PhantomData<(PIOA, PioAClock<Enabled>)>,
44 piob: PhantomData<(PIOB, PioBClock<Enabled>)>,
45 #[cfg(any(feature = "atsam4n_c", feature = "atsam4s_c", feature = "atsam4e_e"))]
46 pioc: PhantomData<(PIOC, PioCClock<Enabled>)>,
47 #[cfg(feature = "atsam4e")]
48 piod: PhantomData<(PIOD, PioDClock<Enabled>)>,
49 #[cfg(feature = "atsam4e_e")]
50 pioe: PhantomData<(PIOE, PioEClock<Enabled>)>,
51}
52
53impl Ports {
54 pub fn new(
55 _pioa: (PIOA, PioAClock<Enabled>),
56 _piob: (PIOB, PioBClock<Enabled>),
57 #[cfg(any(feature = "atsam4n_c", feature = "atsam4s_c", feature = "atsam4e_e"))] _pioc: (
58 PIOC,
59 PioCClock<Enabled>,
60 ),
61 #[cfg(feature = "atsam4e")] _piod: (PIOD, PioDClock<Enabled>),
62 #[cfg(feature = "atsam4e_e")] _pioe: (PIOE, PioEClock<Enabled>),
63 ) -> Self {
64 Ports {
66 pioa: PhantomData,
67 piob: PhantomData,
68 #[cfg(any(feature = "atsam4n_c", feature = "atsam4s_c", feature = "atsam4e_e"))]
69 pioc: PhantomData,
70 #[cfg(feature = "atsam4e")]
71 piod: PhantomData,
72 #[cfg(feature = "atsam4e_e")]
73 pioe: PhantomData,
74 }
75 }
76}
77
78pub struct Input<MODE> {
82 _mode: PhantomData<MODE>,
83}
84
85pub struct Output<MODE> {
89 _mode: PhantomData<MODE>,
90}
91
92pub struct PfA;
94pub struct PfB;
96pub struct PfC;
98pub struct PfD;
100pub struct SysFn;
102pub struct ExFn;
104
105pub struct Floating;
107pub struct PullDown;
109pub struct PullUp;
111
112pub struct PushPull;
114pub struct OpenDrain;
116
117macro_rules! pins {
118 ([
119 $($PinTypeA:ident: ($pin_identA:ident, $pin_noA:expr, $extfnA:ident),)*
120 ],[
121 $($PinTypeB:ident: ($pin_identB:ident, $pin_noB:expr, $extfnB:ident, $sysioB:ident),)*
122 ],[
123 $($PinTypeC:ident: ($pin_identC:ident, $pin_noC:expr, $extfnC:ident),)*
124 ],[
125 $($PinTypeD:ident: ($pin_identD:ident, $pin_noD:expr),)*
126 ],[
127 $($PinTypeE:ident: ($pin_identE:ident, $pin_noE:expr),)*
128 ]) => {
129 pub struct Pins {
131 $(
132 pub $pin_identA: $PinTypeA<Input<Floating>>,
134 )*
135 $(
136 pub $pin_identB: $PinTypeB<Input<Floating>>,
138 )*
139 $(
140 #[cfg(any(feature = "atsam4n_c", feature = "atsam4s_c", feature = "atsam4e_e"))]
142 pub $pin_identC: $PinTypeC<Input<Floating>>,
143 )*
144 $(
145 #[cfg(feature = "atsam4e")]
147 pub $pin_identD: $PinTypeD<Input<Floating>>,
148 )*
149 $(
150 #[cfg(feature = "atsam4e_e")]
152 pub $pin_identE: $PinTypeE<Input<Floating>>,
153 )*
154 }
155
156 impl GpioExt for Ports {
157 type Parts = Pins;
158
159 fn split(self) -> Pins {
161 Pins {
162 $(
163 $pin_identA: $PinTypeA { _mode: PhantomData },
164 )*
165 $(
166 $pin_identB: $PinTypeB { _mode: PhantomData },
167 )*
168 $(
169 #[cfg(any(feature = "atsam4n_c", feature = "atsam4s_c", feature = "atsam4e_e"))]
170 $pin_identC: $PinTypeC { _mode: PhantomData },
171 )*
172 $(
173 #[cfg(feature = "atsam4e")]
174 $pin_identD: $PinTypeD { _mode: PhantomData },
175 )*
176 $(
177 #[cfg(feature = "atsam4e_e")]
178 $pin_identE: $PinTypeE { _mode: PhantomData },
179 )*
180 }
181 }
182 }
183
184 $(
185 pin!($PinTypeA, $pin_identA, $pin_noA, PIOA, pioa);
186 pin_sysio!($PinTypeA, $pin_noA, false);
187 pin_extrafn!($PinTypeA, $extfnA);
188 )*
189 pin_generic!(PIOA);
190 $(
191 pin!($PinTypeB, $pin_identB, $pin_noB, PIOB, piob);
192 pin_sysio!($PinTypeB, $pin_noB, $sysioB);
193 pin_extrafn!($PinTypeB, $extfnB);
194 )*
195 pin_generic!(PIOB);
196 $(
197 #[cfg(any(feature = "atsam4n_c", feature = "atsam4s_c", feature = "atsam4e_e"))]
198 pin!($PinTypeC, $pin_identC, $pin_noC, PIOC, pioc);
199 #[cfg(any(feature = "atsam4n_c", feature = "atsam4s_c", feature = "atsam4e_e"))]
200 pin_sysio!($PinTypeC, $pin_noC, false);
201 #[cfg(any(feature = "atsam4n_c", feature = "atsam4s_c", feature = "atsam4e_e"))]
202 pin_extrafn!($PinTypeC, $extfnC);
203 )*
204 #[cfg(any(feature = "atsam4n_c", feature = "atsam4s_c", feature = "atsam4e_e"))]
205 pin_generic!(PIOC);
206 $(
207 #[cfg(feature = "atsam4e")]
208 pin!($PinTypeD, $pin_identD, $pin_noD, PIOD, piod);
209 #[cfg(feature = "atsam4e")]
210 pin_sysio!($PinTypeD, $pin_noD, false);
211 )*
212 #[cfg(feature = "atsam4e")]
213 pin_generic!(PIOD);
214 $(
215 #[cfg(feature = "atsam4e_e")]
216 pin!($PinTypeE, $pin_identE, $pin_noE, PIOE, pioe);
217 #[cfg(feature = "atsam4e_e")]
218 pin_sysio!($PinTypeE, $pin_noE, false);
219 )*
220 #[cfg(feature = "atsam4e_e")]
221 pin_generic!(PIOE);
222 };
223}
224
225macro_rules! pin_extrafn {
230 (
231 $PinType:ident,
232 true
233 ) => {
234 impl<MODE> $PinType<MODE> {
235 pub fn into_extra_function(self, _matrix: &MATRIX) -> $PinType<ExFn> {
236 $PinType { _mode: PhantomData }
237 }
238 }
239 };
240 (
241 $PinType:ident,
242 false
243 ) => {};
244}
245
246macro_rules! pin_sysio {
251 (
252 $PinType:ident,
253 $i:expr,
254 false
255 ) => {
256 impl<MODE> $PinType<MODE> {
257 fn prepare_pin_for_function_use(&mut self) {
258 unsafe {
259 self.pudr().write_with_zero(|w| w.bits(1 << $i)); self.ppddr().write_with_zero(|w| w.bits(1 << $i)); self.mddr().write_with_zero(|w| w.bits(1 << $i)); self.ifscdr().write_with_zero(|w| w.bits(1 << $i)); }
264 }
265
266 fn prepare_pin_for_input_use(&mut self) {
267 self.disable_pin_interrupt(); unsafe {
269 self.mddr().write_with_zero(|w| w.bits(1 << $i)); self.odr().write_with_zero(|w| w.bits(1 << $i)); }
272 }
273
274 pub fn into_peripheral_function_a(mut self, _matrix: &MATRIX) -> $PinType<PfA> {
275 self.prepare_pin_for_function_use();
276 self.abcdsr1()
277 .modify(|r, w| unsafe { w.bits(r.bits() & !(1 << $i)) });
278 self.abcdsr2()
279 .modify(|r, w| unsafe { w.bits(r.bits() & !(1 << $i)) });
280 self.disable_pin();
281
282 $PinType { _mode: PhantomData }
283 }
284
285 pub fn into_peripheral_function_b(mut self, _matrix: &MATRIX) -> $PinType<PfB> {
286 self.prepare_pin_for_function_use();
287 self.abcdsr1()
288 .modify(|r, w| unsafe { w.bits(r.bits() | (1 << $i)) }); self.abcdsr2()
290 .modify(|r, w| unsafe { w.bits(r.bits() & !(1 << $i)) });
291 self.disable_pin();
292
293 $PinType { _mode: PhantomData }
294 }
295
296 pub fn into_peripheral_function_c(mut self, _matrix: &MATRIX) -> $PinType<PfC> {
297 self.prepare_pin_for_function_use();
298 self.abcdsr1()
299 .modify(|r, w| unsafe { w.bits(r.bits() & !(1 << $i)) }); self.abcdsr2()
301 .modify(|r, w| unsafe { w.bits(r.bits() | (1 << $i)) });
302 self.disable_pin();
303
304 $PinType { _mode: PhantomData }
305 }
306
307 pub fn into_peripheral_function_d(mut self, _matrix: &MATRIX) -> $PinType<PfD> {
308 self.prepare_pin_for_function_use();
309 self.abcdsr1()
310 .modify(|r, w| unsafe { w.bits(r.bits() | (1 << $i)) }); self.abcdsr2()
312 .modify(|r, w| unsafe { w.bits(r.bits() | (1 << $i)) });
313 self.disable_pin();
314
315 $PinType { _mode: PhantomData }
316 }
317
318 pub fn into_floating_input(mut self, _matrix: &MATRIX) -> $PinType<Input<Floating>> {
319 self.prepare_pin_for_input_use();
320 unsafe {
321 self.pudr().write_with_zero(|w| w.bits(1 << $i)); self.ppddr().write_with_zero(|w| w.bits(1 << $i)); }
324 self.enable_pin();
325
326 $PinType { _mode: PhantomData }
327 }
328
329 pub fn into_pull_down_input(mut self, _matrix: &MATRIX) -> $PinType<Input<PullDown>> {
330 self.prepare_pin_for_input_use();
331 unsafe {
332 self.pudr().write_with_zero(|w| w.bits(1 << $i)); self.ppder().write_with_zero(|w| w.bits(1 << $i)); }
335 self.enable_pin();
336
337 $PinType { _mode: PhantomData }
338 }
339
340 pub fn into_pull_up_input(mut self, _matrix: &MATRIX) -> $PinType<Input<PullUp>> {
341 self.prepare_pin_for_input_use();
342 unsafe {
343 self.ppddr().write_with_zero(|w| w.bits(1 << $i)); self.puer().write_with_zero(|w| w.bits(1 << $i)); }
346 self.enable_pin();
347
348 $PinType { _mode: PhantomData }
349 }
350
351 pub fn into_open_drain_output(
353 mut self,
354 _matrix: &MATRIX,
355 ) -> $PinType<Output<OpenDrain>> {
356 self.disable_pin_interrupt();
357 unsafe {
358 self.mder().write_with_zero(|w| w.bits(1 << $i)); self.oer().write_with_zero(|w| w.bits(1 << $i)); }
361 self.enable_pin(); $PinType { _mode: PhantomData }
364 }
365
366 pub fn into_push_pull_output(mut self, _matrix: &MATRIX) -> $PinType<Output<PushPull>> {
368 self.disable_pin_interrupt();
369 unsafe {
370 self.mddr().write_with_zero(|w| w.bits(1 << $i)); self.oer().write_with_zero(|w| w.bits(1 << $i)); self.per().write_with_zero(|w| w.bits(1 << $i)); }
374
375 $PinType { _mode: PhantomData }
376 }
377 }
378 };
379
380 (
381 $PinType:ident,
382 $i:expr,
383 true
384 ) => {
385 impl<MODE> $PinType<MODE> {
386 paste! {
387 pub fn into_system_function(self, matrix: &MATRIX) -> $PinType<SysFn> {
389 matrix.ccfg_sysio.modify(|_, w| w.[<sysio $i>]().clear_bit());
390
391 $PinType { _mode: PhantomData }
392 }
393
394 fn disable_system_function(&self, matrix: &MATRIX) {
396 matrix.ccfg_sysio.modify(|_, w| w.[<sysio $i>]().set_bit());
397 }
398 }
399
400 fn prepare_pin_for_function_use(&mut self) {
401 unsafe {
402 self.pudr().write_with_zero(|w| w.bits(1 << $i)); self.ppddr().write_with_zero(|w| w.bits(1 << $i)); self.mddr().write_with_zero(|w| w.bits(1 << $i)); self.ifscdr().write_with_zero(|w| w.bits(1 << $i)); }
407 }
408
409 fn prepare_pin_for_input_use(&mut self) {
410 self.disable_pin_interrupt(); unsafe {
412 self.mddr().write_with_zero(|w| w.bits(1 << $i)); self.odr().write_with_zero(|w| w.bits(1 << $i)); }
415 }
416
417 pub fn into_peripheral_function_a(mut self, matrix: &MATRIX) -> $PinType<PfA> {
418 self.prepare_pin_for_function_use();
419 self.disable_system_function(matrix);
420 self.abcdsr1()
421 .modify(|r, w| unsafe { w.bits(r.bits() & !(1 << $i)) });
422 self.abcdsr2()
423 .modify(|r, w| unsafe { w.bits(r.bits() & !(1 << $i)) });
424 self.disable_pin();
425
426 $PinType { _mode: PhantomData }
427 }
428
429 pub fn into_peripheral_function_b(mut self, matrix: &MATRIX) -> $PinType<PfB> {
430 self.prepare_pin_for_function_use();
431 self.disable_system_function(matrix);
432 self.abcdsr1()
433 .modify(|r, w| unsafe { w.bits(r.bits() | (1 << $i)) }); self.abcdsr2()
435 .modify(|r, w| unsafe { w.bits(r.bits() & !(1 << $i)) });
436 self.disable_pin();
437
438 $PinType { _mode: PhantomData }
439 }
440
441 pub fn into_peripheral_function_c(mut self, matrix: &MATRIX) -> $PinType<PfC> {
442 self.prepare_pin_for_function_use();
443 self.disable_system_function(matrix);
444 self.abcdsr1()
445 .modify(|r, w| unsafe { w.bits(r.bits() & !(1 << $i)) }); self.abcdsr2()
447 .modify(|r, w| unsafe { w.bits(r.bits() | (1 << $i)) });
448 self.disable_pin();
449
450 $PinType { _mode: PhantomData }
451 }
452
453 pub fn into_peripheral_function_d(mut self, matrix: &MATRIX) -> $PinType<PfD> {
454 self.prepare_pin_for_function_use();
455 self.disable_system_function(matrix);
456 self.abcdsr1()
457 .modify(|r, w| unsafe { w.bits(r.bits() | (1 << $i)) }); self.abcdsr2()
459 .modify(|r, w| unsafe { w.bits(r.bits() | (1 << $i)) });
460 self.disable_pin();
461
462 $PinType { _mode: PhantomData }
463 }
464
465 pub fn into_floating_input(mut self, matrix: &MATRIX) -> $PinType<Input<Floating>> {
466 self.prepare_pin_for_input_use();
467 self.disable_system_function(matrix);
468 unsafe {
469 self.pudr().write_with_zero(|w| w.bits(1 << $i)); self.ppddr().write_with_zero(|w| w.bits(1 << $i)); }
472 self.enable_pin();
473
474 $PinType { _mode: PhantomData }
475 }
476
477 pub fn into_pull_down_input(mut self, matrix: &MATRIX) -> $PinType<Input<PullDown>> {
478 self.prepare_pin_for_input_use();
479 self.disable_system_function(matrix);
480 unsafe {
481 self.pudr().write_with_zero(|w| w.bits(1 << $i)); self.ppder().write_with_zero(|w| w.bits(1 << $i)); }
484 self.enable_pin();
485
486 $PinType { _mode: PhantomData }
487 }
488
489 pub fn into_pull_up_input(mut self, matrix: &MATRIX) -> $PinType<Input<PullUp>> {
490 self.prepare_pin_for_input_use();
491 self.disable_system_function(matrix);
492 unsafe {
493 self.ppddr().write_with_zero(|w| w.bits(1 << $i)); self.puer().write_with_zero(|w| w.bits(1 << $i)); }
496 self.enable_pin();
497
498 $PinType { _mode: PhantomData }
499 }
500
501 pub fn into_open_drain_output(
503 mut self,
504 matrix: &MATRIX,
505 ) -> $PinType<Output<OpenDrain>> {
506 self.disable_pin_interrupt();
507 self.disable_system_function(matrix);
508 unsafe {
509 self.mder().write_with_zero(|w| w.bits(1 << $i)); self.oer().write_with_zero(|w| w.bits(1 << $i)); }
512 self.enable_pin(); $PinType { _mode: PhantomData }
515 }
516
517 pub fn into_push_pull_output(mut self, matrix: &MATRIX) -> $PinType<Output<PushPull>> {
519 self.disable_pin_interrupt();
520 self.disable_system_function(matrix);
521 unsafe {
522 self.mddr().write_with_zero(|w| w.bits(1 << $i)); self.oer().write_with_zero(|w| w.bits(1 << $i)); self.per().write_with_zero(|w| w.bits(1 << $i)); }
526
527 $PinType { _mode: PhantomData }
528 }
529 }
530 };
531}
532
533macro_rules! pin {
534 (
535 $PinType:ident,
536 $pin_ident:ident,
537 $i:expr,
538 $PIO:ident,
539 $pio:ident
540 ) => {
541 pub struct $PinType<MODE> {
542 _mode: PhantomData<MODE>,
543 }
544
545 impl<MODE> $PinType<MODE> {
546 pub(crate) fn puer(&mut self) -> &$pio::PUER {
547 unsafe { &(*$PIO::ptr()).puer }
548 }
549
550 pub(crate) fn pudr(&mut self) -> &$pio::PUDR {
551 unsafe { &(*$PIO::ptr()).pudr }
552 }
553
554 pub(crate) fn _ier(&mut self) -> &$pio::IER {
555 unsafe { &(*$PIO::ptr()).ier }
556 }
557
558 pub(crate) fn idr(&mut self) -> &$pio::IDR {
559 unsafe { &(*$PIO::ptr()).idr }
560 }
561
562 pub(crate) fn ppder(&mut self) -> &$pio::PPDER {
563 unsafe { &(*$PIO::ptr()).ppder }
564 }
565
566 pub(crate) fn ppddr(&mut self) -> &$pio::PPDDR {
567 unsafe { &(*$PIO::ptr()).ppddr }
568 }
569
570 pub(crate) fn abcdsr1(&mut self) -> &$pio::ABCDSR {
571 unsafe { &(*$PIO::ptr()).abcdsr[0] }
572 }
573
574 pub(crate) fn abcdsr2(&mut self) -> &$pio::ABCDSR {
575 unsafe { &(*$PIO::ptr()).abcdsr[1] }
576 }
577
578 pub(crate) fn mder(&mut self) -> &$pio::MDER {
579 unsafe { &(*$PIO::ptr()).mder }
580 }
581
582 pub(crate) fn mddr(&mut self) -> &$pio::MDDR {
583 unsafe { &(*$PIO::ptr()).mddr }
584 }
585
586 pub(crate) fn oer(&mut self) -> &$pio::OER {
587 unsafe { &(*$PIO::ptr()).oer }
588 }
589
590 pub(crate) fn odr(&mut self) -> &$pio::ODR {
591 unsafe { &(*$PIO::ptr()).odr }
592 }
593
594 pub(crate) fn per(&mut self) -> &$pio::PER {
595 unsafe { &(*$PIO::ptr()).per }
596 }
597
598 pub(crate) fn pdr(&mut self) -> &$pio::PDR {
599 unsafe { &(*$PIO::ptr()).pdr }
600 }
601
602 pub(crate) fn sodr(&mut self) -> &$pio::SODR {
603 unsafe { &(*$PIO::ptr()).sodr }
604 }
605
606 pub(crate) fn codr(&mut self) -> &$pio::CODR {
607 unsafe { &(*$PIO::ptr()).codr }
608 }
609
610 pub(crate) fn ifscdr(&mut self) -> &$pio::IFSCDR {
611 unsafe { &(*$PIO::ptr()).ifscdr }
612 }
613
614 pub(crate) fn odsr(&self) -> &$pio::ODSR {
615 unsafe { &(*$PIO::ptr()).odsr }
616 }
617
618 pub(crate) fn pdsr(&self) -> &$pio::PDSR {
619 unsafe { &(*$PIO::ptr()).pdsr }
620 }
621
622 fn enable_pin(&mut self) {
623 unsafe { self.per().write_with_zero(|w| w.bits(1 << $i)) };
624 }
625
626 fn disable_pin(&mut self) {
627 unsafe { self.pdr().write_with_zero(|w| w.bits(1 << $i)) };
628 }
629
630 fn _enable_pin_interrupt(&mut self) {
631 unsafe { self._ier().write_with_zero(|w| w.bits(1 << $i)) };
632 }
633
634 fn disable_pin_interrupt(&mut self) {
635 unsafe { self.idr().write_with_zero(|w| w.bits(1 << $i)) };
636 }
637 }
638
639 impl<MODE> InputPin for $PinType<Input<MODE>> {
640 type Error = Infallible;
641
642 fn is_high(&self) -> Result<bool, Self::Error> {
643 Ok(self.pdsr().read().bits() & (1 << $i) != 0)
644 }
645
646 fn is_low(&self) -> Result<bool, Self::Error> {
647 Ok(self.pdsr().read().bits() & (1 << $i) == 0)
648 }
649 }
650
651 impl<MODE> OutputPin for $PinType<Output<MODE>> {
652 type Error = Infallible;
653
654 fn set_high(&mut self) -> Result<(), Self::Error> {
655 unsafe { self.sodr().write_with_zero(|w| w.bits(1 << $i)) };
656 Ok(())
657 }
658
659 fn set_low(&mut self) -> Result<(), Self::Error> {
660 unsafe { self.codr().write_with_zero(|w| w.bits(1 << $i)) };
661 Ok(())
662 }
663 }
664
665 impl<MODE> StatefulOutputPin for $PinType<Output<MODE>> {
666 fn is_set_high(&self) -> Result<bool, Self::Error> {
667 Ok(self.odsr().read().bits() & (1 << $i) != 0)
668 }
669
670 fn is_set_low(&self) -> Result<bool, Self::Error> {
671 Ok(self.odsr().read().bits() & (1 << $i) == 0)
672 }
673 }
674
675 impl<MODE> toggleable::Default for $PinType<Output<MODE>> {}
677
678 impl IoPin<$PinType<Input<Floating>>, Self> for $PinType<Output<PushPull>> {
679 type Error = Infallible;
680 fn into_input_pin(mut self) -> Result<$PinType<Input<Floating>>, Self::Error> {
681 unsafe {
682 self.mddr().write_with_zero(|w| w.bits(1 << $i)); self.odr().write_with_zero(|w| w.bits(1 << $i)); self.pudr().write_with_zero(|w| w.bits(1 << $i)); self.ppddr().write_with_zero(|w| w.bits(1 << $i)); self.per().write_with_zero(|w| w.bits(1 << $i)); }
688
689 Ok($PinType { _mode: PhantomData })
690 }
691 fn into_output_pin(mut self, state: PinState) -> Result<Self, Self::Error> {
692 self.set_state(state).unwrap();
693 Ok(self)
694 }
695 }
696
697 impl IoPin<$PinType<Input<PullDown>>, Self> for $PinType<Output<PushPull>> {
698 type Error = Infallible;
699 fn into_input_pin(mut self) -> Result<$PinType<Input<PullDown>>, Self::Error> {
700 unsafe {
701 self.mddr().write_with_zero(|w| w.bits(1 << $i)); self.odr().write_with_zero(|w| w.bits(1 << $i)); self.pudr().write_with_zero(|w| w.bits(1 << $i)); self.ppder().write_with_zero(|w| w.bits(1 << $i)); self.per().write_with_zero(|w| w.bits(1 << $i)); }
707
708 Ok($PinType { _mode: PhantomData })
709 }
710 fn into_output_pin(mut self, state: PinState) -> Result<Self, Self::Error> {
711 self.set_state(state).unwrap();
712 Ok(self)
713 }
714 }
715
716 impl IoPin<$PinType<Input<PullUp>>, Self> for $PinType<Output<PushPull>> {
717 type Error = Infallible;
718 fn into_input_pin(mut self) -> Result<$PinType<Input<PullUp>>, Self::Error> {
719 unsafe {
720 self.mddr().write_with_zero(|w| w.bits(1 << $i)); self.odr().write_with_zero(|w| w.bits(1 << $i)); self.puer().write_with_zero(|w| w.bits(1 << $i)); self.ppddr().write_with_zero(|w| w.bits(1 << $i)); self.per().write_with_zero(|w| w.bits(1 << $i)); }
726
727 Ok($PinType { _mode: PhantomData })
728 }
729 fn into_output_pin(mut self, state: PinState) -> Result<Self, Self::Error> {
730 self.set_state(state).unwrap();
731 Ok(self)
732 }
733 }
734
735 impl IoPin<Self, $PinType<Output<PushPull>>> for $PinType<Input<Floating>> {
736 type Error = Infallible;
737 fn into_input_pin(self) -> Result<Self, Self::Error> {
738 Ok(self)
739 }
740 fn into_output_pin(
741 mut self,
742 state: PinState,
743 ) -> Result<$PinType<Output<PushPull>>, Self::Error> {
744 unsafe {
745 self.mddr().write_with_zero(|w| w.bits(1 << $i)); self.oer().write_with_zero(|w| w.bits(1 << $i)); self.per().write_with_zero(|w| w.bits(1 << $i)); match state {
749 PinState::Low => {
750 self.codr().write_with_zero(|w| w.bits(1 << $i));
751 }
752 PinState::High => {
753 self.sodr().write_with_zero(|w| w.bits(1 << $i));
754 }
755 }
756 }
757
758 Ok($PinType { _mode: PhantomData })
759 }
760 }
761
762 impl IoPin<Self, $PinType<Output<PushPull>>> for $PinType<Input<PullDown>> {
763 type Error = Infallible;
764 fn into_input_pin(self) -> Result<Self, Self::Error> {
765 Ok(self)
766 }
767 fn into_output_pin(
768 mut self,
769 state: PinState,
770 ) -> Result<$PinType<Output<PushPull>>, Self::Error> {
771 unsafe {
772 self.mddr().write_with_zero(|w| w.bits(1 << $i)); self.oer().write_with_zero(|w| w.bits(1 << $i)); self.per().write_with_zero(|w| w.bits(1 << $i)); match state {
776 PinState::Low => {
777 self.codr().write_with_zero(|w| w.bits(1 << $i));
778 }
779 PinState::High => {
780 self.sodr().write_with_zero(|w| w.bits(1 << $i));
781 }
782 }
783 }
784
785 Ok($PinType { _mode: PhantomData })
786 }
787 }
788
789 impl IoPin<Self, $PinType<Output<PushPull>>> for $PinType<Input<PullUp>> {
790 type Error = Infallible;
791 fn into_input_pin(self) -> Result<Self, Self::Error> {
792 Ok(self)
793 }
794 fn into_output_pin(
795 mut self,
796 state: PinState,
797 ) -> Result<$PinType<Output<PushPull>>, Self::Error> {
798 unsafe {
799 self.mddr().write_with_zero(|w| w.bits(1 << $i)); self.oer().write_with_zero(|w| w.bits(1 << $i)); self.per().write_with_zero(|w| w.bits(1 << $i)); match state {
803 PinState::Low => {
804 self.codr().write_with_zero(|w| w.bits(1 << $i));
805 }
806 PinState::High => {
807 self.sodr().write_with_zero(|w| w.bits(1 << $i));
808 }
809 }
810 }
811
812 Ok($PinType { _mode: PhantomData })
813 }
814 }
815
816 paste! {
817 impl<MODE> $PinType<MODE> {
818 #[inline]
820 fn into_generic(self) -> [<$PIO Generic>]<MODE> {
821 [<$PIO Generic>] {
822 i: $i,
823 _mode: PhantomData,
824 }
825 }
826
827 pub fn downgrade(self) -> PioX<MODE> {
832 self.into_generic().downgrade()
833 }
834 }
835 }
836 };
837}
838
839macro_rules! pin_generic {
840 (
841 $port:ident
842 ) => {
843 paste! {
844 pub struct [<$port Generic>]<MODE> {
845 i: u8,
846 _mode: PhantomData<MODE>,
847 }
848
849 impl<MODE> [<$port Generic>]<MODE> {
850 pub fn downgrade(self) -> PioX<MODE> {
851 PioX::$port(self)
852 }
853 }
854
855 impl<MODE> OutputPin for [<$port Generic>]<Output<MODE>> {
856 type Error = Infallible;
857 fn set_high(&mut self) -> Result<(), Self::Error> {
858 Ok(unsafe { (*$port::ptr()).sodr.write_with_zero(|w| w.bits(1 << self.i) ) })
859 }
860
861 fn set_low(&mut self) -> Result<(), Self::Error> {
862 Ok(unsafe { (*$port::ptr()).codr.write_with_zero(|w| w.bits(1 << self.i) ) })
863 }
864 }
865
866 impl<MODE> InputPin for [<$port Generic>]<Input<MODE>> {
867 type Error = Infallible;
868 fn is_high(&self) -> Result<bool, Self::Error> {
869 Ok(unsafe { (*$port::ptr()).pdsr.read().bits() & (1 << self.i)} != 0)
870 }
871
872 fn is_low(&self) -> Result<bool, Self::Error> {
873 Ok(unsafe { (*$port::ptr()).pdsr.read().bits() & (1 << self.i)} == 0)
874 }
875 }
876
877 impl <MODE> StatefulOutputPin for [<$port Generic>]<Output<MODE>> {
878 fn is_set_high(&self) -> Result<bool, Self::Error> {
879 Ok(unsafe { (*$port::ptr()).odsr.read().bits() & (1 << self.i)} != 0)
880 }
881
882 fn is_set_low(&self) -> Result<bool, Self::Error> {
883 Ok(unsafe { (*$port::ptr()).odsr.read().bits() & (1 << self.i)} == 0)
884 }
885 }
886
887 impl <MODE> toggleable::Default for [<$port Generic>]<Output<MODE>> {}
888
889 impl IoPin<[<$port Generic>]<Input<Floating>>, Self> for [<$port Generic>]<Output<PushPull>> {
890 type Error = Infallible;
891 fn into_input_pin(self) -> Result<[<$port Generic>]<Input<Floating>>, Self::Error> {
892 unsafe {
893 (*$port::ptr()).mddr.write_with_zero(|w| w.bits(1 << self.i)); (*$port::ptr()).odr.write_with_zero(|w| w.bits(1 << self.i)); (*$port::ptr()).pudr.write_with_zero(|w| w.bits(1 << self.i)); (*$port::ptr()).ppddr.write_with_zero(|w| w.bits(1 << self.i)); (*$port::ptr()).per.write_with_zero(|w| w.bits(1 << self.i)); }
899
900 Ok([<$port Generic>] { i: self.i, _mode: PhantomData })
901 }
902 fn into_output_pin(mut self, state: PinState) -> Result<Self, Self::Error> {
903 self.set_state(state).unwrap();
904 Ok(self)
905 }
906 }
907
908 impl IoPin<[<$port Generic>]<Input<PullDown>>, Self> for [<$port Generic>]<Output<PushPull>> {
909 type Error = Infallible;
910 fn into_input_pin(self) -> Result<[<$port Generic>]<Input<PullDown>>, Self::Error> {
911 unsafe {
912 (*$port::ptr()).mddr.write_with_zero(|w| w.bits(1 << self.i)); (*$port::ptr()).odr.write_with_zero(|w| w.bits(1 << self.i)); (*$port::ptr()).pudr.write_with_zero(|w| w.bits(1 << self.i)); (*$port::ptr()).ppder.write_with_zero(|w| w.bits(1 << self.i)); (*$port::ptr()).per.write_with_zero(|w| w.bits(1 << self.i)); }
918
919 Ok([<$port Generic>] { i: self.i, _mode: PhantomData })
920 }
921 fn into_output_pin(mut self, state: PinState) -> Result<Self, Self::Error> {
922 self.set_state(state).unwrap();
923 Ok(self)
924 }
925 }
926
927 impl IoPin<[<$port Generic>]<Input<PullUp>>, Self> for [<$port Generic>]<Output<PushPull>> {
928 type Error = Infallible;
929 fn into_input_pin(self) -> Result<[<$port Generic>]<Input<PullUp>>, Self::Error> {
930 unsafe {
931 (*$port::ptr()).mddr.write_with_zero(|w| w.bits(1 << self.i)); (*$port::ptr()).odr.write_with_zero(|w| w.bits(1 << self.i)); (*$port::ptr()).puer.write_with_zero(|w| w.bits(1 << self.i)); (*$port::ptr()).ppddr.write_with_zero(|w| w.bits(1 << self.i)); (*$port::ptr()).per.write_with_zero(|w| w.bits(1 << self.i)); }
937
938 Ok([<$port Generic>] { i: self.i, _mode: PhantomData })
939 }
940 fn into_output_pin(mut self, state: PinState) -> Result<Self, Self::Error> {
941 self.set_state(state).unwrap();
942 Ok(self)
943 }
944 }
945
946 impl IoPin<Self, [<$port Generic>]<Output<PushPull>>> for [<$port Generic>]<Input<Floating>> {
947 type Error = Infallible;
948 fn into_input_pin(self) -> Result<Self, Self::Error> {
949 Ok(self)
950 }
951 fn into_output_pin(self, state: PinState) -> Result<[<$port Generic>]<Output<PushPull>>, Self::Error> {
952 unsafe {
953 (*$port::ptr()).mddr.write_with_zero(|w| w.bits(1 << self.i)); (*$port::ptr()).oer.write_with_zero(|w| w.bits(1 << self.i)); (*$port::ptr()).per.write_with_zero(|w| w.bits(1 << self.i)); match state {
957 PinState::Low => {
958 (*$port::ptr()).codr.write_with_zero(|w| w.bits(1 << self.i) );
959 }
960 PinState::High => {
961 (*$port::ptr()).sodr.write_with_zero(|w| w.bits(1 << self.i) );
962 }
963 }
964 }
965
966 Ok( [<$port Generic>] { i: self.i, _mode: PhantomData } )
967 }
968 }
969
970 impl IoPin<Self, [<$port Generic>]<Output<PushPull>>> for [<$port Generic>]<Input<PullDown>> {
971 type Error = Infallible;
972 fn into_input_pin(self) -> Result<Self, Self::Error> {
973 Ok(self)
974 }
975 fn into_output_pin(self, state: PinState) -> Result<[<$port Generic>]<Output<PushPull>>, Self::Error> {
976 unsafe {
977 (*$port::ptr()).mddr.write_with_zero(|w| w.bits(1 << self.i)); (*$port::ptr()).oer.write_with_zero(|w| w.bits(1 << self.i)); (*$port::ptr()).per.write_with_zero(|w| w.bits(1 << self.i)); match state {
981 PinState::Low => {
982 (*$port::ptr()).codr.write_with_zero(|w| w.bits(1 << self.i) );
983 }
984 PinState::High => {
985 (*$port::ptr()).sodr.write_with_zero(|w| w.bits(1 << self.i) );
986 }
987 }
988 }
989
990 Ok( [<$port Generic>] { i: self.i, _mode: PhantomData } )
991 }
992 }
993
994 impl IoPin<Self, [<$port Generic>]<Output<PushPull>>> for [<$port Generic>]<Input<PullUp>> {
995 type Error = Infallible;
996 fn into_input_pin(self) -> Result<Self, Self::Error> {
997 Ok(self)
998 }
999 fn into_output_pin(self, state: PinState) -> Result<[<$port Generic>]<Output<PushPull>>, Self::Error> {
1000 unsafe {
1001 (*$port::ptr()).mddr.write_with_zero(|w| w.bits(1 << self.i)); (*$port::ptr()).oer.write_with_zero(|w| w.bits(1 << self.i)); (*$port::ptr()).per.write_with_zero(|w| w.bits(1 << self.i)); match state {
1005 PinState::Low => {
1006 (*$port::ptr()).codr.write_with_zero(|w| w.bits(1 << self.i) );
1007 }
1008 PinState::High => {
1009 (*$port::ptr()).sodr.write_with_zero(|w| w.bits(1 << self.i) );
1010 }
1011 }
1012 }
1013
1014 Ok( [<$port Generic>] { i: self.i, _mode: PhantomData } )
1015 }
1016 }
1017 }
1018 };
1019}
1020
1021#[cfg(feature = "atsam4e")]
1022pins!([
1023 Pa0: (pa0, 0, true), Pa1: (pa1, 1, true), Pa2: (pa2, 2, true), Pa3: (pa3, 3, false),
1027 Pa4: (pa4, 4, true), Pa5: (pa5, 5, true), Pa6: (pa6, 6, false),
1030 Pa7: (pa7, 7, false),
1031 Pa8: (pa8, 8, true), Pa9: (pa9, 9, true), Pa10: (pa10, 10, false),
1034 Pa11: (pa11, 11, true), Pa12: (pa12, 12, false),
1036 Pa13: (pa13, 13, false),
1037 Pa14: (pa14, 14, true), Pa15: (pa15, 15, true), Pa16: (pa16, 16, true), Pa17: (pa17, 17, true), Pa18: (pa18, 18, true), Pa19: (pa19, 19, true), Pa20: (pa20, 20, true), Pa21: (pa21, 21, true), Pa22: (pa22, 22, true), Pa23: (pa23, 23, true), Pa24: (pa24, 24, true), Pa25: (pa25, 25, true), Pa26: (pa26, 26, true), Pa27: (pa27, 27, true), Pa28: (pa28, 28, true), Pa29: (pa29, 29, true), Pa30: (pa30, 30, true), Pa31: (pa31, 31, true), ],[
1056 Pb0: (pb0, 0, true, false), Pb1: (pb1, 1, true, false), Pb2: (pb2, 2, true, false), Pb3: (pb3, 3, true, false), Pb4: (pb4, 4, false, true), Pb5: (pb5, 5, true, true), Pb6: (pb6, 6, false, true), Pb7: (pb7, 7, false, true), Pb8: (pb8, 8, false, false),
1065 Pb9: (pb9, 9, false, false),
1066 Pb10: (pb10, 10, false, true), Pb11: (pb11, 11, false, true), Pb12: (pb12, 12, false, true), Pb13: (pb13, 13, true, false), Pb14: (pb14, 14, true, false), ],
1074[
1075 Pc0: (pc0, 0, true), Pc1: (pc1, 1, true), Pc2: (pc2, 2, true), Pc3: (pc3, 3, true), Pc4: (pc4, 4, true), Pc5: (pc5, 5, false),
1081 Pc6: (pc6, 6, false),
1082 Pc7: (pc7, 7, false),
1083 Pc8: (pc8, 8, false),
1084 Pc9: (pc9, 9, false),
1085 Pc10: (pc10, 10, false),
1086 Pc11: (pc11, 11, false),
1087 Pc12: (pc12, 12, true), Pc13: (pc13, 13, true), Pc14: (pc14, 14, false),
1090 Pc15: (pc15, 15, true), Pc16: (pc16, 16, false),
1092 Pc17: (pc17, 17, false),
1093 Pc18: (pc18, 18, false),
1094 Pc19: (pc19, 19, false),
1095 Pc20: (pc20, 20, false),
1096 Pc21: (pc21, 21, false),
1097 Pc22: (pc22, 22, false),
1098 Pc23: (pc23, 23, false),
1099 Pc24: (pc24, 24, false),
1100 Pc25: (pc25, 25, false),
1101 Pc26: (pc26, 26, true), Pc27: (pc27, 27, true), Pc28: (pc28, 28, false),
1104 Pc29: (pc29, 29, true), Pc30: (pc30, 30, true), Pc31: (pc31, 31, true), ],
1108[
1109 Pd0: (pd0, 0),
1110 Pd1: (pd1, 1),
1111 Pd2: (pd2, 2),
1112 Pd3: (pd3, 3),
1113 Pd4: (pd4, 4),
1114 Pd5: (pd5, 5),
1115 Pd6: (pd6, 6),
1116 Pd7: (pd7, 7),
1117 Pd8: (pd8, 8),
1118 Pd9: (pd9, 9),
1119 Pd10: (pd10, 10),
1120 Pd11: (pd11, 11),
1121 Pd12: (pd12, 12),
1122 Pd13: (pd13, 13),
1123 Pd14: (pd14, 14),
1124 Pd15: (pd15, 15),
1125 Pd16: (pd16, 16),
1126 Pd17: (pd17, 17),
1127 Pd18: (pd18, 18),
1128 Pd19: (pd19, 19),
1129 Pd20: (pd20, 20),
1130 Pd21: (pd21, 21),
1131 Pd22: (pd22, 22),
1132 Pd23: (pd23, 23),
1133 Pd24: (pd24, 24),
1134 Pd25: (pd25, 25),
1135 Pd26: (pd26, 26),
1136 Pd27: (pd27, 27),
1137 Pd28: (pd28, 28),
1138 Pd29: (pd29, 29),
1139 Pd30: (pd30, 30),
1140 Pd31: (pd31, 31),
1141],
1142[
1143 Pe0: (pe0, 0),
1144 Pe1: (pe1, 1),
1145 Pe2: (pe2, 2),
1146 Pe3: (pe3, 3),
1147 Pe4: (pe4, 4),
1148 Pe5: (pe5, 5),
1149
1150 ]);
1152
1153#[cfg(feature = "atsam4n")]
1154pins!([
1155 Pa0: (pa0, 0, true), Pa1: (pa1, 1, true), Pa2: (pa2, 2, true), Pa3: (pa3, 3, false),
1159 Pa4: (pa4, 4, true), Pa5: (pa5, 5, true), Pa6: (pa6, 6, false),
1162 Pa7: (pa7, 7, false),
1163 Pa8: (pa8, 8, true), Pa9: (pa9, 9, true), Pa10: (pa10, 10, false),
1166 Pa11: (pa11, 11, true), Pa12: (pa12, 12, false),
1168 Pa13: (pa13, 13, false),
1169 Pa14: (pa14, 14, true), Pa15: (pa15, 15, true), Pa16: (pa16, 16, true), Pa17: (pa17, 17, true), Pa18: (pa18, 18, true), Pa19: (pa19, 19, true), Pa20: (pa20, 20, true), Pa21: (pa21, 21, true), Pa22: (pa22, 22, true), Pa23: (pa23, 23, false),
1179 Pa24: (pa24, 24, false),
1180 Pa25: (pa25, 25, false),
1181 Pa26: (pa26, 26, false),
1182 Pa27: (pa27, 27, false),
1183 Pa28: (pa28, 28, false),
1184 Pa29: (pa29, 29, false),
1185 Pa30: (pa30, 30, true), Pa31: (pa31, 31, false),
1187],[
1188 Pb0: (pb0, 0, true, false), Pb1: (pb1, 1, true, false), Pb2: (pb2, 2, true, false), Pb3: (pb3, 3, true, false), Pb4: (pb4, 4, false, true), Pb5: (pb5, 5, true, true), Pb6: (pb6, 6, false, true), Pb7: (pb7, 7, false, true), Pb8: (pb8, 8, false, false),
1197 Pb9: (pb9, 9, false, false),
1198 Pb10: (pb10, 10, false, false),
1199 Pb11: (pb11, 11, false, false),
1200 Pb12: (pb12, 12, false, true), Pb13: (pb13, 13, true, false), Pb14: (pb14, 14, false, false),
1203
1204 ],
1206[
1207 Pc0: (pc0, 0, false),
1208 Pc1: (pc1, 1, false),
1209 Pc2: (pc2, 2, false),
1210 Pc3: (pc3, 3, false),
1211 Pc4: (pc4, 4, false),
1212 Pc5: (pc5, 5, false),
1213 Pc6: (pc6, 6, false),
1214 Pc7: (pc7, 7, false),
1215 Pc8: (pc8, 8, false),
1216 Pc9: (pc9, 9, false),
1217 Pc10: (pc10, 10, false),
1218 Pc11: (pc11, 11, false),
1219 Pc12: (pc12, 12, true), Pc13: (pc13, 13, true), Pc14: (pc14, 14, false),
1222 Pc15: (pc15, 15, true), Pc16: (pc16, 16, false),
1224 Pc17: (pc17, 17, false),
1225 Pc18: (pc18, 18, false),
1226 Pc19: (pc19, 19, false),
1227 Pc20: (pc20, 20, false),
1228 Pc21: (pc21, 21, false),
1229 Pc22: (pc22, 22, false),
1230 Pc23: (pc23, 23, false),
1231 Pc24: (pc24, 24, false),
1232 Pc25: (pc25, 25, false),
1233 Pc26: (pc26, 26, false),
1234 Pc27: (pc27, 27, false),
1235 Pc28: (pc28, 28, false),
1236 Pc29: (pc29, 29, true), Pc30: (pc30, 30, true), Pc31: (pc31, 31, true), ], [], []);
1240
1241#[cfg(feature = "atsam4s")]
1242pins!([
1243 Pa0: (pa0, 0, true), Pa1: (pa1, 1, true), Pa2: (pa2, 2, true), Pa3: (pa3, 3, false),
1247 Pa4: (pa4, 4, true), Pa5: (pa5, 5, true), Pa6: (pa6, 6, false),
1250 Pa7: (pa7, 7, false),
1251 Pa8: (pa8, 8, true), Pa9: (pa9, 9, true), Pa10: (pa10, 10, false),
1254 Pa11: (pa11, 11, true), Pa12: (pa12, 12, false),
1256 Pa13: (pa13, 13, false),
1257 Pa14: (pa14, 14, true), Pa15: (pa15, 15, true), Pa16: (pa16, 16, true), Pa17: (pa17, 17, true), Pa18: (pa18, 18, true), Pa19: (pa19, 19, true), Pa20: (pa20, 20, true), Pa21: (pa21, 21, true), Pa22: (pa22, 22, true), Pa23: (pa23, 23, true), Pa24: (pa24, 24, true), Pa25: (pa25, 25, true), Pa26: (pa26, 26, true), Pa27: (pa27, 27, true), Pa28: (pa28, 28, true), Pa29: (pa29, 29, true), Pa30: (pa30, 30, true), Pa31: (pa31, 31, true), ],[
1276 Pb0: (pb0, 0, true, false), Pb1: (pb1, 1, true, false), Pb2: (pb2, 2, true, false), Pb3: (pb3, 3, true, false), Pb4: (pb4, 4, false, true), Pb5: (pb5, 5, true, true), Pb6: (pb6, 6, false, true), Pb7: (pb7, 7, false, true), Pb8: (pb8, 8, false, false),
1285 Pb9: (pb9, 9, false, false),
1286 Pb10: (pb10, 10, false, true), Pb11: (pb11, 11, false, true), Pb12: (pb12, 12, false, true), Pb13: (pb13, 13, true, false), Pb14: (pb14, 14, true, false), ],
1294[
1295 Pc0: (pc0, 0, false),
1296 Pc1: (pc1, 1, false),
1297 Pc2: (pc2, 2, false),
1298 Pc3: (pc3, 3, false),
1299 Pc4: (pc4, 4, false),
1300 Pc5: (pc5, 5, false),
1301 Pc6: (pc6, 6, false),
1302 Pc7: (pc7, 7, false),
1303 Pc8: (pc8, 8, false),
1304 Pc9: (pc9, 9, false),
1305 Pc10: (pc10, 10, false),
1306 Pc11: (pc11, 11, false),
1307 Pc12: (pc12, 12, true), Pc13: (pc13, 13, true), Pc14: (pc14, 14, false),
1310 Pc15: (pc15, 15, true), Pc16: (pc16, 16, false),
1312 Pc17: (pc17, 17, false),
1313 Pc18: (pc18, 18, false),
1314 Pc19: (pc19, 19, false),
1315 Pc20: (pc20, 20, false),
1316 Pc21: (pc21, 21, false),
1317 Pc22: (pc22, 22, false),
1318 Pc23: (pc23, 23, false),
1319 Pc24: (pc24, 24, false),
1320 Pc25: (pc25, 25, false),
1321 Pc26: (pc26, 26, false),
1322 Pc27: (pc27, 27, false),
1323 Pc28: (pc28, 28, false),
1324 Pc29: (pc29, 29, true), Pc30: (pc30, 30, true), Pc31: (pc31, 31, false),
1327], [], []);
1328
1329#[macro_export]
1330macro_rules! define_pin_map {
1331 ($(#[$topattr:meta])* struct $Type:ident,
1332 $( $(#[$attr:meta])* pin $name:ident = $pin_ident:ident<$pin_type:ty, $into_method:ident>),+ , ) => {
1333
1334 paste! {
1335 $(#[$topattr])*
1336 pub struct $Type {
1337 $(
1338 $(#[$attr])*
1339 pub $name: [<P $pin_ident>]<$pin_type>
1340 ),+
1341 }
1342 }
1343
1344 impl $Type {
1345 paste! {
1347 pub fn new(ports: Ports, matrix: &MATRIX) -> Self {
1348 let pins = ports.split();
1349 $(
1352 let [<new_pin $pin_ident>] = pins.[<p $pin_ident>].$into_method(matrix);
1353 )+
1354 $Type {
1355 $(
1356 $name: [<new_pin $pin_ident>]
1357 ),+
1358 }
1359 }
1360 }
1361 }
1362 }
1363}
1364
1365macro_rules! impl_pxx {
1366 ($(($port:ident)),*) => {
1367 paste! {
1368 pub enum PioX<MODE> {
1369 $(
1370 $port([<$port Generic>]<MODE>)
1371 ),*
1372 }
1373
1374 impl<MODE> OutputPin for PioX<Output<MODE>> {
1375 type Error = Infallible;
1376 fn set_high(&mut self) -> Result<(), Infallible> {
1377 match self {
1378 $(PioX::$port(pin) => pin.set_high()),*
1379 }
1380 }
1381
1382 fn set_low(&mut self) -> Result<(), Infallible> {
1383 match self {
1384 $(PioX::$port(pin) => pin.set_low()),*
1385 }
1386 }
1387 }
1388
1389 impl<MODE> StatefulOutputPin for PioX<Output<MODE>> {
1390 fn is_set_high(&self) -> Result<bool, Self::Error> {
1391 match self {
1392 $(PioX::$port(pin) => pin.is_set_high()),*
1393 }
1394 }
1395
1396 fn is_set_low(&self) -> Result<bool, Self::Error> {
1397 match self {
1398 $(PioX::$port(pin) => pin.is_set_low()),*
1399 }
1400 }
1401 }
1402
1403 impl<MODE> InputPin for PioX<Input<MODE>> {
1404 type Error = Infallible;
1405 fn is_high(&self) -> Result<bool, Infallible> {
1406 match self {
1407 $(PioX::$port(pin) => pin.is_high()),*
1408 }
1409 }
1410
1411 fn is_low(&self) -> Result<bool, Infallible> {
1412 match self {
1413 $(PioX::$port(pin) => pin.is_low()),*
1414 }
1415 }
1416 }
1417
1418 impl <MODE> toggleable::Default for PioX<Output<MODE>> {}
1419
1420 impl IoPin<PioX<Input<Floating>>, Self> for PioX<Output<PushPull>> {
1421 type Error = Infallible;
1422 fn into_input_pin(self) -> Result<PioX<Input<Floating>>, Self::Error> {
1423 unsafe {
1424 match self {
1425 $(PioX::$port(pin) => {
1426 (*$port::ptr()).mddr.write_with_zero(|w| w.bits(1 << pin.i)); (*$port::ptr()).odr.write_with_zero(|w| w.bits(1 << pin.i)); (*$port::ptr()).pudr.write_with_zero(|w| w.bits(1 << pin.i)); (*$port::ptr()).ppddr.write_with_zero(|w| w.bits(1 << pin.i)); (*$port::ptr()).per.write_with_zero(|w| w.bits(1 << pin.i)); Ok(PioX::$port([<$port Generic>] { i: pin.i, _mode: PhantomData }))
1433 })*
1434 }
1435 }
1436
1437 }
1438 fn into_output_pin(mut self, state: PinState) -> Result<Self, Self::Error> {
1439 self.set_state(state).unwrap();
1440 Ok(self)
1441 }
1442 }
1443
1444 impl IoPin<PioX<Input<PullDown>>, Self> for PioX<Output<PushPull>> {
1445 type Error = Infallible;
1446 fn into_input_pin(self) -> Result<PioX<Input<PullDown>>, Self::Error> {
1447 unsafe {
1448 match self {
1449 $(PioX::$port(pin) => {
1450 (*$port::ptr()).mddr.write_with_zero(|w| w.bits(1 << pin.i)); (*$port::ptr()).odr.write_with_zero(|w| w.bits(1 << pin.i)); (*$port::ptr()).pudr.write_with_zero(|w| w.bits(1 << pin.i)); (*$port::ptr()).ppder.write_with_zero(|w| w.bits(1 << pin.i)); (*$port::ptr()).per.write_with_zero(|w| w.bits(1 << pin.i)); Ok(PioX::$port([<$port Generic>] { i: pin.i, _mode: PhantomData }))
1457 })*
1458 }
1459 }
1460
1461 }
1462 fn into_output_pin(mut self, state: PinState) -> Result<Self, Self::Error> {
1463 self.set_state(state).unwrap();
1464 Ok(self)
1465 }
1466 }
1467
1468 impl IoPin<PioX<Input<PullUp>>, Self> for PioX<Output<PushPull>> {
1469 type Error = Infallible;
1470 fn into_input_pin(self) -> Result<PioX<Input<PullUp>>, Self::Error> {
1471 unsafe {
1472 match self {
1473 $(PioX::$port(pin) => {
1474 (*$port::ptr()).mddr.write_with_zero(|w| w.bits(1 << pin.i)); (*$port::ptr()).odr.write_with_zero(|w| w.bits(1 << pin.i)); (*$port::ptr()).puer.write_with_zero(|w| w.bits(1 << pin.i)); (*$port::ptr()).ppddr.write_with_zero(|w| w.bits(1 << pin.i)); (*$port::ptr()).per.write_with_zero(|w| w.bits(1 << pin.i)); Ok(PioX::$port([<$port Generic>] { i: pin.i, _mode: PhantomData }))
1481 })*
1482 }
1483 }
1484
1485 }
1486 fn into_output_pin(mut self, state: PinState) -> Result<Self, Self::Error> {
1487 self.set_state(state).unwrap();
1488 Ok(self)
1489 }
1490 }
1491
1492 impl IoPin<Self, PioX<Output<PushPull>>> for PioX<Input<Floating>> {
1493 type Error = Infallible;
1494 fn into_input_pin(self) -> Result<Self, Self::Error> {
1495 Ok(self)
1496 }
1497 fn into_output_pin(self, state: PinState) -> Result<PioX<Output<PushPull>>, Self::Error> {
1498 unsafe {
1499 match self {
1500 $(PioX::$port(pin) => {
1501 (*$port::ptr()).mddr.write_with_zero(|w| w.bits(1 << pin.i)); (*$port::ptr()).oer.write_with_zero(|w| w.bits(1 << pin.i)); (*$port::ptr()).per.write_with_zero(|w| w.bits(1 << pin.i)); match state {
1505 PinState::Low => {
1506 (*$port::ptr()).codr.write_with_zero(|w| w.bits(1 << pin.i) );
1507 }
1508 PinState::High => {
1509 (*$port::ptr()).sodr.write_with_zero(|w| w.bits(1 << pin.i) );
1510 }
1511 }
1512
1513 Ok(PioX::$port([<$port Generic>] { i: pin.i, _mode: PhantomData }))
1514 })*
1515 }
1516 }
1517 }
1518 }
1519
1520 impl IoPin<Self, PioX<Output<PushPull>>> for PioX<Input<PullDown>> {
1521 type Error = Infallible;
1522 fn into_input_pin(self) -> Result<Self, Self::Error> {
1523 Ok(self)
1524 }
1525 fn into_output_pin(self, state: PinState) -> Result<PioX<Output<PushPull>>, Self::Error> {
1526 unsafe {
1527 match self {
1528 $(PioX::$port(pin) => {
1529 (*$port::ptr()).mddr.write_with_zero(|w| w.bits(1 << pin.i)); (*$port::ptr()).oer.write_with_zero(|w| w.bits(1 << pin.i)); (*$port::ptr()).per.write_with_zero(|w| w.bits(1 << pin.i)); match state {
1533 PinState::Low => {
1534 (*$port::ptr()).codr.write_with_zero(|w| w.bits(1 << pin.i) );
1535 }
1536 PinState::High => {
1537 (*$port::ptr()).sodr.write_with_zero(|w| w.bits(1 << pin.i) );
1538 }
1539 }
1540
1541 Ok(PioX::$port([<$port Generic>] { i: pin.i, _mode: PhantomData }))
1542 })*
1543 }
1544 }
1545 }
1546 }
1547
1548 impl IoPin<Self, PioX<Output<PushPull>>> for PioX<Input<PullUp>> {
1549 type Error = Infallible;
1550 fn into_input_pin(self) -> Result<Self, Self::Error> {
1551 Ok(self)
1552 }
1553 fn into_output_pin(self, state: PinState) -> Result<PioX<Output<PushPull>>, Self::Error> {
1554 unsafe {
1555 match self {
1556 $(PioX::$port(pin) => {
1557 (*$port::ptr()).mddr.write_with_zero(|w| w.bits(1 << pin.i)); (*$port::ptr()).oer.write_with_zero(|w| w.bits(1 << pin.i)); (*$port::ptr()).per.write_with_zero(|w| w.bits(1 << pin.i)); match state {
1561 PinState::Low => {
1562 (*$port::ptr()).codr.write_with_zero(|w| w.bits(1 << pin.i) );
1563 }
1564 PinState::High => {
1565 (*$port::ptr()).sodr.write_with_zero(|w| w.bits(1 << pin.i) );
1566 }
1567 }
1568
1569 Ok(PioX::$port([<$port Generic>] { i: pin.i, _mode: PhantomData }))
1570 })*
1571 }
1572 }
1573 }
1574 }
1575 }
1576 }
1577}
1578
1579#[cfg(not(any(feature = "atsam4n_c", feature = "atsam4s_c", feature = "atsam4e")))]
1580impl_pxx! {
1581 (PIOA),
1582 (PIOB)
1583}
1584
1585#[cfg(any(feature = "atsam4n_c", feature = "atsam4s_c"))]
1586impl_pxx! {
1587 (PIOA),
1588 (PIOB),
1589 (PIOC)
1590}
1591
1592#[cfg(feature = "atsam4e_c")]
1593impl_pxx! {
1594 (PIOA),
1595 (PIOB),
1596 (PIOD)
1597}
1598
1599#[cfg(feature = "atsam4e_e")]
1600impl_pxx! {
1601 (PIOA),
1602 (PIOB),
1603 (PIOC),
1604 (PIOD),
1605 (PIOE)
1606}