diff options
| author | xoviat <[email protected]> | 2021-03-20 11:07:35 -0500 |
|---|---|---|
| committer | GitHub <[email protected]> | 2021-03-20 11:07:35 -0500 |
| commit | 451cec56f020d08af8a3c1ccba6bd5ca58718544 (patch) | |
| tree | 7d7e8cff0205f5855ea2c8b2672ce3fad1f5f900 | |
| parent | 6719da3b6e726608fcde1ebdd27eb70ac9bb6d69 (diff) | |
| parent | bf39822092f05dee0ab4d7efd6296e9873555da2 (diff) | |
Merge pull request #98 from xoviat/stm32
consolidate exti mod
| -rw-r--r-- | embassy-stm32/src/exti.rs (renamed from embassy-stm32f4/src/exti.rs) | 342 | ||||
| -rw-r--r-- | embassy-stm32/src/lib.rs | 1 | ||||
| -rw-r--r-- | embassy-stm32f4/src/lib.rs | 3 | ||||
| -rw-r--r-- | embassy-stm32l0/src/exti.rs | 268 | ||||
| -rw-r--r-- | embassy-stm32l0/src/lib.rs | 4 |
5 files changed, 295 insertions, 323 deletions
diff --git a/embassy-stm32f4/src/exti.rs b/embassy-stm32/src/exti.rs index 154ca45c1..a00079450 100644 --- a/embassy-stm32f4/src/exti.rs +++ b/embassy-stm32/src/exti.rs | |||
| @@ -3,35 +3,33 @@ use core::mem; | |||
| 3 | use core::pin::Pin; | 3 | use core::pin::Pin; |
| 4 | use cortex_m; | 4 | use cortex_m; |
| 5 | 5 | ||
| 6 | use embassy::traits::gpio::{WaitForFallingEdge, WaitForRisingEdge}; | 6 | use crate::hal::gpio; |
| 7 | |||
| 8 | use embassy::traits::gpio::{ | ||
| 9 | WaitForAnyEdge, WaitForFallingEdge, WaitForHigh, WaitForLow, WaitForRisingEdge, | ||
| 10 | }; | ||
| 7 | use embassy::util::InterruptFuture; | 11 | use embassy::util::InterruptFuture; |
| 8 | 12 | ||
| 9 | use crate::hal::gpio; | ||
| 10 | use crate::hal::gpio::Edge; | ||
| 11 | use crate::hal::syscfg::SysCfg; | ||
| 12 | use crate::pac::EXTI; | ||
| 13 | use embedded_hal::digital::v2 as digital; | 13 | use embedded_hal::digital::v2 as digital; |
| 14 | 14 | ||
| 15 | use crate::interrupt; | 15 | use crate::interrupt; |
| 16 | 16 | ||
| 17 | pub struct ExtiPin<T: gpio::ExtiPin + WithInterrupt> { | 17 | pub struct ExtiPin<T: Instance> { |
| 18 | pin: T, | 18 | pin: T, |
| 19 | interrupt: T::Interrupt, | 19 | interrupt: T::Interrupt, |
| 20 | } | 20 | } |
| 21 | 21 | ||
| 22 | impl<T: gpio::ExtiPin + WithInterrupt> ExtiPin<T> { | 22 | impl<T: Instance> ExtiPin<T> { |
| 23 | pub fn new(mut pin: T, interrupt: T::Interrupt) -> Self { | 23 | pub fn new(mut pin: T, interrupt: T::Interrupt) -> Self { |
| 24 | let mut syscfg: SysCfg = unsafe { mem::transmute(()) }; | ||
| 25 | |||
| 26 | cortex_m::interrupt::free(|_| { | 24 | cortex_m::interrupt::free(|_| { |
| 27 | pin.make_interrupt_source(&mut syscfg); | 25 | pin.make_source(); |
| 28 | }); | 26 | }); |
| 29 | 27 | ||
| 30 | Self { pin, interrupt } | 28 | Self { pin, interrupt } |
| 31 | } | 29 | } |
| 32 | } | 30 | } |
| 33 | 31 | ||
| 34 | impl<T: gpio::ExtiPin + WithInterrupt + digital::OutputPin> digital::OutputPin for ExtiPin<T> { | 32 | impl<T: Instance + digital::OutputPin> digital::OutputPin for ExtiPin<T> { |
| 35 | type Error = T::Error; | 33 | type Error = T::Error; |
| 36 | 34 | ||
| 37 | fn set_low(&mut self) -> Result<(), Self::Error> { | 35 | fn set_low(&mut self) -> Result<(), Self::Error> { |
| @@ -43,9 +41,7 @@ impl<T: gpio::ExtiPin + WithInterrupt + digital::OutputPin> digital::OutputPin f | |||
| 43 | } | 41 | } |
| 44 | } | 42 | } |
| 45 | 43 | ||
| 46 | impl<T: gpio::ExtiPin + WithInterrupt + digital::StatefulOutputPin> digital::StatefulOutputPin | 44 | impl<T: Instance + digital::StatefulOutputPin> digital::StatefulOutputPin for ExtiPin<T> { |
| 47 | for ExtiPin<T> | ||
| 48 | { | ||
| 49 | fn is_set_low(&self) -> Result<bool, Self::Error> { | 45 | fn is_set_low(&self) -> Result<bool, Self::Error> { |
| 50 | self.pin.is_set_low() | 46 | self.pin.is_set_low() |
| 51 | } | 47 | } |
| @@ -55,9 +51,7 @@ impl<T: gpio::ExtiPin + WithInterrupt + digital::StatefulOutputPin> digital::Sta | |||
| 55 | } | 51 | } |
| 56 | } | 52 | } |
| 57 | 53 | ||
| 58 | impl<T: gpio::ExtiPin + WithInterrupt + digital::ToggleableOutputPin> digital::ToggleableOutputPin | 54 | impl<T: Instance + digital::ToggleableOutputPin> digital::ToggleableOutputPin for ExtiPin<T> { |
| 59 | for ExtiPin<T> | ||
| 60 | { | ||
| 61 | type Error = T::Error; | 55 | type Error = T::Error; |
| 62 | 56 | ||
| 63 | fn toggle(&mut self) -> Result<(), Self::Error> { | 57 | fn toggle(&mut self) -> Result<(), Self::Error> { |
| @@ -65,7 +59,7 @@ impl<T: gpio::ExtiPin + WithInterrupt + digital::ToggleableOutputPin> digital::T | |||
| 65 | } | 59 | } |
| 66 | } | 60 | } |
| 67 | 61 | ||
| 68 | impl<T: gpio::ExtiPin + WithInterrupt + digital::InputPin> digital::InputPin for ExtiPin<T> { | 62 | impl<T: Instance + digital::InputPin> digital::InputPin for ExtiPin<T> { |
| 69 | type Error = T::Error; | 63 | type Error = T::Error; |
| 70 | 64 | ||
| 71 | fn is_high(&self) -> Result<bool, Self::Error> { | 65 | fn is_high(&self) -> Result<bool, Self::Error> { |
| @@ -77,71 +71,129 @@ impl<T: gpio::ExtiPin + WithInterrupt + digital::InputPin> digital::InputPin for | |||
| 77 | } | 71 | } |
| 78 | } | 72 | } |
| 79 | 73 | ||
| 80 | /* | 74 | impl<T: Instance + digital::InputPin + 'static> ExtiPin<T> { |
| 81 | Irq Handler Description | 75 | fn wait_for_state<'a>(self: Pin<&'a mut Self>, state: bool) -> impl Future<Output = ()> + 'a { |
| 82 | EXTI0_IRQn EXTI0_IRQHandler Handler for pins connected to line 0 | ||
| 83 | EXTI1_IRQn EXTI1_IRQHandler Handler for pins connected to line 1 | ||
| 84 | EXTI2_IRQn EXTI2_IRQHandler Handler for pins connected to line 2 | ||
| 85 | EXTI3_IRQn EXTI3_IRQHandler Handler for pins connected to line 3 | ||
| 86 | EXTI4_IRQn EXTI4_IRQHandler Handler for pins connected to line 4 | ||
| 87 | EXTI9_5_IRQn EXTI9_5_IRQHandler Handler for pins connected to line 5 to 9 | ||
| 88 | EXTI15_10_IRQn EXTI15_10_IRQHandler Handler for pins connected to line 10 to 15 | ||
| 89 | */ | ||
| 90 | |||
| 91 | impl<T: gpio::ExtiPin + WithInterrupt + 'static> WaitForRisingEdge for ExtiPin<T> { | ||
| 92 | type Future<'a> = impl Future<Output = ()> + 'a; | ||
| 93 | |||
| 94 | fn wait_for_rising_edge<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> { | ||
| 95 | let s = unsafe { self.get_unchecked_mut() }; | 76 | let s = unsafe { self.get_unchecked_mut() }; |
| 96 | 77 | ||
| 97 | s.pin.clear_interrupt_pending_bit(); | 78 | s.pin.clear_pending_bit(); |
| 98 | async move { | 79 | async move { |
| 99 | let fut = InterruptFuture::new(&mut s.interrupt); | 80 | let fut = InterruptFuture::new(&mut s.interrupt); |
| 100 | let pin = &mut s.pin; | 81 | let pin = &mut s.pin; |
| 101 | cortex_m::interrupt::free(|_| { | 82 | cortex_m::interrupt::free(|_| { |
| 102 | let mut exti: EXTI = unsafe { mem::transmute(()) }; | 83 | pin.trigger_edge(if state { |
| 103 | 84 | EdgeOption::Rising | |
| 104 | pin.trigger_on_edge(&mut exti, Edge::RISING); | 85 | } else { |
| 105 | pin.enable_interrupt(&mut exti); | 86 | EdgeOption::Falling |
| 87 | }); | ||
| 106 | }); | 88 | }); |
| 89 | |||
| 90 | if (state && s.pin.is_high().unwrap_or(false)) | ||
| 91 | || (!state && s.pin.is_low().unwrap_or(false)) | ||
| 92 | { | ||
| 93 | return; | ||
| 94 | } | ||
| 95 | |||
| 107 | fut.await; | 96 | fut.await; |
| 108 | 97 | ||
| 109 | s.pin.clear_interrupt_pending_bit(); | 98 | s.pin.clear_pending_bit(); |
| 110 | } | 99 | } |
| 111 | } | 100 | } |
| 112 | } | 101 | } |
| 113 | 102 | ||
| 114 | impl<T: gpio::ExtiPin + WithInterrupt + 'static> WaitForFallingEdge for ExtiPin<T> { | 103 | impl<T: Instance + 'static> ExtiPin<T> { |
| 115 | type Future<'a> = impl Future<Output = ()> + 'a; | 104 | fn wait_for_edge<'a>( |
| 116 | 105 | self: Pin<&'a mut Self>, | |
| 117 | fn wait_for_falling_edge<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> { | 106 | state: EdgeOption, |
| 107 | ) -> impl Future<Output = ()> + 'a { | ||
| 118 | let s = unsafe { self.get_unchecked_mut() }; | 108 | let s = unsafe { self.get_unchecked_mut() }; |
| 119 | 109 | ||
| 120 | s.pin.clear_interrupt_pending_bit(); | 110 | s.pin.clear_pending_bit(); |
| 121 | async move { | 111 | async move { |
| 122 | let fut = InterruptFuture::new(&mut s.interrupt); | 112 | let fut = InterruptFuture::new(&mut s.interrupt); |
| 123 | let pin = &mut s.pin; | 113 | let pin = &mut s.pin; |
| 124 | cortex_m::interrupt::free(|_| { | 114 | cortex_m::interrupt::free(|_| { |
| 125 | let mut exti: EXTI = unsafe { mem::transmute(()) }; | 115 | pin.trigger_edge(state); |
| 126 | |||
| 127 | pin.trigger_on_edge(&mut exti, Edge::FALLING); | ||
| 128 | pin.enable_interrupt(&mut exti); | ||
| 129 | }); | 116 | }); |
| 117 | |||
| 130 | fut.await; | 118 | fut.await; |
| 131 | 119 | ||
| 132 | s.pin.clear_interrupt_pending_bit(); | 120 | s.pin.clear_pending_bit(); |
| 133 | } | 121 | } |
| 134 | } | 122 | } |
| 135 | } | 123 | } |
| 136 | 124 | ||
| 125 | impl<T: Instance + digital::InputPin + 'static> WaitForHigh for ExtiPin<T> { | ||
| 126 | type Future<'a> = impl Future<Output = ()> + 'a; | ||
| 127 | |||
| 128 | fn wait_for_high<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> { | ||
| 129 | self.wait_for_state(true) | ||
| 130 | } | ||
| 131 | } | ||
| 132 | |||
| 133 | impl<T: Instance + digital::InputPin + 'static> WaitForLow for ExtiPin<T> { | ||
| 134 | type Future<'a> = impl Future<Output = ()> + 'a; | ||
| 135 | |||
| 136 | fn wait_for_low<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> { | ||
| 137 | self.wait_for_state(false) | ||
| 138 | } | ||
| 139 | } | ||
| 140 | |||
| 141 | /* | ||
| 142 | Irq Handler Description | ||
| 143 | EXTI0_IRQn EXTI0_IRQHandler Handler for pins connected to line 0 | ||
| 144 | EXTI1_IRQn EXTI1_IRQHandler Handler for pins connected to line 1 | ||
| 145 | EXTI2_IRQn EXTI2_IRQHandler Handler for pins connected to line 2 | ||
| 146 | EXTI3_IRQn EXTI3_IRQHandler Handler for pins connected to line 3 | ||
| 147 | EXTI4_IRQn EXTI4_IRQHandler Handler for pins connected to line 4 | ||
| 148 | EXTI9_5_IRQn EXTI9_5_IRQHandler Handler for pins connected to line 5 to 9 | ||
| 149 | EXTI15_10_IRQn EXTI15_10_IRQHandler Handler for pins connected to line 10 to 15 | ||
| 150 | */ | ||
| 151 | |||
| 152 | impl<T: Instance + 'static> WaitForRisingEdge for ExtiPin<T> { | ||
| 153 | type Future<'a> = impl Future<Output = ()> + 'a; | ||
| 154 | |||
| 155 | fn wait_for_rising_edge<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> { | ||
| 156 | self.wait_for_edge(EdgeOption::Rising) | ||
| 157 | } | ||
| 158 | } | ||
| 159 | |||
| 160 | impl<T: Instance + 'static> WaitForFallingEdge for ExtiPin<T> { | ||
| 161 | type Future<'a> = impl Future<Output = ()> + 'a; | ||
| 162 | |||
| 163 | fn wait_for_falling_edge<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> { | ||
| 164 | self.wait_for_edge(EdgeOption::Falling) | ||
| 165 | } | ||
| 166 | } | ||
| 167 | |||
| 168 | impl<T: Instance + 'static> WaitForAnyEdge for ExtiPin<T> { | ||
| 169 | type Future<'a> = impl Future<Output = ()> + 'a; | ||
| 170 | |||
| 171 | fn wait_for_any_edge<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> { | ||
| 172 | self.wait_for_edge(EdgeOption::RisingFalling) | ||
| 173 | } | ||
| 174 | } | ||
| 175 | |||
| 137 | mod private { | 176 | mod private { |
| 138 | pub trait Sealed {} | 177 | pub trait Sealed {} |
| 139 | } | 178 | } |
| 140 | 179 | ||
| 180 | #[derive(Copy, Clone)] | ||
| 181 | pub enum EdgeOption { | ||
| 182 | Rising, | ||
| 183 | Falling, | ||
| 184 | RisingFalling, | ||
| 185 | } | ||
| 186 | |||
| 141 | pub trait WithInterrupt: private::Sealed { | 187 | pub trait WithInterrupt: private::Sealed { |
| 142 | type Interrupt: interrupt::Interrupt; | 188 | type Interrupt: interrupt::Interrupt; |
| 143 | } | 189 | } |
| 144 | 190 | ||
| 191 | pub trait Instance: WithInterrupt { | ||
| 192 | fn make_source(&mut self); | ||
| 193 | fn clear_pending_bit(&mut self); | ||
| 194 | fn trigger_edge(&mut self, edge: EdgeOption); | ||
| 195 | } | ||
| 196 | |||
| 145 | macro_rules! exti { | 197 | macro_rules! exti { |
| 146 | ($set:ident, [ | 198 | ($set:ident, [ |
| 147 | $($INT:ident => $pin:ident,)+ | 199 | $($INT:ident => $pin:ident,)+ |
| @@ -151,8 +203,90 @@ macro_rules! exti { | |||
| 151 | impl<T> WithInterrupt for gpio::$set::$pin<T> { | 203 | impl<T> WithInterrupt for gpio::$set::$pin<T> { |
| 152 | type Interrupt = interrupt::$INT; | 204 | type Interrupt = interrupt::$INT; |
| 153 | } | 205 | } |
| 154 | )+ | ||
| 155 | 206 | ||
| 207 | #[cfg(any( | ||
| 208 | feature = "stm32f401", | ||
| 209 | feature = "stm32f405", | ||
| 210 | feature = "stm32f407", | ||
| 211 | feature = "stm32f410", | ||
| 212 | feature = "stm32f411", | ||
| 213 | feature = "stm32f412", | ||
| 214 | feature = "stm32f413", | ||
| 215 | feature = "stm32f415", | ||
| 216 | feature = "stm32f417", | ||
| 217 | feature = "stm32f423", | ||
| 218 | feature = "stm32f427", | ||
| 219 | feature = "stm32f429", | ||
| 220 | feature = "stm32f437", | ||
| 221 | feature = "stm32f439", | ||
| 222 | feature = "stm32f446", | ||
| 223 | feature = "stm32f469", | ||
| 224 | feature = "stm32f479", | ||
| 225 | ))] | ||
| 226 | impl<T> Instance for gpio::$set::$pin<gpio::Input<T>> { | ||
| 227 | fn make_source(&mut self) { | ||
| 228 | use crate::hal::{gpio::Edge, gpio::ExtiPin, syscfg::SysCfg}; | ||
| 229 | use crate::pac::EXTI; | ||
| 230 | let mut syscfg: SysCfg = unsafe { mem::transmute(()) }; | ||
| 231 | self.make_interrupt_source(&mut syscfg); | ||
| 232 | } | ||
| 233 | |||
| 234 | fn clear_pending_bit(&mut self) { | ||
| 235 | use crate::hal::{gpio::Edge, gpio::ExtiPin, syscfg::SysCfg}; | ||
| 236 | |||
| 237 | self.clear_interrupt_pending_bit(); | ||
| 238 | } | ||
| 239 | |||
| 240 | fn trigger_edge(&mut self, edge: EdgeOption) { | ||
| 241 | use crate::hal::{gpio::Edge, gpio::ExtiPin, syscfg::SysCfg}; | ||
| 242 | use crate::pac::EXTI; | ||
| 243 | let mut exti: EXTI = unsafe { mem::transmute(()) }; | ||
| 244 | let edge = match edge { | ||
| 245 | EdgeOption::Falling => Edge::FALLING, | ||
| 246 | EdgeOption::Rising => Edge::RISING, | ||
| 247 | EdgeOption::RisingFalling => Edge::RISING_FALLING, | ||
| 248 | }; | ||
| 249 | self.trigger_on_edge(&mut exti, edge); | ||
| 250 | self.enable_interrupt(&mut exti); | ||
| 251 | } | ||
| 252 | } | ||
| 253 | |||
| 254 | #[cfg(any(feature = "stm32l0x1", feature = "stm32l0x2", feature = "stm32l0x3",))] | ||
| 255 | impl<T> Instance for gpio::$set::$pin<T> { | ||
| 256 | fn make_source(&mut self) {} | ||
| 257 | |||
| 258 | fn clear_pending_bit(&mut self) { | ||
| 259 | use crate::hal::{ | ||
| 260 | exti::{Exti, ExtiLine, GpioLine, TriggerEdge}, | ||
| 261 | syscfg::SYSCFG, | ||
| 262 | }; | ||
| 263 | |||
| 264 | Exti::unpend(GpioLine::from_raw_line(self.pin_number()).unwrap()); | ||
| 265 | } | ||
| 266 | |||
| 267 | fn trigger_edge(&mut self, edge: EdgeOption) { | ||
| 268 | use crate::hal::{ | ||
| 269 | exti::{Exti, ExtiLine, GpioLine, TriggerEdge}, | ||
| 270 | syscfg::SYSCFG, | ||
| 271 | }; | ||
| 272 | |||
| 273 | use crate::pac::EXTI; | ||
| 274 | |||
| 275 | let edge = match edge { | ||
| 276 | EdgeOption::Falling => TriggerEdge::Falling, | ||
| 277 | EdgeOption::Rising => TriggerEdge::Rising, | ||
| 278 | EdgeOption::RisingFalling => TriggerEdge::Both, | ||
| 279 | }; | ||
| 280 | |||
| 281 | let exti: EXTI = unsafe { mem::transmute(()) }; | ||
| 282 | let mut exti = Exti::new(exti); | ||
| 283 | let port = self.port(); | ||
| 284 | let mut syscfg: SYSCFG = unsafe { mem::transmute(()) }; | ||
| 285 | let line = GpioLine::from_raw_line(self.pin_number()).unwrap(); | ||
| 286 | exti.listen_gpio(&mut syscfg, port, line, edge); | ||
| 287 | } | ||
| 288 | } | ||
| 289 | )+ | ||
| 156 | }; | 290 | }; |
| 157 | } | 291 | } |
| 158 | 292 | ||
| @@ -533,3 +667,111 @@ exti!(gpiok, [ | |||
| 533 | EXTI9_5 => PK6, | 667 | EXTI9_5 => PK6, |
| 534 | EXTI9_5 => PK7, | 668 | EXTI9_5 => PK7, |
| 535 | ]); | 669 | ]); |
| 670 | |||
| 671 | #[cfg(any(feature = "stm32l0x1", feature = "stm32l0x2", feature = "stm32l0x3",))] | ||
| 672 | exti!(gpioa, [ | ||
| 673 | EXTI0_1 => PA0, | ||
| 674 | EXTI0_1 => PA1, | ||
| 675 | EXTI2_3 => PA2, | ||
| 676 | EXTI2_3 => PA3, | ||
| 677 | EXTI4_15 => PA4, | ||
| 678 | EXTI4_15 => PA5, | ||
| 679 | EXTI4_15 => PA6, | ||
| 680 | EXTI4_15 => PA7, | ||
| 681 | EXTI4_15 => PA8, | ||
| 682 | EXTI4_15 => PA9, | ||
| 683 | EXTI4_15 => PA10, | ||
| 684 | EXTI4_15 => PA11, | ||
| 685 | EXTI4_15 => PA12, | ||
| 686 | EXTI4_15 => PA13, | ||
| 687 | EXTI4_15 => PA14, | ||
| 688 | EXTI4_15 => PA15, | ||
| 689 | ]); | ||
| 690 | |||
| 691 | #[cfg(any(feature = "stm32l0x1", feature = "stm32l0x2", feature = "stm32l0x3",))] | ||
| 692 | exti!(gpiob, [ | ||
| 693 | EXTI0_1 => PB0, | ||
| 694 | EXTI0_1 => PB1, | ||
| 695 | EXTI2_3 => PB2, | ||
| 696 | EXTI2_3 => PB3, | ||
| 697 | EXTI4_15 => PB4, | ||
| 698 | EXTI4_15 => PB5, | ||
| 699 | EXTI4_15 => PB6, | ||
| 700 | EXTI4_15 => PB7, | ||
| 701 | EXTI4_15 => PB8, | ||
| 702 | EXTI4_15 => PB9, | ||
| 703 | EXTI4_15 => PB10, | ||
| 704 | EXTI4_15 => PB11, | ||
| 705 | EXTI4_15 => PB12, | ||
| 706 | EXTI4_15 => PB13, | ||
| 707 | EXTI4_15 => PB14, | ||
| 708 | EXTI4_15 => PB15, | ||
| 709 | ]); | ||
| 710 | |||
| 711 | #[cfg(any(feature = "stm32l0x1", feature = "stm32l0x2", feature = "stm32l0x3",))] | ||
| 712 | exti!(gpioc, [ | ||
| 713 | EXTI0_1 => PC0, | ||
| 714 | EXTI0_1 => PC1, | ||
| 715 | EXTI2_3 => PC2, | ||
| 716 | EXTI2_3 => PC3, | ||
| 717 | EXTI4_15 => PC4, | ||
| 718 | EXTI4_15 => PC5, | ||
| 719 | EXTI4_15 => PC6, | ||
| 720 | EXTI4_15 => PC7, | ||
| 721 | EXTI4_15 => PC8, | ||
| 722 | EXTI4_15 => PC9, | ||
| 723 | EXTI4_15 => PC10, | ||
| 724 | EXTI4_15 => PC11, | ||
| 725 | EXTI4_15 => PC12, | ||
| 726 | EXTI4_15 => PC13, | ||
| 727 | EXTI4_15 => PC14, | ||
| 728 | EXTI4_15 => PC15, | ||
| 729 | ]); | ||
| 730 | |||
| 731 | #[cfg(any(feature = "stm32l0x1", feature = "stm32l0x2", feature = "stm32l0x3",))] | ||
| 732 | exti!(gpiod, [ | ||
| 733 | EXTI0_1 => PD0, | ||
| 734 | EXTI0_1 => PD1, | ||
| 735 | EXTI2_3 => PD2, | ||
| 736 | EXTI2_3 => PD3, | ||
| 737 | EXTI4_15 => PD4, | ||
| 738 | EXTI4_15 => PD5, | ||
| 739 | EXTI4_15 => PD6, | ||
| 740 | EXTI4_15 => PD7, | ||
| 741 | EXTI4_15 => PD8, | ||
| 742 | EXTI4_15 => PD9, | ||
| 743 | EXTI4_15 => PD10, | ||
| 744 | EXTI4_15 => PD11, | ||
| 745 | EXTI4_15 => PD12, | ||
| 746 | EXTI4_15 => PD13, | ||
| 747 | EXTI4_15 => PD14, | ||
| 748 | EXTI4_15 => PD15, | ||
| 749 | ]); | ||
| 750 | |||
| 751 | #[cfg(any(feature = "stm32l0x1", feature = "stm32l0x2", feature = "stm32l0x3",))] | ||
| 752 | exti!(gpioe, [ | ||
| 753 | EXTI0_1 => PE0, | ||
| 754 | EXTI0_1 => PE1, | ||
| 755 | EXTI2_3 => PE2, | ||
| 756 | EXTI2_3 => PE3, | ||
| 757 | EXTI4_15 => PE4, | ||
| 758 | EXTI4_15 => PE5, | ||
| 759 | EXTI4_15 => PE6, | ||
| 760 | EXTI4_15 => PE7, | ||
| 761 | EXTI4_15 => PE8, | ||
| 762 | EXTI4_15 => PE9, | ||
| 763 | EXTI4_15 => PE10, | ||
| 764 | EXTI4_15 => PE11, | ||
| 765 | EXTI4_15 => PE12, | ||
| 766 | EXTI4_15 => PE13, | ||
| 767 | EXTI4_15 => PE14, | ||
| 768 | EXTI4_15 => PE15, | ||
| 769 | ]); | ||
| 770 | |||
| 771 | #[cfg(any(feature = "stm32l0x1", feature = "stm32l0x2", feature = "stm32l0x3",))] | ||
| 772 | exti!(gpioh, [ | ||
| 773 | EXTI0_1 => PH0, | ||
| 774 | EXTI0_1 => PH1, | ||
| 775 | EXTI4_15 => PH9, | ||
| 776 | EXTI4_15 => PH10, | ||
| 777 | ]); | ||
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index a1f40b2c7..954067f32 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs | |||
| @@ -32,4 +32,5 @@ pub use {stm32l0xx_hal as hal, stm32l0xx_hal::pac}; | |||
| 32 | 32 | ||
| 33 | pub mod fmt; | 33 | pub mod fmt; |
| 34 | 34 | ||
| 35 | pub mod exti; | ||
| 35 | pub mod interrupt; | 36 | pub mod interrupt; |
diff --git a/embassy-stm32f4/src/lib.rs b/embassy-stm32f4/src/lib.rs index 0d490525c..bdd4d0fda 100644 --- a/embassy-stm32f4/src/lib.rs +++ b/embassy-stm32f4/src/lib.rs | |||
| @@ -307,11 +307,10 @@ compile_error!( | |||
| 307 | "Multile chip features activated. You must activate exactly one of the following features: " | 307 | "Multile chip features activated. You must activate exactly one of the following features: " |
| 308 | ); | 308 | ); |
| 309 | 309 | ||
| 310 | pub use embassy_stm32::{fmt, hal, interrupt, pac}; | 310 | pub use embassy_stm32::{exti, fmt, hal, interrupt, pac}; |
| 311 | 311 | ||
| 312 | #[cfg(not(any(feature = "stm32f401", feature = "stm32f410", feature = "stm32f411",)))] | 312 | #[cfg(not(any(feature = "stm32f401", feature = "stm32f410", feature = "stm32f411",)))] |
| 313 | pub mod can; | 313 | pub mod can; |
| 314 | pub mod exti; | ||
| 315 | #[cfg(not(feature = "stm32f410"))] | 314 | #[cfg(not(feature = "stm32f410"))] |
| 316 | pub mod qei; | 315 | pub mod qei; |
| 317 | pub mod rtc; | 316 | pub mod rtc; |
diff --git a/embassy-stm32l0/src/exti.rs b/embassy-stm32l0/src/exti.rs deleted file mode 100644 index f50c3ae8e..000000000 --- a/embassy-stm32l0/src/exti.rs +++ /dev/null | |||
| @@ -1,268 +0,0 @@ | |||
| 1 | use core::future::Future; | ||
| 2 | use core::mem; | ||
| 3 | use core::pin::Pin; | ||
| 4 | |||
| 5 | use embassy::traits::gpio::{ | ||
| 6 | WaitForAnyEdge, WaitForFallingEdge, WaitForHigh, WaitForLow, WaitForRisingEdge, | ||
| 7 | }; | ||
| 8 | use embassy::util::InterruptFuture; | ||
| 9 | |||
| 10 | use crate::hal::{ | ||
| 11 | exti::{Exti, ExtiLine, GpioLine, TriggerEdge}, | ||
| 12 | gpio, | ||
| 13 | syscfg::SYSCFG, | ||
| 14 | }; | ||
| 15 | use crate::interrupt; | ||
| 16 | use crate::pac::EXTI; | ||
| 17 | use embedded_hal::digital::v2::InputPin; | ||
| 18 | |||
| 19 | pub struct ExtiPin<T: PinWithInterrupt> { | ||
| 20 | pin: T, | ||
| 21 | interrupt: T::Interrupt, | ||
| 22 | } | ||
| 23 | |||
| 24 | impl<T: PinWithInterrupt + 'static> ExtiPin<T> { | ||
| 25 | pub fn new(pin: T, interrupt: T::Interrupt) -> ExtiPin<T> { | ||
| 26 | ExtiPin { pin, interrupt } | ||
| 27 | } | ||
| 28 | |||
| 29 | fn wait_for_edge<'a>( | ||
| 30 | self: Pin<&'a mut Self>, | ||
| 31 | edge: TriggerEdge, | ||
| 32 | ) -> impl Future<Output = ()> + 'a { | ||
| 33 | let line = self.pin.line(); | ||
| 34 | let s = unsafe { self.get_unchecked_mut() }; | ||
| 35 | |||
| 36 | Exti::unpend(line); | ||
| 37 | |||
| 38 | async move { | ||
| 39 | let exti: EXTI = unsafe { mem::transmute(()) }; | ||
| 40 | let mut exti = Exti::new(exti); | ||
| 41 | |||
| 42 | let fut = InterruptFuture::new(&mut s.interrupt); | ||
| 43 | |||
| 44 | let port = s.pin.port(); | ||
| 45 | cortex_m::interrupt::free(|_| { | ||
| 46 | let mut syscfg: SYSCFG = unsafe { mem::transmute(()) }; | ||
| 47 | exti.listen_gpio(&mut syscfg, port, line, edge); | ||
| 48 | }); | ||
| 49 | |||
| 50 | fut.await; | ||
| 51 | |||
| 52 | Exti::unpend(line); | ||
| 53 | } | ||
| 54 | } | ||
| 55 | } | ||
| 56 | |||
| 57 | impl<T: InputPin + PinWithInterrupt + 'static> ExtiPin<T> { | ||
| 58 | fn wait_for_state<'a>(self: Pin<&'a mut Self>, state: bool) -> impl Future<Output = ()> + 'a { | ||
| 59 | let line = self.pin.line(); | ||
| 60 | let s = unsafe { self.get_unchecked_mut() }; | ||
| 61 | |||
| 62 | Exti::unpend(line); | ||
| 63 | |||
| 64 | async move { | ||
| 65 | let exti: EXTI = unsafe { mem::transmute(()) }; | ||
| 66 | let mut exti = Exti::new(exti); | ||
| 67 | |||
| 68 | let fut = InterruptFuture::new(&mut s.interrupt); | ||
| 69 | |||
| 70 | let port = s.pin.port(); | ||
| 71 | cortex_m::interrupt::free(|_| { | ||
| 72 | let mut syscfg: SYSCFG = unsafe { mem::transmute(()) }; | ||
| 73 | let edge = if state { | ||
| 74 | TriggerEdge::Rising | ||
| 75 | } else { | ||
| 76 | TriggerEdge::Falling | ||
| 77 | }; | ||
| 78 | exti.listen_gpio(&mut syscfg, port, line, edge); | ||
| 79 | }); | ||
| 80 | |||
| 81 | let pin_has_state = if state { | ||
| 82 | s.pin.is_high() | ||
| 83 | } else { | ||
| 84 | s.pin.is_low() | ||
| 85 | } | ||
| 86 | .unwrap_or(false); | ||
| 87 | if pin_has_state { | ||
| 88 | return (); | ||
| 89 | } | ||
| 90 | |||
| 91 | fut.await; | ||
| 92 | |||
| 93 | Exti::unpend(line); | ||
| 94 | } | ||
| 95 | } | ||
| 96 | } | ||
| 97 | |||
| 98 | impl<T: PinWithInterrupt + 'static> WaitForRisingEdge for ExtiPin<T> { | ||
| 99 | type Future<'a> = impl Future<Output = ()> + 'a; | ||
| 100 | |||
| 101 | fn wait_for_rising_edge<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> { | ||
| 102 | self.wait_for_edge(TriggerEdge::Rising) | ||
| 103 | } | ||
| 104 | } | ||
| 105 | |||
| 106 | impl<T: PinWithInterrupt + 'static> WaitForFallingEdge for ExtiPin<T> { | ||
| 107 | type Future<'a> = impl Future<Output = ()> + 'a; | ||
| 108 | |||
| 109 | fn wait_for_falling_edge<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> { | ||
| 110 | self.wait_for_edge(TriggerEdge::Falling) | ||
| 111 | } | ||
| 112 | } | ||
| 113 | |||
| 114 | impl<T: PinWithInterrupt + 'static> WaitForAnyEdge for ExtiPin<T> { | ||
| 115 | type Future<'a> = impl Future<Output = ()> + 'a; | ||
| 116 | |||
| 117 | fn wait_for_any_edge<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> { | ||
| 118 | self.wait_for_edge(TriggerEdge::Both) | ||
| 119 | } | ||
| 120 | } | ||
| 121 | |||
| 122 | impl<T: InputPin + PinWithInterrupt + 'static> WaitForHigh for ExtiPin<T> { | ||
| 123 | type Future<'a> = impl Future<Output = ()> + 'a; | ||
| 124 | |||
| 125 | fn wait_for_high<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> { | ||
| 126 | self.wait_for_state(true) | ||
| 127 | } | ||
| 128 | } | ||
| 129 | |||
| 130 | impl<T: InputPin + PinWithInterrupt + 'static> WaitForLow for ExtiPin<T> { | ||
| 131 | type Future<'a> = impl Future<Output = ()> + 'a; | ||
| 132 | |||
| 133 | fn wait_for_low<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> { | ||
| 134 | self.wait_for_state(false) | ||
| 135 | } | ||
| 136 | } | ||
| 137 | |||
| 138 | mod private { | ||
| 139 | pub trait Sealed {} | ||
| 140 | } | ||
| 141 | |||
| 142 | pub trait PinWithInterrupt: private::Sealed { | ||
| 143 | type Interrupt: interrupt::Interrupt; | ||
| 144 | fn port(&self) -> gpio::Port; | ||
| 145 | fn line(&self) -> GpioLine; | ||
| 146 | } | ||
| 147 | |||
| 148 | macro_rules! exti { | ||
| 149 | ($set:ident, [ | ||
| 150 | $($INT:ident => $pin:ident,)+ | ||
| 151 | ]) => { | ||
| 152 | $( | ||
| 153 | impl<T> private::Sealed for gpio::$set::$pin<T> {} | ||
| 154 | impl<T> PinWithInterrupt for gpio::$set::$pin<T> { | ||
| 155 | type Interrupt = interrupt::$INT; | ||
| 156 | fn port(&self) -> gpio::Port { | ||
| 157 | self.port() | ||
| 158 | } | ||
| 159 | fn line(&self) -> GpioLine { | ||
| 160 | GpioLine::from_raw_line(self.pin_number()).unwrap() | ||
| 161 | } | ||
| 162 | } | ||
| 163 | )+ | ||
| 164 | |||
| 165 | }; | ||
| 166 | } | ||
| 167 | |||
| 168 | exti!(gpioa, [ | ||
| 169 | EXTI0_1 => PA0, | ||
| 170 | EXTI0_1 => PA1, | ||
| 171 | EXTI2_3 => PA2, | ||
| 172 | EXTI2_3 => PA3, | ||
| 173 | EXTI4_15 => PA4, | ||
| 174 | EXTI4_15 => PA5, | ||
| 175 | EXTI4_15 => PA6, | ||
| 176 | EXTI4_15 => PA7, | ||
| 177 | EXTI4_15 => PA8, | ||
| 178 | EXTI4_15 => PA9, | ||
| 179 | EXTI4_15 => PA10, | ||
| 180 | EXTI4_15 => PA11, | ||
| 181 | EXTI4_15 => PA12, | ||
| 182 | EXTI4_15 => PA13, | ||
| 183 | EXTI4_15 => PA14, | ||
| 184 | EXTI4_15 => PA15, | ||
| 185 | ]); | ||
| 186 | |||
| 187 | exti!(gpiob, [ | ||
| 188 | EXTI0_1 => PB0, | ||
| 189 | EXTI0_1 => PB1, | ||
| 190 | EXTI2_3 => PB2, | ||
| 191 | EXTI2_3 => PB3, | ||
| 192 | EXTI4_15 => PB4, | ||
| 193 | EXTI4_15 => PB5, | ||
| 194 | EXTI4_15 => PB6, | ||
| 195 | EXTI4_15 => PB7, | ||
| 196 | EXTI4_15 => PB8, | ||
| 197 | EXTI4_15 => PB9, | ||
| 198 | EXTI4_15 => PB10, | ||
| 199 | EXTI4_15 => PB11, | ||
| 200 | EXTI4_15 => PB12, | ||
| 201 | EXTI4_15 => PB13, | ||
| 202 | EXTI4_15 => PB14, | ||
| 203 | EXTI4_15 => PB15, | ||
| 204 | ]); | ||
| 205 | |||
| 206 | exti!(gpioc, [ | ||
| 207 | EXTI0_1 => PC0, | ||
| 208 | EXTI0_1 => PC1, | ||
| 209 | EXTI2_3 => PC2, | ||
| 210 | EXTI2_3 => PC3, | ||
| 211 | EXTI4_15 => PC4, | ||
| 212 | EXTI4_15 => PC5, | ||
| 213 | EXTI4_15 => PC6, | ||
| 214 | EXTI4_15 => PC7, | ||
| 215 | EXTI4_15 => PC8, | ||
| 216 | EXTI4_15 => PC9, | ||
| 217 | EXTI4_15 => PC10, | ||
| 218 | EXTI4_15 => PC11, | ||
| 219 | EXTI4_15 => PC12, | ||
| 220 | EXTI4_15 => PC13, | ||
| 221 | EXTI4_15 => PC14, | ||
| 222 | EXTI4_15 => PC15, | ||
| 223 | ]); | ||
| 224 | |||
| 225 | exti!(gpiod, [ | ||
| 226 | EXTI0_1 => PD0, | ||
| 227 | EXTI0_1 => PD1, | ||
| 228 | EXTI2_3 => PD2, | ||
| 229 | EXTI2_3 => PD3, | ||
| 230 | EXTI4_15 => PD4, | ||
| 231 | EXTI4_15 => PD5, | ||
| 232 | EXTI4_15 => PD6, | ||
| 233 | EXTI4_15 => PD7, | ||
| 234 | EXTI4_15 => PD8, | ||
| 235 | EXTI4_15 => PD9, | ||
| 236 | EXTI4_15 => PD10, | ||
| 237 | EXTI4_15 => PD11, | ||
| 238 | EXTI4_15 => PD12, | ||
| 239 | EXTI4_15 => PD13, | ||
| 240 | EXTI4_15 => PD14, | ||
| 241 | EXTI4_15 => PD15, | ||
| 242 | ]); | ||
| 243 | |||
| 244 | exti!(gpioe, [ | ||
| 245 | EXTI0_1 => PE0, | ||
| 246 | EXTI0_1 => PE1, | ||
| 247 | EXTI2_3 => PE2, | ||
| 248 | EXTI2_3 => PE3, | ||
| 249 | EXTI4_15 => PE4, | ||
| 250 | EXTI4_15 => PE5, | ||
| 251 | EXTI4_15 => PE6, | ||
| 252 | EXTI4_15 => PE7, | ||
| 253 | EXTI4_15 => PE8, | ||
| 254 | EXTI4_15 => PE9, | ||
| 255 | EXTI4_15 => PE10, | ||
| 256 | EXTI4_15 => PE11, | ||
| 257 | EXTI4_15 => PE12, | ||
| 258 | EXTI4_15 => PE13, | ||
| 259 | EXTI4_15 => PE14, | ||
| 260 | EXTI4_15 => PE15, | ||
| 261 | ]); | ||
| 262 | |||
| 263 | exti!(gpioh, [ | ||
| 264 | EXTI0_1 => PH0, | ||
| 265 | EXTI0_1 => PH1, | ||
| 266 | EXTI4_15 => PH9, | ||
| 267 | EXTI4_15 => PH10, | ||
| 268 | ]); | ||
diff --git a/embassy-stm32l0/src/lib.rs b/embassy-stm32l0/src/lib.rs index e80fe6cb4..a684c4e3e 100644 --- a/embassy-stm32l0/src/lib.rs +++ b/embassy-stm32l0/src/lib.rs | |||
| @@ -19,6 +19,4 @@ compile_error!( | |||
| 19 | "Multile chip features activated. You must activate exactly one of the following features: " | 19 | "Multile chip features activated. You must activate exactly one of the following features: " |
| 20 | ); | 20 | ); |
| 21 | 21 | ||
| 22 | pub use embassy_stm32::{fmt, hal, interrupt, pac}; | 22 | pub use embassy_stm32::{exti, fmt, hal, interrupt, pac}; |
| 23 | |||
| 24 | pub mod exti; | ||
