aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-rp/src/gpio.rs61
1 files changed, 61 insertions, 0 deletions
diff --git a/embassy-rp/src/gpio.rs b/embassy-rp/src/gpio.rs
index 73e893523..ad9d4262d 100644
--- a/embassy-rp/src/gpio.rs
+++ b/embassy-rp/src/gpio.rs
@@ -75,6 +75,15 @@ pub enum Bank {
75 Qspi = 1, 75 Qspi = 1,
76} 76}
77 77
78#[derive(Debug, Eq, PartialEq, Copy, Clone, Default)]
79#[cfg_attr(feature = "defmt", derive(defmt::Format))]
80pub struct DormantWakeConfig {
81 pub edge_high: bool,
82 pub edge_low: bool,
83 pub level_high: bool,
84 pub level_low: bool,
85}
86
78pub struct Input<'d, T: Pin> { 87pub struct Input<'d, T: Pin> {
79 pin: Flex<'d, T>, 88 pin: Flex<'d, T>,
80} 89}
@@ -128,6 +137,11 @@ impl<'d, T: Pin> Input<'d, T> {
128 pub async fn wait_for_any_edge(&mut self) { 137 pub async fn wait_for_any_edge(&mut self) {
129 self.pin.wait_for_any_edge().await; 138 self.pin.wait_for_any_edge().await;
130 } 139 }
140
141 #[inline]
142 pub fn dormant_wake(&mut self, cfg: DormantWakeConfig) -> DormantWake<T> {
143 self.pin.dormant_wake(cfg)
144 }
131} 145}
132 146
133/// Interrupt trigger levels. 147/// Interrupt trigger levels.
@@ -639,15 +653,62 @@ impl<'d, T: Pin> Flex<'d, T> {
639 pub async fn wait_for_any_edge(&mut self) { 653 pub async fn wait_for_any_edge(&mut self) {
640 InputFuture::new(&mut self.pin, InterruptTrigger::AnyEdge).await; 654 InputFuture::new(&mut self.pin, InterruptTrigger::AnyEdge).await;
641 } 655 }
656
657 #[inline]
658 pub fn dormant_wake(&mut self, cfg: DormantWakeConfig) -> DormantWake<T> {
659 let idx = self.pin._pin() as usize;
660 self.pin.io().intr(idx / 8).write(|w| {
661 w.set_edge_high(idx % 8, cfg.edge_high);
662 w.set_edge_low(idx % 8, cfg.edge_low);
663 });
664 self.pin.io().int_dormant_wake().inte(idx / 8).write_set(|w| {
665 w.set_edge_high(idx % 8, cfg.edge_high);
666 w.set_edge_low(idx % 8, cfg.edge_low);
667 w.set_level_high(idx % 8, cfg.level_high);
668 w.set_level_low(idx % 8, cfg.level_low);
669 });
670 DormantWake {
671 pin: self.pin.reborrow(),
672 cfg,
673 }
674 }
642} 675}
643 676
644impl<'d, T: Pin> Drop for Flex<'d, T> { 677impl<'d, T: Pin> Drop for Flex<'d, T> {
645 #[inline] 678 #[inline]
646 fn drop(&mut self) { 679 fn drop(&mut self) {
680 let idx = self.pin._pin() as usize;
647 self.pin.pad_ctrl().write(|_| {}); 681 self.pin.pad_ctrl().write(|_| {});
648 self.pin.gpio().ctrl().write(|w| { 682 self.pin.gpio().ctrl().write(|w| {
649 w.set_funcsel(pac::io::vals::Gpio0ctrlFuncsel::NULL as _); 683 w.set_funcsel(pac::io::vals::Gpio0ctrlFuncsel::NULL as _);
650 }); 684 });
685 self.pin.io().int_dormant_wake().inte(idx / 8).write_clear(|w| {
686 w.set_edge_high(idx % 8, true);
687 w.set_edge_low(idx % 8, true);
688 w.set_level_high(idx % 8, true);
689 w.set_level_low(idx % 8, true);
690 });
691 }
692}
693
694pub struct DormantWake<'w, T: Pin> {
695 pin: PeripheralRef<'w, T>,
696 cfg: DormantWakeConfig,
697}
698
699impl<'w, T: Pin> Drop for DormantWake<'w, T> {
700 fn drop(&mut self) {
701 let idx = self.pin._pin() as usize;
702 self.pin.io().intr(idx / 8).write(|w| {
703 w.set_edge_high(idx % 8, self.cfg.edge_high);
704 w.set_edge_low(idx % 8, self.cfg.edge_low);
705 });
706 self.pin.io().int_dormant_wake().inte(idx / 8).write_clear(|w| {
707 w.set_edge_high(idx % 8, true);
708 w.set_edge_low(idx % 8, true);
709 w.set_level_high(idx % 8, true);
710 w.set_level_low(idx % 8, true);
711 });
651 } 712 }
652} 713}
653 714