diff --git a/embassy-stm32f4-examples/src/bin/exti.rs b/embassy-stm32f4-examples/src/bin/exti.rs index 0c6561cd..2201189e 100644 --- a/embassy-stm32f4-examples/src/bin/exti.rs +++ b/embassy-stm32f4-examples/src/bin/exti.rs @@ -13,22 +13,19 @@ use cortex_m_rt::entry; use embassy::executor::{task, Executor}; use embassy::traits::gpio::*; use embassy::util::Forever; -use embassy_stm32f4::exti; +use embassy_stm32f4::exti::ExtiPin; use embassy_stm32f4::interrupt; use futures::pin_mut; use stm32f4xx_hal::prelude::*; use stm32f4xx_hal::stm32; -static EXTI: Forever = Forever::new(); - #[task] async fn run(dp: stm32::Peripherals, _cp: cortex_m::Peripherals) { let gpioa = dp.GPIOA.split(); let button = gpioa.pa0.into_pull_up_input(); - let exti = EXTI.put(exti::ExtiManager::new(dp.EXTI, dp.SYSCFG.constrain())); - let pin = exti.new_pin(button, interrupt::take!(EXTI0)); + let pin = ExtiPin::new(button, interrupt::take!(EXTI0)); pin_mut!(pin); info!("Starting loop"); diff --git a/embassy-stm32f4/src/exti.rs b/embassy-stm32f4/src/exti.rs index 660e3be3..9df02163 100644 --- a/embassy-stm32f4/src/exti.rs +++ b/embassy-stm32f4/src/exti.rs @@ -1,48 +1,38 @@ +use core::cell::UnsafeCell; use core::future::Future; use core::mem; use core::pin::Pin; +use cortex_m; use embassy::traits::gpio::{WaitForFallingEdge, WaitForRisingEdge}; use embassy::util::InterruptFuture; use crate::hal::gpio; -use crate::hal::gpio::{Edge, ExtiPin as HalExtiPin}; +use crate::hal::gpio::Edge; use crate::hal::syscfg::SysCfg; use crate::pac::EXTI; use embedded_hal::digital::v2 as digital; use crate::interrupt; -pub struct ExtiManager { - syscfg: SysCfg, -} - -impl<'a> ExtiManager { - pub fn new(_exti: EXTI, syscfg: SysCfg) -> Self { - Self { syscfg } - } - - pub fn new_pin(&'static mut self, mut pin: T, interrupt: T::Interrupt) -> ExtiPin - where - T: HalExtiPin + WithInterrupt, - { - pin.make_interrupt_source(&mut self.syscfg); - - ExtiPin { - pin, - interrupt, - _mgr: self, - } - } -} - -pub struct ExtiPin { +pub struct ExtiPin { pin: T, interrupt: T::Interrupt, - _mgr: &'static ExtiManager, } -impl digital::OutputPin for ExtiPin { +impl ExtiPin { + pub fn new(mut pin: T, interrupt: T::Interrupt) -> Self { + let mut syscfg: SysCfg = unsafe { mem::transmute(()) }; + + cortex_m::interrupt::free(|_| { + pin.make_interrupt_source(&mut syscfg); + }); + + Self { pin, interrupt } + } +} + +impl digital::OutputPin for ExtiPin { type Error = T::Error; fn set_low(&mut self) -> Result<(), Self::Error> { @@ -54,7 +44,7 @@ impl digital::OutputPin for } } -impl digital::StatefulOutputPin +impl digital::StatefulOutputPin for ExtiPin { fn is_set_low(&self) -> Result { @@ -66,7 +56,7 @@ impl digital::Statef } } -impl digital::ToggleableOutputPin +impl digital::ToggleableOutputPin for ExtiPin { type Error = T::Error; @@ -76,7 +66,7 @@ impl digital::Togg } } -impl digital::InputPin for ExtiPin { +impl digital::InputPin for ExtiPin { type Error = T::Error; fn is_high(&self) -> Result { @@ -99,7 +89,7 @@ impl digital::InputPin for Ex EXTI15_10_IRQn EXTI15_10_IRQHandler Handler for pins connected to line 10 to 15 */ -impl WaitForRisingEdge for ExtiPin { +impl WaitForRisingEdge for ExtiPin { type Future<'a> = impl Future + 'a; fn wait_for_rising_edge<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> { @@ -108,10 +98,13 @@ impl WaitForRisingEdge for ExtiPin { s.pin.clear_interrupt_pending_bit(); async move { let fut = InterruptFuture::new(&mut s.interrupt); - let mut exti: EXTI = unsafe { mem::transmute(()) }; + let pin = &mut s.pin; + cortex_m::interrupt::free(|_| { + let mut exti: EXTI = unsafe { mem::transmute(()) }; - s.pin.trigger_on_edge(&mut exti, Edge::RISING); - s.pin.enable_interrupt(&mut exti); + pin.trigger_on_edge(&mut exti, Edge::RISING); + pin.enable_interrupt(&mut exti); + }); fut.await; s.pin.clear_interrupt_pending_bit(); @@ -119,7 +112,7 @@ impl WaitForRisingEdge for ExtiPin { } } -impl WaitForFallingEdge for ExtiPin { +impl WaitForFallingEdge for ExtiPin { type Future<'a> = impl Future + 'a; fn wait_for_falling_edge<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> { @@ -128,10 +121,13 @@ impl WaitForFallingEdge for ExtiPin s.pin.clear_interrupt_pending_bit(); async move { let fut = InterruptFuture::new(&mut s.interrupt); - let mut exti: EXTI = unsafe { mem::transmute(()) }; + let pin = &mut s.pin; + cortex_m::interrupt::free(|_| { + let mut exti: EXTI = unsafe { mem::transmute(()) }; - s.pin.trigger_on_edge(&mut exti, Edge::FALLING); - s.pin.enable_interrupt(&mut exti); + pin.trigger_on_edge(&mut exti, Edge::FALLING); + pin.enable_interrupt(&mut exti); + }); fut.await; s.pin.clear_interrupt_pending_bit(); diff --git a/embassy-stm32l0/src/exti.rs b/embassy-stm32l0/src/exti.rs index c93d213e..32c56c49 100644 --- a/embassy-stm32l0/src/exti.rs +++ b/embassy-stm32l0/src/exti.rs @@ -13,34 +13,16 @@ use crate::hal::{ use crate::interrupt; use crate::pac::EXTI; -pub struct ExtiManager { - syscfg: SYSCFG, -} - -impl<'a> ExtiManager { - pub fn new(_exti: Exti, syscfg: SYSCFG) -> Self { - Self { syscfg } - } - - pub fn new_pin(&'static mut self, pin: T, interrupt: T::Interrupt) -> ExtiPin - where - T: PinWithInterrupt, - { - ExtiPin { - pin, - interrupt, - mgr: self, - } - } -} - pub struct ExtiPin { pin: T, interrupt: T::Interrupt, - mgr: &'static ExtiManager, } impl ExtiPin { + pub fn new(pin: T, interrupt: T::Interrupt) -> ExtiPin { + ExtiPin { pin, interrupt } + } + fn wait_for_edge<'a>( self: Pin<&'a mut Self>, edge: TriggerEdge, @@ -57,10 +39,9 @@ impl ExtiPin { let fut = InterruptFuture::new(&mut s.interrupt); let port = s.pin.port(); - let syscfg = &s.mgr.syscfg as *const _ as *mut SYSCFG; cortex_m::interrupt::free(|_| { - let syscfg = unsafe { &mut *syscfg }; - exti.listen_gpio(syscfg, port, line, edge); + let mut syscfg: SYSCFG = unsafe { mem::transmute(()) }; + exti.listen_gpio(&mut syscfg, port, line, edge); }); fut.await; @@ -105,11 +86,13 @@ pub trait PinWithInterrupt: private::Sealed { } macro_rules! exti { - ($($PER:ident => ($set:ident, $pin:ident),)+) => { + ($set:ident, [ + $($INT:ident => $pin:ident,)+ + ]) => { $( impl private::Sealed for gpio::$set::$pin {} impl PinWithInterrupt for gpio::$set::$pin { - type Interrupt = interrupt::$PER; + type Interrupt = interrupt::$INT; fn port(&self) -> gpio::Port { self.port() } @@ -118,107 +101,108 @@ macro_rules! exti { } } )+ - } + + }; } -exti! { - EXTI0_1 => (gpioa, PA0), - EXTI0_1 => (gpioa, PA1), - EXTI2_3 => (gpioa, PA2), - EXTI2_3 => (gpioa, PA3), - EXTI4_15 => (gpioa, PA4), - EXTI4_15 => (gpioa, PA5), - EXTI4_15 => (gpioa, PA6), - EXTI4_15 => (gpioa, PA7), - EXTI4_15 => (gpioa, PA8), - EXTI4_15 => (gpioa, PA9), - EXTI4_15 => (gpioa, PA10), - EXTI4_15 => (gpioa, PA11), - EXTI4_15 => (gpioa, PA12), - EXTI4_15 => (gpioa, PA13), - EXTI4_15 => (gpioa, PA14), - EXTI4_15 => (gpioa, PA15), -} +exti!(gpioa, [ + EXTI0_1 => PA0, + EXTI0_1 => PA1, + EXTI2_3 => PA2, + EXTI2_3 => PA3, + EXTI4_15 => PA4, + EXTI4_15 => PA5, + EXTI4_15 => PA6, + EXTI4_15 => PA7, + EXTI4_15 => PA8, + EXTI4_15 => PA9, + EXTI4_15 => PA10, + EXTI4_15 => PA11, + EXTI4_15 => PA12, + EXTI4_15 => PA13, + EXTI4_15 => PA14, + EXTI4_15 => PA15, +]); -exti! { - EXTI0_1 => (gpiob, PB0), - EXTI0_1 => (gpiob, PB1), - EXTI2_3 => (gpiob, PB2), - EXTI2_3 => (gpiob, PB3), - EXTI4_15 => (gpiob, PB4), - EXTI4_15 => (gpiob, PB5), - EXTI4_15 => (gpiob, PB6), - EXTI4_15 => (gpiob, PB7), - EXTI4_15 => (gpiob, PB8), - EXTI4_15 => (gpiob, PB9), - EXTI4_15 => (gpiob, PB10), - EXTI4_15 => (gpiob, PB11), - EXTI4_15 => (gpiob, PB12), - EXTI4_15 => (gpiob, PB13), - EXTI4_15 => (gpiob, PB14), - EXTI4_15 => (gpiob, PB15), -} +exti!(gpiob, [ + EXTI0_1 => PB0, + EXTI0_1 => PB1, + EXTI2_3 => PB2, + EXTI2_3 => PB3, + EXTI4_15 => PB4, + EXTI4_15 => PB5, + EXTI4_15 => PB6, + EXTI4_15 => PB7, + EXTI4_15 => PB8, + EXTI4_15 => PB9, + EXTI4_15 => PB10, + EXTI4_15 => PB11, + EXTI4_15 => PB12, + EXTI4_15 => PB13, + EXTI4_15 => PB14, + EXTI4_15 => PB15, +]); -exti! { - EXTI0_1 => (gpioc, PC0), - EXTI0_1 => (gpioc, PC1), - EXTI2_3 => (gpioc, PC2), - EXTI2_3 => (gpioc, PC3), - EXTI4_15 => (gpioc, PC4), - EXTI4_15 => (gpioc, PC5), - EXTI4_15 => (gpioc, PC6), - EXTI4_15 => (gpioc, PC7), - EXTI4_15 => (gpioc, PC8), - EXTI4_15 => (gpioc, PC9), - EXTI4_15 => (gpioc, PC10), - EXTI4_15 => (gpioc, PC11), - EXTI4_15 => (gpioc, PC12), - EXTI4_15 => (gpioc, PC13), - EXTI4_15 => (gpioc, PC14), - EXTI4_15 => (gpioc, PC15), -} +exti!(gpioc, [ + EXTI0_1 => PC0, + EXTI0_1 => PC1, + EXTI2_3 => PC2, + EXTI2_3 => PC3, + EXTI4_15 => PC4, + EXTI4_15 => PC5, + EXTI4_15 => PC6, + EXTI4_15 => PC7, + EXTI4_15 => PC8, + EXTI4_15 => PC9, + EXTI4_15 => PC10, + EXTI4_15 => PC11, + EXTI4_15 => PC12, + EXTI4_15 => PC13, + EXTI4_15 => PC14, + EXTI4_15 => PC15, +]); -exti! { - EXTI0_1 => (gpiod, PD0), - EXTI0_1 => (gpiod, PD1), - EXTI2_3 => (gpiod, PD2), - EXTI2_3 => (gpiod, PD3), - EXTI4_15 => (gpiod, PD4), - EXTI4_15 => (gpiod, PD5), - EXTI4_15 => (gpiod, PD6), - EXTI4_15 => (gpiod, PD7), - EXTI4_15 => (gpiod, PD8), - EXTI4_15 => (gpiod, PD9), - EXTI4_15 => (gpiod, PD10), - EXTI4_15 => (gpiod, PD11), - EXTI4_15 => (gpiod, PD12), - EXTI4_15 => (gpiod, PD13), - EXTI4_15 => (gpiod, PD14), - EXTI4_15 => (gpiod, PD15), -} +exti!(gpiod, [ + EXTI0_1 => PD0, + EXTI0_1 => PD1, + EXTI2_3 => PD2, + EXTI2_3 => PD3, + EXTI4_15 => PD4, + EXTI4_15 => PD5, + EXTI4_15 => PD6, + EXTI4_15 => PD7, + EXTI4_15 => PD8, + EXTI4_15 => PD9, + EXTI4_15 => PD10, + EXTI4_15 => PD11, + EXTI4_15 => PD12, + EXTI4_15 => PD13, + EXTI4_15 => PD14, + EXTI4_15 => PD15, +]); -exti! { - EXTI0_1 => (gpioe, PE0), - EXTI0_1 => (gpioe, PE1), - EXTI2_3 => (gpioe, PE2), - EXTI2_3 => (gpioe, PE3), - EXTI4_15 => (gpioe, PE4), - EXTI4_15 => (gpioe, PE5), - EXTI4_15 => (gpioe, PE6), - EXTI4_15 => (gpioe, PE7), - EXTI4_15 => (gpioe, PE8), - EXTI4_15 => (gpioe, PE9), - EXTI4_15 => (gpioe, PE10), - EXTI4_15 => (gpioe, PE11), - EXTI4_15 => (gpioe, PE12), - EXTI4_15 => (gpioe, PE13), - EXTI4_15 => (gpioe, PE14), - EXTI4_15 => (gpioe, PE15), -} +exti!(gpioe, [ + EXTI0_1 => PE0, + EXTI0_1 => PE1, + EXTI2_3 => PE2, + EXTI2_3 => PE3, + EXTI4_15 => PE4, + EXTI4_15 => PE5, + EXTI4_15 => PE6, + EXTI4_15 => PE7, + EXTI4_15 => PE8, + EXTI4_15 => PE9, + EXTI4_15 => PE10, + EXTI4_15 => PE11, + EXTI4_15 => PE12, + EXTI4_15 => PE13, + EXTI4_15 => PE14, + EXTI4_15 => PE15, +]); -exti! { - EXTI0_1 => (gpioh, PH0), - EXTI0_1 => (gpioh, PH1), - EXTI4_15 => (gpioh, PH9), - EXTI4_15 => (gpioh, PH10), -} +exti!(gpioh, [ + EXTI0_1 => PH0, + EXTI0_1 => PH1, + EXTI4_15 => PH9, + EXTI4_15 => PH10, +]);