1use core::{convert::Infallible, future::poll_fn, marker::PhantomData, task::Poll};
4
5use embassy_hal_internal::{Peri, PeripheralType, impl_peripheral, interrupt::InterruptExt as _};
6use embassy_sync::waitqueue::AtomicWaker;
7
8use crate::{
9 event_link::{IcuInterrupt as _, InterruptEvent},
10 interrupt,
11 interrupt::typelevel::{Handler as InterruptHandler, Interrupt as InterruptType},
12 pac::{
13 self,
14 common::RW,
15 pfs::Pfs,
16 pfs::vals::{OutputType, PortDirection, PortMode},
17 },
18 write_protect::ProtectedModify as _,
19};
20
21#[cfg(not(ra8))]
23use crate::pac::icu::vals::{Fclksel, Irqmd};
24#[cfg(ra8)]
25use crate::pac::icu_common::vals::{Fclksel, Irqmd};
26
27#[cfg(any(pfs_ra8, pfs_port_drive))]
28use crate::pac::pfs::vals::PortDrive;
29
30#[derive(Copy, Clone, PartialEq)]
35#[cfg_attr(feature = "defmt", derive(defmt::Format))]
36pub struct PinId(u8);
37
38impl PinId {
39 #[inline(always)]
41 pub const fn from_port_pin(port: u8, pin: u8) -> Self {
42 assert!(port <= 9);
45
46 assert!(pin <= 15);
49
50 let pin_number = ((port & 0x0F) << 4) | (pin & 0x0F);
51 Self(pin_number)
52 }
53
54 #[inline(always)]
56 pub const fn port(&self) -> u8 {
57 (self.0 >> 4) & 0x0F
58 }
59
60 #[inline(always)]
62 pub const fn pin(&self) -> u8 {
63 self.0 & 0x0F
64 }
65}
66
67#[derive(Debug, Eq, PartialEq, Copy, Clone)]
73#[cfg_attr(feature = "defmt", derive(defmt::Format))]
74pub enum DriveCapacity {
75 Low,
77
78 Middle,
80}
81
82#[derive(Debug, Eq, PartialEq, Copy, Clone)]
84#[cfg_attr(feature = "defmt", derive(defmt::Format))]
85pub enum OutputMode {
86 PushPull,
88
89 OpenDrain,
91}
92
93#[derive(Clone, Copy)]
95pub enum GpioTrigger {
96 #[allow(missing_docs)]
97 Falling,
98 #[allow(missing_docs)]
99 Rising,
100 #[allow(missing_docs)]
101 Both,
102}
103
104#[cfg_attr(feature = "defmt", derive(defmt::Format))]
108pub enum Debounce {
109 Off,
111
112 Min1,
114
115 Min8,
117
118 Min32,
120
121 Min64,
123}
124
125#[derive(Debug, Eq, PartialEq, Copy, Clone)]
127#[cfg_attr(feature = "defmt", derive(defmt::Format))]
128pub enum Level {
129 #[allow(missing_docs)]
130 Low,
131 #[allow(missing_docs)]
132 High,
133}
134
135#[allow(private_bounds)]
137pub trait GpioIrq<I: InterruptiblePin>: SealedGpioIrq {}
138
139pub(crate) trait SealedGpioIrq: PeripheralType {}
140
141macro_rules! declare_port_irq {
142 ($num:literal) => {
143 paste::paste! {
144 impl crate::gpio::SealedGpioIrq for crate::peripherals::[< GPIO_IRQ $num >] {}
145 }
146 };
147}
148pub(crate) use declare_port_irq;
149
150pub struct AnyPin {
152 pub(crate) pin_port: PinId,
153}
154
155#[allow(private_bounds)]
157pub trait ControlKind: SealedControlKind {}
158trait SealedControlKind {}
159
160pub enum Basic {}
164impl ControlKind for Basic {}
165impl SealedControlKind for Basic {}
166
167pub enum WithPullUp {}
171impl ControlKind for WithPullUp {}
172impl SealedControlKind for WithPullUp {}
173
174pub enum WithOpenDrain {}
178impl ControlKind for WithOpenDrain {}
179impl SealedControlKind for WithOpenDrain {}
180
181pub struct Flex<'d, C: ControlKind> {
185 pin: Peri<'d, AnyPin>,
186 phantom: PhantomData<C>,
187}
188
189#[allow(private_bounds)]
191pub struct InterruptFlex<'d, I: InterruptiblePin, C: ControlKind> {
192 pin: Flex<'d, C>,
193 phantom: PhantomData<&'d I>,
194 phantom_k: PhantomData<C>,
195}
196
197pub struct Input<'d, C: ControlKind> {
199 pin: Flex<'d, C>,
200}
201
202pub struct Output<'d, C: ControlKind> {
204 pin: Flex<'d, C>,
205}
206
207#[cfg_attr(feature = "defmt", derive(defmt::Format))]
213#[derive(Copy, Clone)]
214#[repr(u8)]
215pub enum PortFunction {
216 #[doc = "Hi-Z / JTAG / SWD"]
217 HiZ = 0x0,
218 #[doc = "Low-Power Asynchronous General Purpose Timer"]
219 Agt = 0x01,
220 #[doc = "General PWM Timer"]
221 Gpt0 = 0x02,
222 #[doc = "General PWM Timer"]
223 Gpt1 = 0x03,
224 #[doc = "Serial Communications Interface"]
225 Sci0 = 0x04,
226 #[doc = "Serial Communications Interface"]
227 Sci1 = 0x05,
228 #[doc = "Serial Peripheral Interface"]
229 Spi = 0x06,
230 #[doc = "Inter-Integrated Circuit Bus Interface"]
231 I2c = 0x07,
232 #[doc = "Key Interrupt Function"]
233 Kint = 0x08,
234 #[doc = "CLKOUT / Analog Comparator / Real-Time Clock"]
235 ClkCmpRtc = 0x09,
236 #[doc = "Clock Frequency Accuracy / ADC14"]
237 CacAdc = 0x0a,
238 #[doc = "Capacitive Touch"]
239 Ctsu = 0x0c,
240 #[doc = "Segment LCD"]
241 Slcdc = 0x0d,
242 #[doc = "Controller Area Network Bus"]
243 Can = 0x10,
244 #[doc = "Serial Sound Interface Enhanced"]
245 Ssie = 0x12,
246 #[doc = "USB Full-Speed"]
247 UsbFs = 0x13,
248}
249
250pub struct InputInterruptHandler<I: Pin> {
252 _phantom: PhantomData<I>,
253}
254
255trait PortPin {
256 fn port_pin(&self, port: u8, pin: u8) -> pac::common::Reg<pac::pfs::regs::Pin, RW>;
257}
258
259impl PortPin for Pfs {
260 #[inline(always)]
261 fn port_pin(&self, port_num: u8, pin_num: u8) -> pac::common::Reg<pac::pfs::regs::Pin, RW> {
262 self.pin((usize::from(port_num) * 16) + usize::from(pin_num))
263 }
264}
265
266pub(crate) trait SealedPin {
267 fn pin_port(&self) -> PinId;
268
269 #[inline(always)]
270 fn _pin(&self) -> u8 {
271 self.pin_port().pin()
272 }
273
274 #[inline(always)]
275 fn _port(&self) -> u8 {
276 self.pin_port().port()
277 }
278
279 #[inline]
280 #[cfg(any(pfs_ra8, pfs_port_drive))]
281 fn set_drive_capacity(&self, drive_capacity: DriveCapacity) {
282 let pfs = pac::PFS;
283 let port_num = self._port() as _;
284 let pin_num = self._pin() as _;
285 let pfs_reg = pfs.port_pin(port_num, pin_num);
286
287 pfs_reg.protected_modify(|r| match drive_capacity {
288 DriveCapacity::Low => r.set_dscr(PortDrive::Low),
289 DriveCapacity::Middle => r.set_dscr(PortDrive::Middle),
290 });
291 }
292
293 fn set_output_mode(&self, output_mode: OutputMode) {
294 let pfs = pac::PFS;
295 let port_num = self._port() as _;
296 let pin_num = self._pin() as _;
297 let pfs_reg = pfs.port_pin(port_num, pin_num);
298
299 match output_mode {
300 OutputMode::PushPull => pfs_reg.protected_modify(|r| r.set_ncodr(OutputType::Cmos)),
301 OutputMode::OpenDrain => pfs_reg.protected_modify(|r| r.set_ncodr(OutputType::Nmos)),
302 }
303 }
304
305 fn set_pull_up(&self, pull_up: bool) {
306 let pfs = pac::PFS;
307 let port_num = self._port() as _;
308 let pin_num = self._pin() as _;
309 let pfs_reg = pfs.port_pin(port_num, pin_num);
310
311 trace!("P{}{:02}: set_pull_up({})", port_num, pin_num, pull_up);
312
313 pfs_reg.protected_modify(|r| r.set_pcr(pull_up));
322
323 #[cfg(feature = "strict-assert")]
324 assert_eq!(pfs_reg.read().pcr(), pull_up, "set_pull_up failed");
325
326 trace!("P{}{:02}: {}", port_num, pin_num, pfs_reg.read());
327 }
328
329 #[inline(always)]
331 fn set_high(&self) {
332 let port = self.regs();
333 port.pcntr3().write(|r| r.set_posr(self._pin() as _, true));
334 }
335
336 #[inline(always)]
338 fn set_low(&self) {
339 let port = self.regs();
340 port.pcntr3().write(|r| r.set_porr(self._pin() as _, true));
341 }
342
343 #[inline]
345 fn is_high(&self) -> bool {
346 let port = self.regs();
347 port.pcntr2().read().pidr(self._pin() as _)
348 }
349
350 #[inline]
352 fn is_low(&self) -> bool {
353 !self.is_high()
354 }
355
356 #[inline]
358 fn level(&self) -> Level {
359 let port = self.regs();
360
361 match port.pcntr2().read().pidr(self._pin() as _) {
362 false => Level::Low,
363 true => Level::High,
364 }
365 }
366
367 #[inline(always)]
369 fn set_level(&self, level: Level) {
370 match level {
371 Level::Low => self.set_low(),
372 Level::High => self.set_high(),
373 }
374 }
375
376 #[inline(always)]
378 fn is_set_low(&self) -> bool {
379 !self.is_set_high()
380 }
381
382 #[inline(always)]
384 fn is_set_high(&self) -> bool {
385 let port = self.regs();
386 port.pcntr1().read().podr(self._pin() as _)
387 }
388
389 #[inline]
391 fn output_level(&self) -> Level {
392 match self.is_set_high() {
393 true => Level::High,
394 false => Level::Low,
395 }
396 }
397
398 #[inline(always)]
400 fn toggle(&self) {
401 match self.is_set_high() {
402 true => self.set_low(),
403 false => self.set_high(),
404 }
405 }
406
407 #[inline]
408 fn set_as_output(&self) {
409 let pfs = pac::PFS;
419 let port_num = self._port() as _;
420 let pin_num = self._pin() as _;
421 let pfs_reg = pfs.port_pin(port_num, pin_num);
422
423 trace!("P{}{:02}: → Output", port_num, pin_num);
424
425 pfs_reg.protected_modify(|r| {
432 r.set_pmr(PortMode::Gpio);
433 r.set_pdr(PortDirection::Output);
434 r.set_pcr(false);
435 });
436
437 #[cfg(feature = "strict-assert")]
438 {
439 let status = pfs_reg.read();
440 assert_eq!(status.pmr(), PortMode::Gpio);
441 assert_eq!(status.pdr(), PortDirection::Output);
442 assert_eq!(status.pcr(), false);
443 }
444 }
445
446 #[inline]
447 fn set_as_input(&self) {
448 let pfs = pac::PFS;
449 let port_num = self._port() as _;
450 let pin_num = self._pin() as _;
451 let pfs_reg = pfs.port_pin(port_num, pin_num);
452
453 trace!("P{}{:02}: → Input", port_num, pin_num);
454
455 pfs_reg.protected_modify(|r| {
462 r.set_pmr(PortMode::Gpio);
463 r.set_pdr(PortDirection::Input);
464 });
465
466 #[cfg(feature = "strict-assert")]
467 {
468 let status = pfs_reg.read();
469 assert_eq!(status.pmr(), PortMode::Gpio);
470 assert_eq!(status.pdr(), PortDirection::Input);
471 }
472 }
473
474 fn set_as_analog(&self) {
476 let pfs = pac::PFS;
477
478 let port_num = self._port() as _;
479 let pin_num = self._pin() as _;
480 let pfs_reg = pfs.port_pin(port_num, pin_num);
481
482 pfs_reg.protected_modify(|r| {
483 r.set_pdr(PortDirection::Input);
484 r.set_asel(true);
485 r.set_pcr(false);
486 });
487
488 #[cfg(feature = "strict-assert")]
489 {
490 let status = pfs_reg.read();
491 assert_eq!(status.pdr(), PortDirection::Input);
492 assert_eq!(status.asel(), true);
493 assert_eq!(status.pcr(), false);
494 }
495 }
496
497 fn set_as_pf(&self, port_func: PortFunction) {
498 let port_num = self._port() as _;
499 let pin_num = self._pin() as _;
500
501 let pfs = crate::pac::PFS;
502
503 let pfs_reg = pfs.port_pin(port_num, pin_num);
504
505 pfs_reg.protected_modify(|r| r.set_pmr(PortMode::Gpio));
507
508 pfs_reg.protected_modify(|r| {
509 r.set_pmr(PortMode::Peripheral);
510 r.set_psel(port_func.into());
511 });
512
513 debug!("P{}{:02}: {}", port_num, pin_num, pfs_reg.read());
514
515 #[cfg(feature = "strict-assert")]
516 {
517 let status = pfs_reg.read();
518 assert_eq!(status.pmr(), PortMode::Peripheral, "PMR was ignored");
519 assert_eq!(status.psel(), port_func.into(), "PSEL was ignored");
520 }
521 }
522
523 fn regs(&self) -> crate::pac::port::Port;
525}
526
527#[allow(private_bounds)]
529pub trait Pin: PeripheralType + Into<AnyPin> + SealedPin + Sized + 'static {
530 #[inline]
534 fn pin(&self) -> u8 {
535 self._pin()
536 }
537
538 #[inline]
540 fn port(&self) -> u8 {
541 self._port()
542 }
543
544 #[inline]
546 fn pin_port(&self) -> PinId {
547 SealedPin::pin_port(self)
548 }
549}
550
551#[allow(private_bounds)]
556pub trait PullUpPin: SealedPullUpPin {}
557
558pub(crate) trait SealedPullUpPin: Pin {}
559
560#[allow(private_bounds)]
565pub trait OpenDrainPin: SealedOpenDrainPin {}
566
567pub(crate) trait SealedOpenDrainPin: Pin {}
568
569#[allow(private_bounds)]
571pub trait InterruptiblePin: SealedIntPin + Pin {}
572
573pub(crate) trait SealedIntPin {
574 const INTERRUPT_EVENT: InterruptEvent;
575
576 fn waker() -> &'static AtomicWaker;
577}
578
579impl From<PortFunction> for pac::pfs::vals::PortFunction {
580 fn from(value: PortFunction) -> Self {
581 Self::from_bits(value as u8)
582 }
583}
584
585impl From<bool> for Level {
586 fn from(value: bool) -> Self {
587 match value {
588 false => Self::Low,
589 true => Self::High,
590 }
591 }
592}
593
594impl Pin for AnyPin {}
595
596impl SealedPin for AnyPin {
597 #[inline(always)]
598 fn pin_port(&self) -> PinId {
599 self.pin_port
600 }
601
602 #[inline(always)]
603 fn regs(&self) -> crate::pac::port::Port {
604 let port_ptr = crate::pac::PORT0.as_ptr() as usize;
608 let offset = 0x20 * self._port() as usize;
609 unsafe { crate::pac::port::Port::from_ptr(port_ptr.wrapping_add(offset) as _) }
610 }
611}
612
613impl AnyPin {
614 #[inline]
621 pub unsafe fn steal(pin_port: PinId) -> Peri<'static, Self> {
622 unsafe { Peri::new_unchecked(Self { pin_port }) }
623 }
624
625 #[cfg(feature = "unstable-pac")]
627 #[inline]
628 pub fn block(&self) -> crate::pac::port::Port {
629 SealedPin::regs(self)
630 }
631}
632
633impl<'d> Input<'d, Basic> {
634 pub fn new_basic(pin: Peri<'d, impl Pin>) -> Self {
639 Self::new(pin)
640 }
641}
642
643impl<'d> Input<'d, WithPullUp> {
644 #[inline]
650 pub fn new_with_pull_up(pin: Peri<'d, impl Pin>, pull_up: bool) -> Self {
651 let mut this = Self::new(pin);
652
653 this.set_pull_up(pull_up);
654
655 this
656 }
657
658 pub fn set_pull_up(&mut self, pull_up: bool) {
664 self.pin.set_pull_up(pull_up);
665 }
666}
667
668impl<'d, C: ControlKind> Input<'d, C> {
669 #[inline]
674 pub fn new(pin: Peri<'d, impl Pin>) -> Self {
675 let mut pin = Flex::new(pin);
676
677 pin.set_as_input();
678
679 Self { pin }
680 }
681
682 #[inline]
684 pub fn is_low(&mut self) -> bool {
685 self.pin.is_low()
686 }
687
688 #[inline]
690 pub fn is_high(&mut self) -> bool {
691 self.pin.is_high()
692 }
693
694 #[inline]
696 pub fn level(&mut self) -> Level {
697 self.pin.level()
698 }
699}
700
701impl<'d> Output<'d, Basic> {
702 pub fn new_basic(
709 pin: Peri<'d, impl Pin>,
710 initial: Level,
711 #[cfg(any(pfs_ra8, pfs_port_drive))] drive_capacity: DriveCapacity,
712 ) -> Self {
713 Self::new(
714 pin,
715 initial,
716 #[cfg(any(pfs_ra8, pfs_port_drive))]
717 drive_capacity,
718 )
719 }
720}
721
722impl<'d> Output<'d, WithOpenDrain> {
723 #[inline]
730 pub fn new_with_open_drain(
731 pin: Peri<'d, impl Pin>,
732 initial: Level,
733 #[cfg(any(pfs_ra8, pfs_port_drive))] drive_capacity: DriveCapacity,
734 output_mode: OutputMode,
735 ) -> Self {
736 let mut this = Self::new(
737 pin,
738 initial,
739 #[cfg(any(pfs_ra8, pfs_port_drive))]
740 drive_capacity,
741 );
742
743 this.set_output_mode(output_mode);
744
745 this
746 }
747
748 #[inline]
750 pub fn set_output_mode(&mut self, output_mode: OutputMode) {
751 self.pin.set_output_mode(output_mode);
752 }
753}
754
755impl<'d, C: ControlKind> Output<'d, C> {
756 #[inline]
763 pub(crate) fn new(
764 pin: Peri<'d, impl Pin>,
765 initial: Level,
766 #[cfg(any(pfs_ra8, pfs_port_drive))] drive_capacity: DriveCapacity,
767 ) -> Self {
768 let mut this = Flex::new(pin);
769
770 this.set_as_output();
771 this.set_level(initial);
772 #[cfg(any(pfs_ra8, pfs_port_drive))]
773 this.set_drive_capacity(drive_capacity);
774
775 Self { pin: this }
776 }
777
778 #[inline]
784 #[cfg(any(pfs_ra8, pfs_port_drive))]
785 pub fn set_drive_capacity(&mut self, drive_capacity: DriveCapacity) {
786 self.pin.set_drive_capacity(drive_capacity)
787 }
788
789 #[inline(always)]
791 pub fn set_low(&mut self) {
792 self.pin.set_low();
793 }
794
795 #[inline(always)]
797 pub fn set_high(&mut self) {
798 self.pin.set_high();
799 }
800
801 #[inline(always)]
803 pub fn set_level(&mut self, level: Level) {
804 self.pin.set_level(level)
805 }
806
807 #[inline(always)]
809 pub fn toggle(&mut self) {
810 self.pin.toggle();
811 }
812
813 #[inline]
815 pub fn is_set_low(&mut self) -> bool {
816 self.pin.is_set_low()
817 }
818
819 #[inline]
821 pub fn is_set_high(&mut self) -> bool {
822 self.pin.is_set_high()
823 }
824
825 #[inline]
827 pub fn output_level(&mut self) -> Level {
828 self.pin.output_level()
829 }
830
831 #[inline]
833 pub fn print_pfs_state(&self) {
834 self.pin.print_pfs_state();
835 }
836}
837
838impl<'d> Flex<'d, WithPullUp> {
839 #[inline]
841 pub fn new_with_pull_up(pin: Peri<'d, impl PullUpPin>, pull_up: bool) -> Self {
842 let mut this = Self {
843 pin: pin.into(),
844 phantom: PhantomData,
845 };
846
847 this.set_pull_up(pull_up);
848
849 trace!(
850 "Flex<WithPullUp>: port={}, pin={}",
851 this.pin._port(),
852 this.pin._pin()
853 );
854
855 this
856 }
857
858 pub fn set_pull_up(&mut self, pull_up: bool) {
864 self.pin.set_pull_up(pull_up);
865 }
866}
867
868impl<'d> Flex<'d, WithOpenDrain> {
869 #[inline]
871 pub fn new_with_open_drain(
872 pin: Peri<'d, impl OpenDrainPin>,
873 pull_up: bool,
874 output_mode: OutputMode,
875 ) -> Self {
876 let mut this = Self {
877 pin: pin.into(),
878 phantom: PhantomData,
879 };
880
881 this.set_pull_up(pull_up);
882 this.set_output_mode(output_mode);
883
884 trace!(
885 "Flex<OpenDrain>: port={}, pin={}",
886 this.pin._port(),
887 this.pin._pin()
888 );
889
890 this
891 }
892
893 #[inline]
899 pub fn set_pull_up(&mut self, pull_up: bool) {
900 self.pin.set_pull_up(pull_up);
901 }
902
903 #[inline]
905 pub fn set_output_mode(&mut self, output_mode: OutputMode) {
906 self.pin.set_output_mode(output_mode);
907 }
908}
909
910impl<'d> Flex<'d, Basic> {
911 #[inline]
913 pub fn new_basic(pin: Peri<'d, impl Pin>) -> Self {
914 let this = Self {
915 pin: pin.into(),
916 phantom: PhantomData,
917 };
918
919 trace!(
920 "Flex<Basic>: port={}, pin={}",
921 this.pin._port(),
922 this.pin._pin()
923 );
924
925 this
926 }
927}
928
929impl<'d, C: ControlKind> Flex<'d, C> {
930 #[inline]
932 pub(crate) fn new(pin: Peri<'d, impl Pin>) -> Self {
933 let this = Self {
934 pin: pin.into(),
935 phantom: PhantomData,
936 };
937
938 trace!(
939 "Flex<Basic>: port={}, pin={}",
940 this.pin._port(),
941 this.pin._pin()
942 );
943
944 this
945 }
946
947 #[inline]
949 pub fn set_as_input(&mut self) {
950 self.pin.set_as_input();
951 }
952
953 #[inline]
955 pub fn is_low(&mut self) -> bool {
956 self.pin.is_low()
957 }
958
959 #[inline]
961 pub fn is_high(&mut self) -> bool {
962 self.pin.is_high()
963 }
964
965 #[inline]
967 pub fn level(&mut self) -> Level {
968 self.pin.level()
969 }
970
971 #[inline]
973 pub fn set_as_output(&mut self) {
974 self.pin.set_as_output();
975 }
976
977 #[inline]
981 #[cfg(any(pfs_ra8, pfs_port_drive))]
982 pub fn set_drive_capacity(&mut self, drive_capacity: DriveCapacity) {
983 self.pin.set_drive_capacity(drive_capacity)
984 }
985
986 #[inline(always)]
988 pub fn set_low(&mut self) {
989 self.pin.set_low();
990 }
991
992 #[inline(always)]
994 pub fn set_high(&mut self) {
995 self.pin.set_high();
996 }
997
998 #[inline(always)]
1000 pub fn set_level(&mut self, level: Level) {
1001 self.pin.set_level(level)
1002 }
1003
1004 #[inline(always)]
1006 pub fn toggle(&mut self) {
1007 self.pin.toggle();
1008 }
1009
1010 #[inline]
1012 pub fn is_set_low(&mut self) -> bool {
1013 self.pin.is_set_low()
1014 }
1015
1016 #[inline]
1018 pub fn is_set_high(&mut self) -> bool {
1019 self.pin.is_set_high()
1020 }
1021
1022 #[inline]
1024 pub fn output_level(&mut self) -> Level {
1025 self.pin.output_level()
1026 }
1027
1028 pub fn set_as_analog(&mut self) {
1030 self.pin.set_as_analog();
1031 }
1032
1033 pub fn set_as_pf(&mut self, func: PortFunction) {
1035 self.pin.set_as_pf(func);
1036 }
1037
1038 pub fn print_pfs_state(&self) {
1040 #[cfg(feature = "defmt")]
1041 {
1042 let pfs = pac::PFS;
1043 let port_num = self.pin._port() as _;
1044 let pin_num = self.pin._pin() as _;
1045
1046 let pfs_reg = pfs.port_pin(port_num, pin_num);
1048 debug!("P{}{:02}: {}", port_num, pin_num, pfs_reg.read());
1049 }
1050 }
1051}
1052
1053impl<'d, C: ControlKind> Drop for Flex<'d, C> {
1054 fn drop(&mut self) {
1055 trace!("P{}{:02} Flex::drop", self.pin.port(), self.pin._pin());
1056 self.set_as_input();
1057 self.pin.set_pull_up(false);
1058 }
1059}
1060
1061impl<'d, I: InterruptiblePin> InterruptFlex<'d, I, WithPullUp> {
1062 pub fn set_pull_up(&mut self, pull_up: bool) {
1067 self.pin.set_pull_up(pull_up);
1068 }
1069}
1070
1071impl<'d, I: InterruptiblePin, C: ControlKind> InterruptFlex<'d, I, C> {
1072 #[inline]
1074 pub fn new<Int: InterruptType>(
1075 pin: Peri<'d, I>,
1076 gpio_irq: Peri<'d, impl GpioIrq<I>>,
1077 irq: impl interrupt::typelevel::Binding<Int, InputInterruptHandler<I>>,
1078 ) -> Self {
1079 let _ = gpio_irq;
1080 let _ = irq;
1081
1082 unsafe {
1084 Int::IRQ.enable();
1085 Int::IRQ.icu_enable(I::INTERRUPT_EVENT);
1086 }
1087
1088 let pfs = pac::PFS;
1089 let pin = Flex::new(pin);
1090
1091 let port_num = pin.pin._port() as _;
1092 let pin_num = pin.pin._pin() as _;
1093 let pfs_reg = pfs.port_pin(port_num, pin_num);
1094
1095 pfs_reg.protected_modify(|r| r.set_isel(true));
1096
1097 let mut this = Self {
1098 pin,
1099 phantom: PhantomData,
1100 phantom_k: PhantomData,
1101 };
1102
1103 this.set_as_input();
1104 this.set_trigger(GpioTrigger::Falling);
1105 this.set_debounce(Debounce::Off);
1106
1107 this
1108 }
1109
1110 pub fn set_trigger(&mut self, trigger: GpioTrigger) {
1121 #[cfg(not(ra8m1))]
1122 let icu = pac::ICU;
1123 #[cfg(ra8m1)]
1124 let icu = pac::ICU_COMMON;
1125
1126 let reg = icu.irqcr((I::INTERRUPT_EVENT as u8 - 1) as _);
1128
1129 match trigger {
1130 GpioTrigger::Falling => reg.modify(|r| r.set_irqmd(Irqmd::FallingEdge)),
1131 GpioTrigger::Rising => reg.modify(|r| r.set_irqmd(Irqmd::RisingEdge)),
1132 GpioTrigger::Both => reg.modify(|r| r.set_irqmd(Irqmd::AnyEdge)),
1133 }
1134 }
1135
1136 pub fn set_debounce(&mut self, debounce: Debounce) {
1140 #[cfg(not(ra8m1))]
1141 let icu = pac::ICU;
1142 #[cfg(ra8m1)]
1143 let icu = pac::ICU_COMMON;
1144
1145 let reg = icu.irqcr((I::INTERRUPT_EVENT as u8 - 1) as _);
1147
1148 match debounce {
1149 Debounce::Off => reg.modify(|r| r.set_flten(false)),
1150 Debounce::Min1 => {
1151 reg.modify(|r| {
1152 r.set_flten(true);
1153 r.set_fclksel(Fclksel::Pclkb1);
1154 });
1155 }
1156 Debounce::Min8 => {
1157 reg.modify(|r| {
1158 r.set_flten(true);
1159 r.set_fclksel(Fclksel::Pclkb8);
1160 });
1161 }
1162 Debounce::Min32 => {
1163 reg.modify(|r| {
1164 r.set_flten(true);
1165 r.set_fclksel(Fclksel::Pclkb32);
1166 });
1167 }
1168 Debounce::Min64 => {
1169 reg.modify(|r| {
1170 r.set_flten(true);
1171 r.set_fclksel(Fclksel::Pclkb64);
1172 });
1173 }
1174 }
1175 }
1176
1177 #[inline]
1182 pub fn set_as_input(&mut self) {
1183 self.pin.set_as_input();
1184 }
1185
1186 pub async fn wait_for_low(&mut self) {
1193 poll_fn(|cx| {
1194 if self.pin.is_low() {
1195 return Poll::Ready(());
1196 }
1197 I::waker().register(cx.waker());
1198 Poll::Pending
1199 })
1200 .await
1201 }
1202
1203 pub async fn wait_for_high(&mut self) {
1210 poll_fn(|cx| {
1211 if self.pin.is_high() {
1212 return Poll::Ready(());
1213 }
1214 I::waker().register(cx.waker());
1215 Poll::Pending
1216 })
1217 .await
1218 }
1219
1220 pub async fn wait_for_event(&mut self) -> Level {
1223 let mut event = false;
1224 poll_fn(|cx| {
1225 if !event {
1226 event = true;
1227 I::waker().register(cx.waker());
1228 Poll::Pending
1229 } else {
1230 Poll::Ready(self.pin.level())
1231 }
1232 })
1233 .await
1234 }
1235
1236 #[inline]
1238 pub fn is_low(&mut self) -> bool {
1239 self.pin.is_low()
1240 }
1241
1242 #[inline]
1244 pub fn is_high(&mut self) -> bool {
1245 self.pin.is_high()
1246 }
1247
1248 #[inline]
1250 pub fn level(&mut self) -> Level {
1251 self.pin.level()
1252 }
1253
1254 #[inline]
1256 pub fn set_as_output(&mut self) {
1257 self.pin.set_as_output();
1258 }
1259
1260 #[inline]
1264 #[cfg(any(pfs_ra8, pfs_port_drive))]
1265 pub fn set_drive_capacity(&mut self, drive_capacity: DriveCapacity) {
1266 self.pin.set_drive_capacity(drive_capacity)
1267 }
1268
1269 #[inline]
1271 pub fn set_low(&mut self) {
1272 self.pin.set_low();
1273 }
1274
1275 #[inline]
1277 pub fn set_high(&mut self) {
1278 self.pin.set_high();
1279 }
1280
1281 #[inline]
1283 pub fn set_level(&mut self, level: Level) {
1284 self.pin.set_level(level)
1285 }
1286
1287 #[inline]
1289 pub fn toggle(&mut self) {
1290 self.pin.toggle();
1291 }
1292
1293 #[inline]
1295 pub fn is_set_low(&mut self) -> bool {
1296 self.pin.is_set_low()
1297 }
1298
1299 #[inline]
1301 pub fn is_set_high(&mut self) -> bool {
1302 self.pin.is_set_high()
1303 }
1304
1305 #[inline]
1307 pub fn output_level(&mut self) -> Level {
1308 self.pin.output_level()
1309 }
1310
1311 pub fn set_as_pf(&mut self, func: PortFunction) {
1313 self.pin.set_as_pf(func);
1314 }
1315
1316 pub fn print_pfs_state(&self) {
1318 self.pin.print_pfs_state();
1319 }
1320}
1321
1322macro_rules! gpio_pin {
1323 ($pin_name:ident, $port_number:literal, $pin_number:literal, $port:ident) => {
1324 impl crate::gpio::Pin for crate::peripherals::$pin_name {}
1325
1326 impl crate::gpio::SealedPin for crate::peripherals::$pin_name {
1327 #[inline(always)]
1328 fn pin_port(&self) -> crate::gpio::PinId {
1329 crate::gpio::PinId::from_port_pin($port_number, $pin_number)
1330 }
1331
1332 #[inline(always)]
1333 fn regs(&self) -> crate::pac::port::Port {
1334 unsafe { crate::pac::port::Port::from_ptr(crate::pac::$port.as_ptr() as _) }
1337 }
1338 }
1339
1340 impl From<crate::peripherals::$pin_name> for crate::gpio::AnyPin {
1341 fn from(val: crate::peripherals::$pin_name) -> Self {
1342 use crate::gpio::SealedPin as _;
1343 Self {
1344 pin_port: val.pin_port(),
1345 }
1346 }
1347 }
1348 };
1349}
1350pub(crate) use gpio_pin;
1351
1352impl_peripheral!(AnyPin);
1353
1354impl<Pin: InterruptiblePin, Int: InterruptType> InterruptHandler<Int>
1355 for InputInterruptHandler<Pin>
1356{
1357 unsafe fn on_interrupt() {
1358 Int::IRQ.icu_unpend();
1359 Pin::waker().wake()
1360 }
1361}
1362
1363impl<'d, C: ControlKind> embedded_hal_1::digital::ErrorType for Input<'d, C> {
1364 type Error = Infallible;
1365}
1366
1367impl<'d, C: ControlKind> embedded_hal_1::digital::InputPin for Input<'d, C> {
1368 fn is_high(&mut self) -> Result<bool, Self::Error> {
1369 Ok(self.is_high())
1370 }
1371
1372 fn is_low(&mut self) -> Result<bool, Self::Error> {
1373 Ok(self.is_low())
1374 }
1375}
1376
1377impl<'d, C: ControlKind> embedded_hal_1::digital::ErrorType for Output<'d, C> {
1378 type Error = Infallible;
1379}
1380
1381impl<'d, C: ControlKind> embedded_hal_1::digital::OutputPin for Output<'d, C> {
1382 fn set_low(&mut self) -> Result<(), Self::Error> {
1383 self.set_low();
1384 Ok(())
1385 }
1386
1387 fn set_high(&mut self) -> Result<(), Self::Error> {
1388 self.set_high();
1389 Ok(())
1390 }
1391}
1392
1393impl<'d, C: ControlKind> embedded_hal_1::digital::StatefulOutputPin for Output<'d, C> {
1394 fn is_set_high(&mut self) -> Result<bool, Self::Error> {
1395 Ok(self.is_set_high())
1396 }
1397
1398 fn is_set_low(&mut self) -> Result<bool, Self::Error> {
1399 Ok(self.is_set_low())
1400 }
1401
1402 fn toggle(&mut self) -> Result<(), Self::Error> {
1403 self.toggle();
1404 Ok(())
1405 }
1406}