aboutsummaryrefslogtreecommitdiff
path: root/src/gpio.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpio.rs')
-rw-r--r--src/gpio.rs243
1 files changed, 242 insertions, 1 deletions
diff --git a/src/gpio.rs b/src/gpio.rs
index 4f79aff93..332c4c8b2 100644
--- a/src/gpio.rs
+++ b/src/gpio.rs
@@ -3,13 +3,96 @@
3//! concrete pin type. 3//! concrete pin type.
4 4
5use core::convert::Infallible; 5use core::convert::Infallible;
6use core::future::Future;
6use core::marker::PhantomData; 7use core::marker::PhantomData;
8use core::pin::pin;
7 9
8use embassy_hal_internal::{Peri, PeripheralType}; 10use embassy_hal_internal::{Peri, PeripheralType};
11use maitake_sync::WaitMap;
9use paste::paste; 12use paste::paste;
10 13
14use crate::pac::interrupt;
11use crate::pac::port0::pcr0::{Dse, Inv, Mux, Pe, Ps, Sre}; 15use crate::pac::port0::pcr0::{Dse, Inv, Mux, Pe, Ps, Sre};
12 16
17struct BitIter(u32);
18
19impl Iterator for BitIter {
20 type Item = usize;
21
22 fn next(&mut self) -> Option<Self::Item> {
23 match self.0.trailing_zeros() {
24 32 => None,
25 b => {
26 self.0 &= !(1 << b);
27 Some(b as usize)
28 }
29 }
30 }
31}
32
33const PORT_COUNT: usize = 5;
34
35static PORT_WAIT_MAPS: [WaitMap<usize, ()>; PORT_COUNT] = [
36 WaitMap::new(),
37 WaitMap::new(),
38 WaitMap::new(),
39 WaitMap::new(),
40 WaitMap::new(),
41];
42
43fn irq_handler(port_index: usize, gpio_base: *const crate::pac::gpio0::RegisterBlock) {
44 let gpio = unsafe { &*gpio_base };
45 let isfr = gpio.isfr0().read().bits();
46
47 for pin in BitIter(isfr) {
48 // Clear all pending interrupts
49 gpio.isfr0().write(|w| unsafe { w.bits(1 << pin) });
50 gpio.icr(pin).modify(|_, w| w.irqc().irqc0()); // Disable interrupt
51
52 // Wake the corresponding port waker
53 if let Some(w) = PORT_WAIT_MAPS.get(port_index) {
54 w.wake(&pin, ());
55 }
56 }
57}
58
59#[interrupt]
60fn GPIO0() {
61 irq_handler(0, crate::pac::Gpio0::ptr());
62}
63
64#[interrupt]
65fn GPIO1() {
66 irq_handler(1, crate::pac::Gpio1::ptr());
67}
68
69#[interrupt]
70fn GPIO2() {
71 irq_handler(2, crate::pac::Gpio2::ptr());
72}
73
74#[interrupt]
75fn GPIO3() {
76 irq_handler(3, crate::pac::Gpio3::ptr());
77}
78
79#[interrupt]
80fn GPIO4() {
81 irq_handler(4, crate::pac::Gpio4::ptr());
82}
83
84pub(crate) unsafe fn init() {
85 use embassy_hal_internal::interrupt::InterruptExt;
86
87 crate::pac::interrupt::GPIO0.enable();
88 crate::pac::interrupt::GPIO1.enable();
89 crate::pac::interrupt::GPIO2.enable();
90 crate::pac::interrupt::GPIO3.enable();
91 crate::pac::interrupt::GPIO4.enable();
92
93 cortex_m::interrupt::enable();
94}
95
13/// Logical level for GPIO pins. 96/// Logical level for GPIO pins.
14#[derive(Copy, Clone, Eq, PartialEq, Debug)] 97#[derive(Copy, Clone, Eq, PartialEq, Debug)]
15#[cfg_attr(feature = "defmt", derive(defmt::Format))] 98#[cfg_attr(feature = "defmt", derive(defmt::Format))]
@@ -598,6 +681,77 @@ impl<'d> Flex<'d> {
598 } 681 }
599} 682}
600 683
684/// Async methods
685impl<'d> Flex<'d> {
686 /// Helper function that waits for a given interrupt trigger
687 async fn wait_for_inner(&mut self, level: crate::pac::gpio0::icr::Irqc) {
688 // First, ensure that we have a waker that is ready for this port+pin
689 let w = PORT_WAIT_MAPS[self.pin.port].wait(self.pin.pin);
690 let mut w = pin!(w);
691 // Wait for the subscription to occur, which requires polling at least once
692 //
693 // This function returns a result, but can only be an Err if:
694 //
695 // * We call `.close()` on a WaitMap, which we never do
696 // * We have a duplicate key, which can't happen because `wait_for_*` methods
697 // take an &mut ref of their unique port+pin combo
698 //
699 // So we wait for it to complete, but ignore the result.
700 _ = w.as_mut().subscribe().await;
701
702 // Now that our waker is in the map, we can enable the appropriate interrupt
703 //
704 // Clear any existing pending interrupt on this pin
705 self.pin
706 .gpio()
707 .isfr0()
708 .write(|w| unsafe { w.bits(1 << self.pin.pin()) });
709 self.pin.gpio().icr(self.pin.pin()).write(|w| w.isf().isf1());
710
711 // Pin interrupt configuration
712 self.pin
713 .gpio()
714 .icr(self.pin.pin())
715 .modify(|_, w| w.irqc().variant(level));
716
717 // Finally, we can await the matching call to `.wake()` from the interrupt.
718 //
719 // Again, technically, this could return a result, but for the same reasons
720 // as above, this can't be an error in our case, so just wait for it to complete
721 _ = w.await;
722 }
723
724 /// Wait until the pin is high. If it is already high, return immediately.
725 #[inline]
726 pub fn wait_for_high(&mut self) -> impl Future<Output = ()> + use<'_, 'd> {
727 self.wait_for_inner(crate::pac::gpio0::icr::Irqc::Irqc12)
728 }
729
730 /// Wait until the pin is low. If it is already low, return immediately.
731 #[inline]
732 pub fn wait_for_low(&mut self) -> impl Future<Output = ()> + use<'_, 'd> {
733 self.wait_for_inner(crate::pac::gpio0::icr::Irqc::Irqc8)
734 }
735
736 /// Wait for the pin to undergo a transition from low to high.
737 #[inline]
738 pub fn wait_for_rising_edge(&mut self) -> impl Future<Output = ()> + use<'_, 'd> {
739 self.wait_for_inner(crate::pac::gpio0::icr::Irqc::Irqc9)
740 }
741
742 /// Wait for the pin to undergo a transition from high to low.
743 #[inline]
744 pub fn wait_for_falling_edge(&mut self) -> impl Future<Output = ()> + use<'_, 'd> {
745 self.wait_for_inner(crate::pac::gpio0::icr::Irqc::Irqc10)
746 }
747
748 /// Wait for the pin to undergo any transition, i.e low to high OR high to low.
749 #[inline]
750 pub fn wait_for_any_edge(&mut self) -> impl Future<Output = ()> + use<'_, 'd> {
751 self.wait_for_inner(crate::pac::gpio0::icr::Irqc::Irqc11)
752 }
753}
754
601/// GPIO output driver that owns a `Flex` pin. 755/// GPIO output driver that owns a `Flex` pin.
602pub struct Output<'d> { 756pub struct Output<'d> {
603 flex: Flex<'d>, 757 flex: Flex<'d>,
@@ -691,12 +845,99 @@ impl<'d> Input<'d> {
691 self.flex 845 self.flex
692 } 846 }
693 847
694 // Get the pin level. 848 /// Get the pin level.
695 pub fn get_level(&self) -> Level { 849 pub fn get_level(&self) -> Level {
696 self.flex.get_level() 850 self.flex.get_level()
697 } 851 }
698} 852}
699 853
854/// Async methods
855impl<'d> Input<'d> {
856 /// Wait until the pin is high. If it is already high, return immediately.
857 #[inline]
858 pub fn wait_for_high(&mut self) -> impl Future<Output = ()> + use<'_, 'd> {
859 self.flex.wait_for_high()
860 }
861
862 /// Wait until the pin is low. If it is already low, return immediately.
863 #[inline]
864 pub fn wait_for_low(&mut self) -> impl Future<Output = ()> + use<'_, 'd> {
865 self.flex.wait_for_low()
866 }
867
868 /// Wait for the pin to undergo a transition from low to high.
869 #[inline]
870 pub fn wait_for_rising_edge(&mut self) -> impl Future<Output = ()> + use<'_, 'd> {
871 self.flex.wait_for_rising_edge()
872 }
873
874 /// Wait for the pin to undergo a transition from high to low.
875 #[inline]
876 pub fn wait_for_falling_edge(&mut self) -> impl Future<Output = ()> + use<'_, 'd> {
877 self.flex.wait_for_falling_edge()
878 }
879
880 /// Wait for the pin to undergo any transition, i.e low to high OR high to low.
881 #[inline]
882 pub fn wait_for_any_edge(&mut self) -> impl Future<Output = ()> + use<'_, 'd> {
883 self.flex.wait_for_any_edge()
884 }
885}
886
887impl embedded_hal_async::digital::Wait for Input<'_> {
888 async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
889 self.wait_for_high().await;
890 Ok(())
891 }
892
893 async fn wait_for_low(&mut self) -> Result<(), Self::Error> {
894 self.wait_for_low().await;
895 Ok(())
896 }
897
898 async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> {
899 self.wait_for_rising_edge().await;
900 Ok(())
901 }
902
903 async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> {
904 self.wait_for_falling_edge().await;
905 Ok(())
906 }
907
908 async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> {
909 self.wait_for_any_edge().await;
910 Ok(())
911 }
912}
913
914impl embedded_hal_async::digital::Wait for Flex<'_> {
915 async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
916 self.wait_for_high().await;
917 Ok(())
918 }
919
920 async fn wait_for_low(&mut self) -> Result<(), Self::Error> {
921 self.wait_for_low().await;
922 Ok(())
923 }
924
925 async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> {
926 self.wait_for_rising_edge().await;
927 Ok(())
928 }
929
930 async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> {
931 self.wait_for_falling_edge().await;
932 Ok(())
933 }
934
935 async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> {
936 self.wait_for_any_edge().await;
937 Ok(())
938 }
939}
940
700// Both embedded_hal 0.2 and 1.0 must be supported by embassy HALs. 941// Both embedded_hal 0.2 and 1.0 must be supported by embassy HALs.
701impl embedded_hal_02::digital::v2::InputPin for Flex<'_> { 942impl embedded_hal_02::digital::v2::InputPin for Flex<'_> {
702 // GPIO operations on this block cannot fail, therefor we set the error type 943 // GPIO operations on this block cannot fail, therefor we set the error type