1extern crate alloc;
8
9use paste::paste;
10
11use core::convert::Infallible;
12use core::future::Future;
13use core::task::{Context, Poll, Waker};
14
15use crate::Peripheral;
16use crate::pac;
17
18const MSS_GPIO_INTERRUPT_COUNT: usize = 38;
19unsafe fn base_init() {
20 unsafe {
21 pac::MSS_GPIO_init(pac::GPIO0_LO);
22 pac::MSS_GPIO_init(pac::GPIO1_LO);
23 pac::MSS_GPIO_init(pac::GPIO2_LO);
24 (*pac::SYSREG).GPIO_INTERRUPT_FAB_CR = 0x0;
27
28 for i in 0..MSS_GPIO_INTERRUPT_COUNT {
29 pac::PLIC_SetPriority(
30 pac::PLIC_IRQn_Type_PLIC_GPIO0_BIT0_or_GPIO2_BIT0_INT_OFFSET + i as u32,
31 2,
32 );
33 }
34 for i in
35 pac::PLIC_IRQn_Type_PLIC_F2M_0_INT_OFFSET..=pac::PLIC_IRQn_Type_PLIC_F2M_63_INT_OFFSET
36 {
37 pac::PLIC_SetPriority(i, 2);
38 }
39 }
40}
41
42#[derive(Default, Debug)]
47struct GpioInterruptData {
48 waker: Option<Waker>,
49 triggered: bool,
50}
51
52const NUM_INTERRUPTS: usize = 38 + 64; static mut GPIO_INTERRUPTS: [GpioInterruptData; NUM_INTERRUPTS] = [const {
54 GpioInterruptData {
55 waker: None,
56 triggered: false,
57 }
58}; NUM_INTERRUPTS];
59
60#[repr(u8)]
61#[derive(Default, Copy, Clone, Debug, PartialEq)]
62#[doc(hidden)]
63pub enum InterruptTrigger {
64 #[default]
65 LevelHigh = pac::GPIO_IRQ_LEVEL_HIGH as u8,
66 LevelLow = pac::GPIO_IRQ_LEVEL_LOW as u8,
67 EdgePositive = pac::GPIO_IRQ_EDGE_POSITIVE as u8,
68 EdgeNegative = pac::GPIO_IRQ_EDGE_NEGATIVE as u8,
69 EdgeBoth = pac::GPIO_IRQ_EDGE_BOTH as u8,
70}
71
72#[doc(hidden)]
73#[derive(Debug, Clone, Copy)]
74pub struct Interrupt {
75 interrupt_idx: u8,
76 plic_idx: u8,
77}
78
79impl Interrupt {
80 pub const NONE: Self = Self {
81 interrupt_idx: 255,
82 plic_idx: 255,
83 };
84
85 unsafe fn triggered(&self) -> bool {
86 unsafe { GPIO_INTERRUPTS[self.interrupt_idx as usize].triggered }
87 }
88
89 unsafe fn set_waker(&mut self, waker: Waker) {
90 unsafe {
91 GPIO_INTERRUPTS[self.interrupt_idx as usize].waker = Some(waker);
92 }
93 }
94
95 fn is_none(&self) -> bool {
96 self.interrupt_idx == 255 && self.plic_idx == 255
97 }
98}
99
100pub trait GpioInterrupt: 'static {
101 #[doc(hidden)]
102 fn address(&self) -> Interrupt;
103}
104
105macro_rules! impl_gpio_interrupt {
106 ($interrupt:ident, $interrupt_idx:expr, $interrupt_handler:ident, $plic_idx:expr) => {
107 paste! {
108 impl_gpio_interrupt!($interrupt, [<$interrupt _TAKEN>], $interrupt_idx, $interrupt_handler, $plic_idx);
109 }
110 };
111
112 ($interrupt:ident, $interrupt_idx:expr, $interrupt_handler:ident) => {
113 impl_gpio_interrupt!($interrupt, $interrupt_idx, $interrupt_handler, 255);
114 };
115
116 ($INTERRUPT:ident, $INTERRUPT_TAKEN:ident, $interrupt_idx:expr, $interrupt_handler:ident, $plic_idx:expr) => {
117 #[allow(non_camel_case_types)]
118 pub struct $INTERRUPT {
119 _private: (),
120 }
121 static mut $INTERRUPT_TAKEN: bool = false;
122
123 impl crate::Peripheral for $INTERRUPT {
124 fn take() -> Option<Self> {
125 critical_section::with(|_| unsafe {
126 if $INTERRUPT_TAKEN {
127 None
128 } else {
129 $INTERRUPT_TAKEN = true;
130 Some(Self { _private: () })
131 }
132 })
133 }
134
135 unsafe fn steal() -> Self {
136 Self { _private: () }
137 }
138 }
139
140 impl GpioInterrupt for $INTERRUPT {
141 fn address(&self) -> Interrupt {
142 Interrupt {
143 interrupt_idx: $interrupt_idx,
144 plic_idx: $plic_idx as u8,
145 }
146 }
147 }
148
149 #[unsafe(no_mangle)]
150 extern "C" fn $interrupt_handler() -> u8 {
151 let interrupt = unsafe { &mut GPIO_INTERRUPTS[$interrupt_idx] };
152 trace!("GPIO interrupt {} triggered: {:?}", $interrupt_idx, interrupt);
153 if let Some(waker) = interrupt.waker.take() {
154 interrupt.triggered = true;
155 waker.wake();
156 }
157 pac::EXT_IRQ_DISABLE as u8
158 }
159 };
160}
161
162impl_gpio_interrupt!(
163 GPIO0_0_OR_GPIO2_0_INT,
164 0,
165 PLIC_gpio0_bit0_or_gpio2_bit13_IRQHandler
168);
169impl_gpio_interrupt!(
170 GPIO0_1_OR_GPIO2_1_INT,
171 1,
172 PLIC_gpio0_bit1_or_gpio2_bit13_IRQHandler
173);
174impl_gpio_interrupt!(
175 GPIO0_2_OR_GPIO2_2_INT,
176 2,
177 PLIC_gpio0_bit2_or_gpio2_bit13_IRQHandler
178);
179impl_gpio_interrupt!(
180 GPIO0_3_OR_GPIO2_3_INT,
181 3,
182 PLIC_gpio0_bit3_or_gpio2_bit13_IRQHandler
183);
184impl_gpio_interrupt!(
185 GPIO0_4_OR_GPIO2_4_INT,
186 4,
187 PLIC_gpio0_bit4_or_gpio2_bit13_IRQHandler
188);
189impl_gpio_interrupt!(
190 GPIO0_5_OR_GPIO2_5_INT,
191 5,
192 PLIC_gpio0_bit5_or_gpio2_bit13_IRQHandler
193);
194impl_gpio_interrupt!(
195 GPIO0_6_OR_GPIO2_6_INT,
196 6,
197 PLIC_gpio0_bit6_or_gpio2_bit13_IRQHandler
198);
199impl_gpio_interrupt!(
200 GPIO0_7_OR_GPIO2_7_INT,
201 7,
202 PLIC_gpio0_bit7_or_gpio2_bit13_IRQHandler
203);
204impl_gpio_interrupt!(
205 GPIO0_8_OR_GPIO2_8_INT,
206 8,
207 PLIC_gpio0_bit8_or_gpio2_bit13_IRQHandler
208);
209impl_gpio_interrupt!(
210 GPIO0_9_OR_GPIO2_9_INT,
211 9,
212 PLIC_gpio0_bit9_or_gpio2_bit13_IRQHandler
213);
214impl_gpio_interrupt!(
215 GPIO0_10_OR_GPIO2_10_INT,
216 10,
217 PLIC_gpio0_bit10_or_gpio2_bit13_IRQHandler
218);
219impl_gpio_interrupt!(
220 GPIO0_11_OR_GPIO2_11_INT,
221 11,
222 PLIC_gpio0_bit11_or_gpio2_bit13_IRQHandler
223);
224impl_gpio_interrupt!(
225 GPIO0_12_OR_GPIO2_12_INT,
226 12,
227 PLIC_gpio0_bit12_or_gpio2_bit13_IRQHandler
228);
229impl_gpio_interrupt!(
230 GPIO0_13_OR_GPIO2_13_INT,
231 13,
232 PLIC_gpio0_bit13_or_gpio2_bit13_IRQHandler
233);
234impl_gpio_interrupt!(
235 GPIO1_0_OR_GPIO2_14_INT,
236 14,
237 PLIC_gpio1_bit0_or_gpio2_bit14_IRQHandler
238);
239impl_gpio_interrupt!(
240 GPIO1_1_OR_GPIO2_15_INT,
241 15,
242 PLIC_gpio1_bit1_or_gpio2_bit15_IRQHandler
243);
244impl_gpio_interrupt!(
245 GPIO1_2_OR_GPIO2_16_INT,
246 16,
247 PLIC_gpio1_bit2_or_gpio2_bit16_IRQHandler
248);
249impl_gpio_interrupt!(
250 GPIO1_3_OR_GPIO2_17_INT,
251 17,
252 PLIC_gpio1_bit3_or_gpio2_bit17_IRQHandler
253);
254impl_gpio_interrupt!(
255 GPIO1_4_OR_GPIO2_18_INT,
256 18,
257 PLIC_gpio1_bit4_or_gpio2_bit18_IRQHandler
258);
259impl_gpio_interrupt!(
260 GPIO1_5_OR_GPIO2_19_INT,
261 19,
262 PLIC_gpio1_bit5_or_gpio2_bit19_IRQHandler
263);
264impl_gpio_interrupt!(
265 GPIO1_6_OR_GPIO2_20_INT,
266 20,
267 PLIC_gpio1_bit6_or_gpio2_bit20_IRQHandler
268);
269impl_gpio_interrupt!(
270 GPIO1_7_OR_GPIO2_21_INT,
271 21,
272 PLIC_gpio1_bit7_or_gpio2_bit21_IRQHandler
273);
274impl_gpio_interrupt!(
275 GPIO1_8_OR_GPIO2_22_INT,
276 22,
277 PLIC_gpio1_bit8_or_gpio2_bit22_IRQHandler
278);
279impl_gpio_interrupt!(
280 GPIO1_9_OR_GPIO2_23_INT,
281 23,
282 PLIC_gpio1_bit9_or_gpio2_bit23_IRQHandler
283);
284impl_gpio_interrupt!(
285 GPIO1_10_OR_GPIO2_24_INT,
286 24,
287 PLIC_gpio1_bit10_or_gpio2_bit24_IRQHandler
288);
289impl_gpio_interrupt!(
290 GPIO1_11_OR_GPIO2_25_INT,
291 25,
292 PLIC_gpio1_bit11_or_gpio2_bit25_IRQHandler
293);
294impl_gpio_interrupt!(
295 GPIO1_12_OR_GPIO2_26_INT,
296 26,
297 PLIC_gpio1_bit12_or_gpio2_bit26_IRQHandler
298);
299impl_gpio_interrupt!(
300 GPIO1_13_OR_GPIO2_27_INT,
301 27,
302 PLIC_gpio1_bit13_or_gpio2_bit27_IRQHandler
303);
304impl_gpio_interrupt!(
305 GPIO1_14_OR_GPIO2_28_INT,
306 28,
307 PLIC_gpio1_bit14_or_gpio2_bit28_IRQHandler
308);
309impl_gpio_interrupt!(
310 GPIO1_15_OR_GPIO2_29_INT,
311 29,
312 PLIC_gpio1_bit15_or_gpio2_bit29_IRQHandler
313);
314impl_gpio_interrupt!(
315 GPIO1_16_OR_GPIO2_30_INT,
316 30,
317 PLIC_gpio1_bit16_or_gpio2_bit30_IRQHandler
318);
319impl_gpio_interrupt!(
320 GPIO1_17_OR_GPIO2_31_INT,
321 31,
322 PLIC_gpio1_bit17_or_gpio2_bit31_IRQHandler
323);
324impl_gpio_interrupt!(GPIO1_18_INT, 32, PLIC_gpio1_bit18_IRQHandler);
325impl_gpio_interrupt!(GPIO1_19_INT, 33, PLIC_gpio1_bit19_IRQHandler);
326impl_gpio_interrupt!(GPIO1_20_INT, 34, PLIC_gpio1_bit20_IRQHandler);
327impl_gpio_interrupt!(GPIO1_21_INT, 35, PLIC_gpio1_bit21_IRQHandler);
328impl_gpio_interrupt!(GPIO1_22_INT, 36, PLIC_gpio1_bit22_IRQHandler);
329impl_gpio_interrupt!(GPIO1_23_INT, 37, PLIC_gpio1_bit23_IRQHandler);
330
331macro_rules! impl_f2m_interrupt {
332 ($num:expr) => {
333 paste! {
334 impl_gpio_interrupt!([<F2M_ $num _INT>], 38 + $num, [<PLIC_f2m_ $num _IRQHandler>], pac::[<PLIC_IRQn_Type_PLIC_F2M_ $num _INT_OFFSET>]);
335 }
336 };
337}
338
339impl_f2m_interrupt!(0);
340impl_f2m_interrupt!(1);
341impl_f2m_interrupt!(2);
342impl_f2m_interrupt!(3);
343impl_f2m_interrupt!(4);
344impl_f2m_interrupt!(5);
345impl_f2m_interrupt!(6);
346impl_f2m_interrupt!(7);
347impl_f2m_interrupt!(8);
348impl_f2m_interrupt!(9);
349impl_f2m_interrupt!(10);
350impl_f2m_interrupt!(11);
351impl_f2m_interrupt!(12);
352impl_f2m_interrupt!(13);
353impl_f2m_interrupt!(14);
354impl_f2m_interrupt!(15);
355impl_f2m_interrupt!(16);
356impl_f2m_interrupt!(17);
357impl_f2m_interrupt!(18);
358impl_f2m_interrupt!(19);
359impl_f2m_interrupt!(20);
360impl_f2m_interrupt!(21);
361impl_f2m_interrupt!(22);
362impl_f2m_interrupt!(23);
363impl_f2m_interrupt!(24);
364impl_f2m_interrupt!(25);
365impl_f2m_interrupt!(26);
366impl_f2m_interrupt!(27);
367impl_f2m_interrupt!(28);
368impl_f2m_interrupt!(29);
369impl_f2m_interrupt!(30);
370impl_f2m_interrupt!(31);
371impl_f2m_interrupt!(32);
372impl_f2m_interrupt!(33);
373impl_f2m_interrupt!(34);
374impl_f2m_interrupt!(35);
375impl_f2m_interrupt!(36);
376impl_f2m_interrupt!(37);
377impl_f2m_interrupt!(38);
378impl_f2m_interrupt!(39);
379impl_f2m_interrupt!(40);
380impl_f2m_interrupt!(41);
381impl_f2m_interrupt!(42);
382impl_f2m_interrupt!(43);
383impl_f2m_interrupt!(44);
384impl_f2m_interrupt!(45);
385impl_f2m_interrupt!(46);
386impl_f2m_interrupt!(47);
387impl_f2m_interrupt!(48);
388impl_f2m_interrupt!(49);
389impl_f2m_interrupt!(50);
390impl_f2m_interrupt!(51);
391impl_f2m_interrupt!(52);
392impl_f2m_interrupt!(53);
393impl_f2m_interrupt!(54);
394impl_f2m_interrupt!(55);
395impl_f2m_interrupt!(56);
396impl_f2m_interrupt!(57);
397impl_f2m_interrupt!(58);
398impl_f2m_interrupt!(59);
399impl_f2m_interrupt!(60);
400impl_f2m_interrupt!(61);
401impl_f2m_interrupt!(62);
402impl_f2m_interrupt!(63);
403
404#[derive(Debug, Clone, Copy)]
409#[allow(dead_code)]
410#[doc(hidden)]
411pub enum GpioPeripheral {
412 Mss(*mut pac::GPIO_TypeDef),
413 FpgaCore(pac::gpio_instance_t),
414}
415
416impl GpioPeripheral {
417 pub fn is_gpio2(&self) -> bool {
418 if let GpioPeripheral::Mss(gpio) = self {
419 gpio == &pac::GPIO2_LO
420 } else {
421 false
422 }
423 }
424}
425
426#[doc(hidden)]
427#[derive(Debug, Clone, Copy)]
428pub struct Pin {
429 number: u8,
430 peripheral: GpioPeripheral,
431 interrupt: Interrupt,
432}
433
434impl Pin {
435 #[doc(hidden)]
437 pub fn new(number: u8, peripheral: GpioPeripheral, interrupt: Interrupt) -> Self {
438 Self {
439 number,
440 peripheral,
441 interrupt,
442 }
443 }
444
445 #[doc(hidden)]
446 pub fn config_output(&self) {
447 unsafe {
448 match self.peripheral {
449 GpioPeripheral::Mss(typedef) => {
450 trace!("Configuring MSS GPIO {:?} to output", self);
451 pac::MSS_GPIO_config(typedef, self.number as u32, pac::MSS_GPIO_OUTPUT_MODE);
452 }
453 GpioPeripheral::FpgaCore(address) => {
454 let mut address = address;
455 trace!("Configuring FPGA Core GPIO {:?} to output", self);
456 pac::GPIO_config(&mut address, self.number as u32, pac::MSS_GPIO_OUTPUT_MODE);
457 }
458 }
459 }
460 }
461
462 #[doc(hidden)]
463 pub fn config_input(&self, config: InterruptTrigger) {
464 unsafe {
465 match self.peripheral {
466 GpioPeripheral::Mss(typedef) => {
467 trace!(
468 "Configuring MSS GPIO {:?} to input with trigger {:?}",
469 self,
470 config
471 );
472 pac::MSS_GPIO_config(
473 typedef,
474 self.number as u32,
475 pac::MSS_GPIO_INPUT_MODE | config as u32,
476 );
477 }
478 GpioPeripheral::FpgaCore(address) => {
479 let mut address = address;
480 trace!(
481 "Configuring FPGA Core GPIO {:?} to input with trigger {:?}",
482 self,
483 config
484 );
485 pac::GPIO_config(
486 &mut address,
487 self.number as u32,
488 pac::MSS_GPIO_INPUT_MODE | config as u32,
489 );
490 }
491 }
492 }
493 }
494
495 #[doc(hidden)]
496 pub fn set_high(&self) {
497 unsafe {
498 match self.peripheral {
499 GpioPeripheral::Mss(typedef) => {
500 trace!("Setting MSS GPIO {:?} to high", self);
501 pac::MSS_GPIO_set_output(typedef, self.number as u32, 1);
502 }
503 GpioPeripheral::FpgaCore(address) => {
504 let mut address = address;
505 let mut gpio_outputs = pac::GPIO_get_outputs(&mut address);
506 gpio_outputs |= 1 << self.number;
507 trace!(
508 "Setting FPGA Core GPIO {:?} to high with value {:?}",
509 self,
510 gpio_outputs
511 );
512 pac::GPIO_set_outputs(&mut address, gpio_outputs);
513 }
514 }
515 }
516 }
517
518 #[doc(hidden)]
519 pub fn set_low(&self) {
520 unsafe {
521 match self.peripheral {
522 GpioPeripheral::Mss(typedef) => {
523 trace!("Setting MSS GPIO {:?} to low", self);
524 pac::MSS_GPIO_set_output(typedef, self.number as u32, 0);
525 }
526 GpioPeripheral::FpgaCore(address) => {
527 let mut address = address;
528 let mut gpio_outputs = pac::GPIO_get_outputs(&mut address);
529 gpio_outputs &= !(1 << self.number);
530 trace!(
531 "Setting FPGA Core GPIO {:?} to low with value {:?}",
532 self,
533 gpio_outputs
534 );
535 pac::GPIO_set_outputs(&mut address, gpio_outputs);
536 }
537 }
538 }
539 }
540
541 #[doc(hidden)]
542 pub fn is_high(&self) -> bool {
543 unsafe {
544 match self.peripheral {
545 GpioPeripheral::Mss(typedef) => {
546 let inputs = (*typedef).GPIO_IN;
547 inputs & (1 << self.number) != 0
548 }
549 GpioPeripheral::FpgaCore(address) => {
550 let mut address = address;
551 let inputs = pac::GPIO_get_inputs(&mut address);
552 inputs & (1 << self.number) != 0
553 }
554 }
555 }
556 }
557
558 fn enable_interrupt(&self) {
559 unsafe {
560 match self.peripheral {
561 GpioPeripheral::Mss(typedef) => {
562 pac::MSS_GPIO_enable_irq(typedef, self.number as u32);
563 }
564 GpioPeripheral::FpgaCore(address) => {
565 let mut address = address;
566 pac::GPIO_enable_irq(&mut address, self.number as u32);
567 pac::PLIC_EnableIRQ(self.interrupt.plic_idx as u32);
568 }
569 }
570 }
571 }
572
573 fn clear_triggered(&self) {
574 critical_section::with(|_| unsafe {
575 GPIO_INTERRUPTS[self.interrupt.interrupt_idx as usize].triggered = false;
576 });
577 }
578
579 fn clear_interrupt(peripheral: GpioPeripheral, number: u8) {
580 unsafe {
581 match peripheral {
582 GpioPeripheral::Mss(addr) => {
583 pac::MSS_GPIO_clear_irq(addr, number as u32);
584 }
585 GpioPeripheral::FpgaCore(addr) => {
586 let mut address = addr;
587 pac::GPIO_clear_irq(&mut address, number as u32);
588 }
589 }
590 }
591 }
592
593 fn disable_interrupt(peripheral: GpioPeripheral, number: u8) {
594 unsafe {
595 match peripheral {
596 GpioPeripheral::Mss(addr) => {
597 pac::MSS_GPIO_disable_irq(addr, number as u32);
598 }
599 GpioPeripheral::FpgaCore(addr) => {
600 let mut address = addr;
601 pac::GPIO_disable_irq(&mut address, number as u32);
602 }
603 }
604 }
605 }
606}
607
608pub trait GpioPin: 'static {
610 #[doc(hidden)]
611 fn address(&self) -> Pin;
612}
613
614pub struct Output {
615 pub pin: Pin,
616}
617
618impl Output {
622 pub fn new<P: GpioPin>(pin: P) -> Self {
623 let address = pin.address();
624 address.config_output();
625 Self { pin: address }
626 }
627}
628
629impl embedded_hal::digital::ErrorType for Output {
630 type Error = Infallible;
631}
632
633impl embedded_hal::digital::OutputPin for Output {
634 fn set_high(&mut self) -> Result<(), Self::Error> {
635 self.pin.set_high();
636 Ok(())
637 }
638
639 fn set_low(&mut self) -> Result<(), Self::Error> {
640 self.pin.set_low();
641 Ok(())
642 }
643}
644
645pub struct Input {
649 pub pin: Pin,
650}
651
652impl Input {
653 pub fn new<P: GpioPin>(pin: P) -> Self {
654 let address = pin.address();
655 if address.interrupt.is_none() {
656 panic!(
657 "Cannot create an input pin with no interrupt: {:?}",
658 address
659 );
660 }
661 address.config_input(InterruptTrigger::default());
662 Self { pin: address }
663 }
664}
665
666impl embedded_hal::digital::ErrorType for Input {
667 type Error = core::convert::Infallible;
668}
669
670impl embedded_hal::digital::InputPin for Input {
671 fn is_high(&mut self) -> Result<bool, Self::Error> {
672 Ok(self.pin.is_high())
673 }
674
675 fn is_low(&mut self) -> Result<bool, Self::Error> {
676 Ok(!self.pin.is_high())
677 }
678}
679
680#[doc(hidden)]
684pub struct InputFuture {
685 pin: Pin,
686 trigger: InterruptTrigger,
687}
688
689impl InputFuture {
690 pub fn new(pin: Pin, interrupt_trigger: InterruptTrigger) -> Self {
691 critical_section::with(|_| unsafe {
692 GPIO_INTERRUPTS[pin.interrupt.interrupt_idx as usize].triggered = false;
693 });
694 pin.config_input(interrupt_trigger);
695 pin.enable_interrupt();
696 Self {
697 pin,
698 trigger: interrupt_trigger,
699 }
700 }
701}
702
703impl Future for InputFuture {
704 type Output = Result<(), Infallible>;
705
706 fn poll(mut self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
707 let trigger = critical_section::with(|_| unsafe {
708 self.as_mut().pin.interrupt.set_waker(cx.waker().clone());
709 self.as_mut().pin.interrupt.triggered()
710 });
711
712 if ((self.trigger == InterruptTrigger::EdgePositive
713 || self.trigger == InterruptTrigger::LevelHigh)
714 && self.as_mut().pin.is_high())
715 || ((self.trigger == InterruptTrigger::EdgeNegative
716 || self.trigger == InterruptTrigger::LevelLow)
717 && !self.as_mut().pin.is_high())
718 {
719 Poll::Ready(Ok(()))
721 } else if trigger {
722 if ((self.trigger == InterruptTrigger::EdgePositive
723 || self.trigger == InterruptTrigger::LevelHigh)
724 && !self.as_mut().pin.is_high())
725 || ((self.trigger == InterruptTrigger::EdgeNegative
726 || self.trigger == InterruptTrigger::LevelLow)
727 && self.as_mut().pin.is_high())
728 {
729 self.as_mut().pin.clear_triggered();
732 self.as_mut().pin.enable_interrupt();
733 return Poll::Pending;
734 }
735 self.as_mut().pin.clear_triggered();
736 Pin::clear_interrupt(self.as_mut().pin.peripheral, self.as_mut().pin.number);
737 Pin::disable_interrupt(self.as_mut().pin.peripheral, self.as_mut().pin.number);
738 Poll::Ready(Ok(()))
739 } else {
740 Poll::Pending
741 }
742 }
743}
744
745impl embedded_hal_async::digital::Wait for Input {
746 async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
747 if !self.pin.is_high() {
748 InputFuture::new(self.pin, InterruptTrigger::LevelHigh).await
749 } else {
750 Ok(())
751 }
752 }
753
754 async fn wait_for_low(&mut self) -> Result<(), Self::Error> {
755 if self.pin.is_high() {
756 InputFuture::new(self.pin, InterruptTrigger::LevelLow).await
757 } else {
758 Ok(())
759 }
760 }
761
762 async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> {
763 InputFuture::new(self.pin, InterruptTrigger::EdgePositive).await
764 }
765
766 async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> {
767 InputFuture::new(self.pin, InterruptTrigger::EdgeNegative).await
768 }
769
770 async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> {
771 InputFuture::new(self.pin, InterruptTrigger::EdgeBoth).await
772 }
773}
774
775#[macro_export]
780macro_rules! impl_gpio_pin {
784 ($pin:ident, $peripheral:expr, $n:expr, $interrupt:ident) => {
785 paste::paste! {
786 impl_gpio_pin!($pin, [<$pin _TAKEN>], $peripheral, $n, $interrupt);
787 }
788 };
789
790 ($PIN:ident, $PIN_TAKEN:ident, $peripheral:expr, $num:expr, NONE) => {
791 #[allow(non_camel_case_types)]
792 pub struct $PIN {
793 _private: (),
794 }
795 static mut $PIN_TAKEN: bool = false;
796
797 impl $crate::Peripheral for $PIN {
798 fn take() -> Option<Self> {
799 critical_section::with(|_| unsafe {
800 if $PIN_TAKEN {
801 None
802 } else {
803 $PIN_TAKEN = true;
804 Some(Self { _private: () })
805 }
806 })
807 }
808
809 unsafe fn steal() -> Self {
810 Self { _private: () }
811 }
812 }
813
814 impl $crate::gpio::GpioPin for $PIN {
815 fn address(&self) -> $crate::gpio::Pin {
816 $crate::gpio::Pin::new($num, $peripheral, $crate::gpio::Interrupt::NONE)
817 }
818 }
819 };
820
821 ($PIN:ident, $PIN_TAKEN:ident, $peripheral:expr, $num:expr, $interrupt:ident) => {
822 #[allow(non_camel_case_types)]
823 pub struct $PIN {
824 _private: (),
825 }
826 static mut $PIN_TAKEN: bool = false;
827
828 impl $crate::Peripheral for $PIN {
829 fn take() -> Option<Self> {
830 critical_section::with(|_| unsafe {
831 if $PIN_TAKEN {
832 None
833 } else {
834 if $interrupt::take().is_some() {
835 $PIN_TAKEN = true;
836 if $peripheral.is_gpio2() {
837 (*$crate::pac::SYSREG).GPIO_INTERRUPT_FAB_CR |= 1 << $num;
839 trace!(
840 "Enabled GPIO2 interrupt for pin {}; {:x?}",
841 $num,
842 (*$crate::pac::SYSREG).GPIO_INTERRUPT_FAB_CR
843 );
844 }
845 Some(Self { _private: () })
846 } else {
847 None
848 }
849 }
850 })
851 }
852
853 unsafe fn steal() -> Self {
854 Self { _private: () }
855 }
856 }
857
858 impl $crate::gpio::GpioPin for $PIN {
859 fn address(&self) -> $crate::gpio::Pin {
860 $crate::gpio::Pin::new($num, $peripheral, unsafe {
861 $crate::gpio::GpioInterrupt::address(&$interrupt::steal())
862 })
863 }
864 }
865 };
866}
867
868#[macro_export]
869macro_rules! impl_input_peripheral {
870 ($perif:ident, $pin:ident) => {
871 paste::paste! {
872 impl_input_peripheral!($perif, [<$perif _TAKEN>], $pin);
873 }
874 };
875
876 ($PERIF:ident, $PERIF_TAKEN:ident, $pin:ident) => {
877 #[allow(non_camel_case_types)]
878 pub struct $PERIF {
879 pub pin: $crate::gpio::Input,
880 }
881 #[allow(non_upper_case_globals)]
882 static mut $PERIF_TAKEN: bool = false;
883
884 impl $crate::Peripheral for $PERIF {
885 fn take() -> Option<Self> {
886 critical_section::with(|_| unsafe {
887 if $PERIF_TAKEN {
888 None
889 } else {
890 if $pin::take().is_some() {
891 $PERIF_TAKEN = true;
892 Some(Self {
893 pin: $crate::gpio::Input::new($pin::steal()),
894 })
895 } else {
896 None
897 }
898 }
899 })
900 }
901
902 unsafe fn steal() -> Self {
903 unsafe {
904 Self {
905 pin: $crate::gpio::Input::new($pin::steal()),
906 }
907 }
908 }
909 }
910
911 impl embedded_hal::digital::ErrorType for $PERIF {
912 type Error = core::convert::Infallible;
913 }
914
915 impl embedded_hal::digital::InputPin for $PERIF {
916 fn is_high(&mut self) -> Result<bool, Self::Error> {
917 self.pin.is_high()
918 }
919
920 fn is_low(&mut self) -> Result<bool, Self::Error> {
921 self.pin.is_low()
922 }
923 }
924
925 impl embedded_hal_async::digital::Wait for $PERIF {
926 async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
927 self.pin.wait_for_high().await
928 }
929
930 async fn wait_for_low(&mut self) -> Result<(), Self::Error> {
931 self.pin.wait_for_low().await
932 }
933
934 async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> {
935 self.pin.wait_for_rising_edge().await
936 }
937
938 async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> {
939 self.pin.wait_for_falling_edge().await
940 }
941
942 async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> {
943 self.pin.wait_for_any_edge().await
944 }
945 }
946 };
947}
948
949#[macro_export]
950macro_rules! impl_output_peripheral {
951 ($perif:ident, $pin:ident) => {
952 paste::paste! {
953 impl_output_peripheral!($perif, [<$perif _TAKEN>], $pin);
954 }
955 };
956
957 ($PERIF:ident, $PERIF_TAKEN:ident, $pin:ident) => {
958 #[allow(non_camel_case_types)]
959 pub struct $PERIF {
960 pub pin: $crate::gpio::Output,
961 }
962 #[allow(non_upper_case_globals)]
963 static mut $PERIF_TAKEN: bool = false;
964
965 impl $crate::Peripheral for $PERIF {
966 fn take() -> Option<Self> {
967 critical_section::with(|_| unsafe {
968 if $PERIF_TAKEN {
969 None
970 } else {
971 if $pin::take().is_some() {
972 $PERIF_TAKEN = true;
973 Some(Self {
974 pin: $crate::gpio::Output::new($pin::steal()),
975 })
976 } else {
977 None
978 }
979 }
980 })
981 }
982
983 unsafe fn steal() -> Self {
984 unsafe {
985 Self {
986 pin: $crate::gpio::Output::new($pin::steal()),
987 }
988 }
989 }
990 }
991
992 impl embedded_hal::digital::ErrorType for $PERIF {
993 type Error = core::convert::Infallible;
994 }
995
996 impl embedded_hal::digital::OutputPin for $PERIF {
997 fn set_low(&mut self) -> Result<(), Self::Error> {
998 self.pin.set_low()
999 }
1000
1001 fn set_high(&mut self) -> Result<(), Self::Error> {
1002 self.pin.set_high()
1003 }
1004 }
1005 };
1006}
1007
1008#[cfg(feature = "beaglev-fire")]
1013pub use beaglev_fire::*;
1014#[cfg(feature = "beaglev-fire")]
1015mod beaglev_fire {
1016 use super::*;
1017 use crate::pac;
1018
1019 use embedded_hal::digital::InputPin;
1020 use embedded_hal_async::digital::Wait;
1021 use mutually_exclusive_features::exactly_one_of;
1022
1023 exactly_one_of!(
1024 "beaglev-fire-default-cape",
1025 "beaglev-fire-gpio-cape",
1026 "beaglev-fire-no-cape"
1027 );
1028
1029 pub fn init() {
1031 unsafe {
1032 base_init();
1033 #[cfg(any(
1034 feature = "beaglev-fire-gpio-cape",
1035 feature = "beaglev-fire-default-cape"
1036 ))]
1037 beaglev_fire_default_cape::cape_init();
1038 }
1039 }
1040
1041 impl_gpio_pin!(
1044 SD_DETECT,
1045 GpioPeripheral::Mss(pac::GPIO2_LO),
1046 31,
1047 GPIO1_17_OR_GPIO2_31_INT
1048 );
1049 impl_input_peripheral!(SdDetect, SD_DETECT);
1050
1051 impl SdDetect {
1052 pub fn is_inserted(&mut self) -> bool {
1053 self.is_low().unwrap()
1054 }
1055
1056 pub async fn wait_for_inserted(
1057 &mut self,
1058 ) -> Result<(), <Self as embedded_hal::digital::ErrorType>::Error> {
1059 self.wait_for_low().await
1060 }
1061
1062 pub async fn wait_for_removed(
1063 &mut self,
1064 ) -> Result<(), <Self as embedded_hal::digital::ErrorType>::Error> {
1065 self.wait_for_high().await
1066 }
1067 }
1068
1069 impl_gpio_pin!(SD_CHIP_SELECT, GpioPeripheral::Mss(pac::GPIO0_LO), 12, NONE);
1070 impl_output_peripheral!(SdChipSelect, SD_CHIP_SELECT);
1071
1072 impl_gpio_pin!(
1073 USER_BUTTON,
1074 GpioPeripheral::Mss(pac::GPIO0_LO),
1075 13,
1076 GPIO0_13_OR_GPIO2_13_INT
1077 );
1078 impl_input_peripheral!(UserButton, USER_BUTTON);
1079
1080 #[cfg(any(
1154 feature = "beaglev-fire-gpio-cape",
1155 feature = "beaglev-fire-default-cape"
1156 ))]
1157 pub use beaglev_fire_default_cape::*;
1158
1159 #[cfg(any(
1160 feature = "beaglev-fire-gpio-cape",
1161 feature = "beaglev-fire-default-cape"
1162 ))]
1163 mod beaglev_fire_default_cape {
1164 use super::*;
1165 use crate::pac;
1166
1167 pub(crate) unsafe fn cape_init() {
1168 unsafe {
1169 let mut p8: pac::gpio_instance_t = P8_CORE_GPIO;
1171 trace!("Initializing FPGA Core GPIO {:?}", p8);
1172 pac::GPIO_init(&mut p8, P8_CORE_GPIO.base_addr, P8_CORE_GPIO.apb_bus_width);
1173 let mut p9: pac::gpio_instance_t = P9_CORE_GPIO;
1174 trace!("Initializing FPGA Core GPIO {:?}", p9);
1175 pac::GPIO_init(&mut p9, P9_CORE_GPIO.base_addr, P9_CORE_GPIO.apb_bus_width);
1176 }
1177 }
1178
1179 pub const P8_CORE_GPIO: pac::gpio_instance_t = pac::gpio_instance_t {
1180 base_addr: 0x4110_0000,
1181 apb_bus_width: pac::__gpio_apb_width_t_GPIO_APB_32_BITS_BUS,
1182 };
1183
1184 pub const P9_CORE_GPIO: pac::gpio_instance_t = pac::gpio_instance_t {
1185 base_addr: 0x41200000,
1186 apb_bus_width: pac::__gpio_apb_width_t_GPIO_APB_32_BITS_BUS,
1187 };
1188
1189 impl_gpio_pin!(
1190 P8_3,
1191 GpioPeripheral::Mss(pac::GPIO2_LO),
1192 0,
1193 GPIO0_0_OR_GPIO2_0_INT
1194 );
1195 impl_gpio_pin!(
1196 P8_4,
1197 GpioPeripheral::Mss(pac::GPIO2_LO),
1198 1,
1199 GPIO0_1_OR_GPIO2_1_INT
1200 );
1201 impl_gpio_pin!(
1202 P8_5,
1203 GpioPeripheral::Mss(pac::GPIO2_LO),
1204 2,
1205 GPIO0_2_OR_GPIO2_2_INT
1206 );
1207 impl_gpio_pin!(
1208 P8_6,
1209 GpioPeripheral::Mss(pac::GPIO2_LO),
1210 3,
1211 GPIO0_3_OR_GPIO2_3_INT
1212 );
1213 impl_gpio_pin!(
1214 P8_7,
1215 GpioPeripheral::Mss(pac::GPIO2_LO),
1216 4,
1217 GPIO0_4_OR_GPIO2_4_INT
1218 );
1219 impl_gpio_pin!(
1220 P8_8,
1221 GpioPeripheral::Mss(pac::GPIO2_LO),
1222 5,
1223 GPIO0_5_OR_GPIO2_5_INT
1224 );
1225 impl_gpio_pin!(
1226 P8_9,
1227 GpioPeripheral::Mss(pac::GPIO2_LO),
1228 6,
1229 GPIO0_6_OR_GPIO2_6_INT
1230 );
1231 impl_gpio_pin!(
1232 P8_10,
1233 GpioPeripheral::Mss(pac::GPIO2_LO),
1234 7,
1235 GPIO0_7_OR_GPIO2_7_INT
1236 );
1237 impl_gpio_pin!(
1238 P8_11,
1239 GpioPeripheral::Mss(pac::GPIO2_LO),
1240 8,
1241 GPIO0_8_OR_GPIO2_8_INT
1242 );
1243 impl_gpio_pin!(
1244 P8_12,
1245 GpioPeripheral::Mss(pac::GPIO2_LO),
1246 9,
1247 GPIO0_9_OR_GPIO2_9_INT
1248 );
1249 impl_gpio_pin!(
1250 P8_14,
1251 GpioPeripheral::Mss(pac::GPIO2_LO),
1252 11,
1253 GPIO0_11_OR_GPIO2_11_INT
1254 );
1255 impl_gpio_pin!(
1256 P8_15,
1257 GpioPeripheral::Mss(pac::GPIO2_LO),
1258 12,
1259 GPIO0_12_OR_GPIO2_12_INT
1260 );
1261 impl_gpio_pin!(
1262 P8_16,
1263 GpioPeripheral::Mss(pac::GPIO2_LO),
1264 13,
1265 GPIO0_13_OR_GPIO2_13_INT
1266 );
1267 impl_gpio_pin!(
1268 P8_17,
1269 GpioPeripheral::Mss(pac::GPIO2_LO),
1270 14,
1271 GPIO1_0_OR_GPIO2_14_INT
1272 );
1273 impl_gpio_pin!(
1274 P8_18,
1275 GpioPeripheral::Mss(pac::GPIO2_LO),
1276 15,
1277 GPIO1_1_OR_GPIO2_15_INT
1278 );
1279 impl_gpio_pin!(
1280 P8_20,
1281 GpioPeripheral::Mss(pac::GPIO2_LO),
1282 17,
1283 GPIO1_3_OR_GPIO2_17_INT
1284 );
1285 impl_gpio_pin!(
1286 P8_21,
1287 GpioPeripheral::Mss(pac::GPIO2_LO),
1288 18,
1289 GPIO1_4_OR_GPIO2_18_INT
1290 );
1291 impl_gpio_pin!(
1292 P8_22,
1293 GpioPeripheral::Mss(pac::GPIO2_LO),
1294 19,
1295 GPIO1_5_OR_GPIO2_19_INT
1296 );
1297 impl_gpio_pin!(
1298 P8_23,
1299 GpioPeripheral::Mss(pac::GPIO2_LO),
1300 20,
1301 GPIO1_6_OR_GPIO2_20_INT
1302 );
1303 impl_gpio_pin!(
1304 P8_24,
1305 GpioPeripheral::Mss(pac::GPIO2_LO),
1306 21,
1307 GPIO1_7_OR_GPIO2_21_INT
1308 );
1309 impl_gpio_pin!(
1310 P8_25,
1311 GpioPeripheral::Mss(pac::GPIO2_LO),
1312 22,
1313 GPIO1_8_OR_GPIO2_22_INT
1314 );
1315 impl_gpio_pin!(
1316 P8_26,
1317 GpioPeripheral::Mss(pac::GPIO2_LO),
1318 23,
1319 GPIO1_9_OR_GPIO2_23_INT
1320 );
1321 impl_gpio_pin!(
1322 P8_27,
1323 GpioPeripheral::Mss(pac::GPIO2_LO),
1324 24,
1325 GPIO1_10_OR_GPIO2_24_INT
1326 );
1327 impl_gpio_pin!(
1328 P8_28,
1329 GpioPeripheral::Mss(pac::GPIO2_LO),
1330 25,
1331 GPIO1_11_OR_GPIO2_25_INT
1332 );
1333 impl_gpio_pin!(
1334 P8_29,
1335 GpioPeripheral::Mss(pac::GPIO2_LO),
1336 26,
1337 GPIO1_12_OR_GPIO2_26_INT
1338 );
1339 impl_gpio_pin!(
1340 P8_30,
1341 GpioPeripheral::Mss(pac::GPIO2_LO),
1342 27,
1343 GPIO1_13_OR_GPIO2_27_INT
1344 );
1345
1346 impl_gpio_pin!(P8_31, GpioPeripheral::FpgaCore(P8_CORE_GPIO), 0, F2M_8_INT);
1347 impl_gpio_pin!(P8_32, GpioPeripheral::FpgaCore(P8_CORE_GPIO), 1, F2M_9_INT);
1348 impl_gpio_pin!(P8_33, GpioPeripheral::FpgaCore(P8_CORE_GPIO), 2, F2M_10_INT);
1349 impl_gpio_pin!(P8_34, GpioPeripheral::FpgaCore(P8_CORE_GPIO), 3, F2M_11_INT);
1350 impl_gpio_pin!(P8_35, GpioPeripheral::FpgaCore(P8_CORE_GPIO), 4, F2M_12_INT);
1351 impl_gpio_pin!(P8_36, GpioPeripheral::FpgaCore(P8_CORE_GPIO), 5, F2M_13_INT);
1352 impl_gpio_pin!(P8_37, GpioPeripheral::FpgaCore(P8_CORE_GPIO), 6, F2M_14_INT);
1353 impl_gpio_pin!(P8_38, GpioPeripheral::FpgaCore(P8_CORE_GPIO), 7, F2M_15_INT);
1354 impl_gpio_pin!(P8_39, GpioPeripheral::FpgaCore(P8_CORE_GPIO), 8, F2M_16_INT);
1355 impl_gpio_pin!(P8_40, GpioPeripheral::FpgaCore(P8_CORE_GPIO), 9, F2M_17_INT);
1356 impl_gpio_pin!(
1357 P8_41,
1358 GpioPeripheral::FpgaCore(P8_CORE_GPIO),
1359 10,
1360 F2M_18_INT
1361 );
1362 impl_gpio_pin!(
1363 P8_42,
1364 GpioPeripheral::FpgaCore(P8_CORE_GPIO),
1365 11,
1366 F2M_19_INT
1367 );
1368 impl_gpio_pin!(
1369 P8_43,
1370 GpioPeripheral::FpgaCore(P8_CORE_GPIO),
1371 12,
1372 F2M_20_INT
1373 );
1374 impl_gpio_pin!(
1375 P8_44,
1376 GpioPeripheral::FpgaCore(P8_CORE_GPIO),
1377 13,
1378 F2M_21_INT
1379 );
1380 impl_gpio_pin!(
1381 P8_45,
1382 GpioPeripheral::FpgaCore(P8_CORE_GPIO),
1383 14,
1384 F2M_22_INT
1385 );
1386 impl_gpio_pin!(
1387 P8_46,
1388 GpioPeripheral::FpgaCore(P8_CORE_GPIO),
1389 15,
1390 F2M_23_INT
1391 );
1392 impl_gpio_pin!(P9_12, GpioPeripheral::FpgaCore(P9_CORE_GPIO), 1, F2M_25_INT);
1393 impl_gpio_pin!(P9_15, GpioPeripheral::FpgaCore(P9_CORE_GPIO), 4, F2M_28_INT);
1394 impl_gpio_pin!(
1395 P9_23,
1396 GpioPeripheral::FpgaCore(P9_CORE_GPIO),
1397 10,
1398 F2M_34_INT
1399 );
1400 impl_gpio_pin!(
1401 P9_25,
1402 GpioPeripheral::FpgaCore(P9_CORE_GPIO),
1403 12,
1404 F2M_36_INT
1405 );
1406 impl_gpio_pin!(
1407 P9_27,
1408 GpioPeripheral::FpgaCore(P9_CORE_GPIO),
1409 14,
1410 F2M_38_INT
1411 );
1412 impl_gpio_pin!(
1413 P9_30,
1414 GpioPeripheral::FpgaCore(P9_CORE_GPIO),
1415 17,
1416 F2M_41_INT
1417 );
1418 impl_gpio_pin!(
1419 P9_41,
1420 GpioPeripheral::FpgaCore(P9_CORE_GPIO),
1421 19,
1422 F2M_43_INT
1423 );
1424
1425 impl_output_peripheral!(Led0, P8_3);
1426 impl_output_peripheral!(Led1, P8_4);
1427 impl_output_peripheral!(Led2, P8_5);
1428 impl_output_peripheral!(Led3, P8_6);
1429 impl_output_peripheral!(Led4, P8_7);
1430 impl_output_peripheral!(Led5, P8_8);
1431 impl_output_peripheral!(Led6, P8_9);
1432 impl_output_peripheral!(Led7, P8_10);
1433 impl_output_peripheral!(Led8, P8_11);
1434 impl_output_peripheral!(Led9, P8_12);
1435 impl_output_peripheral!(Led11, P8_14);
1436
1437 use embedded_hal::digital::{OutputPin, PinState};
1438 pub struct Leds {
1439 pub led0: Led0,
1440 pub led1: Led1,
1441 pub led2: Led2,
1442 pub led3: Led3,
1443 pub led4: Led4,
1444 pub led5: Led5,
1445 pub led6: Led6,
1446 pub led7: Led7,
1447 pub led8: Led8,
1448 pub led9: Led9,
1449 #[cfg(feature = "beaglev-fire-gpio-cape")]
1450 pub led10: Led10,
1451 pub led11: Led11,
1452 }
1453
1454 impl Leds {
1455 pub fn set_led(&mut self, led_num: usize, on: bool) {
1456 let pin_state = if on { PinState::High } else { PinState::Low };
1457 match led_num {
1458 0 => self.led0.set_state(pin_state),
1459 1 => self.led1.set_state(pin_state),
1460 2 => self.led2.set_state(pin_state),
1461 3 => self.led3.set_state(pin_state),
1462 4 => self.led4.set_state(pin_state),
1463 5 => self.led5.set_state(pin_state),
1464 6 => self.led6.set_state(pin_state),
1465 7 => self.led7.set_state(pin_state),
1466 8 => self.led8.set_state(pin_state),
1467 9 => self.led9.set_state(pin_state),
1468 #[cfg(feature = "beaglev-fire-gpio-cape")]
1469 10 => self.led10.set_state(pin_state),
1470 #[cfg(not(feature = "beaglev-fire-gpio-cape"))]
1471 10 => Ok(()),
1472 11 => self.led11.set_state(pin_state),
1473 _ => panic!("Invalid LED number: {}", led_num),
1474 }
1475 .unwrap();
1476 }
1477 }
1478
1479 impl crate::Peripheral for Leds {
1480 fn take() -> Option<Self> {
1481 let led0 = Led0::take();
1482 let led1 = Led1::take();
1483 let led2 = Led2::take();
1484 let led3 = Led3::take();
1485 let led4 = Led4::take();
1486 let led5 = Led5::take();
1487 let led6 = Led6::take();
1488 let led7 = Led7::take();
1489 let led8 = Led8::take();
1490 let led9 = Led9::take();
1491 #[cfg(feature = "beaglev-fire-gpio-cape")]
1492 let led10 = Led10::take();
1493 let led11 = Led11::take();
1494
1495 #[cfg(feature = "beaglev-fire-default-cape")]
1496 {
1497 if let (
1498 Some(led0),
1499 Some(led1),
1500 Some(led2),
1501 Some(led3),
1502 Some(led4),
1503 Some(led5),
1504 Some(led6),
1505 Some(led7),
1506 Some(led8),
1507 Some(led9),
1508 Some(led11),
1509 ) = (
1510 led0, led1, led2, led3, led4, led5, led6, led7, led8, led9, led11,
1511 ) {
1512 Some(Self {
1513 led0,
1514 led1,
1515 led2,
1516 led3,
1517 led4,
1518 led5,
1519 led6,
1520 led7,
1521 led8,
1522 led9,
1523 led11,
1524 })
1525 } else {
1526 None
1527 }
1528 }
1529 #[cfg(feature = "beaglev-fire-gpio-cape")]
1530 {
1531 if let (
1532 Some(led0),
1533 Some(led1),
1534 Some(led2),
1535 Some(led3),
1536 Some(led4),
1537 Some(led5),
1538 Some(led6),
1539 Some(led7),
1540 Some(led8),
1541 Some(led9),
1542 Some(led10),
1543 Some(led11),
1544 ) = (
1545 led0, led1, led2, led3, led4, led5, led6, led7, led8, led9, led10, led11,
1546 ) {
1547 Some(Self {
1548 led0,
1549 led1,
1550 led2,
1551 led3,
1552 led4,
1553 led5,
1554 led6,
1555 led7,
1556 led8,
1557 led9,
1558 led10,
1559 led11,
1560 })
1561 } else {
1562 None
1563 }
1564 }
1565 }
1566
1567 unsafe fn steal() -> Self {
1568 unsafe {
1569 Self {
1570 led0: Led0::steal(),
1571 led1: Led1::steal(),
1572 led2: Led2::steal(),
1573 led3: Led3::steal(),
1574 led4: Led4::steal(),
1575 led5: Led5::steal(),
1576 led6: Led6::steal(),
1577 led7: Led7::steal(),
1578 led8: Led8::steal(),
1579 led9: Led9::steal(),
1580 #[cfg(feature = "beaglev-fire-gpio-cape")]
1581 led10: Led10::steal(),
1582 led11: Led11::steal(),
1583 }
1584 }
1585 }
1586 }
1587 }
1588
1589 #[cfg(feature = "beaglev-fire-gpio-cape")]
1590 pub use beaglev_fire_gpio_cape::*;
1591
1592 #[cfg(feature = "beaglev-fire-gpio-cape")]
1593 mod beaglev_fire_gpio_cape {
1594 use super::*;
1595 use crate::pac;
1596 impl_gpio_pin!(
1597 P8_13,
1598 GpioPeripheral::Mss(pac::GPIO2_LO),
1599 10,
1600 GPIO0_10_OR_GPIO2_10_INT
1601 );
1602
1603 impl_output_peripheral!(Led10, P8_13);
1604
1605 impl_gpio_pin!(
1606 P8_19,
1607 GpioPeripheral::Mss(pac::GPIO2_LO),
1608 16,
1609 GPIO1_2_OR_GPIO2_16_INT
1610 );
1611
1612 impl_gpio_pin!(P9_11, GpioPeripheral::FpgaCore(P9_CORE_GPIO), 0, F2M_24_INT);
1613 impl_gpio_pin!(P9_13, GpioPeripheral::FpgaCore(P9_CORE_GPIO), 2, F2M_26_INT);
1614 impl_gpio_pin!(P9_16, GpioPeripheral::FpgaCore(P9_CORE_GPIO), 5, F2M_29_INT);
1615 impl_gpio_pin!(P9_17, GpioPeripheral::FpgaCore(P9_CORE_GPIO), 6, F2M_30_INT);
1616 impl_gpio_pin!(P9_18, GpioPeripheral::FpgaCore(P9_CORE_GPIO), 7, F2M_31_INT);
1617 impl_gpio_pin!(P9_21, GpioPeripheral::FpgaCore(P9_CORE_GPIO), 8, F2M_32_INT);
1618 impl_gpio_pin!(P9_22, GpioPeripheral::FpgaCore(P9_CORE_GPIO), 9, F2M_33_INT);
1619 impl_gpio_pin!(
1620 P9_24,
1621 GpioPeripheral::FpgaCore(P9_CORE_GPIO),
1622 11,
1623 F2M_35_INT
1624 );
1625 impl_gpio_pin!(
1626 P9_26,
1627 GpioPeripheral::FpgaCore(P9_CORE_GPIO),
1628 13,
1629 F2M_37_INT
1630 );
1631 impl_gpio_pin!(
1632 P9_28,
1633 GpioPeripheral::FpgaCore(P9_CORE_GPIO),
1634 15,
1635 F2M_39_INT
1636 );
1637 impl_gpio_pin!(
1638 P9_29,
1639 GpioPeripheral::FpgaCore(P9_CORE_GPIO),
1640 16,
1641 F2M_40_INT
1642 );
1643 impl_gpio_pin!(
1644 P9_31,
1645 GpioPeripheral::FpgaCore(P9_CORE_GPIO),
1646 18,
1647 F2M_42_INT
1648 );
1649 impl_gpio_pin!(
1650 P9_41,
1651 GpioPeripheral::FpgaCore(P9_CORE_GPIO),
1652 19,
1653 F2M_44_INT
1654 );
1655 }
1656}