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>] => (*<$port>::ptr()).[<port $name:lower>].modify(|r, w| {
637 w.bits(r.bits() | self.mask)
638 }),)+
639 }
640 }
641
642 #[inline]
643 unsafe fn out_clear(&mut self) {
644 match self.port {
645 $(DynamicPort::[<PORT $name>] => (*<$port>::ptr()).[<port $name:lower>].modify(|r, w| {
646 w.bits(r.bits() & !self.mask)
647 }),)+
648 }
649 }
650
651 #[inline]
652 unsafe fn out_toggle(&mut self) {
653 match self.port {
654 $(DynamicPort::[<PORT $name>] => {
655 if $chip_supports_atomic_toggle {
656 (*<$port>::ptr()).[<pin $name:lower>].write(|w| {
657 w.bits(self.mask)
658 })
659 } else {
660 $crate::avr_device::interrupt::free(|_| {
663 (*<$port>::ptr()).[<port $name:lower>].modify(|r, w| {
664 w.bits(r.bits() ^ self.mask)
665 })
666 })
667 }
668 },)+
669 }
670 }
671
672 #[inline]
673 unsafe fn out_get(&self) -> bool {
674 match self.port {
675 $(DynamicPort::[<PORT $name>] => {
676 (*<$port>::ptr()).[<port $name:lower>].read().bits() & self.mask != 0
677 })+
678 }
679 }
680
681 #[inline]
682 unsafe fn in_get(&self) -> bool {
683 match self.port {
684 $(DynamicPort::[<PORT $name>] => {
685 (*<$port>::ptr()).[<pin $name:lower>].read().bits() & self.mask != 0
686 })+
687 }
688 }
689
690 #[inline]
691 unsafe fn make_output(&mut self) {
692 match self.port {
693 $(DynamicPort::[<PORT $name>] => (*<$port>::ptr()).[<ddr $name:lower>].modify(|r, w| {
694 w.bits(r.bits() | self.mask)
695 }),)+
696 }
697 }
698
699 #[inline]
700 unsafe fn make_input(&mut self, pull_up: bool) {
701 match self.port {
702 $(DynamicPort::[<PORT $name>] => (*<$port>::ptr()).[<ddr $name:lower>].modify(|r, w| {
703 w.bits(r.bits() & !self.mask)
704 }),)+
705 }
706 if pull_up {
707 self.out_set()
708 } else {
709 self.out_clear()
710 }
711 }
712 }
713 }
714
715 $crate::paste::paste! {
716 $($(
717 pub struct [<P $name $pin>] {
718 _private: ()
719 }
720
721 impl $crate::port::PinOps for [<P $name $pin>] {
722 type Dynamic = Dynamic;
723
724 #[inline]
725 fn into_dynamic(self) -> Self::Dynamic {
726 Dynamic::new(DynamicPort::[<PORT $name>], $pin)
727 }
728
729 #[inline]
730 unsafe fn out_set(&mut self) {
731 (*<$port>::ptr()).[<port $name:lower>].modify(|_, w| {
732 w.[<p $name:lower $pin>]().set_bit()
733 })
734 }
735
736 #[inline]
737 unsafe fn out_clear(&mut self) {
738 (*<$port>::ptr()).[<port $name:lower>].modify(|_, w| {
739 w.[<p $name:lower $pin>]().clear_bit()
740 })
741 }
742
743 #[inline]
744 unsafe fn out_toggle(&mut self) {
745 if $chip_supports_atomic_toggle {
746 (*<$port>::ptr()).[<pin $name:lower>].write(|w| {
747 w.[<p $name:lower $pin>]().set_bit()
748 })
749 } else {
750 $crate::avr_device::interrupt::free(|_| {
753 (*<$port>::ptr()).[<port $name:lower>].modify(|r, w| {
754 w.[<p $name:lower $pin>]().bit(!r.[<p $name:lower $pin>]().bit())
755 })
756 })
757 }
758 }
759
760 #[inline]
761 unsafe fn out_get(&self) -> bool {
762 (*<$port>::ptr()).[<port $name:lower>].read().[<p $name:lower $pin>]().bit()
763 }
764
765 #[inline]
766 unsafe fn in_get(&self) -> bool {
767 (*<$port>::ptr()).[<pin $name:lower>].read().[<p $name:lower $pin>]().bit()
768 }
769
770 #[inline]
771 unsafe fn make_output(&mut self) {
772 (*<$port>::ptr()).[<ddr $name:lower>].modify(|_, w| {
773 w.[<p $name:lower $pin>]().set_bit()
774 })
775 }
776
777 #[inline]
778 unsafe fn make_input(&mut self, pull_up: bool) {
779 (*<$port>::ptr()).[<ddr $name:lower>].modify(|_, w| {
780 w.[<p $name:lower $pin>]().clear_bit()
781 });
782 if pull_up {
783 self.out_set()
784 } else {
785 self.out_clear()
786 }
787 }
788 }
789 )+)+
790 }
791 };
792}
793
794#[macro_export]
796macro_rules! impl_port_traditional {
797 ($($tts:tt)*) => {
798 $crate::impl_port_traditional_base!(true, $($tts)*);
799 };
800}
801
802#[macro_export]
805macro_rules! impl_port_traditional_old {
806 ($($tts:tt)*) => {
807 $crate::impl_port_traditional_base!(false, $($tts)*);
808 };
809}
810
811#[macro_export]
812macro_rules! renamed_pins {
813 (
814 $(#[$pins_attr:meta])*
815 pub struct Pins {
816 $($(#[$pin_attr:meta])* pub $pin_name:ident: $pin_type:ty = $pin_orig:ident,)+
817 }
818
819 impl Pins {
820 type Pin = $pin_wrapper:ident;
821 type McuPins = $mcu_pins:ty;
822 }
823 ) => {
824 $crate::paste::paste! {
825 $(#[$pins_attr])*
826 pub struct Pins {
827 $(pub $pin_name: $pin_wrapper<
828 $crate::port::mode::Input<$crate::port::mode::Floating>,
829 [<$pin_name:upper>],
830 >,)+
831 }
832 }
833
834 $crate::paste::paste! {
835 $($(#[$pin_attr])* pub type [<$pin_name:upper>] = $pin_type;)+
836 }
837
838 impl Pins {
839 pub fn with_mcu_pins(pins: $mcu_pins) -> Self {
840 Self {
841 $($pin_name: pins.$pin_orig,)+
842 }
843 }
844 }
845 };
846}