1pub use embedded_hal::digital::PinState;
43
44use crate::{
45 atomic_register_access::{write_bitmask_clear, write_bitmask_set},
46 pac,
47 sio::Sio,
48 typelevel::{self, Sealed},
49};
50
51mod func;
52pub(crate) mod pin;
53mod pin_group;
54mod pull;
55
56pub use func::*;
57pub use pin::{DynBankId, DynPinId, PinId};
58pub use pin_group::PinGroup;
59pub use pull::*;
60
61#[allow(clippy::enum_variant_names)]
63#[derive(Clone, Copy, Eq, PartialEq, Debug)]
64pub enum OutputDriveStrength {
65 TwoMilliAmps,
67 FourMilliAmps,
69 EightMilliAmps,
71 TwelveMilliAmps,
73}
74
75#[derive(Clone, Copy, Eq, PartialEq, Debug)]
77pub enum OutputSlewRate {
78 Slow,
80 Fast,
82}
83
84#[derive(Clone, Copy, Eq, PartialEq, Debug)]
86pub enum Interrupt {
87 LevelLow,
89 LevelHigh,
91 EdgeLow,
93 EdgeHigh,
95}
96impl Interrupt {
97 fn mask(&self) -> u32 {
98 match self {
99 Interrupt::LevelLow => 0b0001,
100 Interrupt::LevelHigh => 0b0010,
101 Interrupt::EdgeLow => 0b0100,
102 Interrupt::EdgeHigh => 0b1000,
103 }
104 }
105}
106
107#[derive(Clone, Copy, Eq, PartialEq, Debug)]
109pub enum InterruptOverride {
110 Normal = 0,
112 Invert = 1,
114 AlwaysLow = 2,
116 AlwaysHigh = 3,
118}
119
120#[derive(Clone, Copy, Eq, PartialEq, Debug)]
122pub enum InputOverride {
123 Normal = 0,
125 Invert = 1,
127 AlwaysLow = 2,
129 AlwaysHigh = 3,
131}
132
133#[derive(Clone, Copy, Eq, PartialEq, Debug)]
134pub enum OutputEnableOverride {
136 Normal = 0,
138 Invert = 1,
140 Disable = 2,
142 Enable = 3,
144}
145
146#[derive(Clone, Copy, Eq, PartialEq, Debug)]
147pub enum OutputOverride {
149 DontInvert = 0,
151 Invert = 1,
153 AlwaysLow = 2,
155 AlwaysHigh = 3,
157}
158
159#[derive(Debug)]
162pub struct Pin<I: PinId, F: func::Function, P: PullType> {
163 id: I,
164 function: F,
165 pull_type: P,
166}
167
168pub unsafe fn new_pin(id: DynPinId) -> Pin<DynPinId, DynFunction, DynPullType> {
174 use pac::io_bank0::gpio::gpio_ctrl::FUNCSEL_A;
175 use pin::pin_sealed::PinIdOps;
176
177 let funcsel = id
178 .io_ctrl()
179 .read()
180 .funcsel()
181 .variant()
182 .expect("Invalid funcsel read from register.");
183 let function = match funcsel {
184 FUNCSEL_A::JTAG => DynFunction::Xip,
185 FUNCSEL_A::SPI => DynFunction::Spi,
186 FUNCSEL_A::UART => DynFunction::Uart,
187 FUNCSEL_A::I2C => DynFunction::I2c,
188 FUNCSEL_A::PWM => DynFunction::Pwm,
189 FUNCSEL_A::SIO => {
190 let mask = id.mask();
191 let cfg = if id.sio_oe().read().bits() & mask == mask {
192 DynSioConfig::Output
193 } else {
194 DynSioConfig::Input
195 };
196 DynFunction::Sio(cfg)
197 }
198 FUNCSEL_A::PIO0 => DynFunction::Pio0,
199 FUNCSEL_A::PIO1 => DynFunction::Pio1,
200 FUNCSEL_A::CLOCK => DynFunction::Clock,
201 FUNCSEL_A::USB => DynFunction::Usb,
202 FUNCSEL_A::NULL => DynFunction::Null,
203 };
204 let pad = id.pad_ctrl().read();
205 let pull_type = match (pad.pue().bit_is_set(), pad.pde().bit_is_set()) {
206 (true, true) => DynPullType::BusKeep,
207 (true, false) => DynPullType::Up,
208 (false, true) => DynPullType::Down,
209 (false, false) => DynPullType::None,
210 };
211
212 Pin {
213 id,
214 function,
215 pull_type,
216 }
217}
218
219impl<I: PinId, F: func::Function, P: PullType> Pin<I, F, P> {
220 pub fn id(&self) -> DynPinId {
222 self.id.as_dyn()
223 }
224
225 pub unsafe fn into_unchecked<F2: func::Function, P2: PullType>(self) -> Pin<I, F2, P2> {
230 Pin {
231 id: self.id,
232 function: F2::from(self.function.as_dyn()),
233 pull_type: P2::from(self.pull_type.as_dyn()),
234 }
235 }
236
237 pub fn reconfigure<F2, P2>(self) -> Pin<I, F2, P2>
239 where
240 F2: func::Function,
241 P2: PullType,
242 I: func::ValidFunction<F2>,
243 {
244 self.into_function().into_pull_type()
245 }
246
247 #[deprecated(
249 note = "Misleading name `mode` when it changes the `function`. Please use `into_function` instead.",
250 since = "0.9.0"
251 )]
252 pub fn into_mode<F2>(self) -> Pin<I, F2, P>
253 where
254 F2: func::Function,
255 I: func::ValidFunction<F2>,
256 {
257 self.into_function()
258 }
259
260 pub fn into_function<F2>(self) -> Pin<I, F2, P>
262 where
263 F2: func::Function,
264 I: func::ValidFunction<F2>,
265 {
266 let prev_function = self.function.as_dyn();
268 let function = F2::from(prev_function);
269 let new_function = function.as_dyn();
270
271 if prev_function != new_function {
272 pin::set_function(&self.id, new_function);
273 }
274
275 Pin {
276 function,
277 id: self.id,
278 pull_type: self.pull_type,
279 }
280 }
281
282 pub fn into_pull_type<M2: PullType>(self) -> Pin<I, F, M2> {
284 let prev_pull_type = self.pull_type.as_dyn();
285 let pull_type = M2::from(prev_pull_type);
286 let new_pull_type = pull_type.as_dyn();
287
288 if prev_pull_type != new_pull_type {
289 pin::set_pull_type(&self.id, new_pull_type);
290 }
291
292 Pin {
293 pull_type,
294 id: self.id,
295 function: self.function,
296 }
297 }
298
299 pub fn into_dyn_pin(self) -> Pin<DynPinId, F, P> {
301 Pin {
302 id: self.id.as_dyn(),
303 function: self.function,
304 pull_type: self.pull_type,
305 }
306 }
307
308 pub fn pull_type(&self) -> DynPullType {
310 self.pull_type.as_dyn()
311 }
312
313 #[inline]
319 pub fn into_floating_disabled(self) -> Pin<I, FunctionNull, PullNone>
320 where
321 I: ValidFunction<FunctionNull>,
322 {
323 self.reconfigure()
324 }
325
326 #[inline]
328 pub fn into_pull_down_disabled(self) -> Pin<I, FunctionNull, PullDown>
329 where
330 I: ValidFunction<FunctionNull>,
331 {
332 self.reconfigure()
333 }
334
335 #[inline]
337 pub fn into_pull_up_disabled(self) -> Pin<I, FunctionNull, PullUp>
338 where
339 I: ValidFunction<FunctionNull>,
340 {
341 self.reconfigure()
342 }
343
344 #[inline]
346 pub fn into_floating_input(self) -> Pin<I, FunctionSio<SioInput>, PullNone>
347 where
348 I: ValidFunction<FunctionSio<SioInput>>,
349 {
350 self.into_function().into_pull_type()
351 }
352
353 #[inline]
355 pub fn into_pull_down_input(self) -> Pin<I, FunctionSio<SioInput>, PullDown>
356 where
357 I: ValidFunction<FunctionSio<SioInput>>,
358 {
359 self.into_function().into_pull_type()
360 }
361
362 #[inline]
364 pub fn into_pull_up_input(self) -> Pin<I, FunctionSio<SioInput>, PullUp>
365 where
366 I: ValidFunction<FunctionSio<SioInput>>,
367 {
368 self.into_function().into_pull_type()
369 }
370
371 #[inline]
373 pub fn into_bus_keep_input(self) -> Pin<I, FunctionSio<SioInput>, PullBusKeep>
374 where
375 I: ValidFunction<FunctionSio<SioInput>>,
376 {
377 self.into_function().into_pull_type()
378 }
379
380 #[inline]
384 pub fn into_push_pull_output(self) -> Pin<I, FunctionSio<SioOutput>, P>
385 where
386 I: ValidFunction<FunctionSio<SioOutput>>,
387 {
388 self.into_function()
389 }
390
391 #[inline]
394 pub fn into_push_pull_output_in_state(
395 mut self,
396 state: PinState,
397 ) -> Pin<I, FunctionSio<SioOutput>, P>
398 where
399 I: ValidFunction<FunctionSio<SioOutput>>,
400 {
401 match state {
402 PinState::High => self._set_high(),
403 PinState::Low => self._set_low(),
404 }
405 self.into_push_pull_output()
406 }
407
408 #[inline]
412 #[deprecated(
413 note = "All gpio are readable, use `.into_push_pull_output()` instead.",
414 since = "0.9.0"
415 )]
416 pub fn into_readable_output(self) -> Pin<I, FunctionSio<SioOutput>, P>
417 where
418 I: ValidFunction<FunctionSio<SioOutput>>,
419 {
420 self.into_function()
421 }
422
423 #[inline]
426 #[deprecated(
427 note = "All gpio are readable, use `.into_push_pull_output_in_state()` instead.",
428 since = "0.9.0"
429 )]
430 pub fn into_readable_output_in_state(self, state: PinState) -> Pin<I, FunctionSio<SioOutput>, P>
431 where
432 I: ValidFunction<FunctionSio<SioOutput>>,
433 {
434 self.into_push_pull_output_in_state(state)
435 }
436
437 #[inline]
446 pub fn get_drive_strength(&self) -> OutputDriveStrength {
447 use pac::pads_bank0::gpio::DRIVE_A;
448 match self.id.pad_ctrl().read().drive().variant() {
449 DRIVE_A::_2M_A => OutputDriveStrength::TwoMilliAmps,
450 DRIVE_A::_4M_A => OutputDriveStrength::FourMilliAmps,
451 DRIVE_A::_8M_A => OutputDriveStrength::EightMilliAmps,
452 DRIVE_A::_12M_A => OutputDriveStrength::TwelveMilliAmps,
453 }
454 }
455
456 #[inline]
458 pub fn set_drive_strength(&mut self, strength: OutputDriveStrength) {
459 use pac::pads_bank0::gpio::DRIVE_A;
460 let variant = match strength {
461 OutputDriveStrength::TwoMilliAmps => DRIVE_A::_2M_A,
462 OutputDriveStrength::FourMilliAmps => DRIVE_A::_4M_A,
463 OutputDriveStrength::EightMilliAmps => DRIVE_A::_8M_A,
464 OutputDriveStrength::TwelveMilliAmps => DRIVE_A::_12M_A,
465 };
466 self.id.pad_ctrl().modify(|_, w| w.drive().variant(variant))
467 }
468
469 #[inline]
471 pub fn get_slew_rate(&self) -> OutputSlewRate {
472 if self.id.pad_ctrl().read().slewfast().bit_is_set() {
473 OutputSlewRate::Fast
474 } else {
475 OutputSlewRate::Slow
476 }
477 }
478
479 #[inline]
481 pub fn set_slew_rate(&mut self, rate: OutputSlewRate) {
482 self.id
483 .pad_ctrl()
484 .modify(|_, w| w.slewfast().bit(OutputSlewRate::Fast == rate));
485 }
486
487 #[inline]
489 pub fn get_schmitt_enabled(&self) -> bool {
490 self.id.pad_ctrl().read().schmitt().bit_is_set()
491 }
492
493 #[inline]
495 pub fn set_schmitt_enabled(&self, enable: bool) {
496 self.id.pad_ctrl().modify(|_, w| w.schmitt().bit(enable));
497 }
498
499 #[inline]
501 pub fn get_output_disable(&mut self) -> bool {
502 self.id.pad_ctrl().read().od().bit_is_set()
503 }
504
505 #[inline]
507 pub fn set_output_disable(&mut self, disable: bool) {
508 self.id.pad_ctrl().modify(|_, w| w.od().bit(disable));
509 }
510
511 #[inline]
513 pub fn get_input_enable(&mut self) -> bool {
514 self.id.pad_ctrl().read().ie().bit_is_set()
515 }
516
517 #[inline]
519 pub fn set_input_enable(&mut self, enable: bool) {
520 self.id.pad_ctrl().modify(|_, w| w.ie().bit(enable));
521 }
522
523 #[inline]
528 pub fn get_input_override(&self) -> InputOverride {
529 use pac::io_bank0::gpio::gpio_ctrl::INOVER_A;
530 match self.id.io_ctrl().read().inover().variant() {
531 INOVER_A::NORMAL => InputOverride::Normal,
532 INOVER_A::INVERT => InputOverride::Invert,
533 INOVER_A::LOW => InputOverride::AlwaysLow,
534 INOVER_A::HIGH => InputOverride::AlwaysHigh,
535 }
536 }
537
538 #[inline]
540 pub fn set_input_override(&mut self, override_value: InputOverride) {
541 use pac::io_bank0::gpio::gpio_ctrl::INOVER_A;
542 let variant = match override_value {
543 InputOverride::Normal => INOVER_A::NORMAL,
544 InputOverride::Invert => INOVER_A::INVERT,
545 InputOverride::AlwaysLow => INOVER_A::LOW,
546 InputOverride::AlwaysHigh => INOVER_A::HIGH,
547 };
548 self.id.io_ctrl().modify(|_, w| w.inover().variant(variant));
549 }
550
551 #[inline]
553 pub fn get_output_enable_override(&self) -> OutputEnableOverride {
554 use pac::io_bank0::gpio::gpio_ctrl::OEOVER_A;
555 match self.id.io_ctrl().read().oeover().variant() {
556 OEOVER_A::NORMAL => OutputEnableOverride::Normal,
557 OEOVER_A::INVERT => OutputEnableOverride::Invert,
558 OEOVER_A::DISABLE => OutputEnableOverride::Disable,
559 OEOVER_A::ENABLE => OutputEnableOverride::Enable,
560 }
561 }
562
563 #[inline]
565 pub fn set_output_enable_override(&mut self, override_value: OutputEnableOverride) {
566 use pac::io_bank0::gpio::gpio_ctrl::OEOVER_A;
567 let variant = match override_value {
568 OutputEnableOverride::Normal => OEOVER_A::NORMAL,
569 OutputEnableOverride::Invert => OEOVER_A::INVERT,
570 OutputEnableOverride::Disable => OEOVER_A::DISABLE,
571 OutputEnableOverride::Enable => OEOVER_A::ENABLE,
572 };
573 self.id.io_ctrl().modify(|_, w| w.oeover().variant(variant));
574 }
575
576 #[inline]
578 pub fn get_output_override(&self) -> OutputOverride {
579 use pac::io_bank0::gpio::gpio_ctrl::OUTOVER_A;
580 match self.id.io_ctrl().read().outover().variant() {
581 OUTOVER_A::NORMAL => OutputOverride::DontInvert,
582 OUTOVER_A::INVERT => OutputOverride::Invert,
583 OUTOVER_A::LOW => OutputOverride::AlwaysLow,
584 OUTOVER_A::HIGH => OutputOverride::AlwaysHigh,
585 }
586 }
587
588 #[inline]
590 pub fn set_output_override(&mut self, override_value: OutputOverride) {
591 use pac::io_bank0::gpio::gpio_ctrl::OUTOVER_A;
592 let variant = match override_value {
593 OutputOverride::DontInvert => OUTOVER_A::NORMAL,
594 OutputOverride::Invert => OUTOVER_A::INVERT,
595 OutputOverride::AlwaysLow => OUTOVER_A::LOW,
596 OutputOverride::AlwaysHigh => OUTOVER_A::HIGH,
597 };
598 self.id
599 .io_ctrl()
600 .modify(|_, w| w.outover().variant(variant));
601 }
602
603 #[inline]
605 pub fn get_interrupt_override(&self) -> InterruptOverride {
606 use pac::io_bank0::gpio::gpio_ctrl::IRQOVER_A;
607 match self.id.io_ctrl().read().irqover().variant() {
608 IRQOVER_A::NORMAL => InterruptOverride::Normal,
609 IRQOVER_A::INVERT => InterruptOverride::Invert,
610 IRQOVER_A::LOW => InterruptOverride::AlwaysLow,
611 IRQOVER_A::HIGH => InterruptOverride::AlwaysHigh,
612 }
613 }
614
615 #[inline]
617 pub fn set_interrupt_override(&mut self, override_value: InterruptOverride) {
618 use pac::io_bank0::gpio::gpio_ctrl::IRQOVER_A;
619 let variant = match override_value {
620 InterruptOverride::Normal => IRQOVER_A::NORMAL,
621 InterruptOverride::Invert => IRQOVER_A::INVERT,
622 InterruptOverride::AlwaysLow => IRQOVER_A::LOW,
623 InterruptOverride::AlwaysHigh => IRQOVER_A::HIGH,
624 };
625 self.id
626 .io_ctrl()
627 .modify(|_, w| w.irqover().variant(variant));
628 }
629
630 #[inline]
634 #[allow(clippy::bool_comparison)] pub(crate) fn _is_low(&self) -> bool {
636 let mask = self.id.mask();
637 self.id.sio_in().read().bits() & mask == 0
638 }
639
640 #[inline]
641 #[allow(clippy::bool_comparison)] pub(crate) fn _is_high(&self) -> bool {
643 !self._is_low()
644 }
645
646 #[inline]
647 pub(crate) fn _set_low(&mut self) {
648 let mask = self.id.mask();
649 self.id
650 .sio_out_clr()
651 .write(|w| unsafe { w.gpio_out_clr().bits(mask) });
652 }
653
654 #[inline]
655 pub(crate) fn _set_high(&mut self) {
656 let mask = self.id.mask();
657 self.id
658 .sio_out_set()
659 .write(|w| unsafe { w.gpio_out_set().bits(mask) });
660 }
661
662 #[inline]
663 pub(crate) fn _toggle(&mut self) {
664 let mask = self.id.mask();
665 self.id
666 .sio_out_xor()
667 .write(|w| unsafe { w.gpio_out_xor().bits(mask) });
668 }
669
670 #[inline]
671 pub(crate) fn _is_set_low(&self) -> bool {
672 let mask = self.id.mask();
673 self.id.sio_out().read().bits() & mask == 0
674 }
675
676 #[inline]
677 pub(crate) fn _is_set_high(&self) -> bool {
678 !self._is_set_low()
679 }
680
681 #[inline]
686 pub fn clear_interrupt(&mut self, interrupt: Interrupt) {
687 let (reg, offset) = self.id.intr();
688 let mask = interrupt.mask();
689 reg.write(|w| unsafe { w.bits(mask << offset) });
690 }
691
692 #[inline]
694 pub fn interrupt_status(&self, interrupt: Interrupt) -> bool {
695 let (reg, offset) = self.id.proc_ints(Sio::core());
696 let mask = interrupt.mask();
697 (reg.read().bits() >> offset) & mask == mask
698 }
699
700 #[inline]
702 pub fn is_interrupt_enabled(&self, interrupt: Interrupt) -> bool {
703 let (reg, offset) = self.id.proc_inte(Sio::core());
704 let mask = interrupt.mask();
705 (reg.read().bits() >> offset) & mask == mask
706 }
707
708 #[inline]
710 pub fn set_interrupt_enabled(&self, interrupt: Interrupt, enabled: bool) {
711 let (reg, offset) = self.id.proc_inte(Sio::core());
712 let mask = interrupt.mask();
713 unsafe {
714 if enabled {
715 write_bitmask_set(reg.as_ptr(), mask << offset);
716 } else {
717 write_bitmask_clear(reg.as_ptr(), mask << offset);
718 }
719 }
720 }
721
722 #[inline]
724 pub fn is_interrupt_forced(&self, interrupt: Interrupt) -> bool {
725 let (reg, offset) = self.id.proc_intf(Sio::core());
726 let mask = interrupt.mask();
727 (reg.read().bits() >> offset) & mask == mask
728 }
729
730 #[inline]
732 pub fn set_interrupt_forced(&self, interrupt: Interrupt, forced: bool) {
733 let (reg, offset) = self.id.proc_intf(Sio::core());
734 let mask = interrupt.mask();
735 unsafe {
736 if forced {
737 write_bitmask_set(reg.as_ptr(), mask << offset);
738 } else {
739 write_bitmask_clear(reg.as_ptr(), mask << offset);
740 }
741 }
742 }
743
744 #[inline]
746 pub fn dormant_wake_status(&self, interrupt: Interrupt) -> bool {
747 let (reg, offset) = self.id.dormant_wake_ints();
748 let mask = interrupt.mask();
749 (reg.read().bits() >> offset) & mask == mask
750 }
751
752 #[inline]
754 pub fn is_dormant_wake_enabled(&self, interrupt: Interrupt) -> bool {
755 let (reg, offset) = self.id.dormant_wake_inte();
756 let mask = interrupt.mask();
757 (reg.read().bits() >> offset) & mask == mask
758 }
759
760 #[inline]
762 pub fn set_dormant_wake_enabled(&self, interrupt: Interrupt, enabled: bool) {
763 let (reg, offset) = self.id.dormant_wake_inte();
764 let mask = interrupt.mask();
765 unsafe {
766 if enabled {
767 write_bitmask_set(reg.as_ptr(), mask << offset);
768 } else {
769 write_bitmask_clear(reg.as_ptr(), mask << offset);
770 }
771 }
772 }
773
774 #[inline]
776 pub fn is_dormant_wake_forced(&self, interrupt: Interrupt) -> bool {
777 let (reg, offset) = self.id.dormant_wake_intf();
778 let mask = interrupt.mask();
779 (reg.read().bits() >> offset) & mask == mask
780 }
781
782 #[inline]
784 pub fn set_dormant_wake_forced(&mut self, interrupt: Interrupt, forced: bool) {
785 let (reg, offset) = self.id.dormant_wake_intf();
786 let mask = interrupt.mask();
787 unsafe {
788 if forced {
789 write_bitmask_set(reg.as_ptr(), mask << offset);
790 } else {
791 write_bitmask_clear(reg.as_ptr(), mask << offset);
792 }
793 }
794 }
795
796 pub fn as_input(&self) -> AsInputPin<I, F, P> {
804 AsInputPin(self)
805 }
806}
807impl<I: PinId, C: SioConfig, P: PullType> Pin<I, FunctionSio<C>, P> {
808 #[inline]
810 pub fn is_sync_bypass(&self) -> bool {
811 let mask = self.id.mask();
812 self.id.proc_in_by_pass().read().bits() & mask == mask
813 }
814
815 #[inline]
819 pub fn set_sync_bypass(&mut self, bypass: bool) {
820 let mask = self.id.mask();
821 let reg = self.id.proc_in_by_pass();
822 unsafe {
823 if bypass {
824 write_bitmask_set(reg.as_ptr(), mask);
825 } else {
826 write_bitmask_clear(reg.as_ptr(), mask);
827 }
828 }
829 }
830}
831impl<F: func::Function, P: PullType> Pin<DynPinId, F, P> {
832 pub fn try_into_pin<P2: pin::pin_sealed::TypeLevelPinId>(self) -> Result<Pin<P2, F, P>, Self> {
836 if P2::ID == self.id {
837 Ok(Pin {
838 id: P2::new(),
839 function: self.function,
840 pull_type: self.pull_type,
841 })
842 } else {
843 Err(self)
844 }
845 }
846
847 pub fn try_into_function<F2>(self) -> Result<Pin<DynPinId, F2, P>, Pin<DynPinId, F, P>>
849 where
850 F2: func::Function,
851 {
852 let prev_function = self.function.as_dyn();
854 let function = F2::from(prev_function);
855 let function_as_dyn = function.as_dyn();
856
857 use func_sealed::Function;
858 if function_as_dyn.is_valid(&self.id) {
859 if function_as_dyn != prev_function.as_dyn() {
860 pin::set_function(&self.id, function_as_dyn);
861 }
862 Ok(Pin {
863 function,
864 id: self.id,
865 pull_type: self.pull_type,
866 })
867 } else {
868 Err(self)
869 }
870 }
871}
872impl<I: PinId, P: PullType> Pin<I, DynFunction, P> {
873 pub fn try_set_function(&mut self, function: DynFunction) -> Result<(), func::InvalidFunction> {
878 use func_sealed::Function;
879 if !function.is_valid(&self.id) {
880 return Err(func::InvalidFunction);
881 } else if function != self.function.as_dyn() {
882 pin::set_function(&self.id, function);
883 self.function = function;
884 }
885 Ok(())
886 }
887
888 pub fn function(&self) -> DynFunction {
890 use func_sealed::Function;
891 self.function.as_dyn()
892 }
893}
894
895impl<I: PinId, F: func::Function> Pin<I, F, DynPullType> {
896 pub fn set_pull_type(&mut self, pull_type: DynPullType) {
898 if pull_type != self.pull_type {
899 pin::set_pull_type(&self.id, pull_type);
900 self.pull_type = pull_type;
901 }
902 }
903}
904
905pub struct AsInputPin<'a, I: PinId, F: func::Function, P: PullType>(&'a Pin<I, F, P>);
907
908pub type Error = core::convert::Infallible;
914
915impl<I, P> embedded_hal_0_2::digital::v2::OutputPin for Pin<I, FunctionSio<SioOutput>, P>
916where
917 I: PinId,
918 P: PullType,
919{
920 type Error = Error;
921
922 fn set_low(&mut self) -> Result<(), Self::Error> {
923 self._set_low();
924 Ok(())
925 }
926
927 fn set_high(&mut self) -> Result<(), Self::Error> {
928 self._set_high();
929 Ok(())
930 }
931}
932
933impl<I, P> embedded_hal_0_2::digital::v2::InputPin for Pin<I, FunctionSio<SioOutput>, P>
936where
937 I: PinId,
938 P: PullType,
939{
940 type Error = Error;
941
942 fn is_high(&self) -> Result<bool, Self::Error> {
943 Ok(self._is_high())
944 }
945
946 fn is_low(&self) -> Result<bool, Self::Error> {
947 Ok(self._is_low())
948 }
949}
950
951impl<I: PinId, F: func::Function, P: PullType> embedded_hal_0_2::digital::v2::InputPin
952 for AsInputPin<'_, I, F, P>
953{
954 type Error = core::convert::Infallible;
955
956 fn is_high(&self) -> Result<bool, Self::Error> {
957 Ok(self.0._is_high())
958 }
959
960 fn is_low(&self) -> Result<bool, Self::Error> {
961 Ok(self.0._is_low())
962 }
963}
964
965impl<I, P> embedded_hal_0_2::digital::v2::StatefulOutputPin for Pin<I, FunctionSio<SioOutput>, P>
966where
967 I: PinId,
968 P: PullType,
969{
970 fn is_set_high(&self) -> Result<bool, Self::Error> {
971 Ok(self._is_set_high())
972 }
973
974 fn is_set_low(&self) -> Result<bool, Self::Error> {
975 Ok(self._is_set_low())
976 }
977}
978
979impl<I, P> embedded_hal_0_2::digital::v2::ToggleableOutputPin for Pin<I, FunctionSio<SioOutput>, P>
980where
981 I: PinId,
982 P: PullType,
983{
984 type Error = Error;
985
986 fn toggle(&mut self) -> Result<(), Self::Error> {
987 self._toggle();
988 Ok(())
989 }
990}
991impl<I, P> embedded_hal_0_2::digital::v2::InputPin for Pin<I, FunctionSio<SioInput>, P>
992where
993 I: PinId,
994 P: PullType,
995{
996 type Error = Error;
997
998 fn is_high(&self) -> Result<bool, Self::Error> {
999 Ok(self._is_high())
1000 }
1001
1002 fn is_low(&self) -> Result<bool, Self::Error> {
1003 Ok(self._is_low())
1004 }
1005}
1006
1007pub trait DefaultTypeState: crate::typelevel::Sealed {
1013 type Function: Function;
1015 type PullType: PullType;
1017}
1018
1019macro_rules! reset_ie {
1025 ( Bank0, $pads:ident ) => {
1026 for id in (0..=29) {
1027 $pads.gpio(id).modify(|_, w| w.ie().clear_bit());
1028 }
1029 };
1030 ( Qspi, $pads:ident ) => {};
1031}
1032
1033macro_rules! gpio {
1034 ( $bank:ident:$prefix:ident, [ $(($id:expr, $pull_type:ident, $func:ident)),* ] ) => {
1035 paste::paste!{
1036 #[doc = "Pin bank " [<$bank>] ]
1037 pub mod [<$bank:snake>] {
1038 use $crate::pac::{[<IO_ $bank:upper>],[<PADS_ $bank:upper>]};
1039 use crate::sio::[<SioGpio $bank>];
1040 use super::{Pin, pin, pull, func};
1041 $(pub use super::pin::[<$bank:lower>]::[<$prefix $id>];)*
1042
1043 $(
1044 impl super::DefaultTypeState for [<$prefix $id>] {
1045 type Function = super::[<Function $func>];
1046 type PullType = super::[<Pull $pull_type>];
1047 }
1048 )*
1049 gpio!(struct: $bank $prefix $([<$prefix $id>], $id, $func, $pull_type),*);
1050
1051 impl Pins {
1052 pub fn new(io : [<IO_ $bank:upper>], pads: [<PADS_ $bank:upper>], sio: [<SioGpio $bank>], reset : &mut $crate::pac::RESETS) -> Self {
1056 use $crate::resets::SubsystemReset;
1057 pads.reset_bring_down(reset);
1058 io.reset_bring_down(reset);
1059
1060 {
1061 use $crate::gpio::pin::DynBankId;
1062 let sio = unsafe { &*$crate::pac::SIO::PTR };
1064 if DynBankId::$bank == DynBankId::Bank0 {
1065 sio.gpio_oe().reset();
1066 sio.gpio_out().reset();
1067 } else {
1068 sio.gpio_hi_oe().reset();
1069 sio.gpio_hi_out().reset();
1070 }
1071 }
1072
1073 io.reset_bring_up(reset);
1074 pads.reset_bring_up(reset);
1075 reset_ie!($bank, pads);
1076 gpio!(members: io, pads, sio, $(([<$prefix $id>], $func, $pull_type)),+)
1077 }
1078 }
1079 }
1080 }
1081 };
1082 (struct: $bank:ident $prefix:ident $($PXi:ident, $id:expr, $func:ident, $pull_type:ident),*) => {
1083 paste::paste!{
1084 #[derive(Debug)]
1086 pub struct Pins {
1087 _io: [<IO_ $bank:upper>],
1088 _pads: [<PADS_ $bank:upper>],
1089 _sio: [<SioGpio $bank>],
1090 $(
1091 #[doc = "Pin " [<$PXi>] ]
1092 pub [<$PXi:snake>]: Pin<pin::[<$bank:lower>]::[<$prefix $id>] , func::[<Function $func>], pull::[<Pull $pull_type>]>,
1093 )*
1094 }
1095 }
1096 };
1097 (members: $io:ident, $pads:ident, $sio:ident, $(($PXi:ident, $func:ident, $pull_type:ident)),+) => {
1098 paste::paste!{
1099 Self {
1100 _io: $io,
1101 _pads: $pads,
1102 _sio: $sio,
1103 $(
1104 [<$PXi:snake>]: Pin {
1105 id: [<$PXi>] (()),
1106 function: func::[<Function $func>] (()),
1107 pull_type: pull::[<Pull $pull_type>] (())
1108 },
1109 )+
1110 }
1111 }
1112 };
1113}
1114
1115gpio!(
1116 Bank0: Gpio,
1117 [
1118 (0, Down, Null),
1119 (1, Down, Null),
1120 (2, Down, Null),
1121 (3, Down, Null),
1122 (4, Down, Null),
1123 (5, Down, Null),
1124 (6, Down, Null),
1125 (7, Down, Null),
1126 (8, Down, Null),
1127 (9, Down, Null),
1128 (10, Down, Null),
1129 (11, Down, Null),
1130 (12, Down, Null),
1131 (13, Down, Null),
1132 (14, Down, Null),
1133 (15, Down, Null),
1134 (16, Down, Null),
1135 (17, Down, Null),
1136 (18, Down, Null),
1137 (19, Down, Null),
1138 (20, Down, Null),
1139 (21, Down, Null),
1140 (22, Down, Null),
1141 (23, Down, Null),
1142 (24, Down, Null),
1143 (25, Down, Null),
1144 (26, Down, Null),
1145 (27, Down, Null),
1146 (28, Down, Null),
1147 (29, Down, Null)
1148 ]
1149);
1150
1151gpio!(
1152 Qspi: Qspi,
1153 [
1154 (Sclk, Down, Null),
1155 (Ss, Up, Null),
1156 (Sd0, None, Null),
1157 (Sd1, None, Null),
1158 (Sd2, None, Null),
1159 (Sd3, None, Null)
1160 ]
1161);
1162
1163pub use bank0::Pins;
1164
1165pub trait AnyPin: Sealed
1178where
1179 Self: typelevel::Sealed,
1180 Self: typelevel::Is<Type = SpecificPin<Self>>,
1181{
1182 type Id: PinId;
1184 type Function: func::Function;
1186 type Pull: PullType;
1188}
1189
1190impl<I, F, P> Sealed for Pin<I, F, P>
1191where
1192 I: PinId,
1193 F: func::Function,
1194 P: PullType,
1195{
1196}
1197
1198impl<I, F, P> AnyPin for Pin<I, F, P>
1199where
1200 I: PinId,
1201 F: func::Function,
1202 P: PullType,
1203{
1204 type Id = I;
1205 type Function = F;
1206 type Pull = P;
1207}
1208
1209pub type SpecificPin<P> = Pin<<P as AnyPin>::Id, <P as AnyPin>::Function, <P as AnyPin>::Pull>;
1215
1216#[macro_export]
1283macro_rules! bsp_pins {
1284 (
1285 $(
1286 $( #[$id_cfg:meta] )*
1287 $Id:ident {
1288 $( #[$name_doc:meta] )*
1289 name: $name:ident $(,)?
1290 $(
1291 aliases: {
1292 $(
1293 $( #[$alias_cfg:meta] )*
1294 $Function:ty, $PullType:ident: $Alias:ident
1295 ),+
1296 }
1297 )?
1298 } $(,)?
1299 )+
1300 ) => {
1301 $crate::paste::paste! {
1302
1303 pub struct Pins {
1335 $(
1336 $( #[$id_cfg] )*
1337 $( #[$name_doc] )*
1338 pub $name: $crate::gpio::Pin<
1339 $crate::gpio::bank0::$Id,
1340 <$crate::gpio::bank0::$Id as $crate::gpio::DefaultTypeState>::Function,
1341 <$crate::gpio::bank0::$Id as $crate::gpio::DefaultTypeState>::PullType,
1342 >,
1343 )+
1344 }
1345
1346 impl Pins {
1347 #[inline]
1358 pub fn new(io : $crate::pac::IO_BANK0, pads: $crate::pac::PADS_BANK0, sio: $crate::sio::SioGpioBank0, reset : &mut $crate::pac::RESETS) -> Self {
1359 let mut pins = $crate::gpio::Pins::new(io,pads,sio,reset);
1360 Self {
1361 $(
1362 $( #[$id_cfg] )*
1363 $name: pins.[<$Id:lower>],
1364 )+
1365 }
1366 }
1367 }
1368 $(
1369 $( #[$id_cfg] )*
1370 $crate::bsp_pins!(@aliases, $( $( $( #[$alias_cfg] )* $Id $Function $PullType $Alias )+ )? );
1371 )+
1372 }
1373 };
1374 ( @aliases, $( $( $( #[$attr:meta] )* $Id:ident $Function:ident $PullType:ident $Alias:ident )+ )? ) => {
1375 $crate::paste::paste! {
1376 $(
1377 $(
1378 $( #[$attr] )*
1379 pub type $Alias = $crate::gpio::Pin<
1381 $crate::gpio::bank0::$Id,
1382 $crate::gpio::$Function,
1383 $crate::gpio::$PullType
1384 >;
1385 )+
1386 )?
1387 }
1388 };
1389}
1390
1391pub struct InOutPin<T: AnyPin> {
1402 inner: Pin<T::Id, FunctionSioOutput, T::Pull>,
1403}
1404
1405impl<T: AnyPin> InOutPin<T> {
1406 pub fn new(inner: T) -> InOutPin<T>
1408 where
1409 T::Id: ValidFunction<FunctionSioOutput>,
1410 {
1411 let mut inner = inner.into();
1412 inner.set_output_enable_override(OutputEnableOverride::Disable);
1413
1414 let inner = inner.into_push_pull_output_in_state(PinState::Low);
1416
1417 Self { inner }
1418 }
1419}
1420
1421impl<T> InOutPin<T>
1422where
1423 T: AnyPin,
1424 T::Id: ValidFunction<T::Function>,
1425{
1426 pub fn release(self) -> T {
1428 let mut inner = self.inner.reconfigure();
1430 inner.set_output_enable_override(OutputEnableOverride::Normal);
1432 T::from(inner)
1434 }
1435}
1436
1437impl<T: AnyPin> embedded_hal_0_2::digital::v2::InputPin for InOutPin<T> {
1438 type Error = Error;
1439 fn is_high(&self) -> Result<bool, Error> {
1440 self.inner.is_high()
1441 }
1442
1443 fn is_low(&self) -> Result<bool, Error> {
1444 self.inner.is_low()
1445 }
1446}
1447
1448impl<T: AnyPin> embedded_hal_0_2::digital::v2::OutputPin for InOutPin<T> {
1449 type Error = Error;
1450 fn set_low(&mut self) -> Result<(), Error> {
1451 self.inner
1453 .set_output_enable_override(OutputEnableOverride::Enable);
1454 Ok(())
1455 }
1456
1457 fn set_high(&mut self) -> Result<(), Error> {
1458 self.inner
1461 .set_output_enable_override(OutputEnableOverride::Disable);
1462 Ok(())
1463 }
1464}
1465
1466mod eh1 {
1467 use embedded_hal::digital::{ErrorType, InputPin, OutputPin, StatefulOutputPin};
1468
1469 use super::{
1470 func, AnyPin, AsInputPin, Error, FunctionSio, InOutPin, OutputEnableOverride, Pin, PinId,
1471 PullType, SioConfig, SioInput, SioOutput,
1472 };
1473
1474 impl<I, P, S> ErrorType for Pin<I, FunctionSio<S>, P>
1475 where
1476 I: PinId,
1477 P: PullType,
1478 S: SioConfig,
1479 {
1480 type Error = Error;
1481 }
1482
1483 impl<I, P> OutputPin for Pin<I, FunctionSio<SioOutput>, P>
1484 where
1485 I: PinId,
1486 P: PullType,
1487 {
1488 fn set_low(&mut self) -> Result<(), Self::Error> {
1489 self._set_low();
1490 Ok(())
1491 }
1492
1493 fn set_high(&mut self) -> Result<(), Self::Error> {
1494 self._set_high();
1495 Ok(())
1496 }
1497 }
1498
1499 impl<I, P> StatefulOutputPin for Pin<I, FunctionSio<SioOutput>, P>
1500 where
1501 I: PinId,
1502 P: PullType,
1503 {
1504 fn is_set_high(&mut self) -> Result<bool, Self::Error> {
1505 Ok(self._is_set_high())
1506 }
1507
1508 fn is_set_low(&mut self) -> Result<bool, Self::Error> {
1509 Ok(self._is_set_low())
1510 }
1511
1512 fn toggle(&mut self) -> Result<(), Self::Error> {
1513 self._toggle();
1514 Ok(())
1515 }
1516 }
1517
1518 impl<I, P> InputPin for Pin<I, FunctionSio<SioInput>, P>
1519 where
1520 I: PinId,
1521 P: PullType,
1522 {
1523 fn is_high(&mut self) -> Result<bool, Self::Error> {
1524 Ok(self._is_high())
1525 }
1526
1527 fn is_low(&mut self) -> Result<bool, Self::Error> {
1528 Ok(self._is_low())
1529 }
1530 }
1531
1532 impl<I, F, P> ErrorType for AsInputPin<'_, I, F, P>
1533 where
1534 I: PinId,
1535 F: func::Function,
1536 P: PullType,
1537 {
1538 type Error = Error;
1539 }
1540
1541 impl<I: PinId, F: func::Function, P: PullType> InputPin for AsInputPin<'_, I, F, P> {
1542 fn is_high(&mut self) -> Result<bool, Self::Error> {
1543 Ok(self.0._is_high())
1544 }
1545
1546 fn is_low(&mut self) -> Result<bool, Self::Error> {
1547 Ok(self.0._is_low())
1548 }
1549 }
1550
1551 impl<I> ErrorType for InOutPin<I>
1552 where
1553 I: AnyPin,
1554 {
1555 type Error = Error;
1556 }
1557
1558 impl<I> OutputPin for InOutPin<I>
1559 where
1560 I: AnyPin,
1561 {
1562 fn set_low(&mut self) -> Result<(), Self::Error> {
1563 self.inner
1565 .set_output_enable_override(OutputEnableOverride::Enable);
1566 Ok(())
1567 }
1568
1569 fn set_high(&mut self) -> Result<(), Self::Error> {
1570 self.inner
1573 .set_output_enable_override(OutputEnableOverride::Disable);
1574 Ok(())
1575 }
1576 }
1577
1578 impl<I> InputPin for InOutPin<I>
1579 where
1580 I: AnyPin,
1581 {
1582 fn is_high(&mut self) -> Result<bool, Self::Error> {
1583 Ok(self.inner._is_high())
1584 }
1585
1586 fn is_low(&mut self) -> Result<bool, Self::Error> {
1587 Ok(self.inner._is_low())
1588 }
1589 }
1590}