1use core::marker::PhantomData;
6use embedded_hal::digital::{ErrorType, InputPin, OutputPin, StatefulOutputPin};
7use embedded_hal_v0::digital::v2::{InputPin as InputPinV0, OutputPin as OutputPinV0};
8
9pub trait PinMode: crate::Sealed {}
10pub mod mode {
12 use core::marker::PhantomData;
13
14 pub trait Io: crate::Sealed + super::PinMode {}
15
16 pub struct Output;
18 impl super::PinMode for Output {}
19 impl Io for Output {}
20 impl crate::Sealed for Output {}
21
22 pub struct OpenDrain;
24 impl super::PinMode for OpenDrain {}
25 impl Io for OpenDrain {}
26 impl crate::Sealed for OpenDrain {}
27
28 pub struct PwmOutput<TC> {
29 pub(crate) _timer: PhantomData<TC>,
30 }
31 impl<TC> super::PinMode for PwmOutput<TC> {}
32 impl<TC> crate::Sealed for PwmOutput<TC> {}
33
34 pub trait InputMode: crate::Sealed {}
35
36 pub struct Input<IMODE = AnyInput> {
38 pub(crate) _imode: PhantomData<IMODE>,
39 }
40 impl<IMODE: InputMode> super::PinMode for Input<IMODE> {}
41 impl<IMODE: InputMode> Io for Input<IMODE> {}
42 impl<IMODE: InputMode> crate::Sealed for Input<IMODE> {}
43
44 pub struct Floating;
46 impl InputMode for Floating {}
47 impl crate::Sealed for Floating {}
48
49 pub struct PullUp;
51 impl InputMode for PullUp {}
52 impl crate::Sealed for PullUp {}
53
54 pub struct AnyInput;
56 impl InputMode for AnyInput {}
57 impl crate::Sealed for AnyInput {}
58
59 pub struct Analog;
61}
62
63pub trait PinOps {
64 type Dynamic;
65
66 fn into_dynamic(self) -> Self::Dynamic;
67
68 unsafe fn out_set(&mut self);
69 unsafe fn out_clear(&mut self);
70 unsafe fn out_toggle(&mut self);
71 unsafe fn out_get(&self) -> bool;
72
73 unsafe fn in_get(&self) -> bool;
74
75 unsafe fn make_output(&mut self);
76 unsafe fn make_input(&mut self, pull_up: bool);
77}
78
79pub struct Pin<MODE, PIN> {
111 pub(crate) pin: PIN,
112 pub(crate) _mode: PhantomData<MODE>,
113}
114
115impl<PIN: PinOps> Pin<mode::Input<mode::Floating>, PIN> {
116 #[doc(hidden)]
117 pub fn new(pin: PIN) -> Self {
118 Pin {
119 pin,
120 _mode: PhantomData,
121 }
122 }
123}
124
125impl<PIN: PinOps, MODE: mode::Io> Pin<MODE, PIN> {
131 pub fn into_output(mut self) -> Pin<mode::Output, PIN> {
134 unsafe { self.pin.out_clear() };
135 unsafe { self.pin.make_output() };
136 Pin {
137 pin: self.pin,
138 _mode: PhantomData,
139 }
140 }
141
142 pub fn into_output_high(mut self) -> Pin<mode::Output, PIN> {
145 unsafe { self.pin.out_set() };
146 unsafe { self.pin.make_output() };
147 Pin {
148 pin: self.pin,
149 _mode: PhantomData,
150 }
151 }
152
153 pub fn into_opendrain(mut self) -> Pin<mode::OpenDrain, PIN> {
156 unsafe { self.pin.out_clear() };
157 unsafe { self.pin.make_output() };
158 Pin {
159 pin: self.pin,
160 _mode: PhantomData,
161 }
162 }
163
164 pub fn into_opendrain_high(mut self) -> Pin<mode::OpenDrain, PIN> {
167 unsafe { self.pin.make_input(false) };
168 Pin {
169 pin: self.pin,
170 _mode: PhantomData,
171 }
172 }
173
174 pub fn into_floating_input(mut self) -> Pin<mode::Input<mode::Floating>, PIN> {
179 unsafe { self.pin.make_input(false) };
180 Pin {
181 pin: self.pin,
182 _mode: PhantomData,
183 }
184 }
185
186 pub fn into_pull_up_input(mut self) -> Pin<mode::Input<mode::PullUp>, PIN> {
190 unsafe { self.pin.make_input(true) };
191 Pin {
192 pin: self.pin,
193 _mode: PhantomData,
194 }
195 }
196
197 pub fn into_analog_input<H, ADC, CLOCK>(
202 self,
203 adc: &mut crate::adc::Adc<H, ADC, CLOCK>,
204 ) -> Pin<mode::Analog, PIN>
205 where
206 Pin<mode::Analog, PIN>: crate::adc::AdcChannel<H, ADC>,
207 ADC: crate::adc::AdcOps<H>,
208 CLOCK: crate::clock::Clock,
209 {
210 let mut new = Pin {
211 pin: self.pin,
212 _mode: PhantomData,
213 };
214 adc.enable_pin(&new);
215 unsafe { new.pin.make_input(false) };
216 new
217 }
218}
219
220impl<PIN: PinOps, MODE: mode::Io> Pin<MODE, PIN> {
237 pub fn downgrade(self) -> Pin<MODE, PIN::Dynamic> {
241 Pin {
242 pin: self.pin.into_dynamic(),
243 _mode: PhantomData,
244 }
245 }
246}
247
248impl<PIN: PinOps, IMODE> Pin<mode::Input<IMODE>, PIN> {
276 pub fn forget_imode(self) -> Pin<mode::Input, PIN> {
279 Pin {
280 pin: self.pin,
281 _mode: PhantomData,
282 }
283 }
284}
285
286impl<PIN: PinOps> Pin<mode::Output, PIN> {
288 #[inline]
290 pub fn set_high(&mut self) {
291 unsafe { self.pin.out_set() }
292 }
293
294 #[inline]
296 pub fn set_low(&mut self) {
297 unsafe { self.pin.out_clear() }
298 }
299
300 #[inline]
302 pub fn toggle(&mut self) {
303 unsafe { self.pin.out_toggle() }
304 }
305
306 #[inline]
310 pub fn is_set_high(&self) -> bool {
311 unsafe { self.pin.out_get() }
312 }
313
314 #[inline]
318 pub fn is_set_low(&self) -> bool {
319 !unsafe { self.pin.out_get() }
320 }
321}
322
323impl<PIN: PinOps> OutputPinV0 for Pin<mode::Output, PIN> {
325 type Error = core::convert::Infallible;
326
327 fn set_high(&mut self) -> Result<(), Self::Error> {
328 self.set_high();
329 Ok(())
330 }
331
332 fn set_low(&mut self) -> Result<(), Self::Error> {
333 self.set_low();
334 Ok(())
335 }
336}
337
338impl<PIN: PinOps> ErrorType for Pin<mode::Output, PIN> {
339 type Error = core::convert::Infallible;
340}
341
342impl<PIN: PinOps> OutputPin for Pin<mode::Output, PIN> {
343 fn set_low(&mut self) -> Result<(), Self::Error> {
344 self.set_low();
345 Ok(())
346 }
347
348 fn set_high(&mut self) -> Result<(), Self::Error> {
349 self.set_high();
350 Ok(())
351 }
352}
353
354impl<PIN: PinOps> StatefulOutputPin for Pin<mode::Output, PIN> {
355 fn is_set_high(&mut self) -> Result<bool, Self::Error> {
356 Ok((*self).is_set_high())
357 }
358
359 fn is_set_low(&mut self) -> Result<bool, Self::Error> {
360 Ok((*self).is_set_low())
361 }
362}
363
364impl<PIN: PinOps> Pin<mode::OpenDrain, PIN> {
366 #[inline]
368 pub fn set_high(&mut self) {
369 unsafe { self.pin.make_input(false) }
370 }
371
372 #[inline]
374 pub fn set_low(&mut self) {
375 unsafe { self.pin.make_output() }
376 }
377
378 #[inline]
382 pub fn is_high(&self) -> bool {
383 unsafe { self.pin.in_get() }
384 }
385
386 #[inline]
390 pub fn is_low(&self) -> bool {
391 !self.is_high()
392 }
393}
394
395impl<PIN: PinOps> OutputPinV0 for Pin<mode::OpenDrain, PIN> {
397 type Error = core::convert::Infallible;
398
399 fn set_high(&mut self) -> Result<(), Self::Error> {
400 self.set_high();
401 Ok(())
402 }
403
404 fn set_low(&mut self) -> Result<(), Self::Error> {
405 self.set_low();
406 Ok(())
407 }
408}
409
410impl<PIN: PinOps> OutputPin for Pin<mode::OpenDrain, PIN> {
411 fn set_low(&mut self) -> Result<(), Self::Error> {
412 self.set_low();
413 Ok(())
414 }
415
416 fn set_high(&mut self) -> Result<(), Self::Error> {
417 self.set_high();
418 Ok(())
419 }
420}
421
422impl<PIN: PinOps> StatefulOutputPin for Pin<mode::OpenDrain, PIN> {
423 fn is_set_high(&mut self) -> Result<bool, Self::Error> {
424 Ok((*self).is_high())
425 }
426
427 fn is_set_low(&mut self) -> Result<bool, Self::Error> {
428 Ok((*self).is_low())
429 }
430}
431
432impl<PIN: PinOps> InputPinV0 for Pin<mode::OpenDrain, PIN> {
434 type Error = core::convert::Infallible;
435
436 fn is_high(&self) -> Result<bool, Self::Error> {
437 Ok(self.is_high())
438 }
439
440 fn is_low(&self) -> Result<bool, Self::Error> {
441 Ok(self.is_low())
442 }
443}
444
445impl<PIN: PinOps> ErrorType for Pin<mode::OpenDrain, PIN> {
446 type Error = core::convert::Infallible;
447}
448
449impl<PIN: PinOps> InputPin for Pin<mode::OpenDrain, PIN> {
450 fn is_high(&mut self) -> Result<bool, Self::Error> {
451 Ok((*self).is_high())
452 }
453
454 fn is_low(&mut self) -> Result<bool, Self::Error> {
455 Ok((*self).is_low())
456 }
457}
458
459impl<PIN: PinOps, IMODE: mode::InputMode> InputPinV0 for Pin<mode::Input<IMODE>, PIN> {
461 type Error = core::convert::Infallible;
462
463 fn is_high(&self) -> Result<bool, Self::Error> {
464 Ok(self.is_high())
465 }
466
467 fn is_low(&self) -> Result<bool, Self::Error> {
468 Ok(self.is_low())
469 }
470}
471
472impl<PIN: PinOps, IMODE: mode::InputMode> ErrorType for Pin<mode::Input<IMODE>, PIN> {
473 type Error = core::convert::Infallible;
474}
475
476impl<PIN: PinOps, IMODE: mode::InputMode> InputPin for Pin<mode::Input<IMODE>, PIN> {
477 fn is_high(&mut self) -> Result<bool, Self::Error> {
478 Ok((*self).is_high())
479 }
480
481 fn is_low(&mut self) -> Result<bool, Self::Error> {
482 Ok((*self).is_low())
483 }
484}
485
486impl<PIN: PinOps, IMODE: mode::InputMode> Pin<mode::Input<IMODE>, PIN> {
488 #[inline]
490 pub fn is_high(&self) -> bool {
491 unsafe { self.pin.in_get() }
492 }
493
494 #[inline]
496 pub fn is_low(&self) -> bool {
497 !unsafe { self.pin.in_get() }
498 }
499}
500
501impl<PIN: PinOps> Pin<mode::Analog, PIN> {
518 pub fn analog_read<H, ADC, CLOCK>(&self, adc: &mut crate::adc::Adc<H, ADC, CLOCK>) -> u16
519 where
520 Pin<mode::Analog, PIN>: crate::adc::AdcChannel<H, ADC>,
521 ADC: crate::adc::AdcOps<H>,
522 CLOCK: crate::clock::Clock,
523 {
524 adc.read_blocking(self)
525 }
526
527 pub fn into_channel<H, ADC>(self) -> crate::adc::Channel<H, ADC>
533 where
534 Pin<mode::Analog, PIN>: crate::adc::AdcChannel<H, ADC>,
535 ADC: crate::adc::AdcOps<H>,
536 {
537 crate::adc::Channel::new(self)
538 }
539
540 pub fn into_digital<H, ADC, CLOCK>(
546 self,
547 adc: &mut crate::adc::Adc<H, ADC, CLOCK>,
548 ) -> Pin<mode::Input<mode::Floating>, PIN>
549 where
550 Pin<mode::Analog, PIN>: crate::adc::AdcChannel<H, ADC>,
551 ADC: crate::adc::AdcOps<H>,
552 CLOCK: crate::clock::Clock,
553 {
554 adc.disable_pin(&self);
555 Pin {
556 pin: self.pin,
557 _mode: PhantomData,
558 }
559 }
560}
561
562#[macro_export]
563macro_rules! impl_port_traditional_base {
564 (
565 $chip_supports_atomic_toggle:literal,
566 $(#[$pins_attr:meta])*
567 enum Ports {
568 $($name:ident: $port:ty = [$($pin:literal),+],)+
569 }
570 ) => {
571 pub type Pin<MODE, PIN = Dynamic> = $crate::port::Pin<MODE, PIN>;
578
579 $crate::paste::paste! {
580 $(#[$pins_attr])*
581 pub struct Pins {
582 $($(pub [<p $name:lower $pin>]: Pin<
583 mode::Input<mode::Floating>,
584 [<P $name $pin>],
585 >,)+)+
586 }
587
588 impl Pins {
589 pub fn new(
590 $(_: $port,)+
591 ) -> Self {
592 Self {
593 $($([<p $name:lower $pin>]: $crate::port::Pin::new(
594 [<P $name $pin>] { _private: (), }
595 ),)+)+
596 }
597 }
598 }
599 }
600
601 $crate::paste::paste! {
602 #[repr(u8)]
603 pub enum DynamicPort {
604 $([<PORT $name>]),+
605 }
606 }
607
608 pub struct Dynamic {
609 port: DynamicPort,
610 mask: u8,
613 }
614
615 impl Dynamic {
616 fn new(port: DynamicPort, num: u8) -> Self {
617 Self {
618 port,
619 mask: 1u8 << num,
620 }
621 }
622 }
623
624 $crate::paste::paste! {
625 impl $crate::port::PinOps for Dynamic {
626 type Dynamic = Self;
627
628 #[inline]
629 fn into_dynamic(self) -> Self::Dynamic {
630 self
631 }
632
633 #[inline]
634 unsafe fn out_set(&mut self) {
635 match self.port {
636 $(DynamicPort::[<PORT $name>] => {
637 (*<$port>::ptr()).[<port $name:lower>]().modify(|r, w| {
638 w.bits(r.bits() | self.mask)
639 });
640 })+
641 }
642 }
643
644 #[inline]
645 unsafe fn out_clear(&mut self) {
646 match self.port {
647 $(DynamicPort::[<PORT $name>] => {
648 (*<$port>::ptr()).[<port $name:lower>]().modify(|r, w| {
649 w.bits(r.bits() & !self.mask)
650 });
651 })+
652 }
653 }
654
655 #[inline]
656 unsafe fn out_toggle(&mut self) {
657 match self.port {
658 $(DynamicPort::[<PORT $name>] => {
659 if $chip_supports_atomic_toggle {
660 (*<$port>::ptr()).[<pin $name:lower>]().write(|w| {
661 w.bits(self.mask)
662 });
663 } else {
664 $crate::avr_device::interrupt::free(|_| {
667 (*<$port>::ptr()).[<port $name:lower>]().modify(|r, w| {
668 w.bits(r.bits() ^ self.mask)
669 })
670 });
671 }
672 },)+
673 }
674 }
675
676 #[inline]
677 unsafe fn out_get(&self) -> bool {
678 match self.port {
679 $(DynamicPort::[<PORT $name>] => {
680 (*<$port>::ptr()).[<port $name:lower>]().read().bits() & self.mask != 0
681 })+
682 }
683 }
684
685 #[inline]
686 unsafe fn in_get(&self) -> bool {
687 match self.port {
688 $(DynamicPort::[<PORT $name>] => {
689 (*<$port>::ptr()).[<pin $name:lower>]().read().bits() & self.mask != 0
690 })+
691 }
692 }
693
694 #[inline]
695 unsafe fn make_output(&mut self) {
696 match self.port {
697 $(DynamicPort::[<PORT $name>] => {
698 (*<$port>::ptr()).[<ddr $name:lower>]().modify(|r, w| {
699 w.bits(r.bits() | self.mask)
700 });
701 })+
702 }
703 }
704
705 #[inline]
706 unsafe fn make_input(&mut self, pull_up: bool) {
707 match self.port {
708 $(DynamicPort::[<PORT $name>] => {
709 (*<$port>::ptr()).[<ddr $name:lower>]().modify(|r, w| {
710 w.bits(r.bits() & !self.mask)
711 });
712 })+
713 }
714 if pull_up {
715 self.out_set()
716 } else {
717 self.out_clear()
718 }
719 }
720 }
721 }
722
723 $crate::paste::paste! {
724 $($(
725 pub struct [<P $name $pin>] {
726 _private: ()
727 }
728
729 impl $crate::port::PinOps for [<P $name $pin>] {
730 type Dynamic = Dynamic;
731
732 #[inline]
733 fn into_dynamic(self) -> Self::Dynamic {
734 Dynamic::new(DynamicPort::[<PORT $name>], $pin)
735 }
736
737 #[inline]
738 unsafe fn out_set(&mut self) {
739 (*<$port>::ptr()).[<port $name:lower>]().modify(|_, w| {
740 w.[<p $name:lower $pin>]().set_bit()
741 });
742 }
743
744 #[inline]
745 unsafe fn out_clear(&mut self) {
746 (*<$port>::ptr()).[<port $name:lower>]().modify(|_, w| {
747 w.[<p $name:lower $pin>]().clear_bit()
748 });
749 }
750
751 #[inline]
752 unsafe fn out_toggle(&mut self) {
753 if $chip_supports_atomic_toggle {
754 (*<$port>::ptr()).[<pin $name:lower>]().write(|w| {
755 w.[<p $name:lower $pin>]().set_bit()
756 });
757 } else {
758 $crate::avr_device::interrupt::free(|_| {
761 (*<$port>::ptr()).[<port $name:lower>]().modify(|r, w| {
762 w.[<p $name:lower $pin>]().bit(!r.[<p $name:lower $pin>]().bit())
763 });
764 })
765 }
766 }
767
768 #[inline]
769 unsafe fn out_get(&self) -> bool {
770 (*<$port>::ptr()).[<port $name:lower>]().read().[<p $name:lower $pin>]().bit()
771 }
772
773 #[inline]
774 unsafe fn in_get(&self) -> bool {
775 (*<$port>::ptr()).[<pin $name:lower>]().read().[<p $name:lower $pin>]().bit()
776 }
777
778 #[inline]
779 unsafe fn make_output(&mut self) {
780 (*<$port>::ptr()).[<ddr $name:lower>]().modify(|_, w| {
781 w.[<p $name:lower $pin>]().set_bit()
782 });
783 }
784
785 #[inline]
786 unsafe fn make_input(&mut self, pull_up: bool) {
787 (*<$port>::ptr()).[<ddr $name:lower>]().modify(|_, w| {
788 w.[<p $name:lower $pin>]().clear_bit()
789 });
790 if pull_up {
791 self.out_set()
792 } else {
793 self.out_clear()
794 }
795 }
796 }
797 )+)+
798 }
799 };
800}
801
802#[macro_export]
804macro_rules! impl_port_traditional {
805 ($($tts:tt)*) => {
806 $crate::impl_port_traditional_base!(true, $($tts)*);
807 };
808}
809
810#[macro_export]
813macro_rules! impl_port_traditional_old {
814 ($($tts:tt)*) => {
815 $crate::impl_port_traditional_base!(false, $($tts)*);
816 };
817}
818
819#[macro_export]
820macro_rules! renamed_pins {
821 (
822 $(#[$pins_attr:meta])*
823 pub struct Pins {
824 $($(#[$pin_attr:meta])* pub $pin_name:ident: $pin_type:ty = $pin_orig:ident,)+
825 }
826
827 impl Pins {
828 type Pin = $pin_wrapper:ident;
829 type McuPins = $mcu_pins:ty;
830 }
831 ) => {
832 $crate::paste::paste! {
833 $(#[$pins_attr])*
834 pub struct Pins {
835 $(pub $pin_name: $pin_wrapper<
836 $crate::port::mode::Input<$crate::port::mode::Floating>,
837 [<$pin_name:upper>],
838 >,)+
839 }
840 }
841
842 $crate::paste::paste! {
843 $($(#[$pin_attr])* pub type [<$pin_name:upper>] = $pin_type;)+
844 }
845
846 impl Pins {
847 pub fn with_mcu_pins(pins: $mcu_pins) -> Self {
848 Self {
849 $($pin_name: pins.$pin_orig,)+
850 }
851 }
852 }
853 };
854}