diff options
| author | Dario Nieuwenhuis <[email protected]> | 2023-08-03 17:30:07 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-08-03 17:30:07 +0000 |
| commit | a40daa923ba031b543ce402f8bd83c2ec41329d8 (patch) | |
| tree | 42d5a3a165cd54ecc255b354a5e0447b27086161 | |
| parent | 4d60c715e683aaadf25d9f066bde805c725fefb4 (diff) | |
| parent | 9dfda46e0c43559a6ca2ed87c0ceb32d19456c62 (diff) | |
Merge pull request #1715 from pennae/rp-dormant-input
rp: add dormant-wake functionality for Input
| -rw-r--r-- | embassy-rp/src/gpio.rs | 61 |
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))] | ||
| 80 | pub struct DormantWakeConfig { | ||
| 81 | pub edge_high: bool, | ||
| 82 | pub edge_low: bool, | ||
| 83 | pub level_high: bool, | ||
| 84 | pub level_low: bool, | ||
| 85 | } | ||
| 86 | |||
| 78 | pub struct Input<'d, T: Pin> { | 87 | pub 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 | ||
| 644 | impl<'d, T: Pin> Drop for Flex<'d, T> { | 677 | impl<'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 | |||
| 694 | pub struct DormantWake<'w, T: Pin> { | ||
| 695 | pin: PeripheralRef<'w, T>, | ||
| 696 | cfg: DormantWakeConfig, | ||
| 697 | } | ||
| 698 | |||
| 699 | impl<'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 | ||
