1#![cfg_attr(
8 soc_etm,
9 doc = "The GPIO pins also provide tasks and events via the ETM interconnect system. For more information, see the [etm] module."
10)]
11#![doc = ""]
12use core::fmt::Display;
54
55use portable_atomic::{AtomicU32, Ordering};
56use procmacros::ram;
57use strum::EnumCount;
58
59#[cfg(any(lp_io, rtc_cntl))]
60use crate::peripherals::gpio::{handle_rtcio, handle_rtcio_with_resistors};
61pub use crate::soc::gpio::*;
62use crate::{
63 interrupt::{self, InterruptHandler, Priority, DEFAULT_INTERRUPT_HANDLER},
64 peripheral::{Peripheral, PeripheralRef},
65 peripherals::{
66 gpio::{handle_gpio_input, handle_gpio_output},
67 Interrupt,
68 GPIO,
69 IO_MUX,
70 },
71 private::{self, Sealed},
72};
73
74mod placeholder;
75
76pub use placeholder::NoPin;
77
78crate::unstable_module! {
79 pub mod interconnect;
80
81 #[cfg(soc_etm)]
82 pub mod etm;
83
84 #[cfg(lp_io)]
85 pub mod lp_io;
86
87 #[cfg(all(rtc_io, not(esp32)))]
88 pub mod rtc_io;
89}
90
91mod user_irq {
92 use portable_atomic::{AtomicPtr, Ordering};
93 use procmacros::ram;
94
95 pub(super) static USER_INTERRUPT_HANDLER: CFnPtr = CFnPtr::new();
97
98 pub(super) struct CFnPtr(AtomicPtr<()>);
99 impl CFnPtr {
100 pub const fn new() -> Self {
101 Self(AtomicPtr::new(core::ptr::null_mut()))
102 }
103
104 pub fn store(&self, f: extern "C" fn()) {
105 self.0.store(f as *mut (), Ordering::Relaxed);
106 }
107
108 pub fn call(&self) {
109 let ptr = self.0.load(Ordering::Relaxed);
110 if !ptr.is_null() {
111 unsafe { (core::mem::transmute::<*mut (), extern "C" fn()>(ptr))() };
112 }
113 }
114 }
115
116 #[ram]
117 pub(super) extern "C" fn user_gpio_interrupt_handler() {
118 super::handle_pin_interrupts(|| USER_INTERRUPT_HANDLER.call());
119 }
120}
121
122#[derive(Debug)]
128#[cfg_attr(feature = "defmt", derive(defmt::Format))]
129pub(crate) struct PinGuard {
130 pin: u8,
131 signal: OutputSignal,
132}
133
134impl crate::private::Sealed for PinGuard {}
135impl Peripheral for PinGuard {
136 type P = Self;
137
138 unsafe fn clone_unchecked(&self) -> Self::P {
139 Self {
140 pin: self.pin,
141 signal: self.signal,
142 }
143 }
144}
145
146impl PinGuard {
147 pub(crate) fn new(mut pin: AnyPin, signal: OutputSignal) -> Self {
148 signal.connect_to(&mut pin);
149 Self {
150 pin: pin.number(),
151 signal,
152 }
153 }
154
155 pub(crate) fn new_unconnected(signal: OutputSignal) -> Self {
156 Self {
157 pin: u8::MAX,
158 signal,
159 }
160 }
161}
162
163impl Drop for PinGuard {
164 fn drop(&mut self) {
165 if self.pin != u8::MAX {
166 let mut pin = unsafe { AnyPin::steal(self.pin) };
167 self.signal.disconnect_from(&mut pin);
168 }
169 }
170}
171
172#[derive(Debug, Eq, PartialEq, Copy, Clone, Hash)]
174#[cfg_attr(feature = "defmt", derive(defmt::Format))]
175pub enum Event {
176 RisingEdge = 1,
178 FallingEdge = 2,
180 AnyEdge = 3,
182 LowLevel = 4,
184 HighLevel = 5,
186}
187
188impl From<WakeEvent> for Event {
189 fn from(value: WakeEvent) -> Self {
190 match value {
191 WakeEvent::LowLevel => Event::LowLevel,
192 WakeEvent::HighLevel => Event::HighLevel,
193 }
194 }
195}
196
197#[instability::unstable]
199#[derive(Debug, Eq, PartialEq, Copy, Clone, Hash)]
200#[cfg_attr(feature = "defmt", derive(defmt::Format))]
201pub enum WakeEvent {
202 LowLevel = 4,
204 HighLevel = 5,
206}
207
208#[derive(Debug, Eq, PartialEq, Copy, Clone, Hash)]
218#[cfg_attr(feature = "defmt", derive(defmt::Format))]
219pub enum Level {
220 Low,
222 High,
224}
225
226impl Sealed for Level {}
227
228impl core::ops::Not for Level {
229 type Output = Self;
230
231 fn not(self) -> Self {
232 match self {
233 Self::Low => Self::High,
234 Self::High => Self::Low,
235 }
236 }
237}
238
239impl From<bool> for Level {
240 fn from(val: bool) -> Self {
241 match val {
242 true => Self::High,
243 false => Self::Low,
244 }
245 }
246}
247
248impl From<Level> for bool {
249 fn from(level: Level) -> bool {
250 match level {
251 Level::Low => false,
252 Level::High => true,
253 }
254 }
255}
256
257#[derive(Debug, Eq, PartialEq, Copy, Clone, Hash)]
259#[cfg_attr(feature = "defmt", derive(defmt::Format))]
260#[instability::unstable]
261#[non_exhaustive]
262pub enum WakeConfigError {
263 EdgeTriggeringNotSupported,
266}
267
268impl Display for WakeConfigError {
269 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
270 match self {
271 WakeConfigError::EdgeTriggeringNotSupported => {
272 write!(
273 f,
274 "Edge triggering is not supported for wake-up from light sleep"
275 )
276 }
277 }
278 }
279}
280
281impl core::error::Error for WakeConfigError {}
282
283#[derive(Debug, Eq, PartialEq, Copy, Clone, Hash)]
285#[cfg_attr(feature = "defmt", derive(defmt::Format))]
286pub enum Pull {
287 None,
289 Up,
291 Down,
293}
294
295#[derive(Debug, Eq, PartialEq, Copy, Clone, Hash, PartialOrd, Ord)]
297#[cfg_attr(feature = "defmt", derive(defmt::Format))]
298pub enum DriveStrength {
299 _5mA = 0,
301 _10mA = 1,
303 _20mA = 2,
305 _40mA = 3,
307}
308
309#[doc(hidden)]
320#[doc = crate::trm_markdown_link!("iomuxgpio")]
321#[derive(Debug, Eq, PartialEq, Copy, Clone, Hash)]
322#[cfg_attr(feature = "defmt", derive(defmt::Format))]
323pub enum AlternateFunction {
324 _0 = 0,
326 _1 = 1,
328 _2 = 2,
330 _3 = 3,
332 _4 = 4,
334 _5 = 5,
336}
337
338impl TryFrom<usize> for AlternateFunction {
339 type Error = ();
340
341 fn try_from(value: usize) -> Result<Self, Self::Error> {
342 match value {
343 0 => Ok(AlternateFunction::_0),
344 1 => Ok(AlternateFunction::_1),
345 2 => Ok(AlternateFunction::_2),
346 3 => Ok(AlternateFunction::_3),
347 4 => Ok(AlternateFunction::_4),
348 5 => Ok(AlternateFunction::_5),
349 _ => Err(()),
350 }
351 }
352}
353
354#[instability::unstable]
356#[derive(Debug, Eq, PartialEq, Copy, Clone, Hash)]
357#[cfg_attr(feature = "defmt", derive(defmt::Format))]
358pub enum RtcFunction {
359 Rtc = 0,
361 Digital = 1,
363}
364
365#[instability::unstable]
367pub trait RtcPin: Pin {
368 #[cfg(xtensa)]
370 fn rtc_number(&self) -> u8;
371
372 #[cfg(any(xtensa, esp32c6))]
374 #[doc(hidden)]
375 fn rtc_set_config(&self, input_enable: bool, mux: bool, func: RtcFunction);
376
377 #[doc(hidden)]
379 fn rtcio_pad_hold(&self, enable: bool);
380
381 #[cfg(any(esp32c3, esp32c2, esp32c6))]
386 #[doc(hidden)]
387 unsafe fn apply_wakeup(&self, wakeup: bool, level: u8);
388}
389
390#[instability::unstable]
393#[cfg(any(lp_io, rtc_cntl))]
394pub trait RtcPinWithResistors: RtcPin {
395 #[doc(hidden)]
397 fn rtcio_pullup(&self, enable: bool);
398 #[doc(hidden)]
400 fn rtcio_pulldown(&self, enable: bool);
401}
402
403pub trait Pin: Sealed {
405 fn number(&self) -> u8;
407
408 #[doc = crate::before_snippet!()]
418 fn degrade(self) -> AnyPin
452 where
453 Self: Sized,
454 {
455 unsafe { AnyPin::steal(self.number()) }
456 }
457
458 #[doc(hidden)]
459 fn output_signals(&self, _: private::Internal) -> &'static [(AlternateFunction, OutputSignal)];
460
461 #[doc(hidden)]
462 fn input_signals(&self, _: private::Internal) -> &'static [(AlternateFunction, InputSignal)];
463}
464
465pub trait InputPin: Pin + Into<AnyPin> + 'static {}
467
468pub trait OutputPin: Pin + Into<AnyPin> + 'static {}
470
471#[instability::unstable]
473pub trait AnalogPin: Pin {
474 #[doc(hidden)]
476 fn set_analog(&self, _: private::Internal);
477}
478
479#[cfg(touch)]
481#[instability::unstable]
482pub trait TouchPin: Pin {
483 #[doc(hidden)]
485 fn set_touch(&self, _: private::Internal);
486
487 #[doc(hidden)]
489 fn touch_measurement(&self, _: private::Internal) -> u16;
490
491 #[doc(hidden)]
493 fn touch_nr(&self, _: private::Internal) -> u8;
494
495 #[doc(hidden)]
497 fn set_threshold(&self, threshold: u16, _: private::Internal);
498}
499
500#[doc(hidden)]
501#[derive(Debug, Eq, PartialEq, Copy, Clone, Hash, EnumCount)]
502#[cfg_attr(feature = "defmt", derive(defmt::Format))]
503pub enum GpioBank {
504 _0,
505 #[cfg(gpio_bank_1)]
506 _1,
507}
508
509impl GpioBank {
510 fn async_operations(self) -> &'static AtomicU32 {
511 static FLAGS: [AtomicU32; GpioBank::COUNT] = [const { AtomicU32::new(0) }; GpioBank::COUNT];
512
513 &FLAGS[self as usize]
514 }
515
516 fn offset(self) -> u8 {
517 match self {
518 Self::_0 => 0,
519 #[cfg(gpio_bank_1)]
520 Self::_1 => 32,
521 }
522 }
523
524 fn write_out_en(self, word: u32, enable: bool) {
525 if enable {
526 self.write_out_en_set(word);
527 } else {
528 self.write_out_en_clear(word);
529 }
530 }
531
532 fn write_out_en_clear(self, word: u32) {
533 match self {
534 Self::_0 => GPIO::regs()
535 .enable_w1tc()
536 .write(|w| unsafe { w.bits(word) }),
537 #[cfg(gpio_bank_1)]
538 Self::_1 => GPIO::regs()
539 .enable1_w1tc()
540 .write(|w| unsafe { w.bits(word) }),
541 };
542 }
543
544 fn write_out_en_set(self, word: u32) {
545 match self {
546 Self::_0 => GPIO::regs()
547 .enable_w1ts()
548 .write(|w| unsafe { w.bits(word) }),
549 #[cfg(gpio_bank_1)]
550 Self::_1 => GPIO::regs()
551 .enable1_w1ts()
552 .write(|w| unsafe { w.bits(word) }),
553 };
554 }
555
556 fn read_input(self) -> u32 {
557 match self {
558 Self::_0 => GPIO::regs().in_().read().bits(),
559 #[cfg(gpio_bank_1)]
560 Self::_1 => GPIO::regs().in1().read().bits(),
561 }
562 }
563
564 fn read_output(self) -> u32 {
565 match self {
566 Self::_0 => GPIO::regs().out().read().bits(),
567 #[cfg(gpio_bank_1)]
568 Self::_1 => GPIO::regs().out1().read().bits(),
569 }
570 }
571
572 fn read_interrupt_status(self) -> u32 {
573 match self {
574 Self::_0 => GPIO::regs().status().read().bits(),
575 #[cfg(gpio_bank_1)]
576 Self::_1 => GPIO::regs().status1().read().bits(),
577 }
578 }
579
580 fn write_interrupt_status_clear(self, word: u32) {
581 match self {
582 Self::_0 => GPIO::regs()
583 .status_w1tc()
584 .write(|w| unsafe { w.bits(word) }),
585 #[cfg(gpio_bank_1)]
586 Self::_1 => GPIO::regs()
587 .status1_w1tc()
588 .write(|w| unsafe { w.bits(word) }),
589 };
590 }
591
592 fn write_output(self, word: u32, set: bool) {
593 if set {
594 self.write_output_set(word);
595 } else {
596 self.write_output_clear(word);
597 }
598 }
599
600 fn write_output_set(self, word: u32) {
601 match self {
602 Self::_0 => GPIO::regs().out_w1ts().write(|w| unsafe { w.bits(word) }),
603 #[cfg(gpio_bank_1)]
604 Self::_1 => GPIO::regs().out1_w1ts().write(|w| unsafe { w.bits(word) }),
605 };
606 }
607
608 fn write_output_clear(self, word: u32) {
609 match self {
610 Self::_0 => GPIO::regs().out_w1tc().write(|w| unsafe { w.bits(word) }),
611 #[cfg(gpio_bank_1)]
612 Self::_1 => GPIO::regs().out1_w1tc().write(|w| unsafe { w.bits(word) }),
613 };
614 }
615}
616
617#[non_exhaustive]
619#[derive(Debug)]
620#[cfg_attr(feature = "defmt", derive(defmt::Format))]
621pub struct GpioPin<const GPIONUM: u8>;
622
623#[derive(Debug)]
625#[cfg_attr(feature = "defmt", derive(defmt::Format))]
626pub struct AnyPin(pub(crate) u8);
627
628impl<const GPIONUM: u8> GpioPin<GPIONUM>
629where
630 Self: Pin,
631{
632 pub unsafe fn steal() -> Self {
638 Self
639 }
640
641 #[doc = crate::before_snippet!()]
648 #[instability::unstable]
653 pub fn split(self) -> (interconnect::InputSignal, interconnect::OutputSignal) {
654 self.degrade().split()
658 }
659}
660
661#[cfg(usb_device)]
664fn disable_usb_pads(gpionum: u8) {
665 cfg_if::cfg_if! {
666 if #[cfg(esp32c3)] {
667 let pins = [18, 19];
668 } else if #[cfg(esp32c6)] {
669 let pins = [12, 13];
670 } else if #[cfg(esp32h2)] {
671 let pins = [26, 27];
672 } else if #[cfg(esp32s3)] {
673 let pins = [19, 20];
674 } else {
675 compile_error!("Please define USB pins for this chip");
676 }
677 }
678
679 if pins.contains(&gpionum) {
680 crate::peripherals::USB_DEVICE::regs()
681 .conf0()
682 .modify(|_, w| {
683 w.usb_pad_enable().clear_bit();
684 w.dm_pullup().clear_bit();
685 w.dm_pulldown().clear_bit();
686 w.dp_pullup().clear_bit();
687 w.dp_pulldown().clear_bit()
688 });
689 }
690}
691
692impl<const GPIONUM: u8> Peripheral for GpioPin<GPIONUM>
693where
694 Self: Pin,
695{
696 type P = GpioPin<GPIONUM>;
697
698 unsafe fn clone_unchecked(&self) -> Self::P {
699 core::ptr::read(self as *const _)
700 }
701}
702
703impl<const GPIONUM: u8> private::Sealed for GpioPin<GPIONUM> {}
704
705pub(crate) fn bind_default_interrupt_handler() {
706 if let Some(handler) = interrupt::bound_handler(Interrupt::GPIO) {
708 let handler = handler as *const unsafe extern "C" fn();
709
710 if !core::ptr::eq(handler, DEFAULT_INTERRUPT_HANDLER.handler() as _) {
713 info!("Not using default GPIO interrupt handler: already bound in vector table");
715 return;
716 }
717 }
718 if interrupt::bound_cpu_interrupt_for(crate::system::Cpu::current(), Interrupt::GPIO).is_some()
721 {
722 info!("Not using default GPIO interrupt handler: peripheral interrupt already in use");
723 return;
724 }
725
726 unsafe { interrupt::bind_interrupt(Interrupt::GPIO, default_gpio_interrupt_handler) };
727 unwrap!(interrupt::enable(Interrupt::GPIO, Priority::min()));
729}
730
731#[derive(Debug)]
733#[cfg_attr(feature = "defmt", derive(defmt::Format))]
734#[instability::unstable]
735pub struct Io {
736 _io_mux: IO_MUX,
737}
738
739impl Io {
740 #[instability::unstable]
742 pub fn new(_io_mux: IO_MUX) -> Self {
743 Io { _io_mux }
744 }
745
746 #[instability::unstable]
753 pub fn set_interrupt_priority(&self, prio: Priority) {
754 unwrap!(interrupt::enable(Interrupt::GPIO, prio));
755 }
756
757 #[cfg_attr(
758 not(multi_core),
759 doc = "Registers an interrupt handler for all GPIO pins."
760 )]
761 #[cfg_attr(
762 multi_core,
763 doc = "Registers an interrupt handler for all GPIO pins on the current core."
764 )]
765 #[doc = ""]
766 #[instability::unstable]
776 pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
777 for core in crate::system::Cpu::other() {
778 crate::interrupt::disable(core, Interrupt::GPIO);
779 }
780 self.set_interrupt_priority(handler.priority());
781 unsafe {
782 interrupt::bind_interrupt(Interrupt::GPIO, user_irq::user_gpio_interrupt_handler)
783 };
784 user_irq::USER_INTERRUPT_HANDLER.store(handler.handler());
785 }
786}
787
788impl crate::private::Sealed for Io {}
789
790#[instability::unstable]
791impl crate::interrupt::InterruptConfigurable for Io {
792 fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
793 self.set_interrupt_handler(handler);
794 }
795}
796
797#[ram]
798extern "C" fn default_gpio_interrupt_handler() {
799 handle_pin_interrupts(|| ());
800}
801
802#[ram]
803fn handle_pin_interrupts(user_handler: fn()) {
804 let intrs_bank0 = InterruptStatusRegisterAccess::Bank0.interrupt_status_read();
805
806 #[cfg(gpio_bank_1)]
807 let intrs_bank1 = InterruptStatusRegisterAccess::Bank1.interrupt_status_read();
808
809 user_handler();
810
811 let banks = [
812 (GpioBank::_0, intrs_bank0),
813 #[cfg(gpio_bank_1)]
814 (GpioBank::_1, intrs_bank1),
815 ];
816
817 for (bank, intrs) in banks {
818 let async_pins = bank.async_operations().fetch_and(!intrs, Ordering::Relaxed);
820
821 let mut intr_bits = intrs & async_pins;
823 while intr_bits != 0 {
824 let pin_pos = intr_bits.trailing_zeros();
825 intr_bits -= 1 << pin_pos;
826
827 let pin_nr = pin_pos as u8 + bank.offset();
828
829 crate::interrupt::free(|| {
830 asynch::PIN_WAKERS[pin_nr as usize].wake();
831 set_int_enable(pin_nr, Some(0), 0, false);
832 });
833 }
834
835 bank.write_interrupt_status_clear(intrs);
836 }
837}
838
839#[doc(hidden)]
840#[macro_export]
841macro_rules! if_output_pin {
842 ({ $($then:tt)* } else { $($else:tt)* }) => { $($else)* };
844
845 (Output $(, $other:ident)* { $($then:tt)* } else { $($else:tt)* }) => { $($then)* };
847
848 ($not:ident $(, $other:ident)* { $($then:tt)* } else { $($else:tt)* }) => {
850 $crate::if_output_pin!($($other),* { $($then)* } else { $($else)* })
851 };
852}
853
854#[doc(hidden)]
855#[macro_export]
856macro_rules! if_rtcio_pin {
857 ({ $($then:tt)* } else { $($else:tt)* }) => { $($else)* };
859
860 (RtcIo $(, $other:ident)* { $($then:tt)* } else { $($else:tt)* }) => { $($then)* };
862 (RtcIoInput $(, $other:ident)* { $($then:tt)* } else { $($else:tt)* }) => { $($then)* };
863
864 ($not:ident $(, $other:ident)* { $($then:tt)* } else { $($else:tt)* }) => {
866 $crate::if_rtcio_pin!($($other),* { $($then)* } else { $($else)* })
867 };
868}
869
870#[doc(hidden)]
871#[macro_export]
872macro_rules! io_type {
873 (Input, $gpionum:literal) => {
874 impl $crate::gpio::InputPin for $crate::gpio::GpioPin<$gpionum> {}
875 };
876 (Output, $gpionum:literal) => {
877 impl $crate::gpio::OutputPin for $crate::gpio::GpioPin<$gpionum> {}
878 };
879 (Analog, $gpionum:literal) => {
880 #[cfg(any(esp32c2, esp32c3, esp32c6, esp32h2))]
882 #[cfg(any(doc, feature = "unstable"))]
883 #[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
884 impl $crate::gpio::AnalogPin for $crate::gpio::GpioPin<$gpionum> {
885 fn set_analog(&self, _: $crate::private::Internal) {
887 use $crate::peripherals::GPIO;
888
889 $crate::gpio::io_mux_reg($gpionum).modify(|_, w| unsafe {
890 w.mcu_sel().bits(1);
891 w.fun_ie().clear_bit();
892 w.fun_wpu().clear_bit();
893 w.fun_wpd().clear_bit()
894 });
895
896 GPIO::regs()
897 .enable_w1tc()
898 .write(|w| unsafe { w.bits(1 << $gpionum) });
899 }
900 }
901 };
902 ($other:ident, $gpionum:literal) => {
903 };
905}
906
907#[doc(hidden)]
908#[macro_export]
909macro_rules! gpio {
910 (
911 $(
912 ($gpionum:literal, [$($type:tt),*]
913 $(
914 ( $( $af_input_num:literal => $af_input_signal:ident )* )
915 ( $( $af_output_num:literal => $af_output_signal:ident )* )
916 )?
917 )
918 )+
919 ) => {
920 paste::paste! {
921 $(
922 $(
923 $crate::io_type!($type, $gpionum);
924 )*
925
926 impl $crate::gpio::Pin for $crate::gpio::GpioPin<$gpionum> {
927 #[inline(always)]
928 fn number(&self) -> u8 {
929 $gpionum
930 }
931
932 fn output_signals(&self, _: $crate::private::Internal) -> &'static [($crate::gpio::AlternateFunction, $crate::gpio::OutputSignal)] {
933 &[
934 $(
935 $(
936 (
937 $crate::gpio::AlternateFunction::[< _ $af_output_num >],
938 $crate::gpio::OutputSignal::$af_output_signal
939 ),
940 )*
941 )?
942 ]
943 }
944
945 fn input_signals(&self, _: $crate::private::Internal) -> &'static [($crate::gpio::AlternateFunction, $crate::gpio::InputSignal)] {
946 &[
947 $(
948 $(
949 (
950 $crate::gpio::AlternateFunction::[< _ $af_input_num >],
951 $crate::gpio::InputSignal::$af_input_signal
952 ),
953 )*
954 )?
955 ]
956 }
957 }
958
959 impl From<$crate::gpio::GpioPin<$gpionum>> for $crate::gpio::AnyPin {
960 fn from(pin: $crate::gpio::GpioPin<$gpionum>) -> Self {
961 $crate::gpio::Pin::degrade(pin)
962 }
963 }
964 )+
965
966 impl $crate::peripheral::Peripheral for $crate::gpio::AnyPin {
967 type P = $crate::gpio::AnyPin;
968 unsafe fn clone_unchecked(&self) -> Self {
969 Self(self.0)
970 }
971 }
972
973 impl $crate::gpio::AnyPin {
974 pub unsafe fn steal(pin: u8) -> Self {
984 const PINS: &[u8] = &[$($gpionum),*];
985 assert!(PINS.contains(&pin), "Pin {} does not exist", pin);
986 Self(pin)
987 }
988
989 pub(crate) fn is_output(&self) -> bool {
990 match self.0 {
991 $(
992 $gpionum => $crate::if_output_pin!($($type),* { true } else { false }),
993 )+
994 _ => false,
995 }
996 }
997 }
998
999 #[doc(hidden)]
1002 macro_rules! handle_gpio_output {
1003 ($this:expr, $inner:ident, $code:tt) => {
1004 match $this.number() {
1005 $(
1006 $gpionum => $crate::if_output_pin!($($type),* {{
1007 #[allow(unused_mut)]
1008 let mut $inner = unsafe { GpioPin::<$gpionum>::steal() };
1009 $code
1010 }} else {{
1011 panic!("Unsupported")
1012 }}),
1013 )+
1014 _ => unreachable!(),
1015 }
1016 }
1017 }
1018
1019 #[doc(hidden)]
1020 macro_rules! handle_gpio_input {
1021 ($this:expr, $inner:ident, $code:tt) => {
1022 match $this.number() {
1023 $(
1024 $gpionum => {{
1025 #[allow(unused_mut)]
1026 let mut $inner = unsafe { GpioPin::<$gpionum>::steal() };
1027 $code
1028 }},
1029 )+
1030 _ => unreachable!(),
1031 }
1032 }
1033 }
1034
1035 pub(crate) use handle_gpio_output;
1036 pub(crate) use handle_gpio_input;
1037
1038 cfg_if::cfg_if! {
1039 if #[cfg(any(lp_io, rtc_cntl))] {
1040 #[doc(hidden)]
1041 macro_rules! handle_rtcio {
1042 ($this:expr, $inner:ident, $code:tt) => {
1043 match $this.number() {
1044 $(
1045 $gpionum => $crate::if_rtcio_pin!($($type),* {{
1046 #[allow(unused_mut)]
1047 let mut $inner = unsafe { GpioPin::<$gpionum>::steal() };
1048 $code
1049 }} else {{
1050 panic!("Unsupported")
1051 }}),
1052 )+
1053 _ => unreachable!(),
1054 }
1055 }
1056 }
1057
1058 #[doc(hidden)]
1059 macro_rules! handle_rtcio_with_resistors {
1060 ($this:expr, $inner:ident, $code:tt) => {
1061 match $this.number() {
1062 $(
1063 $gpionum => $crate::if_rtcio_pin!($($type),* {
1064 $crate::if_output_pin!($($type),* {{
1065 #[allow(unused_mut)]
1066 let mut $inner = unsafe { GpioPin::<$gpionum>::steal() };
1067 $code
1068 }} else {{
1069 panic!("Unsupported")
1070 }})
1071 } else {{
1072 panic!("Unsupported")
1073 }}),
1074 )+
1075 _ => unreachable!(),
1076 }
1077 }
1078 }
1079
1080 pub(crate) use handle_rtcio;
1081 pub(crate) use handle_rtcio_with_resistors;
1082 }
1083 }
1084 }
1085 };
1086}
1087
1088#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1090#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1091pub enum DriveMode {
1092 PushPull,
1097
1098 OpenDrain,
1105}
1106
1107#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1115#[derive(Debug, Clone, Copy, PartialEq, Eq, procmacros::BuilderLite)]
1116#[non_exhaustive]
1117pub struct OutputConfig {
1118 drive_mode: DriveMode,
1120
1121 drive_strength: DriveStrength,
1123
1124 pull: Pull,
1126}
1127
1128impl Default for OutputConfig {
1129 fn default() -> Self {
1130 Self {
1131 drive_mode: DriveMode::PushPull,
1132 drive_strength: DriveStrength::_20mA,
1133 pull: Pull::None,
1134 }
1135 }
1136}
1137
1138#[derive(Debug)]
1142#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1143pub struct Output<'d> {
1144 pin: Flex<'d>,
1145}
1146
1147impl private::Sealed for Output<'_> {}
1148
1149impl<'d> Peripheral for Output<'d> {
1150 type P = Flex<'d>;
1151 unsafe fn clone_unchecked(&self) -> Self::P {
1152 self.pin.clone_unchecked()
1153 }
1154}
1155
1156impl<'d> Output<'d> {
1157 #[doc = crate::before_snippet!()]
1171 #[inline]
1190 pub fn new(
1191 pin: impl Peripheral<P = impl OutputPin> + 'd,
1192 initial_level: Level,
1193 config: OutputConfig,
1194 ) -> Self {
1195 let mut this = Self {
1197 pin: Flex::new(pin),
1198 };
1199 this.set_level(initial_level);
1200 this.apply_config(&config);
1201 this.pin.pin.enable_output(true);
1202
1203 this
1204 }
1205
1206 #[doc = crate::before_snippet!()]
1212 #[inline]
1220 #[instability::unstable]
1221 pub fn split(self) -> (interconnect::InputSignal, interconnect::OutputSignal) {
1222 self.pin.split()
1223 }
1224
1225 #[doc = crate::before_snippet!()]
1231 #[inline]
1240 #[instability::unstable]
1241 pub fn peripheral_input(&self) -> interconnect::InputSignal {
1242 self.pin.peripheral_input()
1243 }
1244
1245 #[doc = crate::before_snippet!()]
1252 #[inline]
1260 #[instability::unstable]
1261 pub fn into_peripheral_output(self) -> interconnect::OutputSignal {
1262 self.pin.into_peripheral_output()
1263 }
1264
1265 #[inline]
1267 pub fn apply_config(&mut self, config: &OutputConfig) {
1268 self.pin.apply_output_config(config)
1269 }
1270
1271 #[inline]
1273 pub fn set_high(&mut self) {
1274 self.set_level(Level::High)
1275 }
1276
1277 #[inline]
1279 pub fn set_low(&mut self) {
1280 self.set_level(Level::Low)
1281 }
1282
1283 #[inline]
1285 pub fn set_level(&mut self, level: Level) {
1286 self.pin.set_level(level)
1287 }
1288
1289 #[inline]
1294 pub fn is_set_high(&self) -> bool {
1295 self.output_level() == Level::High
1296 }
1297
1298 #[inline]
1303 pub fn is_set_low(&self) -> bool {
1304 self.output_level() == Level::Low
1305 }
1306
1307 #[inline]
1312 pub fn output_level(&self) -> Level {
1313 self.pin.output_level()
1314 }
1315
1316 #[inline]
1321 pub fn toggle(&mut self) {
1322 self.pin.toggle();
1323 }
1324
1325 #[inline]
1327 #[instability::unstable]
1328 pub fn into_flex(self) -> Flex<'d> {
1329 self.pin
1330 }
1331}
1332
1333#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1335#[derive(Debug, Clone, Copy, PartialEq, Eq, procmacros::BuilderLite)]
1336#[non_exhaustive]
1337pub struct InputConfig {
1338 pull: Pull,
1340}
1341
1342impl Default for InputConfig {
1343 fn default() -> Self {
1344 Self { pull: Pull::None }
1345 }
1346}
1347
1348#[derive(Debug)]
1353#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1354pub struct Input<'d> {
1355 pin: Flex<'d>,
1356}
1357
1358impl private::Sealed for Input<'_> {}
1359
1360impl<'d> Peripheral for Input<'d> {
1361 type P = Flex<'d>;
1362 unsafe fn clone_unchecked(&self) -> Self::P {
1363 self.pin.clone_unchecked()
1364 }
1365}
1366
1367impl<'d> Input<'d> {
1368 #[doc = crate::before_snippet!()]
1381 #[inline]
1406 pub fn new(pin: impl Peripheral<P = impl InputPin> + 'd, config: InputConfig) -> Self {
1407 let mut pin = Flex::new(pin);
1408
1409 pin.pin.enable_output(false);
1410 pin.enable_input(true);
1411 pin.apply_input_config(&config);
1412
1413 Self { pin }
1414 }
1415
1416 #[doc = crate::before_snippet!()]
1422 #[inline]
1430 #[instability::unstable]
1431 pub fn peripheral_input(&self) -> interconnect::InputSignal {
1432 self.pin.peripheral_input()
1433 }
1434
1435 #[inline]
1437 pub fn is_high(&self) -> bool {
1438 self.level() == Level::High
1439 }
1440
1441 #[inline]
1443 pub fn is_low(&self) -> bool {
1444 self.level() == Level::Low
1445 }
1446
1447 #[inline]
1449 pub fn level(&self) -> Level {
1450 self.pin.level()
1451 }
1452
1453 pub fn apply_config(&mut self, config: &InputConfig) {
1455 self.pin.apply_input_config(config)
1456 }
1457
1458 #[doc = crate::before_snippet!()]
1475 #[inline]
1530 #[instability::unstable]
1531 pub fn listen(&mut self, event: Event) {
1532 self.pin.listen(event);
1533 }
1534
1535 #[inline]
1537 #[instability::unstable]
1538 pub fn unlisten(&mut self) {
1539 self.pin.unlisten();
1540 }
1541
1542 #[inline]
1544 #[instability::unstable]
1545 pub fn clear_interrupt(&mut self) {
1546 self.pin.clear_interrupt();
1547 }
1548
1549 #[inline]
1551 #[instability::unstable]
1552 pub fn is_interrupt_set(&self) -> bool {
1553 self.pin.is_interrupt_set()
1554 }
1555
1556 #[instability::unstable]
1565 #[inline]
1566 pub fn wakeup_enable(&mut self, enable: bool, event: WakeEvent) -> Result<(), WakeConfigError> {
1567 self.pin.wakeup_enable(enable, event)
1568 }
1569
1570 #[doc = crate::before_snippet!()]
1576 #[inline]
1584 #[instability::unstable]
1585 pub fn split(self) -> (interconnect::InputSignal, interconnect::OutputSignal) {
1586 self.pin.split()
1587 }
1588
1589 #[doc = crate::before_snippet!()]
1596 #[inline]
1605 #[instability::unstable]
1606 pub fn into_peripheral_output(self) -> interconnect::OutputSignal {
1607 self.pin.into_peripheral_output()
1608 }
1609
1610 #[inline]
1612 #[instability::unstable]
1613 pub fn into_flex(self) -> Flex<'d> {
1614 self.pin
1615 }
1616}
1617
1618#[derive(Debug)]
1622#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1623pub struct Flex<'d> {
1624 pin: PeripheralRef<'d, AnyPin>,
1625}
1626
1627impl private::Sealed for Flex<'_> {}
1628
1629impl Peripheral for Flex<'_> {
1630 type P = Self;
1631 unsafe fn clone_unchecked(&self) -> Self::P {
1632 Self {
1633 pin: PeripheralRef::new(AnyPin(self.pin.number())),
1634 }
1635 }
1636}
1637
1638impl<'d> Flex<'d> {
1639 #[inline]
1642 #[instability::unstable]
1643 pub fn new(pin: impl Peripheral<P = impl Into<AnyPin>> + 'd) -> Self {
1644 crate::into_mapped_ref!(pin);
1645
1646 #[cfg(usb_device)]
1647 disable_usb_pads(pin.number());
1648
1649 GPIO::regs()
1650 .func_out_sel_cfg(pin.number() as usize)
1651 .modify(|_, w| unsafe { w.out_sel().bits(OutputSignal::GPIO as OutputSignalType) });
1652
1653 io_mux_reg(pin.number()).modify(|_, w| unsafe {
1655 w.mcu_sel().bits(GPIO_FUNCTION as u8);
1656 w.fun_ie().clear_bit();
1657 w.slp_sel().clear_bit()
1658 });
1659
1660 Self { pin }
1661 }
1662
1663 fn number(&self) -> u8 {
1664 self.pin.number()
1665 }
1666
1667 #[doc = crate::before_snippet!()]
1673 #[inline]
1681 #[instability::unstable]
1682 pub fn peripheral_input(&self) -> interconnect::InputSignal {
1683 unsafe { AnyPin::steal(self.number()) }.split().0
1684 }
1685
1686 #[inline]
1688 #[instability::unstable]
1689 pub fn is_high(&self) -> bool {
1690 self.level() == Level::High
1691 }
1692
1693 #[inline]
1695 #[instability::unstable]
1696 pub fn is_low(&self) -> bool {
1697 self.level() == Level::Low
1698 }
1699
1700 #[inline]
1702 #[instability::unstable]
1703 pub fn level(&self) -> Level {
1704 self.pin.is_input_high().into()
1705 }
1706
1707 fn listen_with_options(
1708 &self,
1709 event: Event,
1710 int_enable: bool,
1711 nmi_enable: bool,
1712 wake_up_from_light_sleep: bool,
1713 ) -> Result<(), WakeConfigError> {
1714 if wake_up_from_light_sleep {
1715 match event {
1716 Event::AnyEdge | Event::RisingEdge | Event::FallingEdge => {
1717 return Err(WakeConfigError::EdgeTriggeringNotSupported);
1718 }
1719 _ => {}
1720 }
1721 }
1722
1723 set_int_enable(
1724 self.pin.number(),
1725 Some(gpio_intr_enable(int_enable, nmi_enable)),
1726 event as u8,
1727 wake_up_from_light_sleep,
1728 );
1729
1730 Ok(())
1731 }
1732
1733 #[inline]
1737 #[instability::unstable]
1738 pub fn listen(&mut self, event: Event) {
1739 unwrap!(self.listen_with_options(event, true, false, false));
1742 }
1743
1744 #[inline]
1746 #[instability::unstable]
1747 pub fn unlisten(&mut self) {
1748 set_int_enable(self.pin.number(), Some(0), 0, false);
1749 }
1750
1751 #[inline]
1753 #[instability::unstable]
1754 pub fn is_listening(&self) -> bool {
1755 is_int_enabled(self.pin.number())
1756 }
1757
1758 #[inline]
1760 #[instability::unstable]
1761 pub fn clear_interrupt(&mut self) {
1762 self.pin
1763 .bank()
1764 .write_interrupt_status_clear(self.pin.mask());
1765 }
1766
1767 #[inline]
1769 #[instability::unstable]
1770 pub fn is_interrupt_set(&self) -> bool {
1771 self.pin.bank().read_interrupt_status() & self.pin.mask() != 0
1772 }
1773
1774 #[inline]
1783 #[instability::unstable]
1784 pub fn wakeup_enable(&mut self, enable: bool, event: WakeEvent) -> Result<(), WakeConfigError> {
1785 self.listen_with_options(event.into(), false, false, enable)
1786 }
1787
1788 #[inline]
1790 #[instability::unstable]
1791 pub fn set_as_output(&mut self) {
1792 self.pin.set_to_push_pull_output();
1793 }
1794
1795 #[inline]
1797 #[instability::unstable]
1798 pub fn set_high(&mut self) {
1799 self.set_level(Level::High)
1800 }
1801
1802 #[inline]
1804 #[instability::unstable]
1805 pub fn set_low(&mut self) {
1806 self.set_level(Level::Low)
1807 }
1808
1809 #[inline]
1811 #[instability::unstable]
1812 pub fn set_level(&mut self, level: Level) {
1813 self.pin.set_output_high(level.into());
1814 }
1815
1816 #[inline]
1818 #[instability::unstable]
1819 pub fn is_set_high(&self) -> bool {
1820 self.output_level() == Level::High
1821 }
1822
1823 #[inline]
1825 #[instability::unstable]
1826 pub fn is_set_low(&self) -> bool {
1827 self.output_level() == Level::Low
1828 }
1829
1830 #[inline]
1832 #[instability::unstable]
1833 pub fn output_level(&self) -> Level {
1834 self.pin.is_set_high().into()
1835 }
1836
1837 #[inline]
1839 #[instability::unstable]
1840 pub fn toggle(&mut self) {
1841 let level = self.output_level();
1842 self.set_level(!level);
1843 }
1844
1845 #[inline]
1847 #[instability::unstable]
1848 pub fn set_drive_strength(&mut self, strength: DriveStrength) {
1849 self.pin.set_drive_strength(strength);
1850 }
1851
1852 #[inline]
1854 #[instability::unstable]
1855 pub fn set_as_open_drain(&mut self, pull: Pull) {
1856 self.pin.set_to_open_drain_output();
1857 self.pin.pull_direction(pull);
1858 }
1859
1860 #[inline]
1862 #[instability::unstable]
1863 pub fn pull_direction(&mut self, pull: Pull) {
1864 self.pin.pull_direction(pull);
1865 }
1866
1867 #[inline]
1869 #[instability::unstable]
1870 pub fn enable_input(&mut self, enable_input: bool) {
1871 self.pin.enable_input(enable_input);
1872 }
1873
1874 #[inline]
1876 #[instability::unstable]
1877 pub fn apply_output_config(&mut self, config: &OutputConfig) {
1878 let pull_up = config.pull == Pull::Up;
1879 let pull_down = config.pull == Pull::Down;
1880
1881 #[cfg(esp32)]
1882 crate::soc::gpio::errata36(AnyPin(self.pin.0), pull_up, pull_down);
1883
1884 io_mux_reg(self.number()).modify(|_, w| {
1885 unsafe { w.fun_drv().bits(config.drive_strength as u8) };
1886 w.fun_wpu().bit(pull_up);
1887 w.fun_wpd().bit(pull_down);
1888 w
1889 });
1890
1891 GPIO::regs().pin(self.number() as usize).modify(|_, w| {
1892 w.pad_driver()
1893 .bit(config.drive_mode == DriveMode::OpenDrain)
1894 });
1895 }
1896
1897 #[inline]
1899 #[instability::unstable]
1900 pub fn apply_input_config(&mut self, config: &InputConfig) {
1901 self.pin.pull_direction(config.pull);
1902 }
1903
1904 #[doc = crate::before_snippet!()]
1910 #[inline]
1917 #[instability::unstable]
1918 pub fn split(self) -> (interconnect::InputSignal, interconnect::OutputSignal) {
1919 assert!(self.pin.is_output());
1920 unsafe { AnyPin::steal(self.number()) }.split()
1921 }
1922
1923 #[doc = crate::before_snippet!()]
1930 #[inline]
1938 #[instability::unstable]
1939 pub fn into_peripheral_output(self) -> interconnect::OutputSignal {
1940 self.split().1
1941 }
1942}
1943
1944impl private::Sealed for AnyPin {}
1945
1946impl AnyPin {
1947 fn bank(&self) -> GpioBank {
1948 #[cfg(gpio_bank_1)]
1949 if self.number() >= 32 {
1950 return GpioBank::_1;
1951 }
1952
1953 GpioBank::_0
1954 }
1955
1956 #[inline]
1958 pub(crate) fn init_input(&self, pull: Pull) {
1959 self.pull_direction(pull);
1960
1961 #[cfg(usb_device)]
1962 disable_usb_pads(self.number());
1963
1964 io_mux_reg(self.number()).modify(|_, w| unsafe {
1965 w.mcu_sel().bits(GPIO_FUNCTION as u8);
1966 w.fun_ie().set_bit();
1967 w.slp_sel().clear_bit()
1968 });
1969 }
1970
1971 #[doc = crate::before_snippet!()]
1977 #[inline]
1984 #[instability::unstable]
1985 pub fn split(self) -> (interconnect::InputSignal, interconnect::OutputSignal) {
1986 assert!(self.is_output());
1987 (
1988 interconnect::InputSignal::new(Self(self.0)),
1989 interconnect::OutputSignal::new(Self(self.0)),
1990 )
1991 }
1992
1993 #[inline]
1994 pub(crate) fn set_alternate_function(&self, alternate: AlternateFunction) {
1995 io_mux_reg(self.number()).modify(|_, w| unsafe { w.mcu_sel().bits(alternate as u8) });
1996 }
1997
1998 #[inline]
2006 pub(crate) fn enable_output(&self, enable: bool) {
2007 assert!(self.is_output() || !enable);
2008 self.bank().write_out_en(self.mask(), enable);
2009 }
2010
2011 #[inline]
2013 pub(crate) fn enable_input(&self, on: bool) {
2014 io_mux_reg(self.number()).modify(|_, w| w.fun_ie().bit(on));
2015 }
2016
2017 #[inline]
2018 pub(crate) fn pull_direction(&self, pull: Pull) {
2019 let pull_up = pull == Pull::Up;
2020 let pull_down = pull == Pull::Down;
2021
2022 #[cfg(esp32)]
2023 crate::soc::gpio::errata36(Self(self.0), pull_up, pull_down);
2024
2025 io_mux_reg(self.number()).modify(|_, w| {
2026 w.fun_wpd().bit(pull_down);
2027 w.fun_wpu().bit(pull_up)
2028 });
2029 }
2030
2031 #[inline]
2032 fn mask(&self) -> u32 {
2033 1 << (self.number() % 32)
2034 }
2035
2036 #[inline]
2038 pub(crate) fn is_input_high(&self) -> bool {
2039 self.bank().read_input() & self.mask() != 0
2040 }
2041
2042 #[inline]
2044 pub(crate) fn init_output(
2045 &self,
2046 alternate: AlternateFunction,
2047 open_drain: bool,
2048 input_enable: Option<bool>,
2049 ) {
2050 self.enable_output(true);
2051
2052 let gpio = GPIO::regs();
2053
2054 gpio.pin(self.number() as usize)
2055 .modify(|_, w| w.pad_driver().bit(open_drain));
2056
2057 gpio.func_out_sel_cfg(self.number() as usize)
2058 .modify(|_, w| unsafe { w.out_sel().bits(OutputSignal::GPIO as OutputSignalType) });
2059
2060 #[cfg(usb_device)]
2061 disable_usb_pads(self.number());
2062
2063 io_mux_reg(self.number()).modify(|_, w| unsafe {
2064 w.mcu_sel().bits(alternate as u8);
2065 if let Some(input_enable) = input_enable {
2066 w.fun_ie().bit(input_enable);
2067 }
2068 w.fun_drv().bits(DriveStrength::_20mA as u8);
2069 w.slp_sel().clear_bit()
2070 });
2071 }
2072
2073 #[inline]
2075 pub(crate) fn set_to_open_drain_output(&self) {
2076 self.init_output(GPIO_FUNCTION, true, Some(true));
2077 }
2078
2079 #[inline]
2081 pub(crate) fn set_to_push_pull_output(&self) {
2082 self.init_output(GPIO_FUNCTION, false, None);
2083 }
2084
2085 #[inline]
2087 pub(crate) fn set_output_high(&self, high: bool) {
2088 self.bank().write_output(self.mask(), high);
2089 }
2090
2091 #[inline]
2093 pub(crate) fn set_drive_strength(&self, strength: DriveStrength) {
2094 io_mux_reg(self.number()).modify(|_, w| unsafe { w.fun_drv().bits(strength as u8) });
2095 }
2096
2097 #[inline]
2099 pub(crate) fn enable_open_drain(&self, on: bool) {
2100 GPIO::regs()
2101 .pin(self.number() as usize)
2102 .modify(|_, w| w.pad_driver().bit(on));
2103 }
2104
2105 #[inline]
2107 pub(crate) fn is_set_high(&self) -> bool {
2108 self.bank().read_output() & self.mask() != 0
2109 }
2110}
2111
2112impl Pin for AnyPin {
2113 #[inline(always)]
2114 fn number(&self) -> u8 {
2115 self.0
2116 }
2117
2118 fn output_signals(&self, _: private::Internal) -> &'static [(AlternateFunction, OutputSignal)] {
2119 handle_gpio_output!(self, target, {
2120 Pin::output_signals(&target, private::Internal)
2121 })
2122 }
2123
2124 fn input_signals(&self, _: private::Internal) -> &'static [(AlternateFunction, InputSignal)] {
2125 handle_gpio_input!(self, target, {
2126 Pin::input_signals(&target, private::Internal)
2127 })
2128 }
2129}
2130
2131impl InputPin for AnyPin {}
2132impl OutputPin for AnyPin {}
2133
2134#[cfg(any(lp_io, rtc_cntl))]
2135impl RtcPin for AnyPin {
2136 #[cfg(xtensa)]
2137 #[allow(unused_braces, reason = "False positive")]
2138 fn rtc_number(&self) -> u8 {
2139 handle_rtcio!(self, target, { RtcPin::rtc_number(&target) })
2140 }
2141
2142 #[cfg(any(xtensa, esp32c6))]
2143 fn rtc_set_config(&self, input_enable: bool, mux: bool, func: RtcFunction) {
2144 handle_rtcio!(self, target, {
2145 RtcPin::rtc_set_config(&target, input_enable, mux, func)
2146 })
2147 }
2148
2149 #[allow(unused_braces, reason = "False positive")]
2150 fn rtcio_pad_hold(&self, enable: bool) {
2151 handle_rtcio!(self, target, { RtcPin::rtcio_pad_hold(&target, enable) })
2152 }
2153
2154 #[cfg(any(esp32c2, esp32c3, esp32c6))]
2155 unsafe fn apply_wakeup(&self, wakeup: bool, level: u8) {
2156 handle_rtcio!(self, target, {
2157 RtcPin::apply_wakeup(&target, wakeup, level)
2158 })
2159 }
2160}
2161
2162#[cfg(any(lp_io, rtc_cntl))]
2163impl RtcPinWithResistors for AnyPin {
2164 fn rtcio_pullup(&self, enable: bool) {
2165 handle_rtcio_with_resistors!(self, target, {
2166 RtcPinWithResistors::rtcio_pullup(&target, enable)
2167 })
2168 }
2169
2170 fn rtcio_pulldown(&self, enable: bool) {
2171 handle_rtcio_with_resistors!(self, target, {
2172 RtcPinWithResistors::rtcio_pulldown(&target, enable)
2173 })
2174 }
2175}
2176
2177fn set_int_enable(gpio_num: u8, int_ena: Option<u8>, int_type: u8, wake_up_from_light_sleep: bool) {
2185 GPIO::regs().pin(gpio_num as usize).modify(|_, w| unsafe {
2186 if let Some(int_ena) = int_ena {
2187 w.int_ena().bits(int_ena);
2188 }
2189 w.int_type().bits(int_type);
2190 w.wakeup_enable().bit(wake_up_from_light_sleep)
2191 });
2192}
2193
2194fn is_int_enabled(gpio_num: u8) -> bool {
2195 GPIO::regs().pin(gpio_num as usize).read().int_ena().bits() != 0
2196}
2197
2198mod asynch {
2199 use core::{
2200 future::poll_fn,
2201 task::{Context, Poll},
2202 };
2203
2204 use super::*;
2205 use crate::asynch::AtomicWaker;
2206
2207 #[ram]
2208 pub(super) static PIN_WAKERS: [AtomicWaker; NUM_PINS] =
2209 [const { AtomicWaker::new() }; NUM_PINS];
2210
2211 impl Flex<'_> {
2212 #[inline]
2220 #[instability::unstable]
2221 pub async fn wait_for(&mut self, event: Event) {
2222 let mut future = PinFuture {
2225 pin: Flex {
2226 pin: unsafe { self.pin.clone_unchecked() },
2227 },
2228 };
2229
2230 if future.pin.is_listening() {
2232 set_int_enable(
2233 future.pin.number(),
2234 None, 0, false,
2237 );
2238 poll_fn(|cx| {
2239 if future.pin.is_interrupt_set() {
2240 cx.waker().wake_by_ref();
2241 Poll::Pending
2242 } else {
2243 Poll::Ready(())
2244 }
2245 })
2246 .await;
2247 }
2248
2249 future
2254 .bank()
2255 .async_operations()
2256 .fetch_or(future.mask(), Ordering::Relaxed);
2257
2258 future.pin.listen(event);
2259
2260 future.await
2261 }
2262
2263 #[inline]
2267 #[instability::unstable]
2268 pub async fn wait_for_high(&mut self) {
2269 self.wait_for(Event::HighLevel).await
2270 }
2271
2272 #[inline]
2276 #[instability::unstable]
2277 pub async fn wait_for_low(&mut self) {
2278 self.wait_for(Event::LowLevel).await
2279 }
2280
2281 #[inline]
2285 #[instability::unstable]
2286 pub async fn wait_for_rising_edge(&mut self) {
2287 self.wait_for(Event::RisingEdge).await
2288 }
2289
2290 #[inline]
2294 #[instability::unstable]
2295 pub async fn wait_for_falling_edge(&mut self) {
2296 self.wait_for(Event::FallingEdge).await
2297 }
2298
2299 #[inline]
2304 #[instability::unstable]
2305 pub async fn wait_for_any_edge(&mut self) {
2306 self.wait_for(Event::AnyEdge).await
2307 }
2308 }
2309
2310 impl Input<'_> {
2311 #[inline]
2319 pub async fn wait_for(&mut self, event: Event) {
2320 self.pin.wait_for(event).await
2321 }
2322
2323 #[inline]
2327 pub async fn wait_for_high(&mut self) {
2328 self.pin.wait_for_high().await
2329 }
2330
2331 #[inline]
2335 pub async fn wait_for_low(&mut self) {
2336 self.pin.wait_for_low().await
2337 }
2338
2339 #[inline]
2343 pub async fn wait_for_rising_edge(&mut self) {
2344 self.pin.wait_for_rising_edge().await
2345 }
2346
2347 #[inline]
2351 pub async fn wait_for_falling_edge(&mut self) {
2352 self.pin.wait_for_falling_edge().await
2353 }
2354
2355 #[inline]
2360 pub async fn wait_for_any_edge(&mut self) {
2361 self.pin.wait_for_any_edge().await
2362 }
2363 }
2364
2365 #[must_use = "futures do nothing unless you `.await` or poll them"]
2366 struct PinFuture<'d> {
2367 pin: Flex<'d>,
2368 }
2369
2370 impl PinFuture<'_> {
2371 fn number(&self) -> u8 {
2372 self.pin.number()
2373 }
2374
2375 fn bank(&self) -> GpioBank {
2376 self.pin.pin.bank()
2377 }
2378
2379 fn mask(&self) -> u32 {
2380 self.pin.pin.mask()
2381 }
2382
2383 fn is_done(&self) -> bool {
2384 self.bank().async_operations().load(Ordering::Acquire) & self.mask() == 0
2387 }
2388 }
2389
2390 impl core::future::Future for PinFuture<'_> {
2391 type Output = ();
2392
2393 fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
2394 PIN_WAKERS[self.number() as usize].register(cx.waker());
2395
2396 if self.is_done() {
2397 Poll::Ready(())
2398 } else {
2399 Poll::Pending
2400 }
2401 }
2402 }
2403
2404 impl Drop for PinFuture<'_> {
2405 fn drop(&mut self) {
2406 if self.pin.is_listening() {
2409 set_int_enable(
2413 self.number(),
2414 None, 0, false,
2417 );
2418
2419 while self.pin.is_interrupt_set() {}
2420
2421 self.bank()
2423 .async_operations()
2424 .fetch_and(!self.mask(), Ordering::Relaxed);
2425 }
2426 }
2427 }
2428}
2429
2430mod embedded_hal_impls {
2431 use embedded_hal::digital;
2432
2433 use super::*;
2434
2435 impl digital::ErrorType for Input<'_> {
2436 type Error = core::convert::Infallible;
2437 }
2438
2439 impl digital::InputPin for Input<'_> {
2440 fn is_high(&mut self) -> Result<bool, Self::Error> {
2441 Ok(Self::is_high(self))
2442 }
2443
2444 fn is_low(&mut self) -> Result<bool, Self::Error> {
2445 Ok(Self::is_low(self))
2446 }
2447 }
2448
2449 impl digital::ErrorType for Output<'_> {
2450 type Error = core::convert::Infallible;
2451 }
2452
2453 impl digital::OutputPin for Output<'_> {
2454 fn set_low(&mut self) -> Result<(), Self::Error> {
2455 Self::set_low(self);
2456 Ok(())
2457 }
2458
2459 fn set_high(&mut self) -> Result<(), Self::Error> {
2460 Self::set_high(self);
2461 Ok(())
2462 }
2463 }
2464
2465 impl digital::StatefulOutputPin for Output<'_> {
2466 fn is_set_high(&mut self) -> Result<bool, Self::Error> {
2467 Ok(Self::is_set_high(self))
2468 }
2469
2470 fn is_set_low(&mut self) -> Result<bool, Self::Error> {
2471 Ok(Self::is_set_low(self))
2472 }
2473 }
2474
2475 #[instability::unstable]
2476 impl digital::InputPin for Flex<'_> {
2477 fn is_high(&mut self) -> Result<bool, Self::Error> {
2478 Ok(Self::is_high(self))
2479 }
2480
2481 fn is_low(&mut self) -> Result<bool, Self::Error> {
2482 Ok(Self::is_low(self))
2483 }
2484 }
2485
2486 #[instability::unstable]
2487 impl digital::ErrorType for Flex<'_> {
2488 type Error = core::convert::Infallible;
2489 }
2490
2491 #[instability::unstable]
2492 impl digital::OutputPin for Flex<'_> {
2493 fn set_low(&mut self) -> Result<(), Self::Error> {
2494 Self::set_low(self);
2495 Ok(())
2496 }
2497
2498 fn set_high(&mut self) -> Result<(), Self::Error> {
2499 Self::set_high(self);
2500 Ok(())
2501 }
2502 }
2503
2504 #[instability::unstable]
2505 impl digital::StatefulOutputPin for Flex<'_> {
2506 fn is_set_high(&mut self) -> Result<bool, Self::Error> {
2507 Ok(Self::is_set_high(self))
2508 }
2509
2510 fn is_set_low(&mut self) -> Result<bool, Self::Error> {
2511 Ok(Self::is_set_low(self))
2512 }
2513 }
2514}
2515
2516mod embedded_hal_async_impls {
2517 use embedded_hal_async::digital::Wait;
2518
2519 use super::*;
2520
2521 #[instability::unstable]
2522 impl Wait for Flex<'_> {
2523 async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
2524 Self::wait_for_high(self).await;
2525 Ok(())
2526 }
2527
2528 async fn wait_for_low(&mut self) -> Result<(), Self::Error> {
2529 Self::wait_for_low(self).await;
2530 Ok(())
2531 }
2532
2533 async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> {
2534 Self::wait_for_rising_edge(self).await;
2535 Ok(())
2536 }
2537
2538 async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> {
2539 Self::wait_for_falling_edge(self).await;
2540 Ok(())
2541 }
2542
2543 async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> {
2544 Self::wait_for_any_edge(self).await;
2545 Ok(())
2546 }
2547 }
2548
2549 impl Wait for Input<'_> {
2550 async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
2551 Self::wait_for_high(self).await;
2552 Ok(())
2553 }
2554
2555 async fn wait_for_low(&mut self) -> Result<(), Self::Error> {
2556 Self::wait_for_low(self).await;
2557 Ok(())
2558 }
2559
2560 async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> {
2561 Self::wait_for_rising_edge(self).await;
2562 Ok(())
2563 }
2564
2565 async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> {
2566 Self::wait_for_falling_edge(self).await;
2567 Ok(())
2568 }
2569
2570 async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> {
2571 Self::wait_for_any_edge(self).await;
2572 Ok(())
2573 }
2574 }
2575}