From bf39822092f05dee0ab4d7efd6296e9873555da2 Mon Sep 17 00:00:00 2001 From: xoviat Date: Sat, 20 Mar 2021 11:07:16 -0500 Subject: consolidate ExtiPin into stm32 package --- embassy-stm32/src/exti.rs | 777 ++++++++++++++++++++++++++++++++++++++++++++ embassy-stm32/src/lib.rs | 1 + embassy-stm32f4/src/exti.rs | 535 ------------------------------ embassy-stm32f4/src/lib.rs | 3 +- embassy-stm32l0/src/exti.rs | 268 --------------- embassy-stm32l0/src/lib.rs | 4 +- 6 files changed, 780 insertions(+), 808 deletions(-) create mode 100644 embassy-stm32/src/exti.rs delete mode 100644 embassy-stm32f4/src/exti.rs delete mode 100644 embassy-stm32l0/src/exti.rs diff --git a/embassy-stm32/src/exti.rs b/embassy-stm32/src/exti.rs new file mode 100644 index 000000000..a00079450 --- /dev/null +++ b/embassy-stm32/src/exti.rs @@ -0,0 +1,777 @@ +use core::future::Future; +use core::mem; +use core::pin::Pin; +use cortex_m; + +use crate::hal::gpio; + +use embassy::traits::gpio::{ + WaitForAnyEdge, WaitForFallingEdge, WaitForHigh, WaitForLow, WaitForRisingEdge, +}; +use embassy::util::InterruptFuture; + +use embedded_hal::digital::v2 as digital; + +use crate::interrupt; + +pub struct ExtiPin { + pin: T, + interrupt: T::Interrupt, +} + +impl ExtiPin { + pub fn new(mut pin: T, interrupt: T::Interrupt) -> Self { + cortex_m::interrupt::free(|_| { + pin.make_source(); + }); + + Self { pin, interrupt } + } +} + +impl digital::OutputPin for ExtiPin { + type Error = T::Error; + + fn set_low(&mut self) -> Result<(), Self::Error> { + self.pin.set_low() + } + + fn set_high(&mut self) -> Result<(), Self::Error> { + self.pin.set_high() + } +} + +impl digital::StatefulOutputPin for ExtiPin { + fn is_set_low(&self) -> Result { + self.pin.is_set_low() + } + + fn is_set_high(&self) -> Result { + self.pin.is_set_high() + } +} + +impl digital::ToggleableOutputPin for ExtiPin { + type Error = T::Error; + + fn toggle(&mut self) -> Result<(), Self::Error> { + self.pin.toggle() + } +} + +impl digital::InputPin for ExtiPin { + type Error = T::Error; + + fn is_high(&self) -> Result { + self.pin.is_high() + } + + fn is_low(&self) -> Result { + self.pin.is_low() + } +} + +impl ExtiPin { + fn wait_for_state<'a>(self: Pin<&'a mut Self>, state: bool) -> impl Future + 'a { + let s = unsafe { self.get_unchecked_mut() }; + + s.pin.clear_pending_bit(); + async move { + let fut = InterruptFuture::new(&mut s.interrupt); + let pin = &mut s.pin; + cortex_m::interrupt::free(|_| { + pin.trigger_edge(if state { + EdgeOption::Rising + } else { + EdgeOption::Falling + }); + }); + + if (state && s.pin.is_high().unwrap_or(false)) + || (!state && s.pin.is_low().unwrap_or(false)) + { + return; + } + + fut.await; + + s.pin.clear_pending_bit(); + } + } +} + +impl ExtiPin { + fn wait_for_edge<'a>( + self: Pin<&'a mut Self>, + state: EdgeOption, + ) -> impl Future + 'a { + let s = unsafe { self.get_unchecked_mut() }; + + s.pin.clear_pending_bit(); + async move { + let fut = InterruptFuture::new(&mut s.interrupt); + let pin = &mut s.pin; + cortex_m::interrupt::free(|_| { + pin.trigger_edge(state); + }); + + fut.await; + + s.pin.clear_pending_bit(); + } + } +} + +impl WaitForHigh for ExtiPin { + type Future<'a> = impl Future + 'a; + + fn wait_for_high<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> { + self.wait_for_state(true) + } +} + +impl WaitForLow for ExtiPin { + type Future<'a> = impl Future + 'a; + + fn wait_for_low<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> { + self.wait_for_state(false) + } +} + +/* + Irq Handler Description + EXTI0_IRQn EXTI0_IRQHandler Handler for pins connected to line 0 + EXTI1_IRQn EXTI1_IRQHandler Handler for pins connected to line 1 + EXTI2_IRQn EXTI2_IRQHandler Handler for pins connected to line 2 + EXTI3_IRQn EXTI3_IRQHandler Handler for pins connected to line 3 + EXTI4_IRQn EXTI4_IRQHandler Handler for pins connected to line 4 + EXTI9_5_IRQn EXTI9_5_IRQHandler Handler for pins connected to line 5 to 9 + EXTI15_10_IRQn EXTI15_10_IRQHandler Handler for pins connected to line 10 to 15 +*/ + +impl WaitForRisingEdge for ExtiPin { + type Future<'a> = impl Future + 'a; + + fn wait_for_rising_edge<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> { + self.wait_for_edge(EdgeOption::Rising) + } +} + +impl WaitForFallingEdge for ExtiPin { + type Future<'a> = impl Future + 'a; + + fn wait_for_falling_edge<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> { + self.wait_for_edge(EdgeOption::Falling) + } +} + +impl WaitForAnyEdge for ExtiPin { + type Future<'a> = impl Future + 'a; + + fn wait_for_any_edge<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> { + self.wait_for_edge(EdgeOption::RisingFalling) + } +} + +mod private { + pub trait Sealed {} +} + +#[derive(Copy, Clone)] +pub enum EdgeOption { + Rising, + Falling, + RisingFalling, +} + +pub trait WithInterrupt: private::Sealed { + type Interrupt: interrupt::Interrupt; +} + +pub trait Instance: WithInterrupt { + fn make_source(&mut self); + fn clear_pending_bit(&mut self); + fn trigger_edge(&mut self, edge: EdgeOption); +} + +macro_rules! exti { + ($set:ident, [ + $($INT:ident => $pin:ident,)+ + ]) => { + $( + impl private::Sealed for gpio::$set::$pin {} + impl WithInterrupt for gpio::$set::$pin { + type Interrupt = interrupt::$INT; + } + + #[cfg(any( + feature = "stm32f401", + feature = "stm32f405", + feature = "stm32f407", + feature = "stm32f410", + feature = "stm32f411", + feature = "stm32f412", + feature = "stm32f413", + feature = "stm32f415", + feature = "stm32f417", + feature = "stm32f423", + feature = "stm32f427", + feature = "stm32f429", + feature = "stm32f437", + feature = "stm32f439", + feature = "stm32f446", + feature = "stm32f469", + feature = "stm32f479", + ))] + impl Instance for gpio::$set::$pin> { + fn make_source(&mut self) { + use crate::hal::{gpio::Edge, gpio::ExtiPin, syscfg::SysCfg}; + use crate::pac::EXTI; + let mut syscfg: SysCfg = unsafe { mem::transmute(()) }; + self.make_interrupt_source(&mut syscfg); + } + + fn clear_pending_bit(&mut self) { + use crate::hal::{gpio::Edge, gpio::ExtiPin, syscfg::SysCfg}; + + self.clear_interrupt_pending_bit(); + } + + fn trigger_edge(&mut self, edge: EdgeOption) { + use crate::hal::{gpio::Edge, gpio::ExtiPin, syscfg::SysCfg}; + use crate::pac::EXTI; + let mut exti: EXTI = unsafe { mem::transmute(()) }; + let edge = match edge { + EdgeOption::Falling => Edge::FALLING, + EdgeOption::Rising => Edge::RISING, + EdgeOption::RisingFalling => Edge::RISING_FALLING, + }; + self.trigger_on_edge(&mut exti, edge); + self.enable_interrupt(&mut exti); + } + } + + #[cfg(any(feature = "stm32l0x1", feature = "stm32l0x2", feature = "stm32l0x3",))] + impl Instance for gpio::$set::$pin { + fn make_source(&mut self) {} + + fn clear_pending_bit(&mut self) { + use crate::hal::{ + exti::{Exti, ExtiLine, GpioLine, TriggerEdge}, + syscfg::SYSCFG, + }; + + Exti::unpend(GpioLine::from_raw_line(self.pin_number()).unwrap()); + } + + fn trigger_edge(&mut self, edge: EdgeOption) { + use crate::hal::{ + exti::{Exti, ExtiLine, GpioLine, TriggerEdge}, + syscfg::SYSCFG, + }; + + use crate::pac::EXTI; + + let edge = match edge { + EdgeOption::Falling => TriggerEdge::Falling, + EdgeOption::Rising => TriggerEdge::Rising, + EdgeOption::RisingFalling => TriggerEdge::Both, + }; + + let exti: EXTI = unsafe { mem::transmute(()) }; + let mut exti = Exti::new(exti); + let port = self.port(); + let mut syscfg: SYSCFG = unsafe { mem::transmute(()) }; + let line = GpioLine::from_raw_line(self.pin_number()).unwrap(); + exti.listen_gpio(&mut syscfg, port, line, edge); + } + } + )+ + }; +} + +#[cfg(any( + feature = "stm32f401", + feature = "stm32f405", + feature = "stm32f407", + feature = "stm32f410", + feature = "stm32f411", + feature = "stm32f412", + feature = "stm32f413", + feature = "stm32f415", + feature = "stm32f417", + feature = "stm32f423", + feature = "stm32f427", + feature = "stm32f429", + feature = "stm32f437", + feature = "stm32f439", + feature = "stm32f446", + feature = "stm32f469", + feature = "stm32f479" +))] +exti!(gpioa, [ + EXTI0 => PA0, + EXTI1 => PA1, + EXTI2 => PA2, + EXTI3 => PA3, + EXTI4 => PA4, + EXTI9_5 => PA5, + EXTI9_5 => PA6, + EXTI9_5 => PA7, + EXTI9_5 => PA8, + EXTI9_5 => PA9, + EXTI15_10 => PA10, + EXTI15_10 => PA11, + EXTI15_10 => PA12, + EXTI15_10 => PA13, + EXTI15_10 => PA14, + EXTI15_10 => PA15, +]); + +#[cfg(any( + feature = "stm32f401", + feature = "stm32f405", + feature = "stm32f407", + feature = "stm32f410", + feature = "stm32f411", + feature = "stm32f412", + feature = "stm32f413", + feature = "stm32f415", + feature = "stm32f417", + feature = "stm32f423", + feature = "stm32f427", + feature = "stm32f429", + feature = "stm32f437", + feature = "stm32f439", + feature = "stm32f446", + feature = "stm32f469", + feature = "stm32f479" +))] +exti!(gpiob, [ + EXTI0 => PB0, + EXTI1 => PB1, + EXTI2 => PB2, + EXTI3 => PB3, + EXTI4 => PB4, + EXTI9_5 => PB5, + EXTI9_5 => PB6, + EXTI9_5 => PB7, + EXTI9_5 => PB8, + EXTI9_5 => PB9, + EXTI15_10 => PB10, + EXTI15_10 => PB11, + EXTI15_10 => PB12, + EXTI15_10 => PB13, + EXTI15_10 => PB14, + EXTI15_10 => PB15, +]); + +#[cfg(any( + feature = "stm32f401", + feature = "stm32f405", + feature = "stm32f407", + feature = "stm32f410", + feature = "stm32f411", + feature = "stm32f412", + feature = "stm32f413", + feature = "stm32f415", + feature = "stm32f417", + feature = "stm32f423", + feature = "stm32f427", + feature = "stm32f429", + feature = "stm32f437", + feature = "stm32f439", + feature = "stm32f446", + feature = "stm32f469", + feature = "stm32f479" +))] +exti!(gpioc, [ + EXTI0 => PC0, + EXTI1 => PC1, + EXTI2 => PC2, + EXTI3 => PC3, + EXTI4 => PC4, + EXTI9_5 => PC5, + EXTI9_5 => PC6, + EXTI9_5 => PC7, + EXTI9_5 => PC8, + EXTI9_5 => PC9, + EXTI15_10 => PC10, + EXTI15_10 => PC11, + EXTI15_10 => PC12, + EXTI15_10 => PC13, + EXTI15_10 => PC14, + EXTI15_10 => PC15, +]); + +#[cfg(any( + feature = "stm32f401", + feature = "stm32f405", + feature = "stm32f407", + feature = "stm32f411", + feature = "stm32f412", + feature = "stm32f413", + feature = "stm32f415", + feature = "stm32f417", + feature = "stm32f423", + feature = "stm32f427", + feature = "stm32f429", + feature = "stm32f437", + feature = "stm32f439", + feature = "stm32f446", + feature = "stm32f469", + feature = "stm32f479" +))] +exti!(gpiod, [ + EXTI0 => PD0, + EXTI1 => PD1, + EXTI2 => PD2, + EXTI3 => PD3, + EXTI4 => PD4, + EXTI9_5 => PD5, + EXTI9_5 => PD6, + EXTI9_5 => PD7, + EXTI9_5 => PD8, + EXTI9_5 => PD9, + EXTI15_10 => PD10, + EXTI15_10 => PD11, + EXTI15_10 => PD12, + EXTI15_10 => PD13, + EXTI15_10 => PD14, + EXTI15_10 => PD15, +]); + +#[cfg(any( + feature = "stm32f401", + feature = "stm32f405", + feature = "stm32f407", + feature = "stm32f411", + feature = "stm32f412", + feature = "stm32f413", + feature = "stm32f415", + feature = "stm32f417", + feature = "stm32f423", + feature = "stm32f427", + feature = "stm32f429", + feature = "stm32f437", + feature = "stm32f439", + feature = "stm32f446", + feature = "stm32f469", + feature = "stm32f479" +))] +exti!(gpioe, [ + EXTI0 => PE0, + EXTI1 => PE1, + EXTI2 => PE2, + EXTI3 => PE3, + EXTI4 => PE4, + EXTI9_5 => PE5, + EXTI9_5 => PE6, + EXTI9_5 => PE7, + EXTI9_5 => PE8, + EXTI9_5 => PE9, + EXTI15_10 => PE10, + EXTI15_10 => PE11, + EXTI15_10 => PE12, + EXTI15_10 => PE13, + EXTI15_10 => PE14, + EXTI15_10 => PE15, +]); + +#[cfg(any( + feature = "stm32f405", + feature = "stm32f407", + feature = "stm32f412", + feature = "stm32f413", + feature = "stm32f415", + feature = "stm32f417", + feature = "stm32f423", + feature = "stm32f427", + feature = "stm32f429", + feature = "stm32f437", + feature = "stm32f439", + feature = "stm32f446", + feature = "stm32f469", + feature = "stm32f479" +))] +exti!(gpiof, [ + EXTI0 => PF0, + EXTI1 => PF1, + EXTI2 => PF2, + EXTI3 => PF3, + EXTI4 => PF4, + EXTI9_5 => PF5, + EXTI9_5 => PF6, + EXTI9_5 => PF7, + EXTI9_5 => PF8, + EXTI9_5 => PF9, + EXTI15_10 => PF10, + EXTI15_10 => PF11, + EXTI15_10 => PF12, + EXTI15_10 => PF13, + EXTI15_10 => PF14, + EXTI15_10 => PF15, +]); + +#[cfg(any( + feature = "stm32f405", + feature = "stm32f407", + feature = "stm32f412", + feature = "stm32f413", + feature = "stm32f415", + feature = "stm32f417", + feature = "stm32f423", + feature = "stm32f427", + feature = "stm32f429", + feature = "stm32f437", + feature = "stm32f439", + feature = "stm32f446", + feature = "stm32f469", + feature = "stm32f479" +))] +exti!(gpiog, [ + EXTI0 => PG0, + EXTI1 => PG1, + EXTI2 => PG2, + EXTI3 => PG3, + EXTI4 => PG4, + EXTI9_5 => PG5, + EXTI9_5 => PG6, + EXTI9_5 => PG7, + EXTI9_5 => PG8, + EXTI9_5 => PG9, + EXTI15_10 => PG10, + EXTI15_10 => PG11, + EXTI15_10 => PG12, + EXTI15_10 => PG13, + EXTI15_10 => PG14, + EXTI15_10 => PG15, +]); + +#[cfg(any( + feature = "stm32f405", + feature = "stm32f407", + feature = "stm32f410", + feature = "stm32f411", + feature = "stm32f412", + feature = "stm32f413", + feature = "stm32f415", + feature = "stm32f417", + feature = "stm32f423", + feature = "stm32f427", + feature = "stm32f429", + feature = "stm32f437", + feature = "stm32f439", + feature = "stm32f446", + feature = "stm32f469", + feature = "stm32f479" +))] +exti!(gpioh, [ + EXTI0 => PH0, + EXTI1 => PH1, + EXTI2 => PH2, + EXTI3 => PH3, + EXTI4 => PH4, + EXTI9_5 => PH5, + EXTI9_5 => PH6, + EXTI9_5 => PH7, + EXTI9_5 => PH8, + EXTI9_5 => PH9, + EXTI15_10 => PH10, + EXTI15_10 => PH11, + EXTI15_10 => PH12, + EXTI15_10 => PH13, + EXTI15_10 => PH14, + EXTI15_10 => PH15, +]); + +#[cfg(any(feature = "stm32f401"))] +exti!(gpioh, [ + EXTI0 => PH0, + EXTI1 => PH1, +]); + +#[cfg(any( + feature = "stm32f405", + feature = "stm32f407", + feature = "stm32f415", + feature = "stm32f417", + feature = "stm32f427", + feature = "stm32f429", + feature = "stm32f437", + feature = "stm32f439", + feature = "stm32f469", + feature = "stm32f479" +))] +exti!(gpioi, [ + EXTI0 => PI0, + EXTI1 => PI1, + EXTI2 => PI2, + EXTI3 => PI3, + EXTI4 => PI4, + EXTI9_5 => PI5, + EXTI9_5 => PI6, + EXTI9_5 => PI7, + EXTI9_5 => PI8, + EXTI9_5 => PI9, + EXTI15_10 => PI10, + EXTI15_10 => PI11, + EXTI15_10 => PI12, + EXTI15_10 => PI13, + EXTI15_10 => PI14, + EXTI15_10 => PI15, +]); + +#[cfg(any( + feature = "stm32f427", + feature = "stm32f429", + feature = "stm32f437", + feature = "stm32f439", + feature = "stm32f469", + feature = "stm32f479" +))] +exti!(gpioj, [ + EXTI0 => PJ0, + EXTI1 => PJ1, + EXTI2 => PJ2, + EXTI3 => PJ3, + EXTI4 => PJ4, + EXTI9_5 => PJ5, + EXTI9_5 => PJ6, + EXTI9_5 => PJ7, + EXTI9_5 => PJ8, + EXTI9_5 => PJ9, + EXTI15_10 => PJ10, + EXTI15_10 => PJ11, + EXTI15_10 => PJ12, + EXTI15_10 => PJ13, + EXTI15_10 => PJ14, + EXTI15_10 => PJ15, +]); + +#[cfg(any( + feature = "stm32f427", + feature = "stm32f429", + feature = "stm32f437", + feature = "stm32f439", + feature = "stm32f469", + feature = "stm32f479" +))] +exti!(gpiok, [ + EXTI0 => PK0, + EXTI1 => PK1, + EXTI2 => PK2, + EXTI3 => PK3, + EXTI4 => PK4, + EXTI9_5 => PK5, + EXTI9_5 => PK6, + EXTI9_5 => PK7, +]); + +#[cfg(any(feature = "stm32l0x1", feature = "stm32l0x2", feature = "stm32l0x3",))] +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, +]); + +#[cfg(any(feature = "stm32l0x1", feature = "stm32l0x2", feature = "stm32l0x3",))] +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, +]); + +#[cfg(any(feature = "stm32l0x1", feature = "stm32l0x2", feature = "stm32l0x3",))] +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, +]); + +#[cfg(any(feature = "stm32l0x1", feature = "stm32l0x2", feature = "stm32l0x3",))] +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, +]); + +#[cfg(any(feature = "stm32l0x1", feature = "stm32l0x2", feature = "stm32l0x3",))] +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, +]); + +#[cfg(any(feature = "stm32l0x1", feature = "stm32l0x2", feature = "stm32l0x3",))] +exti!(gpioh, [ + EXTI0_1 => PH0, + EXTI0_1 => PH1, + EXTI4_15 => PH9, + EXTI4_15 => PH10, +]); 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}; pub mod fmt; +pub mod exti; pub mod interrupt; diff --git a/embassy-stm32f4/src/exti.rs b/embassy-stm32f4/src/exti.rs deleted file mode 100644 index 154ca45c1..000000000 --- a/embassy-stm32f4/src/exti.rs +++ /dev/null @@ -1,535 +0,0 @@ -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; -use crate::hal::syscfg::SysCfg; -use crate::pac::EXTI; -use embedded_hal::digital::v2 as digital; - -use crate::interrupt; - -pub struct ExtiPin { - pin: T, - interrupt: T::Interrupt, -} - -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> { - self.pin.set_low() - } - - fn set_high(&mut self) -> Result<(), Self::Error> { - self.pin.set_high() - } -} - -impl digital::StatefulOutputPin - for ExtiPin -{ - fn is_set_low(&self) -> Result { - self.pin.is_set_low() - } - - fn is_set_high(&self) -> Result { - self.pin.is_set_high() - } -} - -impl digital::ToggleableOutputPin - for ExtiPin -{ - type Error = T::Error; - - fn toggle(&mut self) -> Result<(), Self::Error> { - self.pin.toggle() - } -} - -impl digital::InputPin for ExtiPin { - type Error = T::Error; - - fn is_high(&self) -> Result { - self.pin.is_high() - } - - fn is_low(&self) -> Result { - self.pin.is_low() - } -} - -/* - Irq Handler Description - EXTI0_IRQn EXTI0_IRQHandler Handler for pins connected to line 0 - EXTI1_IRQn EXTI1_IRQHandler Handler for pins connected to line 1 - EXTI2_IRQn EXTI2_IRQHandler Handler for pins connected to line 2 - EXTI3_IRQn EXTI3_IRQHandler Handler for pins connected to line 3 - EXTI4_IRQn EXTI4_IRQHandler Handler for pins connected to line 4 - EXTI9_5_IRQn EXTI9_5_IRQHandler Handler for pins connected to line 5 to 9 - EXTI15_10_IRQn EXTI15_10_IRQHandler Handler for pins connected to line 10 to 15 -*/ - -impl WaitForRisingEdge for ExtiPin { - type Future<'a> = impl Future + 'a; - - fn wait_for_rising_edge<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> { - let s = unsafe { self.get_unchecked_mut() }; - - s.pin.clear_interrupt_pending_bit(); - async move { - let fut = InterruptFuture::new(&mut s.interrupt); - let pin = &mut s.pin; - cortex_m::interrupt::free(|_| { - let mut exti: EXTI = unsafe { mem::transmute(()) }; - - pin.trigger_on_edge(&mut exti, Edge::RISING); - pin.enable_interrupt(&mut exti); - }); - fut.await; - - s.pin.clear_interrupt_pending_bit(); - } - } -} - -impl WaitForFallingEdge for ExtiPin { - type Future<'a> = impl Future + 'a; - - fn wait_for_falling_edge<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> { - let s = unsafe { self.get_unchecked_mut() }; - - s.pin.clear_interrupt_pending_bit(); - async move { - let fut = InterruptFuture::new(&mut s.interrupt); - let pin = &mut s.pin; - cortex_m::interrupt::free(|_| { - let mut exti: EXTI = unsafe { mem::transmute(()) }; - - pin.trigger_on_edge(&mut exti, Edge::FALLING); - pin.enable_interrupt(&mut exti); - }); - fut.await; - - s.pin.clear_interrupt_pending_bit(); - } - } -} - -mod private { - pub trait Sealed {} -} - -pub trait WithInterrupt: private::Sealed { - type Interrupt: interrupt::Interrupt; -} - -macro_rules! exti { - ($set:ident, [ - $($INT:ident => $pin:ident,)+ - ]) => { - $( - impl private::Sealed for gpio::$set::$pin {} - impl WithInterrupt for gpio::$set::$pin { - type Interrupt = interrupt::$INT; - } - )+ - - }; -} - -#[cfg(any( - feature = "stm32f401", - feature = "stm32f405", - feature = "stm32f407", - feature = "stm32f410", - feature = "stm32f411", - feature = "stm32f412", - feature = "stm32f413", - feature = "stm32f415", - feature = "stm32f417", - feature = "stm32f423", - feature = "stm32f427", - feature = "stm32f429", - feature = "stm32f437", - feature = "stm32f439", - feature = "stm32f446", - feature = "stm32f469", - feature = "stm32f479" -))] -exti!(gpioa, [ - EXTI0 => PA0, - EXTI1 => PA1, - EXTI2 => PA2, - EXTI3 => PA3, - EXTI4 => PA4, - EXTI9_5 => PA5, - EXTI9_5 => PA6, - EXTI9_5 => PA7, - EXTI9_5 => PA8, - EXTI9_5 => PA9, - EXTI15_10 => PA10, - EXTI15_10 => PA11, - EXTI15_10 => PA12, - EXTI15_10 => PA13, - EXTI15_10 => PA14, - EXTI15_10 => PA15, -]); - -#[cfg(any( - feature = "stm32f401", - feature = "stm32f405", - feature = "stm32f407", - feature = "stm32f410", - feature = "stm32f411", - feature = "stm32f412", - feature = "stm32f413", - feature = "stm32f415", - feature = "stm32f417", - feature = "stm32f423", - feature = "stm32f427", - feature = "stm32f429", - feature = "stm32f437", - feature = "stm32f439", - feature = "stm32f446", - feature = "stm32f469", - feature = "stm32f479" -))] -exti!(gpiob, [ - EXTI0 => PB0, - EXTI1 => PB1, - EXTI2 => PB2, - EXTI3 => PB3, - EXTI4 => PB4, - EXTI9_5 => PB5, - EXTI9_5 => PB6, - EXTI9_5 => PB7, - EXTI9_5 => PB8, - EXTI9_5 => PB9, - EXTI15_10 => PB10, - EXTI15_10 => PB11, - EXTI15_10 => PB12, - EXTI15_10 => PB13, - EXTI15_10 => PB14, - EXTI15_10 => PB15, -]); - -#[cfg(any( - feature = "stm32f401", - feature = "stm32f405", - feature = "stm32f407", - feature = "stm32f410", - feature = "stm32f411", - feature = "stm32f412", - feature = "stm32f413", - feature = "stm32f415", - feature = "stm32f417", - feature = "stm32f423", - feature = "stm32f427", - feature = "stm32f429", - feature = "stm32f437", - feature = "stm32f439", - feature = "stm32f446", - feature = "stm32f469", - feature = "stm32f479" -))] -exti!(gpioc, [ - EXTI0 => PC0, - EXTI1 => PC1, - EXTI2 => PC2, - EXTI3 => PC3, - EXTI4 => PC4, - EXTI9_5 => PC5, - EXTI9_5 => PC6, - EXTI9_5 => PC7, - EXTI9_5 => PC8, - EXTI9_5 => PC9, - EXTI15_10 => PC10, - EXTI15_10 => PC11, - EXTI15_10 => PC12, - EXTI15_10 => PC13, - EXTI15_10 => PC14, - EXTI15_10 => PC15, -]); - -#[cfg(any( - feature = "stm32f401", - feature = "stm32f405", - feature = "stm32f407", - feature = "stm32f411", - feature = "stm32f412", - feature = "stm32f413", - feature = "stm32f415", - feature = "stm32f417", - feature = "stm32f423", - feature = "stm32f427", - feature = "stm32f429", - feature = "stm32f437", - feature = "stm32f439", - feature = "stm32f446", - feature = "stm32f469", - feature = "stm32f479" -))] -exti!(gpiod, [ - EXTI0 => PD0, - EXTI1 => PD1, - EXTI2 => PD2, - EXTI3 => PD3, - EXTI4 => PD4, - EXTI9_5 => PD5, - EXTI9_5 => PD6, - EXTI9_5 => PD7, - EXTI9_5 => PD8, - EXTI9_5 => PD9, - EXTI15_10 => PD10, - EXTI15_10 => PD11, - EXTI15_10 => PD12, - EXTI15_10 => PD13, - EXTI15_10 => PD14, - EXTI15_10 => PD15, -]); - -#[cfg(any( - feature = "stm32f401", - feature = "stm32f405", - feature = "stm32f407", - feature = "stm32f411", - feature = "stm32f412", - feature = "stm32f413", - feature = "stm32f415", - feature = "stm32f417", - feature = "stm32f423", - feature = "stm32f427", - feature = "stm32f429", - feature = "stm32f437", - feature = "stm32f439", - feature = "stm32f446", - feature = "stm32f469", - feature = "stm32f479" -))] -exti!(gpioe, [ - EXTI0 => PE0, - EXTI1 => PE1, - EXTI2 => PE2, - EXTI3 => PE3, - EXTI4 => PE4, - EXTI9_5 => PE5, - EXTI9_5 => PE6, - EXTI9_5 => PE7, - EXTI9_5 => PE8, - EXTI9_5 => PE9, - EXTI15_10 => PE10, - EXTI15_10 => PE11, - EXTI15_10 => PE12, - EXTI15_10 => PE13, - EXTI15_10 => PE14, - EXTI15_10 => PE15, -]); - -#[cfg(any( - feature = "stm32f405", - feature = "stm32f407", - feature = "stm32f412", - feature = "stm32f413", - feature = "stm32f415", - feature = "stm32f417", - feature = "stm32f423", - feature = "stm32f427", - feature = "stm32f429", - feature = "stm32f437", - feature = "stm32f439", - feature = "stm32f446", - feature = "stm32f469", - feature = "stm32f479" -))] -exti!(gpiof, [ - EXTI0 => PF0, - EXTI1 => PF1, - EXTI2 => PF2, - EXTI3 => PF3, - EXTI4 => PF4, - EXTI9_5 => PF5, - EXTI9_5 => PF6, - EXTI9_5 => PF7, - EXTI9_5 => PF8, - EXTI9_5 => PF9, - EXTI15_10 => PF10, - EXTI15_10 => PF11, - EXTI15_10 => PF12, - EXTI15_10 => PF13, - EXTI15_10 => PF14, - EXTI15_10 => PF15, -]); - -#[cfg(any( - feature = "stm32f405", - feature = "stm32f407", - feature = "stm32f412", - feature = "stm32f413", - feature = "stm32f415", - feature = "stm32f417", - feature = "stm32f423", - feature = "stm32f427", - feature = "stm32f429", - feature = "stm32f437", - feature = "stm32f439", - feature = "stm32f446", - feature = "stm32f469", - feature = "stm32f479" -))] -exti!(gpiog, [ - EXTI0 => PG0, - EXTI1 => PG1, - EXTI2 => PG2, - EXTI3 => PG3, - EXTI4 => PG4, - EXTI9_5 => PG5, - EXTI9_5 => PG6, - EXTI9_5 => PG7, - EXTI9_5 => PG8, - EXTI9_5 => PG9, - EXTI15_10 => PG10, - EXTI15_10 => PG11, - EXTI15_10 => PG12, - EXTI15_10 => PG13, - EXTI15_10 => PG14, - EXTI15_10 => PG15, -]); - -#[cfg(any( - feature = "stm32f405", - feature = "stm32f407", - feature = "stm32f410", - feature = "stm32f411", - feature = "stm32f412", - feature = "stm32f413", - feature = "stm32f415", - feature = "stm32f417", - feature = "stm32f423", - feature = "stm32f427", - feature = "stm32f429", - feature = "stm32f437", - feature = "stm32f439", - feature = "stm32f446", - feature = "stm32f469", - feature = "stm32f479" -))] -exti!(gpioh, [ - EXTI0 => PH0, - EXTI1 => PH1, - EXTI2 => PH2, - EXTI3 => PH3, - EXTI4 => PH4, - EXTI9_5 => PH5, - EXTI9_5 => PH6, - EXTI9_5 => PH7, - EXTI9_5 => PH8, - EXTI9_5 => PH9, - EXTI15_10 => PH10, - EXTI15_10 => PH11, - EXTI15_10 => PH12, - EXTI15_10 => PH13, - EXTI15_10 => PH14, - EXTI15_10 => PH15, -]); - -#[cfg(any(feature = "stm32f401"))] -exti!(gpioh, [ - EXTI0 => PH0, - EXTI1 => PH1, -]); - -#[cfg(any( - feature = "stm32f405", - feature = "stm32f407", - feature = "stm32f415", - feature = "stm32f417", - feature = "stm32f427", - feature = "stm32f429", - feature = "stm32f437", - feature = "stm32f439", - feature = "stm32f469", - feature = "stm32f479" -))] -exti!(gpioi, [ - EXTI0 => PI0, - EXTI1 => PI1, - EXTI2 => PI2, - EXTI3 => PI3, - EXTI4 => PI4, - EXTI9_5 => PI5, - EXTI9_5 => PI6, - EXTI9_5 => PI7, - EXTI9_5 => PI8, - EXTI9_5 => PI9, - EXTI15_10 => PI10, - EXTI15_10 => PI11, - EXTI15_10 => PI12, - EXTI15_10 => PI13, - EXTI15_10 => PI14, - EXTI15_10 => PI15, -]); - -#[cfg(any( - feature = "stm32f427", - feature = "stm32f429", - feature = "stm32f437", - feature = "stm32f439", - feature = "stm32f469", - feature = "stm32f479" -))] -exti!(gpioj, [ - EXTI0 => PJ0, - EXTI1 => PJ1, - EXTI2 => PJ2, - EXTI3 => PJ3, - EXTI4 => PJ4, - EXTI9_5 => PJ5, - EXTI9_5 => PJ6, - EXTI9_5 => PJ7, - EXTI9_5 => PJ8, - EXTI9_5 => PJ9, - EXTI15_10 => PJ10, - EXTI15_10 => PJ11, - EXTI15_10 => PJ12, - EXTI15_10 => PJ13, - EXTI15_10 => PJ14, - EXTI15_10 => PJ15, -]); - -#[cfg(any( - feature = "stm32f427", - feature = "stm32f429", - feature = "stm32f437", - feature = "stm32f439", - feature = "stm32f469", - feature = "stm32f479" -))] -exti!(gpiok, [ - EXTI0 => PK0, - EXTI1 => PK1, - EXTI2 => PK2, - EXTI3 => PK3, - EXTI4 => PK4, - EXTI9_5 => PK5, - EXTI9_5 => PK6, - EXTI9_5 => PK7, -]); 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!( "Multile chip features activated. You must activate exactly one of the following features: " ); -pub use embassy_stm32::{fmt, hal, interrupt, pac}; +pub use embassy_stm32::{exti, fmt, hal, interrupt, pac}; #[cfg(not(any(feature = "stm32f401", feature = "stm32f410", feature = "stm32f411",)))] pub mod can; -pub mod exti; #[cfg(not(feature = "stm32f410"))] pub mod qei; 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 @@ -use core::future::Future; -use core::mem; -use core::pin::Pin; - -use embassy::traits::gpio::{ - WaitForAnyEdge, WaitForFallingEdge, WaitForHigh, WaitForLow, WaitForRisingEdge, -}; -use embassy::util::InterruptFuture; - -use crate::hal::{ - exti::{Exti, ExtiLine, GpioLine, TriggerEdge}, - gpio, - syscfg::SYSCFG, -}; -use crate::interrupt; -use crate::pac::EXTI; -use embedded_hal::digital::v2::InputPin; - -pub struct ExtiPin { - pin: T, - interrupt: T::Interrupt, -} - -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, - ) -> impl Future + 'a { - let line = self.pin.line(); - let s = unsafe { self.get_unchecked_mut() }; - - Exti::unpend(line); - - async move { - let exti: EXTI = unsafe { mem::transmute(()) }; - let mut exti = Exti::new(exti); - - let fut = InterruptFuture::new(&mut s.interrupt); - - let port = s.pin.port(); - cortex_m::interrupt::free(|_| { - let mut syscfg: SYSCFG = unsafe { mem::transmute(()) }; - exti.listen_gpio(&mut syscfg, port, line, edge); - }); - - fut.await; - - Exti::unpend(line); - } - } -} - -impl ExtiPin { - fn wait_for_state<'a>(self: Pin<&'a mut Self>, state: bool) -> impl Future + 'a { - let line = self.pin.line(); - let s = unsafe { self.get_unchecked_mut() }; - - Exti::unpend(line); - - async move { - let exti: EXTI = unsafe { mem::transmute(()) }; - let mut exti = Exti::new(exti); - - let fut = InterruptFuture::new(&mut s.interrupt); - - let port = s.pin.port(); - cortex_m::interrupt::free(|_| { - let mut syscfg: SYSCFG = unsafe { mem::transmute(()) }; - let edge = if state { - TriggerEdge::Rising - } else { - TriggerEdge::Falling - }; - exti.listen_gpio(&mut syscfg, port, line, edge); - }); - - let pin_has_state = if state { - s.pin.is_high() - } else { - s.pin.is_low() - } - .unwrap_or(false); - if pin_has_state { - return (); - } - - fut.await; - - Exti::unpend(line); - } - } -} - -impl WaitForRisingEdge for ExtiPin { - type Future<'a> = impl Future + 'a; - - fn wait_for_rising_edge<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> { - self.wait_for_edge(TriggerEdge::Rising) - } -} - -impl WaitForFallingEdge for ExtiPin { - type Future<'a> = impl Future + 'a; - - fn wait_for_falling_edge<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> { - self.wait_for_edge(TriggerEdge::Falling) - } -} - -impl WaitForAnyEdge for ExtiPin { - type Future<'a> = impl Future + 'a; - - fn wait_for_any_edge<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> { - self.wait_for_edge(TriggerEdge::Both) - } -} - -impl WaitForHigh for ExtiPin { - type Future<'a> = impl Future + 'a; - - fn wait_for_high<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> { - self.wait_for_state(true) - } -} - -impl WaitForLow for ExtiPin { - type Future<'a> = impl Future + 'a; - - fn wait_for_low<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> { - self.wait_for_state(false) - } -} - -mod private { - pub trait Sealed {} -} - -pub trait PinWithInterrupt: private::Sealed { - type Interrupt: interrupt::Interrupt; - fn port(&self) -> gpio::Port; - fn line(&self) -> GpioLine; -} - -macro_rules! exti { - ($set:ident, [ - $($INT:ident => $pin:ident,)+ - ]) => { - $( - impl private::Sealed for gpio::$set::$pin {} - impl PinWithInterrupt for gpio::$set::$pin { - type Interrupt = interrupt::$INT; - fn port(&self) -> gpio::Port { - self.port() - } - fn line(&self) -> GpioLine { - GpioLine::from_raw_line(self.pin_number()).unwrap() - } - } - )+ - - }; -} - -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!(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!(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!(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!(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!(gpioh, [ - EXTI0_1 => PH0, - EXTI0_1 => PH1, - EXTI4_15 => PH9, - EXTI4_15 => PH10, -]); 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!( "Multile chip features activated. You must activate exactly one of the following features: " ); -pub use embassy_stm32::{fmt, hal, interrupt, pac}; - -pub mod exti; +pub use embassy_stm32::{exti, fmt, hal, interrupt, pac}; -- cgit