From de4d7f56473df58d9b3fa8ec4917ab86550005ae Mon Sep 17 00:00:00 2001 From: WillaWillNot Date: Fri, 14 Nov 2025 17:00:23 -0500 Subject: Added type-erased AnyBinding for interrupt-handler bindings, and changed Exti driver to accept custom bindings without sacrificing its ability to accept type-erased Channels --- embassy-hal-internal/src/interrupt.rs | 55 +++++++++++++++++++++++++++++++- embassy-stm32/src/exti.rs | 59 +++++++++++++++++++++++++---------- 2 files changed, 97 insertions(+), 17 deletions(-) diff --git a/embassy-hal-internal/src/interrupt.rs b/embassy-hal-internal/src/interrupt.rs index ce6057e2d..c0ea666da 100644 --- a/embassy-hal-internal/src/interrupt.rs +++ b/embassy-hal-internal/src/interrupt.rs @@ -124,6 +124,10 @@ macro_rules! interrupt_mod { /// /// This function must ONLY be called from the interrupt handler for `I`. unsafe fn on_interrupt(); + + /// Source ID of the Handler. No need to override the default outside of internal implementations, + /// where it will always be HandlerType::User. + const SOURCE_ID: HandlerType = HandlerType::User; } /// Compile-time assertion that an interrupt has been bound to a handler. @@ -137,7 +141,56 @@ macro_rules! interrupt_mod { /// to be called every time the `I` interrupt fires. /// /// This allows drivers to check bindings at compile-time. - pub unsafe trait Binding> {} + pub unsafe trait Binding> { + /// Obtain a type-erased Binding. + /// + /// If using the `bind_interrupts!` macro, you will likely have to use a fully qualified path + /// to call this on the output struct: `>::into_any()` + fn into_any() -> AnyBinding { + AnyBinding { + irq: I::IRQ, + handler_source: H::SOURCE_ID, + } + } + } + + #[doc(hidden)] + #[derive(Copy, Clone)] + pub struct PrivateHandlerType { + pub(crate) _private: (), + } + impl PrivateHandlerType { + pub(crate) const fn new() -> Self { + Self { + _private: (), + } + } + } + + /// Driver which defined the Handler. Always User for user-defined handlers. + #[derive(Copy, Clone)] + pub enum HandlerType { + User, + Embassy(PrivateHandlerType), + EmbassyStm32Exti(PrivateHandlerType), + } + + /// Type-erased Binding. + /// + /// Useful for proving a particular binding has been made to a driver which also accepts + /// type-erased peripheral arguments that hide the necessary Interrupt type at compile time. + pub struct AnyBinding { + irq: super::Interrupt, + handler_source: HandlerType, + } + impl AnyBinding { + pub const fn irq(&self) -> super::Interrupt { + self.irq + } + pub const fn source(&self) -> HandlerType { + self.handler_source + } + } } } }; diff --git a/embassy-stm32/src/exti.rs b/embassy-stm32/src/exti.rs index 899d5e677..172435caa 100644 --- a/embassy-stm32/src/exti.rs +++ b/embassy-stm32/src/exti.rs @@ -10,9 +10,11 @@ use embassy_sync::waitqueue::AtomicWaker; use futures_util::FutureExt; use crate::gpio::{AnyPin, Input, Level, Pin as GpioPin, PinNumber, Pull}; +use crate::interrupt::Interrupt as InterruptEnum; +use crate::interrupt::typelevel::{AnyBinding, HandlerType, Interrupt as InterruptType, PrivateHandlerType}; use crate::pac::EXTI; use crate::pac::exti::regs::Lines; -use crate::{Peri, interrupt, pac, peripherals}; +use crate::{Peri, pac, peripherals}; const EXTI_COUNT: usize = 16; static EXTI_WAKERS: [AtomicWaker; EXTI_COUNT] = [const { AtomicWaker::new() }; EXTI_COUNT]; @@ -106,15 +108,24 @@ impl<'d> Unpin for ExtiInput<'d> {} impl<'d> ExtiInput<'d> { /// Create an EXTI input. - pub fn new(pin: Peri<'d, T>, ch: Peri<'d, T::ExtiChannel>, pull: Pull) -> Self { + /// + /// The interrupt [Binding] must be type-erased to [AnyBinding] via [Binding::into_any()] in order + /// to support type-erased [AnyChannel] arguments. + /// + /// The Binding must bind the Channel's IRQ to [InterruptHandler]. + pub fn new(pin: Peri<'d, T>, ch: Peri<'d, T::ExtiChannel>, pull: Pull, binding: AnyBinding) -> Self { // Needed if using AnyPin+AnyChannel. assert_eq!(pin.pin(), ch.number()); + assert_eq!(ch.irq(), binding.irq()); + assert!(matches!(binding.source(), HandlerType::EmbassyStm32Exti(_))); Self { pin: Input::new(pin, pull), } } + //pub fn new, I: Instance, C: Channel>( + /// Get whether the pin is high. pub fn is_high(&self) -> bool { self.pin.is_high() @@ -328,7 +339,7 @@ macro_rules! foreach_exti_irq { (EXTI15) => { $action!(EXTI15); }; // plus the weird ones - (EXTI0_1) => { $action!( EXTI0_1 ); }; + (EXTI0_1) => { $action!(EXTI0_1); }; (EXTI15_10) => { $action!(EXTI15_10); }; (EXTI15_4) => { $action!(EXTI15_4); }; (EXTI1_0) => { $action!(EXTI1_0); }; @@ -341,18 +352,25 @@ macro_rules! foreach_exti_irq { }; } -macro_rules! impl_irq { - ($e:ident) => { - #[allow(non_snake_case)] - #[cfg(feature = "rt")] - #[interrupt] - unsafe fn $e() { - on_irq() - } - }; +///EXTI interrupt handler. All EXTI interrupt vectors should be bound to this handler. +/// +/// It is generic over the [Interrupt](crate::interrupt::typelevel::Interrupt) rather +/// than the [Instance](crate::exti::Instance) because it should not be bound multiple +/// times to the same vector on chips which multiplex multiple EXTI interrupts into one vector. +// +// It technically doesn't need to be generic at all, except to satisfy the generic argument +// of [Handler](crate::interrupt::typelevel::Handler). All EXTI interrupts eventually +// land in the same on_irq() function. +pub struct InterruptHandler { + _phantom: PhantomData, } -foreach_exti_irq!(impl_irq); +impl crate::interrupt::typelevel::Handler for InterruptHandler { + const SOURCE_ID: HandlerType = HandlerType::EmbassyStm32Exti(PrivateHandlerType::new()); + unsafe fn on_interrupt() { + on_irq() + } +} trait SealedChannel {} @@ -361,6 +379,8 @@ trait SealedChannel {} pub trait Channel: PeripheralType + SealedChannel + Sized { /// Get the EXTI channel number. fn number(&self) -> PinNumber; + /// Get the EXTI IRQ, which may be the same for multiple channels + fn irq(&self) -> InterruptEnum; } /// Type-erased EXTI channel. @@ -368,6 +388,7 @@ pub trait Channel: PeripheralType + SealedChannel + Sized { /// This represents ownership over any EXTI channel, known at runtime. pub struct AnyChannel { number: PinNumber, + irq: InterruptEnum, } impl_peripheral!(AnyChannel); @@ -376,6 +397,9 @@ impl Channel for AnyChannel { fn number(&self) -> PinNumber { self.number } + fn irq(&self) -> InterruptEnum { + self.irq + } } macro_rules! impl_exti { @@ -385,12 +409,15 @@ macro_rules! impl_exti { fn number(&self) -> PinNumber { $number } + fn irq(&self) -> InterruptEnum { + crate::_generated::peripheral_interrupts::EXTI::$type::IRQ + } } - impl From for AnyChannel { - fn from(val: peripherals::$type) -> Self { + fn from(_val: peripherals::$type) -> Self { Self { - number: val.number() as PinNumber, + number: $number, + irq: crate::_generated::peripheral_interrupts::EXTI::$type::IRQ, } } } -- cgit From 623623a25f213f76de932eaf4458c3120823d205 Mon Sep 17 00:00:00 2001 From: WillaWillNot Date: Thu, 20 Nov 2025 16:24:15 -0500 Subject: Updated documentation, fixed EXTI definition issues with chips that have touch sensing, updated examples, added generation of convenience method to bind_interrupts for easier type erasure --- .../layer-by-layer/blinky-async/src/main.rs | 16 ++++++- docs/pages/faq.adoc | 6 ++- docs/pages/layer_by_layer.adoc | 2 +- embassy-hal-internal/CHANGELOG.md | 2 + embassy-hal-internal/src/interrupt.rs | 5 ++ embassy-stm32/CHANGELOG.md | 3 ++ embassy-stm32/build.rs | 4 ++ embassy-stm32/src/exti.rs | 53 ++++++++++++++-------- embassy-stm32/src/lib.rs | 15 +++++- examples/boot/application/stm32f3/src/bin/a.rs | 16 ++++++- examples/boot/application/stm32f7/src/bin/a.rs | 16 ++++++- examples/boot/application/stm32h7/src/bin/a.rs | 16 ++++++- examples/boot/application/stm32l0/src/bin/a.rs | 16 ++++++- examples/boot/application/stm32l1/src/bin/a.rs | 16 ++++++- examples/boot/application/stm32l4/src/bin/a.rs | 16 ++++++- examples/boot/application/stm32wl/src/bin/a.rs | 16 ++++++- examples/stm32c0/src/bin/button_exti.rs | 16 ++++++- .../stm32f0/src/bin/button_controlled_blink.rs | 16 ++++++- examples/stm32f0/src/bin/button_exti.rs | 16 ++++++- examples/stm32f3/src/bin/button_events.rs | 16 ++++++- examples/stm32f3/src/bin/button_exti.rs | 16 ++++++- examples/stm32f4/src/bin/button_exti.rs | 16 ++++++- examples/stm32f4/src/bin/eth_w5500.rs | 12 ++++- examples/stm32f4/src/bin/usb_hid_keyboard.rs | 12 ++++- examples/stm32f7/src/bin/button_exti.rs | 16 ++++++- examples/stm32g0/src/bin/button_exti.rs | 16 ++++++- examples/stm32g4/src/bin/button_exti.rs | 16 ++++++- examples/stm32h5/src/bin/button_exti.rs | 16 ++++++- examples/stm32h7/src/bin/button_exti.rs | 16 ++++++- examples/stm32h7rs/src/bin/button_exti.rs | 16 ++++++- examples/stm32l0/src/bin/button_exti.rs | 16 ++++++- examples/stm32l4/src/bin/button_exti.rs | 16 ++++++- examples/stm32l5/src/bin/button_exti.rs | 16 ++++++- examples/stm32n6/src/bin/blinky.rs | 16 ++++++- examples/stm32u0/src/bin/button_exti.rs | 16 ++++++- examples/stm32wb/src/bin/button_exti.rs | 16 ++++++- examples/stm32wba/src/bin/button_exti.rs | 16 ++++++- examples/stm32wba6/src/bin/button_exti.rs | 16 ++++++- examples/stm32wl/src/bin/button_exti.rs | 16 ++++++- examples/stm32wle5/src/bin/button_exti.rs | 16 ++++++- 40 files changed, 509 insertions(+), 85 deletions(-) diff --git a/docs/examples/layer-by-layer/blinky-async/src/main.rs b/docs/examples/layer-by-layer/blinky-async/src/main.rs index 004602816..5871534c5 100644 --- a/docs/examples/layer-by-layer/blinky-async/src/main.rs +++ b/docs/examples/layer-by-layer/blinky-async/src/main.rs @@ -2,15 +2,27 @@ #![no_main] use embassy_executor::Spawner; -use embassy_stm32::exti::ExtiInput; +use embassy_stm32::bind_interrupts; +use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::{Level, Output, Pull, Speed}; +use embassy_stm32::interrupt; use {defmt_rtt as _, panic_probe as _}; +bind_interrupts!( + pub struct Irqs{ + EXTI15_10 => exti::InterruptHandler; +}); + #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); let mut led = Output::new(p.PB14, Level::Low, Speed::VeryHigh); - let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up); + let mut button = ExtiInput::new( + p.PC13, + p.EXTI13, + Pull::Up, + Irqs::as_any::>(), + ); loop { button.wait_for_any_edge().await; diff --git a/docs/pages/faq.adoc b/docs/pages/faq.adoc index 8098e12ac..e59ef7b46 100644 --- a/docs/pages/faq.adoc +++ b/docs/pages/faq.adoc @@ -171,7 +171,11 @@ Note that the git revision should match any other embassy patches or git depende == Can I use manual ISRs alongside Embassy? -Yes! This can be useful if you need to respond to an event as fast as possible, and the latency caused by the usual “ISR, wake, return from ISR, context switch to woken task” flow is too much for your application. Simply define a `#[interrupt] fn INTERRUPT_NAME() {}` handler as you would link:https://docs.rust-embedded.org/book/start/interrupts.html[in any other embedded rust project]. +Yes! This can be useful if you need to respond to an event as fast as possible, and the latency caused by the usual “ISR, wake, return from ISR, context switch to woken task” flow is too much for your application. + +You may simply define a `#[interrupt] fn INTERRUPT_NAME() {}` handler as you would link:https://docs.rust-embedded.org/book/start/interrupts.html[in any other embedded rust project]. + +Or you may define a struct implementing the `embassy-[family]::interrupt::typelevel::Handler` trait with an on_interrupt() method, and bind it to the interrupt vector via the `bind_interrupts!` macro, which introduces only a single indirection. This allows the mixing of manual ISRs with Embassy driver-defined ISRs; handlers will be called directly in the order they appear in the macro. == How can I measure resource usage (CPU, RAM, etc.)? diff --git a/docs/pages/layer_by_layer.adoc b/docs/pages/layer_by_layer.adoc index 0692ee4fa..f554e642a 100644 --- a/docs/pages/layer_by_layer.adoc +++ b/docs/pages/layer_by_layer.adoc @@ -76,7 +76,7 @@ The async version looks very similar to the HAL version, apart from a few minor * The peripheral initialization is done by the main macro, and is handed to the main task. * Before checking the button state, the application is awaiting a transition in the pin state (low -> high or high -> low). -When `button.wait_for_any_edge().await` is called, the executor will pause the main task and put the microcontroller in sleep mode, unless there are other tasks that can run. Internally, the Embassy HAL has configured the interrupt handler for the button (in `ExtiInput`), so that whenever an interrupt is raised, the task awaiting the button will be woken up. +When `button.wait_for_any_edge().await` is called, the executor will pause the main task and put the microcontroller in sleep mode, unless there are other tasks that can run. On this chip, interrupt signals on EXTI lines 10-15 (including the button on EXTI line 13) raise the hardware interrupt EXTI15_10. This interrupt handler has been bound (using `bind_interrupts!`) to call the `InterruptHandler` provided by the exti module, so that whenever an interrupt is raised, the task awaiting the button via `wait_for_any_edge()` will be woken up. The minimal overhead of the executor and the ability to run multiple tasks "concurrently" combined with the enormous simplification of the application, makes `async` a great fit for embedded. diff --git a/embassy-hal-internal/CHANGELOG.md b/embassy-hal-internal/CHANGELOG.md index c78923a93..cb637a0ec 100644 --- a/embassy-hal-internal/CHANGELOG.md +++ b/embassy-hal-internal/CHANGELOG.md @@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased - ReleaseDate +- feat: type erasure from Binding to AnyBinding, so that drivers accepting type erased peripheral arguments can still check bindings + ## 0.1.1 - 2025-08-15 - First release with changelog. diff --git a/embassy-hal-internal/src/interrupt.rs b/embassy-hal-internal/src/interrupt.rs index c0ea666da..c97dee70b 100644 --- a/embassy-hal-internal/src/interrupt.rs +++ b/embassy-hal-internal/src/interrupt.rs @@ -170,8 +170,11 @@ macro_rules! interrupt_mod { /// Driver which defined the Handler. Always User for user-defined handlers. #[derive(Copy, Clone)] pub enum HandlerType { + /// Defined in user code, or otherwise has not had its SOURCE_ID overridden. User, + /// Defined somewhere within Embassy. Embassy(PrivateHandlerType), + /// Defined by the [embassy-stm32::exti] module. EmbassyStm32Exti(PrivateHandlerType), } @@ -184,9 +187,11 @@ macro_rules! interrupt_mod { handler_source: HandlerType, } impl AnyBinding { + /// Get the IRQ (vector number) of the interrupt. pub const fn irq(&self) -> super::Interrupt { self.irq } + /// Get the source of the handler bound to the interrupt. pub const fn source(&self) -> HandlerType { self.handler_source } diff --git a/embassy-stm32/CHANGELOG.md b/embassy-stm32/CHANGELOG.md index d2f675dbc..7311ea683 100644 --- a/embassy-stm32/CHANGELOG.md +++ b/embassy-stm32/CHANGELOG.md @@ -71,6 +71,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - fix: fixing channel numbers on vbat and vddcore for adc on adc - adc: adding disable to vbat - feat: stm32/flash: add async support for h7 family +- feat: exti brought in line with other drivers' interrupt rebinding system +- feat: bind_interrupts generates convenience method for type erasing to AnyBinding +- fix: exti2 now usable as a normal exti on chips with touch sensing ## 0.4.0 - 2025-08-26 diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 8cbd38e10..6be3ada51 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -56,12 +56,16 @@ fn main() { eprintln!("chip: {chip_name}"); + cfgs.declare("unimpl_tsc"); for p in METADATA.peripherals { if let Some(r) = &p.registers { cfgs.enable(r.kind); foreach_version_cfg(&mut cfgs, r.kind, r.version, |cfgs, cfg_name| { cfgs.enable(cfg_name); }); + } else if p.name == "TSC" { + //Even if the registers are missing, EXTI needs to know if TSC is present in silicon to know whether the EXTI2 interrupt is shadowed by EXTI2_TSC + cfgs.enable("unimpl_tsc") } } diff --git a/embassy-stm32/src/exti.rs b/embassy-stm32/src/exti.rs index 172435caa..93e15a90d 100644 --- a/embassy-stm32/src/exti.rs +++ b/embassy-stm32/src/exti.rs @@ -11,10 +11,10 @@ use futures_util::FutureExt; use crate::gpio::{AnyPin, Input, Level, Pin as GpioPin, PinNumber, Pull}; use crate::interrupt::Interrupt as InterruptEnum; -use crate::interrupt::typelevel::{AnyBinding, HandlerType, Interrupt as InterruptType, PrivateHandlerType}; +use crate::interrupt::typelevel::{AnyBinding, Handler, HandlerType, Interrupt as InterruptType, PrivateHandlerType}; use crate::pac::EXTI; use crate::pac::exti::regs::Lines; -use crate::{Peri, pac, peripherals}; +use crate::{Peri, pac}; const EXTI_COUNT: usize = 16; static EXTI_WAKERS: [AtomicWaker; EXTI_COUNT] = [const { AtomicWaker::new() }; EXTI_COUNT]; @@ -109,10 +109,12 @@ impl<'d> Unpin for ExtiInput<'d> {} impl<'d> ExtiInput<'d> { /// Create an EXTI input. /// - /// The interrupt [Binding] must be type-erased to [AnyBinding] via [Binding::into_any()] in order - /// to support type-erased [AnyChannel] arguments. - /// /// The Binding must bind the Channel's IRQ to [InterruptHandler]. + /// + /// The interrupt [Binding](crate::interrupt::typelevel::Binding) must be type-erased to [AnyBinding] + /// via [into_any()](crate::interrupt::typelevel::Binding::into_any()), in order to support type-erased + /// [AnyChannel] arguments. [bind_interrupts](crate::bind_interrupts) also generates a convenience + /// method as_any() for type erasure that doesn't need a trait object. pub fn new(pin: Peri<'d, T>, ch: Peri<'d, T::ExtiChannel>, pull: Pull, binding: AnyBinding) -> Self { // Needed if using AnyPin+AnyChannel. assert_eq!(pin.pin(), ch.number()); @@ -354,18 +356,17 @@ macro_rules! foreach_exti_irq { ///EXTI interrupt handler. All EXTI interrupt vectors should be bound to this handler. /// -/// It is generic over the [Interrupt](crate::interrupt::typelevel::Interrupt) rather -/// than the [Instance](crate::exti::Instance) because it should not be bound multiple +/// It is generic over the [Interrupt](InterruptType) rather +/// than the [Channel] because it should not be bound multiple /// times to the same vector on chips which multiplex multiple EXTI interrupts into one vector. // // It technically doesn't need to be generic at all, except to satisfy the generic argument -// of [Handler](crate::interrupt::typelevel::Handler). All EXTI interrupts eventually -// land in the same on_irq() function. +// of [Handler]. All EXTI interrupts eventually land in the same on_irq() function. pub struct InterruptHandler { _phantom: PhantomData, } -impl crate::interrupt::typelevel::Handler for InterruptHandler { +impl Handler for InterruptHandler { const SOURCE_ID: HandlerType = HandlerType::EmbassyStm32Exti(PrivateHandlerType::new()); unsafe fn on_interrupt() { on_irq() @@ -377,10 +378,15 @@ trait SealedChannel {} /// EXTI channel trait. #[allow(private_bounds)] pub trait Channel: PeripheralType + SealedChannel + Sized { - /// Get the EXTI channel number. + /// EXTI channel number. fn number(&self) -> PinNumber; - /// Get the EXTI IRQ, which may be the same for multiple channels + /// [Enum-level Interrupt](InterruptEnum), which may be the same for multiple channels. fn irq(&self) -> InterruptEnum; + /// [Type-level Interrupt](InterruptType), which may be the same for multiple channels. + /// Unavailable on type-erased [AnyChannel], where it is defined as the unit type. + /// has no trait bound, so mostly only useful for doc reference (e.g. while writing + /// [bind_interrupts](crate::bind_interrupts) invocation.) Use irq() for programmatic access. + type INTERRUPT; } /// Type-erased EXTI channel. @@ -400,24 +406,32 @@ impl Channel for AnyChannel { fn irq(&self) -> InterruptEnum { self.irq } + type INTERRUPT = bool; } macro_rules! impl_exti { ($type:ident, $number:expr) => { - impl SealedChannel for peripherals::$type {} - impl Channel for peripherals::$type { + impl_exti!(@inner $type, $number, crate::_generated::peripheral_interrupts::EXTI::$type); + }; + ($type:ident, $number:expr, @tsc) => { + impl_exti!(@inner $type, $number, crate::_generated::peripheral_interrupts::TSC::GLOBAL); + }; + (@inner $type:ident, $number:expr, $irq:path) => { + impl SealedChannel for crate::peripherals::$type {} + impl Channel for crate::peripherals::$type { fn number(&self) -> PinNumber { $number } fn irq(&self) -> InterruptEnum { - crate::_generated::peripheral_interrupts::EXTI::$type::IRQ + <$irq>::IRQ } + type INTERRUPT = $irq; } - impl From for AnyChannel { - fn from(_val: peripherals::$type) -> Self { + impl From for AnyChannel { + fn from(_val: crate::peripherals::$type) -> Self { Self { number: $number, - irq: crate::_generated::peripheral_interrupts::EXTI::$type::IRQ, + irq: <$irq>::IRQ, } } } @@ -426,7 +440,10 @@ macro_rules! impl_exti { impl_exti!(EXTI0, 0); impl_exti!(EXTI1, 1); +#[cfg(not(any(tsc, unimpl_tsc)))] impl_exti!(EXTI2, 2); +#[cfg(any(tsc, unimpl_tsc))] +impl_exti!(EXTI2, 2, @tsc); impl_exti!(EXTI3, 3); impl_exti!(EXTI4, 4); impl_exti!(EXTI5, 5); diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index ef6f1d6dc..e5ffbd753 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs @@ -151,7 +151,7 @@ pub use crate::_generated::interrupt; /// Macro to bind interrupts to handlers. /// /// This defines the right interrupt handlers, and creates a unit struct (like `struct Irqs;`) -/// and implements the right [`Binding`]s for it. You can pass this struct to drivers to +/// and implements the right [`Binding`](crate::interrupt::typelevel::Binding)s for it. You can pass this struct to drivers to /// prove at compile-time that the right interrupts have been bound. /// /// Example of how to bind one interrupt: @@ -195,6 +195,19 @@ macro_rules! bind_interrupts { $(#[$outer])* $vis struct $name; + impl $name { + #[doc = r"Convenience method to call Binding::into_any(). Unlike the trait method, can be called with a turbofish."] + pub fn as_any< + I: $crate::interrupt::typelevel::Interrupt, + H: $crate::interrupt::typelevel::Handler + >() -> $crate::interrupt::typelevel::AnyBinding + where + Self: $crate::interrupt::typelevel::Binding + { + >::into_any() + } + } + $( #[allow(non_snake_case)] #[unsafe(no_mangle)] diff --git a/examples/boot/application/stm32f3/src/bin/a.rs b/examples/boot/application/stm32f3/src/bin/a.rs index b608b2e01..e42e24885 100644 --- a/examples/boot/application/stm32f3/src/bin/a.rs +++ b/examples/boot/application/stm32f3/src/bin/a.rs @@ -6,12 +6,19 @@ use defmt_rtt::*; use embassy_boot_stm32::{AlignedBuffer, FirmwareUpdater, FirmwareUpdaterConfig}; use embassy_embedded_hal::adapter::BlockingAsync; use embassy_executor::Spawner; -use embassy_stm32::exti::ExtiInput; +use embassy_stm32::bind_interrupts; +use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::flash::{Flash, WRITE_SIZE}; use embassy_stm32::gpio::{Level, Output, Pull, Speed}; +use embassy_stm32::interrupt; use embassy_sync::mutex::Mutex; use panic_reset as _; +bind_interrupts!( + pub struct Irqs{ + EXTI15_10 => exti::InterruptHandler; +}); + #[cfg(feature = "skip-include")] static APP_B: &[u8] = &[0, 1, 2, 3]; #[cfg(not(feature = "skip-include"))] @@ -23,7 +30,12 @@ async fn main(_spawner: Spawner) { let flash = Flash::new_blocking(p.FLASH); let flash = Mutex::new(BlockingAsync::new(flash)); - let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up); + let mut button = ExtiInput::new( + p.PC13, + p.EXTI13, + Pull::Up, + Irqs::as_any::>(), + ); let mut led = Output::new(p.PA5, Level::Low, Speed::Low); led.set_high(); diff --git a/examples/boot/application/stm32f7/src/bin/a.rs b/examples/boot/application/stm32f7/src/bin/a.rs index 172b4c235..5ec220c2e 100644 --- a/examples/boot/application/stm32f7/src/bin/a.rs +++ b/examples/boot/application/stm32f7/src/bin/a.rs @@ -7,9 +7,11 @@ use core::cell::RefCell; use defmt_rtt::*; use embassy_boot_stm32::{AlignedBuffer, BlockingFirmwareUpdater, FirmwareUpdaterConfig}; use embassy_executor::Spawner; -use embassy_stm32::exti::ExtiInput; +use embassy_stm32::bind_interrupts; +use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::flash::{Flash, WRITE_SIZE}; use embassy_stm32::gpio::{Level, Output, Pull, Speed}; +use embassy_stm32::interrupt; use embassy_sync::blocking_mutex::Mutex; use embedded_storage::nor_flash::NorFlash; use panic_reset as _; @@ -19,13 +21,23 @@ static APP_B: &[u8] = &[0, 1, 2, 3]; #[cfg(not(feature = "skip-include"))] static APP_B: &[u8] = include_bytes!("../../b.bin"); +bind_interrupts!( + pub struct Irqs{ + EXTI15_10 => exti::InterruptHandler; +}); + #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); let flash = Flash::new_blocking(p.FLASH); let flash = Mutex::new(RefCell::new(flash)); - let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down); + let mut button = ExtiInput::new( + p.PC13, + p.EXTI13, + Pull::Down, + Irqs::as_any::>(), + ); let mut led = Output::new(p.PB7, Level::Low, Speed::Low); led.set_high(); diff --git a/examples/boot/application/stm32h7/src/bin/a.rs b/examples/boot/application/stm32h7/src/bin/a.rs index c1b1a267a..00ac89564 100644 --- a/examples/boot/application/stm32h7/src/bin/a.rs +++ b/examples/boot/application/stm32h7/src/bin/a.rs @@ -7,13 +7,20 @@ use core::cell::RefCell; use defmt_rtt::*; use embassy_boot_stm32::{AlignedBuffer, BlockingFirmwareUpdater, FirmwareUpdaterConfig}; use embassy_executor::Spawner; -use embassy_stm32::exti::ExtiInput; +use embassy_stm32::bind_interrupts; +use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::flash::{Flash, WRITE_SIZE}; use embassy_stm32::gpio::{Level, Output, Pull, Speed}; +use embassy_stm32::interrupt; use embassy_sync::blocking_mutex::Mutex; use embedded_storage::nor_flash::NorFlash; use panic_reset as _; +bind_interrupts!( + pub struct Irqs{ + EXTI15_10 => exti::InterruptHandler; +}); + #[cfg(feature = "skip-include")] static APP_B: &[u8] = &[0, 1, 2, 3]; #[cfg(not(feature = "skip-include"))] @@ -25,7 +32,12 @@ async fn main(_spawner: Spawner) { let flash = Flash::new_blocking(p.FLASH); let flash = Mutex::new(RefCell::new(flash)); - let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down); + let mut button = ExtiInput::new( + p.PC13, + p.EXTI13, + Pull::Down, + Irqs::as_any::>(), + ); let mut led = Output::new(p.PB14, Level::Low, Speed::Low); led.set_high(); diff --git a/examples/boot/application/stm32l0/src/bin/a.rs b/examples/boot/application/stm32l0/src/bin/a.rs index dcc10e5c6..6f21d9be0 100644 --- a/examples/boot/application/stm32l0/src/bin/a.rs +++ b/examples/boot/application/stm32l0/src/bin/a.rs @@ -6,13 +6,20 @@ use defmt_rtt::*; use embassy_boot_stm32::{AlignedBuffer, FirmwareUpdater, FirmwareUpdaterConfig}; use embassy_embedded_hal::adapter::BlockingAsync; use embassy_executor::Spawner; -use embassy_stm32::exti::ExtiInput; +use embassy_stm32::bind_interrupts; +use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::flash::{Flash, WRITE_SIZE}; use embassy_stm32::gpio::{Level, Output, Pull, Speed}; +use embassy_stm32::interrupt; use embassy_sync::mutex::Mutex; use embassy_time::Timer; use panic_reset as _; +bind_interrupts!( + pub struct Irqs{ + EXTI2_3 => exti::InterruptHandler; +}); + #[cfg(feature = "skip-include")] static APP_B: &[u8] = &[0, 1, 2, 3]; #[cfg(not(feature = "skip-include"))] @@ -24,7 +31,12 @@ async fn main(_spawner: Spawner) { let flash = Flash::new_blocking(p.FLASH); let flash = Mutex::new(BlockingAsync::new(flash)); - let mut button = ExtiInput::new(p.PB2, p.EXTI2, Pull::Up); + let mut button = ExtiInput::new( + p.PB2, + p.EXTI2, + Pull::Up, + Irqs::as_any::>(), + ); let mut led = Output::new(p.PB5, Level::Low, Speed::Low); diff --git a/examples/boot/application/stm32l1/src/bin/a.rs b/examples/boot/application/stm32l1/src/bin/a.rs index dcc10e5c6..16f280776 100644 --- a/examples/boot/application/stm32l1/src/bin/a.rs +++ b/examples/boot/application/stm32l1/src/bin/a.rs @@ -6,9 +6,11 @@ use defmt_rtt::*; use embassy_boot_stm32::{AlignedBuffer, FirmwareUpdater, FirmwareUpdaterConfig}; use embassy_embedded_hal::adapter::BlockingAsync; use embassy_executor::Spawner; -use embassy_stm32::exti::ExtiInput; +use embassy_stm32::bind_interrupts; +use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::flash::{Flash, WRITE_SIZE}; use embassy_stm32::gpio::{Level, Output, Pull, Speed}; +use embassy_stm32::interrupt; use embassy_sync::mutex::Mutex; use embassy_time::Timer; use panic_reset as _; @@ -18,6 +20,11 @@ static APP_B: &[u8] = &[0, 1, 2, 3]; #[cfg(not(feature = "skip-include"))] static APP_B: &[u8] = include_bytes!("../../b.bin"); +bind_interrupts!( + pub struct Irqs{ + EXTI2 => exti::InterruptHandler; +}); + #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); @@ -26,7 +33,12 @@ async fn main(_spawner: Spawner) { let mut button = ExtiInput::new(p.PB2, p.EXTI2, Pull::Up); - let mut led = Output::new(p.PB5, Level::Low, Speed::Low); + let mut led = Output::new( + p.PB5, + Level::Low, + Speed::Low, + Irqs::as_any::>(), + ); led.set_high(); diff --git a/examples/boot/application/stm32l4/src/bin/a.rs b/examples/boot/application/stm32l4/src/bin/a.rs index 7f8015c04..5e5d45193 100644 --- a/examples/boot/application/stm32l4/src/bin/a.rs +++ b/examples/boot/application/stm32l4/src/bin/a.rs @@ -6,9 +6,11 @@ use defmt_rtt::*; use embassy_boot_stm32::{AlignedBuffer, FirmwareUpdater, FirmwareUpdaterConfig}; use embassy_embedded_hal::adapter::BlockingAsync; use embassy_executor::Spawner; -use embassy_stm32::exti::ExtiInput; +use embassy_stm32::bind_interrupts; +use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::flash::{Flash, WRITE_SIZE}; use embassy_stm32::gpio::{Level, Output, Pull, Speed}; +use embassy_stm32::interrupt; use embassy_sync::mutex::Mutex; use panic_reset as _; @@ -17,13 +19,23 @@ static APP_B: &[u8] = &[0, 1, 2, 3]; #[cfg(not(feature = "skip-include"))] static APP_B: &[u8] = include_bytes!("../../b.bin"); +bind_interrupts!( + pub struct Irqs{ + EXTI15_10 => exti::InterruptHandler; +}); + #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); let flash = Flash::new_blocking(p.FLASH); let flash = Mutex::new(BlockingAsync::new(flash)); - let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up); + let mut button = ExtiInput::new( + p.PC13, + p.EXTI13, + Pull::Up, + Irqs::as_any::>(), + ); let mut led = Output::new(p.PB14, Level::Low, Speed::Low); led.set_high(); diff --git a/examples/boot/application/stm32wl/src/bin/a.rs b/examples/boot/application/stm32wl/src/bin/a.rs index 3f381fd80..ad45c1262 100644 --- a/examples/boot/application/stm32wl/src/bin/a.rs +++ b/examples/boot/application/stm32wl/src/bin/a.rs @@ -9,9 +9,11 @@ use embassy_boot_stm32::{AlignedBuffer, FirmwareUpdater, FirmwareUpdaterConfig}; use embassy_embedded_hal::adapter::BlockingAsync; use embassy_executor::Spawner; use embassy_stm32::SharedData; -use embassy_stm32::exti::ExtiInput; +use embassy_stm32::bind_interrupts; +use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::flash::{Flash, WRITE_SIZE}; use embassy_stm32::gpio::{Level, Output, Pull, Speed}; +use embassy_stm32::interrupt; use embassy_sync::mutex::Mutex; use panic_reset as _; @@ -20,6 +22,11 @@ static APP_B: &[u8] = &[0, 1, 2, 3]; #[cfg(not(feature = "skip-include"))] static APP_B: &[u8] = include_bytes!("../../b.bin"); +bind_interrupts!( + pub struct Irqs{ + EXTEXTI0I2_3 => exti::InterruptHandler; +}); + #[unsafe(link_section = ".shared_data")] static SHARED_DATA: MaybeUninit = MaybeUninit::uninit(); @@ -29,7 +36,12 @@ async fn main(_spawner: Spawner) { let flash = Flash::new_blocking(p.FLASH); let flash = Mutex::new(BlockingAsync::new(flash)); - let mut button = ExtiInput::new(p.PA0, p.EXTI0, Pull::Up); + let mut button = ExtiInput::new( + p.PA0, + p.EXTI0, + Pull::Up, + Irqs::as_any::>(), + ); let mut led = Output::new(p.PB9, Level::Low, Speed::Low); led.set_high(); diff --git a/examples/stm32c0/src/bin/button_exti.rs b/examples/stm32c0/src/bin/button_exti.rs index 34a08bbc6..dbc9e2f50 100644 --- a/examples/stm32c0/src/bin/button_exti.rs +++ b/examples/stm32c0/src/bin/button_exti.rs @@ -3,16 +3,28 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::exti::ExtiInput; +use embassy_stm32::bind_interrupts; +use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; +use embassy_stm32::interrupt; use {defmt_rtt as _, panic_probe as _}; +bind_interrupts!( + pub struct Irqs{ + EXTI4_15 => exti::InterruptHandler; +}); + #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up); + let mut button = ExtiInput::new( + p.PC13, + p.EXTI13, + Pull::Up, + Irqs::as_any::>(), + ); info!("Press the USER button..."); diff --git a/examples/stm32f0/src/bin/button_controlled_blink.rs b/examples/stm32f0/src/bin/button_controlled_blink.rs index 0b678af01..f57d5d200 100644 --- a/examples/stm32f0/src/bin/button_controlled_blink.rs +++ b/examples/stm32f0/src/bin/button_controlled_blink.rs @@ -8,13 +8,20 @@ use core::sync::atomic::{AtomicU32, Ordering}; use defmt::info; use embassy_executor::Spawner; use embassy_stm32::Peri; -use embassy_stm32::exti::ExtiInput; +use embassy_stm32::bind_interrupts; +use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::{AnyPin, Level, Output, Pull, Speed}; +use embassy_stm32::interrupt; use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; static BLINK_MS: AtomicU32 = AtomicU32::new(0); +bind_interrupts!( + pub struct Irqs{ + EXTI4_15 => exti::InterruptHandler; +}); + #[embassy_executor::task] async fn led_task(led: Peri<'static, AnyPin>) { // Configure the LED pin as a push pull output and obtain handler. @@ -37,7 +44,12 @@ async fn main(spawner: Spawner) { // Configure the button pin and obtain handler. // On the Nucleo F091RC there is a button connected to pin PC13. - let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::None); + let mut button = ExtiInput::new( + p.PC13, + p.EXTI13, + Pull::None, + Irqs::as_any::>(), + ); // Create and initialize a delay variable to manage delay loop let mut del_var = 2000; diff --git a/examples/stm32f0/src/bin/button_exti.rs b/examples/stm32f0/src/bin/button_exti.rs index fd615a215..67ea19215 100644 --- a/examples/stm32f0/src/bin/button_exti.rs +++ b/examples/stm32f0/src/bin/button_exti.rs @@ -3,17 +3,29 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::exti::ExtiInput; +use embassy_stm32::bind_interrupts; +use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; +use embassy_stm32::interrupt; use {defmt_rtt as _, panic_probe as _}; +bind_interrupts!( + pub struct Irqs{ + EXTI4_15 => exti::InterruptHandler; +}); + #[embassy_executor::main] async fn main(_spawner: Spawner) { // Initialize and create handle for devicer peripherals let p = embassy_stm32::init(Default::default()); // Configure the button pin and obtain handler. // On the Nucleo F091RC there is a button connected to pin PC13. - let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down); + let mut button = ExtiInput::new( + p.PC13, + p.EXTI13, + Pull::Down, + Irqs::as_any::>(), + ); info!("Press the USER button..."); loop { diff --git a/examples/stm32f3/src/bin/button_events.rs b/examples/stm32f3/src/bin/button_events.rs index 99957a641..78c6592ee 100644 --- a/examples/stm32f3/src/bin/button_events.rs +++ b/examples/stm32f3/src/bin/button_events.rs @@ -11,13 +11,20 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::exti::ExtiInput; +use embassy_stm32::bind_interrupts; +use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::{Level, Output, Pull, Speed}; +use embassy_stm32::interrupt; use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; use embassy_sync::channel::Channel; use embassy_time::{Duration, Timer, with_timeout}; use {defmt_rtt as _, panic_probe as _}; +bind_interrupts!( + pub struct Irqs{ + EXTI0 => exti::InterruptHandler; +}); + struct Leds<'a> { leds: [Output<'a>; 8], direction: i8, @@ -99,7 +106,12 @@ static CHANNEL: Channel = Channel::new(); #[embassy_executor::main] async fn main(spawner: Spawner) { let p = embassy_stm32::init(Default::default()); - let button = ExtiInput::new(p.PA0, p.EXTI0, Pull::Down); + let button = ExtiInput::new( + p.PA0, + p.EXTI0, + Pull::Down, + Irqs::as_any::>(), + ); info!("Press the USER button..."); let leds = [ Output::new(p.PE9, Level::Low, Speed::Low), diff --git a/examples/stm32f3/src/bin/button_exti.rs b/examples/stm32f3/src/bin/button_exti.rs index a55530e0e..d6d613447 100644 --- a/examples/stm32f3/src/bin/button_exti.rs +++ b/examples/stm32f3/src/bin/button_exti.rs @@ -3,16 +3,28 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::exti::ExtiInput; +use embassy_stm32::bind_interrupts; +use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; +use embassy_stm32::interrupt; use {defmt_rtt as _, panic_probe as _}; +bind_interrupts!( + pub struct Irqs{ + EXTI0 => exti::InterruptHandler; +}); + #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let mut button = ExtiInput::new(p.PA0, p.EXTI0, Pull::Down); + let mut button = ExtiInput::new( + p.PA0, + p.EXTI0, + Pull::Down, + Irqs::as_any::>(), + ); info!("Press the USER button..."); diff --git a/examples/stm32f4/src/bin/button_exti.rs b/examples/stm32f4/src/bin/button_exti.rs index 2a546dac5..77831224b 100644 --- a/examples/stm32f4/src/bin/button_exti.rs +++ b/examples/stm32f4/src/bin/button_exti.rs @@ -3,16 +3,28 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::exti::ExtiInput; +use embassy_stm32::bind_interrupts; +use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; +use embassy_stm32::interrupt; use {defmt_rtt as _, panic_probe as _}; +bind_interrupts!( + pub struct Irqs{ + EXTI15_10 => exti::InterruptHandler; +}); + #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down); + let mut button = ExtiInput::new( + p.PC13, + p.EXTI13, + Pull::Down, + Irqs::as_any::>(), + ); info!("Press the USER button..."); diff --git a/examples/stm32f4/src/bin/eth_w5500.rs b/examples/stm32f4/src/bin/eth_w5500.rs index 0adcda614..f7d2ce7de 100644 --- a/examples/stm32f4/src/bin/eth_w5500.rs +++ b/examples/stm32f4/src/bin/eth_w5500.rs @@ -7,8 +7,10 @@ use embassy_net::tcp::TcpSocket; use embassy_net::{Ipv4Address, StackResources}; use embassy_net_wiznet::chip::W5500; use embassy_net_wiznet::{Device, Runner, State}; -use embassy_stm32::exti::ExtiInput; +use embassy_stm32::bind_interrupts; +use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::{Level, Output, Pull, Speed}; +use embassy_stm32::interrupt; use embassy_stm32::mode::Async; use embassy_stm32::rng::Rng; use embassy_stm32::spi::Spi; @@ -23,6 +25,7 @@ use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { HASH_RNG => rng::InterruptHandler; + EXTI0 => exti::InterruptHandler; }); type EthernetSPI = ExclusiveDevice, Output<'static>, Delay>; @@ -75,7 +78,12 @@ async fn main(spawner: Spawner) -> ! { let cs = Output::new(p.PA4, Level::High, Speed::VeryHigh); let spi = unwrap!(ExclusiveDevice::new(spi, cs, Delay)); - let w5500_int = ExtiInput::new(p.PB0, p.EXTI0, Pull::Up); + let w5500_int = ExtiInput::new( + p.PB0, + p.EXTI0, + Pull::Up, + Irqs::as_any::>(), + ); let w5500_reset = Output::new(p.PB1, Level::High, Speed::VeryHigh); let mac_addr = [0x02, 234, 3, 4, 82, 231]; diff --git a/examples/stm32f4/src/bin/usb_hid_keyboard.rs b/examples/stm32f4/src/bin/usb_hid_keyboard.rs index 9971e43f5..60922c2e8 100644 --- a/examples/stm32f4/src/bin/usb_hid_keyboard.rs +++ b/examples/stm32f4/src/bin/usb_hid_keyboard.rs @@ -6,8 +6,10 @@ use core::sync::atomic::{AtomicBool, AtomicU8, Ordering}; use defmt::*; use embassy_executor::Spawner; use embassy_futures::join::join; -use embassy_stm32::exti::ExtiInput; +use embassy_stm32::bind_interrupts; +use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; +use embassy_stm32::interrupt; use embassy_stm32::time::Hertz; use embassy_stm32::usb::Driver; use embassy_stm32::{Config, bind_interrupts, peripherals, usb}; @@ -21,6 +23,7 @@ use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { OTG_FS => usb::InterruptHandler; + EXTI15_10 => exti::InterruptHandler; }); static HID_PROTOCOL_MODE: AtomicU8 = AtomicU8::new(HidProtocolMode::Boot as u8); @@ -123,7 +126,12 @@ async fn main(_spawner: Spawner) { let (reader, mut writer) = hid.split(); - let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down); + let mut button = ExtiInput::new( + p.PC13, + p.EXTI13, + Pull::Down, + Irqs::as_any::>(), + ); // Do stuff with the class! let in_fut = async { diff --git a/examples/stm32f7/src/bin/button_exti.rs b/examples/stm32f7/src/bin/button_exti.rs index 2a546dac5..77831224b 100644 --- a/examples/stm32f7/src/bin/button_exti.rs +++ b/examples/stm32f7/src/bin/button_exti.rs @@ -3,16 +3,28 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::exti::ExtiInput; +use embassy_stm32::bind_interrupts; +use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; +use embassy_stm32::interrupt; use {defmt_rtt as _, panic_probe as _}; +bind_interrupts!( + pub struct Irqs{ + EXTI15_10 => exti::InterruptHandler; +}); + #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down); + let mut button = ExtiInput::new( + p.PC13, + p.EXTI13, + Pull::Down, + Irqs::as_any::>(), + ); info!("Press the USER button..."); diff --git a/examples/stm32g0/src/bin/button_exti.rs b/examples/stm32g0/src/bin/button_exti.rs index 34a08bbc6..dbc9e2f50 100644 --- a/examples/stm32g0/src/bin/button_exti.rs +++ b/examples/stm32g0/src/bin/button_exti.rs @@ -3,16 +3,28 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::exti::ExtiInput; +use embassy_stm32::bind_interrupts; +use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; +use embassy_stm32::interrupt; use {defmt_rtt as _, panic_probe as _}; +bind_interrupts!( + pub struct Irqs{ + EXTI4_15 => exti::InterruptHandler; +}); + #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up); + let mut button = ExtiInput::new( + p.PC13, + p.EXTI13, + Pull::Up, + Irqs::as_any::>(), + ); info!("Press the USER button..."); diff --git a/examples/stm32g4/src/bin/button_exti.rs b/examples/stm32g4/src/bin/button_exti.rs index 2a546dac5..77831224b 100644 --- a/examples/stm32g4/src/bin/button_exti.rs +++ b/examples/stm32g4/src/bin/button_exti.rs @@ -3,16 +3,28 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::exti::ExtiInput; +use embassy_stm32::bind_interrupts; +use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; +use embassy_stm32::interrupt; use {defmt_rtt as _, panic_probe as _}; +bind_interrupts!( + pub struct Irqs{ + EXTI15_10 => exti::InterruptHandler; +}); + #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down); + let mut button = ExtiInput::new( + p.PC13, + p.EXTI13, + Pull::Down, + Irqs::as_any::>(), + ); info!("Press the USER button..."); diff --git a/examples/stm32h5/src/bin/button_exti.rs b/examples/stm32h5/src/bin/button_exti.rs index 2a546dac5..f49f0ff1c 100644 --- a/examples/stm32h5/src/bin/button_exti.rs +++ b/examples/stm32h5/src/bin/button_exti.rs @@ -3,16 +3,28 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::exti::ExtiInput; +use embassy_stm32::bind_interrupts; +use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; +use embassy_stm32::interrupt; use {defmt_rtt as _, panic_probe as _}; +bind_interrupts!( + pub struct Irqs{ + EXTI13 => exti::InterruptHandler; +}); + #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down); + let mut button = ExtiInput::new( + p.PC13, + p.EXTI13, + Pull::Down, + Irqs::as_any::>(), + ); info!("Press the USER button..."); diff --git a/examples/stm32h7/src/bin/button_exti.rs b/examples/stm32h7/src/bin/button_exti.rs index 2a546dac5..77831224b 100644 --- a/examples/stm32h7/src/bin/button_exti.rs +++ b/examples/stm32h7/src/bin/button_exti.rs @@ -3,16 +3,28 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::exti::ExtiInput; +use embassy_stm32::bind_interrupts; +use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; +use embassy_stm32::interrupt; use {defmt_rtt as _, panic_probe as _}; +bind_interrupts!( + pub struct Irqs{ + EXTI15_10 => exti::InterruptHandler; +}); + #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down); + let mut button = ExtiInput::new( + p.PC13, + p.EXTI13, + Pull::Down, + Irqs::as_any::>(), + ); info!("Press the USER button..."); diff --git a/examples/stm32h7rs/src/bin/button_exti.rs b/examples/stm32h7rs/src/bin/button_exti.rs index 34a08bbc6..d4cf36fcc 100644 --- a/examples/stm32h7rs/src/bin/button_exti.rs +++ b/examples/stm32h7rs/src/bin/button_exti.rs @@ -3,16 +3,28 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::exti::ExtiInput; +use embassy_stm32::bind_interrupts; +use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; +use embassy_stm32::interrupt; use {defmt_rtt as _, panic_probe as _}; +bind_interrupts!( + pub struct Irqs{ + EXTI13 => exti::InterruptHandler; +}); + #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up); + let mut button = ExtiInput::new( + p.PC13, + p.EXTI13, + Pull::Up, + Irqs::as_any::>(), + ); info!("Press the USER button..."); diff --git a/examples/stm32l0/src/bin/button_exti.rs b/examples/stm32l0/src/bin/button_exti.rs index 7ff4a7d52..afdeb14af 100644 --- a/examples/stm32l0/src/bin/button_exti.rs +++ b/examples/stm32l0/src/bin/button_exti.rs @@ -4,16 +4,28 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::Config; -use embassy_stm32::exti::ExtiInput; +use embassy_stm32::bind_interrupts; +use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; +use embassy_stm32::interrupt; use {defmt_rtt as _, panic_probe as _}; +bind_interrupts!( + pub struct Irqs{ + EXTI2_3 => exti::InterruptHandler; +}); + #[embassy_executor::main] async fn main(_spawner: Spawner) { let config = Config::default(); let p = embassy_stm32::init(config); - let mut button = ExtiInput::new(p.PB2, p.EXTI2, Pull::Up); + let mut button = ExtiInput::new( + p.PB2, + p.EXTI2, + Pull::Up, + Irqs::as_any::>(), + ); info!("Press the USER button..."); diff --git a/examples/stm32l4/src/bin/button_exti.rs b/examples/stm32l4/src/bin/button_exti.rs index 34a08bbc6..4d03671c0 100644 --- a/examples/stm32l4/src/bin/button_exti.rs +++ b/examples/stm32l4/src/bin/button_exti.rs @@ -3,16 +3,28 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::exti::ExtiInput; +use embassy_stm32::bind_interrupts; +use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; +use embassy_stm32::interrupt; use {defmt_rtt as _, panic_probe as _}; +bind_interrupts!( + pub struct Irqs{ + EXTI15_10 => exti::InterruptHandler; +}); + #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up); + let mut button = ExtiInput::new( + p.PC13, + p.EXTI13, + Pull::Up, + Irqs::as_any::>(), + ); info!("Press the USER button..."); diff --git a/examples/stm32l5/src/bin/button_exti.rs b/examples/stm32l5/src/bin/button_exti.rs index e6639d22b..02e2013c9 100644 --- a/examples/stm32l5/src/bin/button_exti.rs +++ b/examples/stm32l5/src/bin/button_exti.rs @@ -3,16 +3,28 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::exti::ExtiInput; +use embassy_stm32::bind_interrupts; +use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; +use embassy_stm32::interrupt; use {defmt_rtt as _, panic_probe as _}; +bind_interrupts!( + pub struct Irqs{ + EXTI13 => exti::InterruptHandler; +}); + #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down); + let mut button = ExtiInput::new( + p.PC13, + p.EXTI13, + Pull::Down, + Irqs::as_any::>(), + ); info!("Press the USER button..."); diff --git a/examples/stm32n6/src/bin/blinky.rs b/examples/stm32n6/src/bin/blinky.rs index 018967f08..c72e45628 100644 --- a/examples/stm32n6/src/bin/blinky.rs +++ b/examples/stm32n6/src/bin/blinky.rs @@ -3,11 +3,18 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::exti::ExtiInput; +use embassy_stm32::bind_interrupts; +use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::{Level, Output, Pull, Speed}; +use embassy_stm32::interrupt; use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; +bind_interrupts!( + pub struct Irqs{ + EXTI13 => exti::InterruptHandler; +}); + #[embassy_executor::task] async fn button_task(mut p: ExtiInput<'static>) { loop { @@ -22,7 +29,12 @@ async fn main(spawner: Spawner) { info!("Hello World!"); let mut led = Output::new(p.PG10, Level::High, Speed::Low); - let button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up); + let button = ExtiInput::new( + p.PC13, + p.EXTI13, + Pull::Up, + Irqs::as_any::>(), + ); spawner.spawn(button_task(button).unwrap()); diff --git a/examples/stm32u0/src/bin/button_exti.rs b/examples/stm32u0/src/bin/button_exti.rs index 34a08bbc6..dbc9e2f50 100644 --- a/examples/stm32u0/src/bin/button_exti.rs +++ b/examples/stm32u0/src/bin/button_exti.rs @@ -3,16 +3,28 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::exti::ExtiInput; +use embassy_stm32::bind_interrupts; +use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; +use embassy_stm32::interrupt; use {defmt_rtt as _, panic_probe as _}; +bind_interrupts!( + pub struct Irqs{ + EXTI4_15 => exti::InterruptHandler; +}); + #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up); + let mut button = ExtiInput::new( + p.PC13, + p.EXTI13, + Pull::Up, + Irqs::as_any::>(), + ); info!("Press the USER button..."); diff --git a/examples/stm32wb/src/bin/button_exti.rs b/examples/stm32wb/src/bin/button_exti.rs index 2871fd55f..2736b98f1 100644 --- a/examples/stm32wb/src/bin/button_exti.rs +++ b/examples/stm32wb/src/bin/button_exti.rs @@ -3,16 +3,28 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::exti::ExtiInput; +use embassy_stm32::bind_interrupts; +use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; +use embassy_stm32::interrupt; use {defmt_rtt as _, panic_probe as _}; +bind_interrupts!( + pub struct Irqs{ + EXTI4 => exti::InterruptHandler; +}); + #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let mut button = ExtiInput::new(p.PC4, p.EXTI4, Pull::Up); + let mut button = ExtiInput::new( + p.PC4, + p.EXTI4, + Pull::Up, + Irqs::as_any::>(), + ); info!("Press the USER button..."); diff --git a/examples/stm32wba/src/bin/button_exti.rs b/examples/stm32wba/src/bin/button_exti.rs index 34a08bbc6..d4cf36fcc 100644 --- a/examples/stm32wba/src/bin/button_exti.rs +++ b/examples/stm32wba/src/bin/button_exti.rs @@ -3,16 +3,28 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::exti::ExtiInput; +use embassy_stm32::bind_interrupts; +use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; +use embassy_stm32::interrupt; use {defmt_rtt as _, panic_probe as _}; +bind_interrupts!( + pub struct Irqs{ + EXTI13 => exti::InterruptHandler; +}); + #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up); + let mut button = ExtiInput::new( + p.PC13, + p.EXTI13, + Pull::Up, + Irqs::as_any::>(), + ); info!("Press the USER button..."); diff --git a/examples/stm32wba6/src/bin/button_exti.rs b/examples/stm32wba6/src/bin/button_exti.rs index 34a08bbc6..d4cf36fcc 100644 --- a/examples/stm32wba6/src/bin/button_exti.rs +++ b/examples/stm32wba6/src/bin/button_exti.rs @@ -3,16 +3,28 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::exti::ExtiInput; +use embassy_stm32::bind_interrupts; +use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; +use embassy_stm32::interrupt; use {defmt_rtt as _, panic_probe as _}; +bind_interrupts!( + pub struct Irqs{ + EXTI13 => exti::InterruptHandler; +}); + #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up); + let mut button = ExtiInput::new( + p.PC13, + p.EXTI13, + Pull::Up, + Irqs::as_any::>(), + ); info!("Press the USER button..."); diff --git a/examples/stm32wl/src/bin/button_exti.rs b/examples/stm32wl/src/bin/button_exti.rs index 953b13bac..183f93f2f 100644 --- a/examples/stm32wl/src/bin/button_exti.rs +++ b/examples/stm32wl/src/bin/button_exti.rs @@ -6,10 +6,17 @@ use core::mem::MaybeUninit; use defmt::*; use embassy_executor::Spawner; use embassy_stm32::SharedData; -use embassy_stm32::exti::ExtiInput; +use embassy_stm32::bind_interrupts; +use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; +use embassy_stm32::interrupt; use {defmt_rtt as _, panic_probe as _}; +bind_interrupts!( + pub struct Irqs{ + EXTI0 => exti::InterruptHandler; +}); + #[unsafe(link_section = ".shared_data")] static SHARED_DATA: MaybeUninit = MaybeUninit::uninit(); @@ -18,7 +25,12 @@ async fn main(_spawner: Spawner) { let p = embassy_stm32::init_primary(Default::default(), &SHARED_DATA); info!("Hello World!"); - let mut button = ExtiInput::new(p.PA0, p.EXTI0, Pull::Up); + let mut button = ExtiInput::new( + p.PA0, + p.EXTI0, + Pull::Up, + Irqs::as_any::>(), + ); info!("Press the USER button..."); diff --git a/examples/stm32wle5/src/bin/button_exti.rs b/examples/stm32wle5/src/bin/button_exti.rs index 878eca7d0..196afa330 100644 --- a/examples/stm32wle5/src/bin/button_exti.rs +++ b/examples/stm32wle5/src/bin/button_exti.rs @@ -5,12 +5,19 @@ use defmt::*; #[cfg(feature = "defmt-rtt")] use defmt_rtt as _; use embassy_executor::Spawner; -use embassy_stm32::exti::ExtiInput; +use embassy_stm32::bind_interrupts; +use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; +use embassy_stm32::interrupt; use embassy_stm32::low_power; use panic_probe as _; use static_cell::StaticCell; +bind_interrupts!( + pub struct Irqs{ + EXTI0 => exti::InterruptHandler; +}); + #[embassy_executor::main(executor = "low_power::Executor")] async fn async_main(_spawner: Spawner) { let mut config = embassy_stm32::Config::default(); @@ -64,7 +71,12 @@ async fn async_main(_spawner: Spawner) { info!("Hello World!"); - let mut button = ExtiInput::new(p.PA0, p.EXTI0, Pull::Up); + let mut button = ExtiInput::new( + p.PA0, + p.EXTI0, + Pull::Up, + Irqs::as_any::>(), + ); info!("Press the USER button..."); -- cgit From 54d57bc72f0e2b3eef0fa92d0b730ed6efd7bcaa Mon Sep 17 00:00:00 2001 From: WillaWillNot Date: Fri, 21 Nov 2025 20:35:54 -0500 Subject: Fixed broken examples/formatting reported by CI --- .vscode/settings.json | 6 +++++- docs/examples/layer-by-layer/blinky-async/src/main.rs | 3 +-- examples/boot/application/stm32f3/src/bin/a.rs | 3 +-- examples/boot/application/stm32f7/src/bin/a.rs | 3 +-- examples/boot/application/stm32h7/src/bin/a.rs | 3 +-- examples/boot/application/stm32l0/src/bin/a.rs | 3 +-- examples/boot/application/stm32l1/src/bin/a.rs | 15 +++++++-------- examples/boot/application/stm32l4/src/bin/a.rs | 3 +-- examples/boot/application/stm32wl/src/bin/a.rs | 6 ++---- examples/stm32c0/src/bin/button_exti.rs | 3 +-- examples/stm32f0/src/bin/button_controlled_blink.rs | 4 +--- examples/stm32f0/src/bin/button_exti.rs | 3 +-- examples/stm32f3/src/bin/button_events.rs | 3 +-- examples/stm32f3/src/bin/button_exti.rs | 3 +-- examples/stm32f4/src/bin/button_exti.rs | 3 +-- examples/stm32f4/src/bin/eth_w5500.rs | 4 +--- examples/stm32f4/src/bin/usb_hid_keyboard.rs | 4 +--- examples/stm32f7/src/bin/button_exti.rs | 3 +-- examples/stm32g0/src/bin/button_exti.rs | 3 +-- examples/stm32g4/src/bin/button_exti.rs | 3 +-- examples/stm32h5/src/bin/button_exti.rs | 3 +-- examples/stm32h7/src/bin/button_exti.rs | 3 +-- examples/stm32h7rs/src/bin/button_exti.rs | 3 +-- examples/stm32l0/src/bin/button_exti.rs | 4 +--- examples/stm32l4/src/bin/button_exti.rs | 3 +-- examples/stm32l4/src/bin/spe_adin1110_http_server.rs | 11 +++++++++-- examples/stm32l4/src/bin/spi_dma.rs | 4 ++-- examples/stm32l5/src/bin/button_exti.rs | 3 +-- examples/stm32n6/src/bin/blinky.rs | 3 +-- examples/stm32u0/src/bin/button_exti.rs | 3 +-- examples/stm32wb/src/bin/button_exti.rs | 3 +-- examples/stm32wba/src/bin/button_exti.rs | 3 +-- examples/stm32wba6/src/bin/button_exti.rs | 3 +-- examples/stm32wl/src/bin/button_exti.rs | 4 +--- examples/stm32wle5/src/bin/button_exti.rs | 4 +--- 35 files changed, 55 insertions(+), 83 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index c504f3ccd..3c9cce18b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -61,4 +61,8 @@ // "examples/stm32wl/Cargo.toml", // "examples/wasm/Cargo.toml", ], -} + "rust-analyzer.rustfmt.extraArgs": [ + //Uncomment to run rustfmt with nightly-only settings that match the CI + // "+nightly" + ], +} \ No newline at end of file diff --git a/docs/examples/layer-by-layer/blinky-async/src/main.rs b/docs/examples/layer-by-layer/blinky-async/src/main.rs index 5871534c5..02cee2a4b 100644 --- a/docs/examples/layer-by-layer/blinky-async/src/main.rs +++ b/docs/examples/layer-by-layer/blinky-async/src/main.rs @@ -2,10 +2,9 @@ #![no_main] use embassy_executor::Spawner; -use embassy_stm32::bind_interrupts; use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::{Level, Output, Pull, Speed}; -use embassy_stm32::interrupt; +use embassy_stm32::{bind_interrupts, interrupt}; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!( diff --git a/examples/boot/application/stm32f3/src/bin/a.rs b/examples/boot/application/stm32f3/src/bin/a.rs index e42e24885..8e0a6685e 100644 --- a/examples/boot/application/stm32f3/src/bin/a.rs +++ b/examples/boot/application/stm32f3/src/bin/a.rs @@ -6,11 +6,10 @@ use defmt_rtt::*; use embassy_boot_stm32::{AlignedBuffer, FirmwareUpdater, FirmwareUpdaterConfig}; use embassy_embedded_hal::adapter::BlockingAsync; use embassy_executor::Spawner; -use embassy_stm32::bind_interrupts; use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::flash::{Flash, WRITE_SIZE}; use embassy_stm32::gpio::{Level, Output, Pull, Speed}; -use embassy_stm32::interrupt; +use embassy_stm32::{bind_interrupts, interrupt}; use embassy_sync::mutex::Mutex; use panic_reset as _; diff --git a/examples/boot/application/stm32f7/src/bin/a.rs b/examples/boot/application/stm32f7/src/bin/a.rs index 5ec220c2e..db808934f 100644 --- a/examples/boot/application/stm32f7/src/bin/a.rs +++ b/examples/boot/application/stm32f7/src/bin/a.rs @@ -7,11 +7,10 @@ use core::cell::RefCell; use defmt_rtt::*; use embassy_boot_stm32::{AlignedBuffer, BlockingFirmwareUpdater, FirmwareUpdaterConfig}; use embassy_executor::Spawner; -use embassy_stm32::bind_interrupts; use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::flash::{Flash, WRITE_SIZE}; use embassy_stm32::gpio::{Level, Output, Pull, Speed}; -use embassy_stm32::interrupt; +use embassy_stm32::{bind_interrupts, interrupt}; use embassy_sync::blocking_mutex::Mutex; use embedded_storage::nor_flash::NorFlash; use panic_reset as _; diff --git a/examples/boot/application/stm32h7/src/bin/a.rs b/examples/boot/application/stm32h7/src/bin/a.rs index 00ac89564..ed2d5b89e 100644 --- a/examples/boot/application/stm32h7/src/bin/a.rs +++ b/examples/boot/application/stm32h7/src/bin/a.rs @@ -7,11 +7,10 @@ use core::cell::RefCell; use defmt_rtt::*; use embassy_boot_stm32::{AlignedBuffer, BlockingFirmwareUpdater, FirmwareUpdaterConfig}; use embassy_executor::Spawner; -use embassy_stm32::bind_interrupts; use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::flash::{Flash, WRITE_SIZE}; use embassy_stm32::gpio::{Level, Output, Pull, Speed}; -use embassy_stm32::interrupt; +use embassy_stm32::{bind_interrupts, interrupt}; use embassy_sync::blocking_mutex::Mutex; use embedded_storage::nor_flash::NorFlash; use panic_reset as _; diff --git a/examples/boot/application/stm32l0/src/bin/a.rs b/examples/boot/application/stm32l0/src/bin/a.rs index 6f21d9be0..3f9e6d24e 100644 --- a/examples/boot/application/stm32l0/src/bin/a.rs +++ b/examples/boot/application/stm32l0/src/bin/a.rs @@ -6,11 +6,10 @@ use defmt_rtt::*; use embassy_boot_stm32::{AlignedBuffer, FirmwareUpdater, FirmwareUpdaterConfig}; use embassy_embedded_hal::adapter::BlockingAsync; use embassy_executor::Spawner; -use embassy_stm32::bind_interrupts; use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::flash::{Flash, WRITE_SIZE}; use embassy_stm32::gpio::{Level, Output, Pull, Speed}; -use embassy_stm32::interrupt; +use embassy_stm32::{bind_interrupts, interrupt}; use embassy_sync::mutex::Mutex; use embassy_time::Timer; use panic_reset as _; diff --git a/examples/boot/application/stm32l1/src/bin/a.rs b/examples/boot/application/stm32l1/src/bin/a.rs index 16f280776..b5432eb91 100644 --- a/examples/boot/application/stm32l1/src/bin/a.rs +++ b/examples/boot/application/stm32l1/src/bin/a.rs @@ -6,11 +6,10 @@ use defmt_rtt::*; use embassy_boot_stm32::{AlignedBuffer, FirmwareUpdater, FirmwareUpdaterConfig}; use embassy_embedded_hal::adapter::BlockingAsync; use embassy_executor::Spawner; -use embassy_stm32::bind_interrupts; use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::flash::{Flash, WRITE_SIZE}; use embassy_stm32::gpio::{Level, Output, Pull, Speed}; -use embassy_stm32::interrupt; +use embassy_stm32::{bind_interrupts, interrupt}; use embassy_sync::mutex::Mutex; use embassy_time::Timer; use panic_reset as _; @@ -31,15 +30,15 @@ async fn main(_spawner: Spawner) { let flash = Flash::new_blocking(p.FLASH); let flash = Mutex::new(BlockingAsync::new(flash)); - let mut button = ExtiInput::new(p.PB2, p.EXTI2, Pull::Up); - - let mut led = Output::new( - p.PB5, - Level::Low, - Speed::Low, + let mut button = ExtiInput::new( + p.PB2, + p.EXTI2, + Pull::Up, Irqs::as_any::>(), ); + let mut led = Output::new(p.PB5, Level::Low, Speed::Low); + led.set_high(); let config = FirmwareUpdaterConfig::from_linkerfile(&flash, &flash); diff --git a/examples/boot/application/stm32l4/src/bin/a.rs b/examples/boot/application/stm32l4/src/bin/a.rs index 5e5d45193..349e57f94 100644 --- a/examples/boot/application/stm32l4/src/bin/a.rs +++ b/examples/boot/application/stm32l4/src/bin/a.rs @@ -6,11 +6,10 @@ use defmt_rtt::*; use embassy_boot_stm32::{AlignedBuffer, FirmwareUpdater, FirmwareUpdaterConfig}; use embassy_embedded_hal::adapter::BlockingAsync; use embassy_executor::Spawner; -use embassy_stm32::bind_interrupts; use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::flash::{Flash, WRITE_SIZE}; use embassy_stm32::gpio::{Level, Output, Pull, Speed}; -use embassy_stm32::interrupt; +use embassy_stm32::{bind_interrupts, interrupt}; use embassy_sync::mutex::Mutex; use panic_reset as _; diff --git a/examples/boot/application/stm32wl/src/bin/a.rs b/examples/boot/application/stm32wl/src/bin/a.rs index ad45c1262..285d57e41 100644 --- a/examples/boot/application/stm32wl/src/bin/a.rs +++ b/examples/boot/application/stm32wl/src/bin/a.rs @@ -8,12 +8,10 @@ use defmt_rtt::*; use embassy_boot_stm32::{AlignedBuffer, FirmwareUpdater, FirmwareUpdaterConfig}; use embassy_embedded_hal::adapter::BlockingAsync; use embassy_executor::Spawner; -use embassy_stm32::SharedData; -use embassy_stm32::bind_interrupts; use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::flash::{Flash, WRITE_SIZE}; use embassy_stm32::gpio::{Level, Output, Pull, Speed}; -use embassy_stm32::interrupt; +use embassy_stm32::{SharedData, bind_interrupts, interrupt}; use embassy_sync::mutex::Mutex; use panic_reset as _; @@ -24,7 +22,7 @@ static APP_B: &[u8] = include_bytes!("../../b.bin"); bind_interrupts!( pub struct Irqs{ - EXTEXTI0I2_3 => exti::InterruptHandler; + EXTI0 => exti::InterruptHandler; }); #[unsafe(link_section = ".shared_data")] diff --git a/examples/stm32c0/src/bin/button_exti.rs b/examples/stm32c0/src/bin/button_exti.rs index dbc9e2f50..52fdc39c5 100644 --- a/examples/stm32c0/src/bin/button_exti.rs +++ b/examples/stm32c0/src/bin/button_exti.rs @@ -3,10 +3,9 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::bind_interrupts; use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; -use embassy_stm32::interrupt; +use embassy_stm32::{bind_interrupts, interrupt}; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!( diff --git a/examples/stm32f0/src/bin/button_controlled_blink.rs b/examples/stm32f0/src/bin/button_controlled_blink.rs index f57d5d200..f9f636bad 100644 --- a/examples/stm32f0/src/bin/button_controlled_blink.rs +++ b/examples/stm32f0/src/bin/button_controlled_blink.rs @@ -7,11 +7,9 @@ use core::sync::atomic::{AtomicU32, Ordering}; use defmt::info; use embassy_executor::Spawner; -use embassy_stm32::Peri; -use embassy_stm32::bind_interrupts; use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::{AnyPin, Level, Output, Pull, Speed}; -use embassy_stm32::interrupt; +use embassy_stm32::{Peri, bind_interrupts, interrupt}; use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; diff --git a/examples/stm32f0/src/bin/button_exti.rs b/examples/stm32f0/src/bin/button_exti.rs index 67ea19215..e91010514 100644 --- a/examples/stm32f0/src/bin/button_exti.rs +++ b/examples/stm32f0/src/bin/button_exti.rs @@ -3,10 +3,9 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::bind_interrupts; use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; -use embassy_stm32::interrupt; +use embassy_stm32::{bind_interrupts, interrupt}; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!( diff --git a/examples/stm32f3/src/bin/button_events.rs b/examples/stm32f3/src/bin/button_events.rs index 78c6592ee..e52622d55 100644 --- a/examples/stm32f3/src/bin/button_events.rs +++ b/examples/stm32f3/src/bin/button_events.rs @@ -11,10 +11,9 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::bind_interrupts; use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::{Level, Output, Pull, Speed}; -use embassy_stm32::interrupt; +use embassy_stm32::{bind_interrupts, interrupt}; use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; use embassy_sync::channel::Channel; use embassy_time::{Duration, Timer, with_timeout}; diff --git a/examples/stm32f3/src/bin/button_exti.rs b/examples/stm32f3/src/bin/button_exti.rs index d6d613447..4a75e031c 100644 --- a/examples/stm32f3/src/bin/button_exti.rs +++ b/examples/stm32f3/src/bin/button_exti.rs @@ -3,10 +3,9 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::bind_interrupts; use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; -use embassy_stm32::interrupt; +use embassy_stm32::{bind_interrupts, interrupt}; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!( diff --git a/examples/stm32f4/src/bin/button_exti.rs b/examples/stm32f4/src/bin/button_exti.rs index 77831224b..93560ed06 100644 --- a/examples/stm32f4/src/bin/button_exti.rs +++ b/examples/stm32f4/src/bin/button_exti.rs @@ -3,10 +3,9 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::bind_interrupts; use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; -use embassy_stm32::interrupt; +use embassy_stm32::{bind_interrupts, interrupt}; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!( diff --git a/examples/stm32f4/src/bin/eth_w5500.rs b/examples/stm32f4/src/bin/eth_w5500.rs index f7d2ce7de..f59f1d3b5 100644 --- a/examples/stm32f4/src/bin/eth_w5500.rs +++ b/examples/stm32f4/src/bin/eth_w5500.rs @@ -7,16 +7,14 @@ use embassy_net::tcp::TcpSocket; use embassy_net::{Ipv4Address, StackResources}; use embassy_net_wiznet::chip::W5500; use embassy_net_wiznet::{Device, Runner, State}; -use embassy_stm32::bind_interrupts; use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::{Level, Output, Pull, Speed}; -use embassy_stm32::interrupt; use embassy_stm32::mode::Async; use embassy_stm32::rng::Rng; use embassy_stm32::spi::Spi; use embassy_stm32::spi::mode::Master; use embassy_stm32::time::Hertz; -use embassy_stm32::{Config, bind_interrupts, peripherals, rng, spi}; +use embassy_stm32::{Config, bind_interrupts, interrupt, peripherals, rng, spi}; use embassy_time::{Delay, Timer}; use embedded_hal_bus::spi::ExclusiveDevice; use embedded_io_async::Write; diff --git a/examples/stm32f4/src/bin/usb_hid_keyboard.rs b/examples/stm32f4/src/bin/usb_hid_keyboard.rs index 60922c2e8..b5a7e86e4 100644 --- a/examples/stm32f4/src/bin/usb_hid_keyboard.rs +++ b/examples/stm32f4/src/bin/usb_hid_keyboard.rs @@ -6,13 +6,11 @@ use core::sync::atomic::{AtomicBool, AtomicU8, Ordering}; use defmt::*; use embassy_executor::Spawner; use embassy_futures::join::join; -use embassy_stm32::bind_interrupts; use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; -use embassy_stm32::interrupt; use embassy_stm32::time::Hertz; use embassy_stm32::usb::Driver; -use embassy_stm32::{Config, bind_interrupts, peripherals, usb}; +use embassy_stm32::{Config, bind_interrupts, interrupt, peripherals, usb}; use embassy_usb::class::hid::{ HidBootProtocol, HidProtocolMode, HidReaderWriter, HidSubclass, ReportId, RequestHandler, State, }; diff --git a/examples/stm32f7/src/bin/button_exti.rs b/examples/stm32f7/src/bin/button_exti.rs index 77831224b..93560ed06 100644 --- a/examples/stm32f7/src/bin/button_exti.rs +++ b/examples/stm32f7/src/bin/button_exti.rs @@ -3,10 +3,9 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::bind_interrupts; use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; -use embassy_stm32::interrupt; +use embassy_stm32::{bind_interrupts, interrupt}; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!( diff --git a/examples/stm32g0/src/bin/button_exti.rs b/examples/stm32g0/src/bin/button_exti.rs index dbc9e2f50..52fdc39c5 100644 --- a/examples/stm32g0/src/bin/button_exti.rs +++ b/examples/stm32g0/src/bin/button_exti.rs @@ -3,10 +3,9 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::bind_interrupts; use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; -use embassy_stm32::interrupt; +use embassy_stm32::{bind_interrupts, interrupt}; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!( diff --git a/examples/stm32g4/src/bin/button_exti.rs b/examples/stm32g4/src/bin/button_exti.rs index 77831224b..93560ed06 100644 --- a/examples/stm32g4/src/bin/button_exti.rs +++ b/examples/stm32g4/src/bin/button_exti.rs @@ -3,10 +3,9 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::bind_interrupts; use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; -use embassy_stm32::interrupt; +use embassy_stm32::{bind_interrupts, interrupt}; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!( diff --git a/examples/stm32h5/src/bin/button_exti.rs b/examples/stm32h5/src/bin/button_exti.rs index f49f0ff1c..70dee04be 100644 --- a/examples/stm32h5/src/bin/button_exti.rs +++ b/examples/stm32h5/src/bin/button_exti.rs @@ -3,10 +3,9 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::bind_interrupts; use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; -use embassy_stm32::interrupt; +use embassy_stm32::{bind_interrupts, interrupt}; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!( diff --git a/examples/stm32h7/src/bin/button_exti.rs b/examples/stm32h7/src/bin/button_exti.rs index 77831224b..93560ed06 100644 --- a/examples/stm32h7/src/bin/button_exti.rs +++ b/examples/stm32h7/src/bin/button_exti.rs @@ -3,10 +3,9 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::bind_interrupts; use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; -use embassy_stm32::interrupt; +use embassy_stm32::{bind_interrupts, interrupt}; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!( diff --git a/examples/stm32h7rs/src/bin/button_exti.rs b/examples/stm32h7rs/src/bin/button_exti.rs index d4cf36fcc..29159a3b3 100644 --- a/examples/stm32h7rs/src/bin/button_exti.rs +++ b/examples/stm32h7rs/src/bin/button_exti.rs @@ -3,10 +3,9 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::bind_interrupts; use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; -use embassy_stm32::interrupt; +use embassy_stm32::{bind_interrupts, interrupt}; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!( diff --git a/examples/stm32l0/src/bin/button_exti.rs b/examples/stm32l0/src/bin/button_exti.rs index afdeb14af..043261347 100644 --- a/examples/stm32l0/src/bin/button_exti.rs +++ b/examples/stm32l0/src/bin/button_exti.rs @@ -3,11 +3,9 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::Config; -use embassy_stm32::bind_interrupts; use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; -use embassy_stm32::interrupt; +use embassy_stm32::{Config, bind_interrupts, interrupt}; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!( diff --git a/examples/stm32l4/src/bin/button_exti.rs b/examples/stm32l4/src/bin/button_exti.rs index 4d03671c0..82479eb24 100644 --- a/examples/stm32l4/src/bin/button_exti.rs +++ b/examples/stm32l4/src/bin/button_exti.rs @@ -3,10 +3,9 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::bind_interrupts; use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; -use embassy_stm32::interrupt; +use embassy_stm32::{bind_interrupts, interrupt}; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!( diff --git a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs index 0dbf515cf..e079f22c7 100644 --- a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs +++ b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs @@ -24,6 +24,7 @@ use embassy_futures::yield_now; use embassy_net::tcp::TcpSocket; use embassy_net::{Ipv4Address, Ipv4Cidr, Stack, StackResources, StaticConfigV4}; use embassy_net_adin1110::{ADIN1110, Device, Runner}; +use embassy_stm32::exti::ExtiInput; use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; use embassy_stm32::i2c::{self, Config as I2C_Config, I2c}; use embassy_stm32::mode::Async; @@ -31,7 +32,7 @@ use embassy_stm32::rng::{self, Rng}; use embassy_stm32::spi::mode::Master; use embassy_stm32::spi::{Config as SPI_Config, Spi}; use embassy_stm32::time::Hertz; -use embassy_stm32::{bind_interrupts, exti, pac, peripherals}; +use embassy_stm32::{bind_interrupts, exti, interrupt, pac, peripherals}; use embassy_time::{Delay, Duration, Ticker, Timer}; use embedded_hal_async::i2c::I2c as I2cBus; use embedded_hal_bus::spi::ExclusiveDevice; @@ -45,6 +46,7 @@ bind_interrupts!(struct Irqs { I2C3_EV => i2c::EventInterruptHandler; I2C3_ER => i2c::ErrorInterruptHandler; RNG => rng::InterruptHandler; + EXTI15_10 => exti::InterruptHandler; }); // Basic settings @@ -125,7 +127,12 @@ async fn main(spawner: Spawner) { let spe_cfg1 = Input::new(dp.PC9, Pull::None); let _spe_ts_capt = Output::new(dp.PC6, Level::Low, Speed::Low); - let spe_int = exti::ExtiInput::new(dp.PB11, dp.EXTI11, Pull::None); + let spe_int = ExtiInput::new( + dp.PB11, + dp.EXTI11, + Pull::None, + Irqs::as_any::>(), + ); let spe_spi_cs_n = Output::new(dp.PB12, Level::High, Speed::High); let spe_spi_sclk = dp.PB13; diff --git a/examples/stm32l4/src/bin/spi_dma.rs b/examples/stm32l4/src/bin/spi_dma.rs index 946a759b1..970a0c608 100644 --- a/examples/stm32l4/src/bin/spi_dma.rs +++ b/examples/stm32l4/src/bin/spi_dma.rs @@ -34,8 +34,8 @@ async fn main(_spawner: Spawner) { info!("waiting for ready"); } - let write = [0x0A; 10]; - let mut read = [0; 10]; + let write = [0x0Au8; 10]; + let mut read = [0u8; 10]; cs.set_low(); spi.transfer(&mut read, &write).await.ok(); cs.set_high(); diff --git a/examples/stm32l5/src/bin/button_exti.rs b/examples/stm32l5/src/bin/button_exti.rs index 02e2013c9..41412b00f 100644 --- a/examples/stm32l5/src/bin/button_exti.rs +++ b/examples/stm32l5/src/bin/button_exti.rs @@ -3,10 +3,9 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::bind_interrupts; use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; -use embassy_stm32::interrupt; +use embassy_stm32::{bind_interrupts, interrupt}; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!( diff --git a/examples/stm32n6/src/bin/blinky.rs b/examples/stm32n6/src/bin/blinky.rs index c72e45628..764b8d6ef 100644 --- a/examples/stm32n6/src/bin/blinky.rs +++ b/examples/stm32n6/src/bin/blinky.rs @@ -3,10 +3,9 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::bind_interrupts; use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::{Level, Output, Pull, Speed}; -use embassy_stm32::interrupt; +use embassy_stm32::{bind_interrupts, interrupt}; use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; diff --git a/examples/stm32u0/src/bin/button_exti.rs b/examples/stm32u0/src/bin/button_exti.rs index dbc9e2f50..52fdc39c5 100644 --- a/examples/stm32u0/src/bin/button_exti.rs +++ b/examples/stm32u0/src/bin/button_exti.rs @@ -3,10 +3,9 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::bind_interrupts; use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; -use embassy_stm32::interrupt; +use embassy_stm32::{bind_interrupts, interrupt}; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!( diff --git a/examples/stm32wb/src/bin/button_exti.rs b/examples/stm32wb/src/bin/button_exti.rs index 2736b98f1..e2698450a 100644 --- a/examples/stm32wb/src/bin/button_exti.rs +++ b/examples/stm32wb/src/bin/button_exti.rs @@ -3,10 +3,9 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::bind_interrupts; use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; -use embassy_stm32::interrupt; +use embassy_stm32::{bind_interrupts, interrupt}; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!( diff --git a/examples/stm32wba/src/bin/button_exti.rs b/examples/stm32wba/src/bin/button_exti.rs index d4cf36fcc..29159a3b3 100644 --- a/examples/stm32wba/src/bin/button_exti.rs +++ b/examples/stm32wba/src/bin/button_exti.rs @@ -3,10 +3,9 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::bind_interrupts; use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; -use embassy_stm32::interrupt; +use embassy_stm32::{bind_interrupts, interrupt}; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!( diff --git a/examples/stm32wba6/src/bin/button_exti.rs b/examples/stm32wba6/src/bin/button_exti.rs index d4cf36fcc..29159a3b3 100644 --- a/examples/stm32wba6/src/bin/button_exti.rs +++ b/examples/stm32wba6/src/bin/button_exti.rs @@ -3,10 +3,9 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::bind_interrupts; use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; -use embassy_stm32::interrupt; +use embassy_stm32::{bind_interrupts, interrupt}; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!( diff --git a/examples/stm32wl/src/bin/button_exti.rs b/examples/stm32wl/src/bin/button_exti.rs index 183f93f2f..c22de0322 100644 --- a/examples/stm32wl/src/bin/button_exti.rs +++ b/examples/stm32wl/src/bin/button_exti.rs @@ -5,11 +5,9 @@ use core::mem::MaybeUninit; use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::SharedData; -use embassy_stm32::bind_interrupts; use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; -use embassy_stm32::interrupt; +use embassy_stm32::{SharedData, bind_interrupts, interrupt}; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!( diff --git a/examples/stm32wle5/src/bin/button_exti.rs b/examples/stm32wle5/src/bin/button_exti.rs index 196afa330..538801990 100644 --- a/examples/stm32wle5/src/bin/button_exti.rs +++ b/examples/stm32wle5/src/bin/button_exti.rs @@ -5,11 +5,9 @@ use defmt::*; #[cfg(feature = "defmt-rtt")] use defmt_rtt as _; use embassy_executor::Spawner; -use embassy_stm32::bind_interrupts; use embassy_stm32::exti::{self, ExtiInput}; use embassy_stm32::gpio::Pull; -use embassy_stm32::interrupt; -use embassy_stm32::low_power; +use embassy_stm32::{bind_interrupts, interrupt, low_power}; use panic_probe as _; use static_cell::StaticCell; -- cgit From 764c921a573e42f510a74d61f31302b8609bbd6c Mon Sep 17 00:00:00 2001 From: WillaWillNot Date: Sat, 22 Nov 2025 16:48:19 -0500 Subject: Reverted adding AnyBinding, removed AnyChannel, removed ability for ExtiInput to accept AnyPin and AnyChannel arguments, added ExtiPin trait for all pins which is lost on converstion to AnyPin and contains type-level ExtiChannel information --- .../layer-by-layer/blinky-async/src/main.rs | 7 +-- embassy-hal-internal/CHANGELOG.md | 2 - embassy-hal-internal/src/interrupt.rs | 60 +------------------ embassy-stm32/CHANGELOG.md | 6 +- embassy-stm32/src/exti.rs | 69 +++++++++------------- embassy-stm32/src/gpio.rs | 21 ++++--- embassy-stm32/src/lib.rs | 17 ++---- examples/boot/application/stm32f3/src/bin/a.rs | 7 +-- examples/boot/application/stm32f7/src/bin/a.rs | 7 +-- examples/boot/application/stm32h7/src/bin/a.rs | 7 +-- examples/boot/application/stm32l0/src/bin/a.rs | 7 +-- examples/boot/application/stm32l1/src/bin/a.rs | 7 +-- examples/boot/application/stm32l4/src/bin/a.rs | 7 +-- examples/boot/application/stm32wl/src/bin/a.rs | 7 +-- examples/stm32c0/src/bin/button_exti.rs | 7 +-- .../stm32f0/src/bin/button_controlled_blink.rs | 7 +-- examples/stm32f0/src/bin/button_exti.rs | 7 +-- examples/stm32f3/src/bin/button_events.rs | 7 +-- examples/stm32f3/src/bin/button_exti.rs | 7 +-- examples/stm32f4/src/bin/button_exti.rs | 7 +-- examples/stm32f4/src/bin/eth_w5500.rs | 7 +-- examples/stm32f4/src/bin/usb_hid_keyboard.rs | 7 +-- examples/stm32f7/src/bin/button_exti.rs | 7 +-- examples/stm32g0/src/bin/button_exti.rs | 7 +-- examples/stm32g4/src/bin/button_exti.rs | 7 +-- examples/stm32h5/src/bin/button_exti.rs | 7 +-- examples/stm32h7/src/bin/button_exti.rs | 7 +-- examples/stm32h7rs/src/bin/button_exti.rs | 7 +-- examples/stm32l0/src/bin/button_exti.rs | 7 +-- examples/stm32l4/src/bin/button_exti.rs | 7 +-- .../stm32l4/src/bin/spe_adin1110_http_server.rs | 7 +-- examples/stm32l5/src/bin/button_exti.rs | 7 +-- examples/stm32n6/src/bin/blinky.rs | 7 +-- examples/stm32u0/src/bin/button_exti.rs | 7 +-- examples/stm32wb/src/bin/button_exti.rs | 7 +-- examples/stm32wba/src/bin/button_exti.rs | 7 +-- examples/stm32wba6/src/bin/button_exti.rs | 7 +-- examples/stm32wl/src/bin/button_exti.rs | 7 +-- examples/stm32wle5/src/bin/button_exti.rs | 7 +-- 39 files changed, 80 insertions(+), 326 deletions(-) diff --git a/docs/examples/layer-by-layer/blinky-async/src/main.rs b/docs/examples/layer-by-layer/blinky-async/src/main.rs index 02cee2a4b..007f7da46 100644 --- a/docs/examples/layer-by-layer/blinky-async/src/main.rs +++ b/docs/examples/layer-by-layer/blinky-async/src/main.rs @@ -16,12 +16,7 @@ bind_interrupts!( async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); let mut led = Output::new(p.PB14, Level::Low, Speed::VeryHigh); - let mut button = ExtiInput::new( - p.PC13, - p.EXTI13, - Pull::Up, - Irqs::as_any::>(), - ); + let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up, Irqs); loop { button.wait_for_any_edge().await; diff --git a/embassy-hal-internal/CHANGELOG.md b/embassy-hal-internal/CHANGELOG.md index cb637a0ec..c78923a93 100644 --- a/embassy-hal-internal/CHANGELOG.md +++ b/embassy-hal-internal/CHANGELOG.md @@ -8,8 +8,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased - ReleaseDate -- feat: type erasure from Binding to AnyBinding, so that drivers accepting type erased peripheral arguments can still check bindings - ## 0.1.1 - 2025-08-15 - First release with changelog. diff --git a/embassy-hal-internal/src/interrupt.rs b/embassy-hal-internal/src/interrupt.rs index c97dee70b..ce6057e2d 100644 --- a/embassy-hal-internal/src/interrupt.rs +++ b/embassy-hal-internal/src/interrupt.rs @@ -124,10 +124,6 @@ macro_rules! interrupt_mod { /// /// This function must ONLY be called from the interrupt handler for `I`. unsafe fn on_interrupt(); - - /// Source ID of the Handler. No need to override the default outside of internal implementations, - /// where it will always be HandlerType::User. - const SOURCE_ID: HandlerType = HandlerType::User; } /// Compile-time assertion that an interrupt has been bound to a handler. @@ -141,61 +137,7 @@ macro_rules! interrupt_mod { /// to be called every time the `I` interrupt fires. /// /// This allows drivers to check bindings at compile-time. - pub unsafe trait Binding> { - /// Obtain a type-erased Binding. - /// - /// If using the `bind_interrupts!` macro, you will likely have to use a fully qualified path - /// to call this on the output struct: `>::into_any()` - fn into_any() -> AnyBinding { - AnyBinding { - irq: I::IRQ, - handler_source: H::SOURCE_ID, - } - } - } - - #[doc(hidden)] - #[derive(Copy, Clone)] - pub struct PrivateHandlerType { - pub(crate) _private: (), - } - impl PrivateHandlerType { - pub(crate) const fn new() -> Self { - Self { - _private: (), - } - } - } - - /// Driver which defined the Handler. Always User for user-defined handlers. - #[derive(Copy, Clone)] - pub enum HandlerType { - /// Defined in user code, or otherwise has not had its SOURCE_ID overridden. - User, - /// Defined somewhere within Embassy. - Embassy(PrivateHandlerType), - /// Defined by the [embassy-stm32::exti] module. - EmbassyStm32Exti(PrivateHandlerType), - } - - /// Type-erased Binding. - /// - /// Useful for proving a particular binding has been made to a driver which also accepts - /// type-erased peripheral arguments that hide the necessary Interrupt type at compile time. - pub struct AnyBinding { - irq: super::Interrupt, - handler_source: HandlerType, - } - impl AnyBinding { - /// Get the IRQ (vector number) of the interrupt. - pub const fn irq(&self) -> super::Interrupt { - self.irq - } - /// Get the source of the handler bound to the interrupt. - pub const fn source(&self) -> HandlerType { - self.handler_source - } - } + pub unsafe trait Binding> {} } } }; diff --git a/embassy-stm32/CHANGELOG.md b/embassy-stm32/CHANGELOG.md index 6e6a07037..b0c74f7d0 100644 --- a/embassy-stm32/CHANGELOG.md +++ b/embassy-stm32/CHANGELOG.md @@ -74,9 +74,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - fix: fixing channel numbers on vbat and vddcore for adc on adc - adc: adding disable to vbat - feat: stm32/flash: add async support for h7 family -- feat: exti brought in line with other drivers' interrupt rebinding system -- feat: bind_interrupts generates convenience method for type erasing to AnyBinding -- fix: exti2 now usable as a normal exti on chips with touch sensing +- feat: exti brought in line with other drivers' interrupt rebinding system ([#4922](https://github.com/embassy-rs/embassy/pull/4922)) +- removal: ExtiInput no longer accepts AnyPin/AnyChannel; AnyChannel removed entirely +- change: build script now generates `unimpl_tsc` cfg option when a chip has a TSC peripheral but no driver ## 0.4.0 - 2025-08-26 diff --git a/embassy-stm32/src/exti.rs b/embassy-stm32/src/exti.rs index 93e15a90d..57217034e 100644 --- a/embassy-stm32/src/exti.rs +++ b/embassy-stm32/src/exti.rs @@ -5,13 +5,13 @@ use core::marker::PhantomData; use core::pin::Pin; use core::task::{Context, Poll}; -use embassy_hal_internal::{PeripheralType, impl_peripheral}; +use embassy_hal_internal::PeripheralType; use embassy_sync::waitqueue::AtomicWaker; use futures_util::FutureExt; -use crate::gpio::{AnyPin, Input, Level, Pin as GpioPin, PinNumber, Pull}; +use crate::gpio::{AnyPin, ExtiPin, Input, Level, Pin as GpioPin, PinNumber, Pull}; use crate::interrupt::Interrupt as InterruptEnum; -use crate::interrupt::typelevel::{AnyBinding, Handler, HandlerType, Interrupt as InterruptType, PrivateHandlerType}; +use crate::interrupt::typelevel::{Binding, Handler, Interrupt as InterruptType}; use crate::pac::EXTI; use crate::pac::exti::regs::Lines; use crate::{Peri, pac}; @@ -110,24 +110,20 @@ impl<'d> ExtiInput<'d> { /// Create an EXTI input. /// /// The Binding must bind the Channel's IRQ to [InterruptHandler]. - /// - /// The interrupt [Binding](crate::interrupt::typelevel::Binding) must be type-erased to [AnyBinding] - /// via [into_any()](crate::interrupt::typelevel::Binding::into_any()), in order to support type-erased - /// [AnyChannel] arguments. [bind_interrupts](crate::bind_interrupts) also generates a convenience - /// method as_any() for type erasure that doesn't need a trait object. - pub fn new(pin: Peri<'d, T>, ch: Peri<'d, T::ExtiChannel>, pull: Pull, binding: AnyBinding) -> Self { - // Needed if using AnyPin+AnyChannel. - assert_eq!(pin.pin(), ch.number()); - assert_eq!(ch.irq(), binding.irq()); - assert!(matches!(binding.source(), HandlerType::EmbassyStm32Exti(_))); - + pub fn new( + pin: Peri<'d, T>, + _ch: Peri<'d, T::ExtiChannel>, + pull: Pull, + _irq: impl Binding< + <::ExtiChannel as Channel>::IRQ, + InterruptHandler<<::ExtiChannel as Channel>::IRQ>, + >, + ) -> Self { Self { pin: Input::new(pin, pull), } } - //pub fn new, I: Instance, C: Channel>( - /// Get whether the pin is high. pub fn is_high(&self) -> bool { self.pin.is_high() @@ -367,7 +363,6 @@ pub struct InterruptHandler { } impl Handler for InterruptHandler { - const SOURCE_ID: HandlerType = HandlerType::EmbassyStm32Exti(PrivateHandlerType::new()); unsafe fn on_interrupt() { on_irq() } @@ -383,30 +378,19 @@ pub trait Channel: PeripheralType + SealedChannel + Sized { /// [Enum-level Interrupt](InterruptEnum), which may be the same for multiple channels. fn irq(&self) -> InterruptEnum; /// [Type-level Interrupt](InterruptType), which may be the same for multiple channels. - /// Unavailable on type-erased [AnyChannel], where it is defined as the unit type. - /// has no trait bound, so mostly only useful for doc reference (e.g. while writing - /// [bind_interrupts](crate::bind_interrupts) invocation.) Use irq() for programmatic access. - type INTERRUPT; + type IRQ: InterruptType; } -/// Type-erased EXTI channel. +//Doc isn't hidden in order to surface the explanation to users, even though it's completely inoperable, not just deprecated. +//Entire type along with doc can probably be removed after deprecation has appeared in a release once. +/// Deprecated type-erased EXTI channel. /// -/// This represents ownership over any EXTI channel, known at runtime. +/// Support for AnyChannel was removed in order to support manually bindable EXTI interrupts via bind_interrupts; [ExtiInput::new()] +/// must know the required IRQ at compile time, and therefore cannot support type-erased channels. +#[deprecated = "type-erased EXTI channels are no longer supported, in order to support manually bindable EXTI interrupts (more info: https://github.com/embassy-rs/embassy/pull/4922)"] pub struct AnyChannel { + #[allow(unused)] number: PinNumber, - irq: InterruptEnum, -} - -impl_peripheral!(AnyChannel); -impl SealedChannel for AnyChannel {} -impl Channel for AnyChannel { - fn number(&self) -> PinNumber { - self.number - } - fn irq(&self) -> InterruptEnum { - self.irq - } - type INTERRUPT = bool; } macro_rules! impl_exti { @@ -425,16 +409,17 @@ macro_rules! impl_exti { fn irq(&self) -> InterruptEnum { <$irq>::IRQ } - type INTERRUPT = $irq; + type IRQ = $irq; } + + //Still here to surface deprecation messages to the user - remove when removing AnyChannel + #[allow(deprecated)] impl From for AnyChannel { fn from(_val: crate::peripherals::$type) -> Self { - Self { - number: $number, - irq: <$irq>::IRQ, - } + Self { + number: $number, } - } + }} }; } diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs index 17c5a9962..e7d4e9ad3 100644 --- a/embassy-stm32/src/gpio.rs +++ b/embassy-stm32/src/gpio.rs @@ -812,15 +812,19 @@ pub type PinNumber = u8; #[cfg(stm32n6)] pub type PinNumber = u16; -/// GPIO pin trait. +/// Pin that can be used to configure an [ExtiInput](crate::exti::ExtiInput). This trait is lost when converting to [AnyPin]. +#[cfg(feature = "exti")] #[allow(private_bounds)] -pub trait Pin: PeripheralType + Into + SealedPin + Sized + 'static { +pub trait ExtiPin: PeripheralType + SealedPin { /// EXTI channel assigned to this pin. /// /// For example, PC4 uses EXTI4. - #[cfg(feature = "exti")] type ExtiChannel: crate::exti::Channel; +} +/// GPIO pin trait. +#[allow(private_bounds)] +pub trait Pin: PeripheralType + Into + SealedPin + Sized + 'static { /// Number of the pin within the port (0..31) #[inline] fn pin(&self) -> PinNumber { @@ -834,7 +838,7 @@ pub trait Pin: PeripheralType + Into + SealedPin + Sized + 'static { } } -/// Type-erased GPIO pin +/// Type-erased GPIO pin. pub struct AnyPin { pin_port: PinNumber, } @@ -862,10 +866,7 @@ impl AnyPin { } impl_peripheral!(AnyPin); -impl Pin for AnyPin { - #[cfg(feature = "exti")] - type ExtiChannel = crate::exti::AnyChannel; -} +impl Pin for AnyPin {} impl SealedPin for AnyPin { #[inline] fn pin_port(&self) -> PinNumber { @@ -878,7 +879,9 @@ impl SealedPin for AnyPin { foreach_pin!( ($pin_name:ident, $port_name:ident, $port_num:expr, $pin_num:expr, $exti_ch:ident) => { impl Pin for peripherals::$pin_name { - #[cfg(feature = "exti")] + } + #[cfg(feature = "exti")] + impl ExtiPin for peripherals::$pin_name { type ExtiChannel = peripherals::$exti_ch; } impl SealedPin for peripherals::$pin_name { diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index e5ffbd753..08231dc60 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs @@ -178,6 +178,10 @@ pub use crate::_generated::interrupt; /// } /// ); /// ``` +/// +/// Some chips collate multiple interrupt signals into a single interrupt vector. In the above example, I2C2_3 is a +/// single vector which is activated by events and errors on both peripherals I2C2 and I2C3. Check your chip's list +/// of interrupt vectors if you get an unexpected compile error trying to bind the standard name. // developer note: this macro can't be in `embassy-hal-internal` due to the use of `$crate`. #[macro_export] macro_rules! bind_interrupts { @@ -195,19 +199,6 @@ macro_rules! bind_interrupts { $(#[$outer])* $vis struct $name; - impl $name { - #[doc = r"Convenience method to call Binding::into_any(). Unlike the trait method, can be called with a turbofish."] - pub fn as_any< - I: $crate::interrupt::typelevel::Interrupt, - H: $crate::interrupt::typelevel::Handler - >() -> $crate::interrupt::typelevel::AnyBinding - where - Self: $crate::interrupt::typelevel::Binding - { - >::into_any() - } - } - $( #[allow(non_snake_case)] #[unsafe(no_mangle)] diff --git a/examples/boot/application/stm32f3/src/bin/a.rs b/examples/boot/application/stm32f3/src/bin/a.rs index 8e0a6685e..da3cbf1e6 100644 --- a/examples/boot/application/stm32f3/src/bin/a.rs +++ b/examples/boot/application/stm32f3/src/bin/a.rs @@ -29,12 +29,7 @@ async fn main(_spawner: Spawner) { let flash = Flash::new_blocking(p.FLASH); let flash = Mutex::new(BlockingAsync::new(flash)); - let mut button = ExtiInput::new( - p.PC13, - p.EXTI13, - Pull::Up, - Irqs::as_any::>(), - ); + let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up, Irqs); let mut led = Output::new(p.PA5, Level::Low, Speed::Low); led.set_high(); diff --git a/examples/boot/application/stm32f7/src/bin/a.rs b/examples/boot/application/stm32f7/src/bin/a.rs index db808934f..62f1da269 100644 --- a/examples/boot/application/stm32f7/src/bin/a.rs +++ b/examples/boot/application/stm32f7/src/bin/a.rs @@ -31,12 +31,7 @@ async fn main(_spawner: Spawner) { let flash = Flash::new_blocking(p.FLASH); let flash = Mutex::new(RefCell::new(flash)); - let mut button = ExtiInput::new( - p.PC13, - p.EXTI13, - Pull::Down, - Irqs::as_any::>(), - ); + let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down, Irqs); let mut led = Output::new(p.PB7, Level::Low, Speed::Low); led.set_high(); diff --git a/examples/boot/application/stm32h7/src/bin/a.rs b/examples/boot/application/stm32h7/src/bin/a.rs index ed2d5b89e..226971e02 100644 --- a/examples/boot/application/stm32h7/src/bin/a.rs +++ b/examples/boot/application/stm32h7/src/bin/a.rs @@ -31,12 +31,7 @@ async fn main(_spawner: Spawner) { let flash = Flash::new_blocking(p.FLASH); let flash = Mutex::new(RefCell::new(flash)); - let mut button = ExtiInput::new( - p.PC13, - p.EXTI13, - Pull::Down, - Irqs::as_any::>(), - ); + let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down, Irqs); let mut led = Output::new(p.PB14, Level::Low, Speed::Low); led.set_high(); diff --git a/examples/boot/application/stm32l0/src/bin/a.rs b/examples/boot/application/stm32l0/src/bin/a.rs index 3f9e6d24e..0aa723eaa 100644 --- a/examples/boot/application/stm32l0/src/bin/a.rs +++ b/examples/boot/application/stm32l0/src/bin/a.rs @@ -30,12 +30,7 @@ async fn main(_spawner: Spawner) { let flash = Flash::new_blocking(p.FLASH); let flash = Mutex::new(BlockingAsync::new(flash)); - let mut button = ExtiInput::new( - p.PB2, - p.EXTI2, - Pull::Up, - Irqs::as_any::>(), - ); + let mut button = ExtiInput::new(p.PB2, p.EXTI2, Pull::Up, Irqs); let mut led = Output::new(p.PB5, Level::Low, Speed::Low); diff --git a/examples/boot/application/stm32l1/src/bin/a.rs b/examples/boot/application/stm32l1/src/bin/a.rs index b5432eb91..7ad7046fb 100644 --- a/examples/boot/application/stm32l1/src/bin/a.rs +++ b/examples/boot/application/stm32l1/src/bin/a.rs @@ -30,12 +30,7 @@ async fn main(_spawner: Spawner) { let flash = Flash::new_blocking(p.FLASH); let flash = Mutex::new(BlockingAsync::new(flash)); - let mut button = ExtiInput::new( - p.PB2, - p.EXTI2, - Pull::Up, - Irqs::as_any::>(), - ); + let mut button = ExtiInput::new(p.PB2, p.EXTI2, Pull::Up, Irqs); let mut led = Output::new(p.PB5, Level::Low, Speed::Low); diff --git a/examples/boot/application/stm32l4/src/bin/a.rs b/examples/boot/application/stm32l4/src/bin/a.rs index 349e57f94..4edd338c5 100644 --- a/examples/boot/application/stm32l4/src/bin/a.rs +++ b/examples/boot/application/stm32l4/src/bin/a.rs @@ -29,12 +29,7 @@ async fn main(_spawner: Spawner) { let flash = Flash::new_blocking(p.FLASH); let flash = Mutex::new(BlockingAsync::new(flash)); - let mut button = ExtiInput::new( - p.PC13, - p.EXTI13, - Pull::Up, - Irqs::as_any::>(), - ); + let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up, Irqs); let mut led = Output::new(p.PB14, Level::Low, Speed::Low); led.set_high(); diff --git a/examples/boot/application/stm32wl/src/bin/a.rs b/examples/boot/application/stm32wl/src/bin/a.rs index 285d57e41..58063eb50 100644 --- a/examples/boot/application/stm32wl/src/bin/a.rs +++ b/examples/boot/application/stm32wl/src/bin/a.rs @@ -34,12 +34,7 @@ async fn main(_spawner: Spawner) { let flash = Flash::new_blocking(p.FLASH); let flash = Mutex::new(BlockingAsync::new(flash)); - let mut button = ExtiInput::new( - p.PA0, - p.EXTI0, - Pull::Up, - Irqs::as_any::>(), - ); + let mut button = ExtiInput::new(p.PA0, p.EXTI0, Pull::Up, Irqs); let mut led = Output::new(p.PB9, Level::Low, Speed::Low); led.set_high(); diff --git a/examples/stm32c0/src/bin/button_exti.rs b/examples/stm32c0/src/bin/button_exti.rs index 52fdc39c5..9d54479da 100644 --- a/examples/stm32c0/src/bin/button_exti.rs +++ b/examples/stm32c0/src/bin/button_exti.rs @@ -18,12 +18,7 @@ async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let mut button = ExtiInput::new( - p.PC13, - p.EXTI13, - Pull::Up, - Irqs::as_any::>(), - ); + let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up, Irqs); info!("Press the USER button..."); diff --git a/examples/stm32f0/src/bin/button_controlled_blink.rs b/examples/stm32f0/src/bin/button_controlled_blink.rs index f9f636bad..9c7bf8a95 100644 --- a/examples/stm32f0/src/bin/button_controlled_blink.rs +++ b/examples/stm32f0/src/bin/button_controlled_blink.rs @@ -42,12 +42,7 @@ async fn main(spawner: Spawner) { // Configure the button pin and obtain handler. // On the Nucleo F091RC there is a button connected to pin PC13. - let mut button = ExtiInput::new( - p.PC13, - p.EXTI13, - Pull::None, - Irqs::as_any::>(), - ); + let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::None, Irqs); // Create and initialize a delay variable to manage delay loop let mut del_var = 2000; diff --git a/examples/stm32f0/src/bin/button_exti.rs b/examples/stm32f0/src/bin/button_exti.rs index e91010514..d1312e1be 100644 --- a/examples/stm32f0/src/bin/button_exti.rs +++ b/examples/stm32f0/src/bin/button_exti.rs @@ -19,12 +19,7 @@ async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); // Configure the button pin and obtain handler. // On the Nucleo F091RC there is a button connected to pin PC13. - let mut button = ExtiInput::new( - p.PC13, - p.EXTI13, - Pull::Down, - Irqs::as_any::>(), - ); + let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down, Irqs); info!("Press the USER button..."); loop { diff --git a/examples/stm32f3/src/bin/button_events.rs b/examples/stm32f3/src/bin/button_events.rs index e52622d55..643f499ed 100644 --- a/examples/stm32f3/src/bin/button_events.rs +++ b/examples/stm32f3/src/bin/button_events.rs @@ -105,12 +105,7 @@ static CHANNEL: Channel = Channel::new(); #[embassy_executor::main] async fn main(spawner: Spawner) { let p = embassy_stm32::init(Default::default()); - let button = ExtiInput::new( - p.PA0, - p.EXTI0, - Pull::Down, - Irqs::as_any::>(), - ); + let button = ExtiInput::new(p.PA0, p.EXTI0, Pull::Down, Irqs); info!("Press the USER button..."); let leds = [ Output::new(p.PE9, Level::Low, Speed::Low), diff --git a/examples/stm32f3/src/bin/button_exti.rs b/examples/stm32f3/src/bin/button_exti.rs index 4a75e031c..1df4735ca 100644 --- a/examples/stm32f3/src/bin/button_exti.rs +++ b/examples/stm32f3/src/bin/button_exti.rs @@ -18,12 +18,7 @@ async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let mut button = ExtiInput::new( - p.PA0, - p.EXTI0, - Pull::Down, - Irqs::as_any::>(), - ); + let mut button = ExtiInput::new(p.PA0, p.EXTI0, Pull::Down, Irqs); info!("Press the USER button..."); diff --git a/examples/stm32f4/src/bin/button_exti.rs b/examples/stm32f4/src/bin/button_exti.rs index 93560ed06..e7e1549a8 100644 --- a/examples/stm32f4/src/bin/button_exti.rs +++ b/examples/stm32f4/src/bin/button_exti.rs @@ -18,12 +18,7 @@ async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let mut button = ExtiInput::new( - p.PC13, - p.EXTI13, - Pull::Down, - Irqs::as_any::>(), - ); + let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down, Irqs); info!("Press the USER button..."); diff --git a/examples/stm32f4/src/bin/eth_w5500.rs b/examples/stm32f4/src/bin/eth_w5500.rs index f59f1d3b5..e274d2a66 100644 --- a/examples/stm32f4/src/bin/eth_w5500.rs +++ b/examples/stm32f4/src/bin/eth_w5500.rs @@ -76,12 +76,7 @@ async fn main(spawner: Spawner) -> ! { let cs = Output::new(p.PA4, Level::High, Speed::VeryHigh); let spi = unwrap!(ExclusiveDevice::new(spi, cs, Delay)); - let w5500_int = ExtiInput::new( - p.PB0, - p.EXTI0, - Pull::Up, - Irqs::as_any::>(), - ); + let w5500_int = ExtiInput::new(p.PB0, p.EXTI0, Pull::Up, Irqs); let w5500_reset = Output::new(p.PB1, Level::High, Speed::VeryHigh); let mac_addr = [0x02, 234, 3, 4, 82, 231]; diff --git a/examples/stm32f4/src/bin/usb_hid_keyboard.rs b/examples/stm32f4/src/bin/usb_hid_keyboard.rs index b5a7e86e4..2d834dcf7 100644 --- a/examples/stm32f4/src/bin/usb_hid_keyboard.rs +++ b/examples/stm32f4/src/bin/usb_hid_keyboard.rs @@ -124,12 +124,7 @@ async fn main(_spawner: Spawner) { let (reader, mut writer) = hid.split(); - let mut button = ExtiInput::new( - p.PC13, - p.EXTI13, - Pull::Down, - Irqs::as_any::>(), - ); + let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down, Irqs); // Do stuff with the class! let in_fut = async { diff --git a/examples/stm32f7/src/bin/button_exti.rs b/examples/stm32f7/src/bin/button_exti.rs index 93560ed06..e7e1549a8 100644 --- a/examples/stm32f7/src/bin/button_exti.rs +++ b/examples/stm32f7/src/bin/button_exti.rs @@ -18,12 +18,7 @@ async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let mut button = ExtiInput::new( - p.PC13, - p.EXTI13, - Pull::Down, - Irqs::as_any::>(), - ); + let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down, Irqs); info!("Press the USER button..."); diff --git a/examples/stm32g0/src/bin/button_exti.rs b/examples/stm32g0/src/bin/button_exti.rs index 52fdc39c5..9d54479da 100644 --- a/examples/stm32g0/src/bin/button_exti.rs +++ b/examples/stm32g0/src/bin/button_exti.rs @@ -18,12 +18,7 @@ async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let mut button = ExtiInput::new( - p.PC13, - p.EXTI13, - Pull::Up, - Irqs::as_any::>(), - ); + let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up, Irqs); info!("Press the USER button..."); diff --git a/examples/stm32g4/src/bin/button_exti.rs b/examples/stm32g4/src/bin/button_exti.rs index 93560ed06..e7e1549a8 100644 --- a/examples/stm32g4/src/bin/button_exti.rs +++ b/examples/stm32g4/src/bin/button_exti.rs @@ -18,12 +18,7 @@ async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let mut button = ExtiInput::new( - p.PC13, - p.EXTI13, - Pull::Down, - Irqs::as_any::>(), - ); + let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down, Irqs); info!("Press the USER button..."); diff --git a/examples/stm32h5/src/bin/button_exti.rs b/examples/stm32h5/src/bin/button_exti.rs index 70dee04be..220f89228 100644 --- a/examples/stm32h5/src/bin/button_exti.rs +++ b/examples/stm32h5/src/bin/button_exti.rs @@ -18,12 +18,7 @@ async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let mut button = ExtiInput::new( - p.PC13, - p.EXTI13, - Pull::Down, - Irqs::as_any::>(), - ); + let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down, Irqs); info!("Press the USER button..."); diff --git a/examples/stm32h7/src/bin/button_exti.rs b/examples/stm32h7/src/bin/button_exti.rs index 93560ed06..e7e1549a8 100644 --- a/examples/stm32h7/src/bin/button_exti.rs +++ b/examples/stm32h7/src/bin/button_exti.rs @@ -18,12 +18,7 @@ async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let mut button = ExtiInput::new( - p.PC13, - p.EXTI13, - Pull::Down, - Irqs::as_any::>(), - ); + let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down, Irqs); info!("Press the USER button..."); diff --git a/examples/stm32h7rs/src/bin/button_exti.rs b/examples/stm32h7rs/src/bin/button_exti.rs index 29159a3b3..d63290d42 100644 --- a/examples/stm32h7rs/src/bin/button_exti.rs +++ b/examples/stm32h7rs/src/bin/button_exti.rs @@ -18,12 +18,7 @@ async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let mut button = ExtiInput::new( - p.PC13, - p.EXTI13, - Pull::Up, - Irqs::as_any::>(), - ); + let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up, Irqs); info!("Press the USER button..."); diff --git a/examples/stm32l0/src/bin/button_exti.rs b/examples/stm32l0/src/bin/button_exti.rs index 043261347..a118c7a5a 100644 --- a/examples/stm32l0/src/bin/button_exti.rs +++ b/examples/stm32l0/src/bin/button_exti.rs @@ -18,12 +18,7 @@ async fn main(_spawner: Spawner) { let config = Config::default(); let p = embassy_stm32::init(config); - let mut button = ExtiInput::new( - p.PB2, - p.EXTI2, - Pull::Up, - Irqs::as_any::>(), - ); + let mut button = ExtiInput::new(p.PB2, p.EXTI2, Pull::Up, Irqs); info!("Press the USER button..."); diff --git a/examples/stm32l4/src/bin/button_exti.rs b/examples/stm32l4/src/bin/button_exti.rs index 82479eb24..c84b11dab 100644 --- a/examples/stm32l4/src/bin/button_exti.rs +++ b/examples/stm32l4/src/bin/button_exti.rs @@ -18,12 +18,7 @@ async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let mut button = ExtiInput::new( - p.PC13, - p.EXTI13, - Pull::Up, - Irqs::as_any::>(), - ); + let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up, Irqs); info!("Press the USER button..."); diff --git a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs index e079f22c7..8f2510cdc 100644 --- a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs +++ b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs @@ -127,12 +127,7 @@ async fn main(spawner: Spawner) { let spe_cfg1 = Input::new(dp.PC9, Pull::None); let _spe_ts_capt = Output::new(dp.PC6, Level::Low, Speed::Low); - let spe_int = ExtiInput::new( - dp.PB11, - dp.EXTI11, - Pull::None, - Irqs::as_any::>(), - ); + let spe_int = ExtiInput::new(dp.PB11, dp.EXTI11, Pull::None, Irqs); let spe_spi_cs_n = Output::new(dp.PB12, Level::High, Speed::High); let spe_spi_sclk = dp.PB13; diff --git a/examples/stm32l5/src/bin/button_exti.rs b/examples/stm32l5/src/bin/button_exti.rs index 41412b00f..225a7b3fd 100644 --- a/examples/stm32l5/src/bin/button_exti.rs +++ b/examples/stm32l5/src/bin/button_exti.rs @@ -18,12 +18,7 @@ async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let mut button = ExtiInput::new( - p.PC13, - p.EXTI13, - Pull::Down, - Irqs::as_any::>(), - ); + let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down, Irqs); info!("Press the USER button..."); diff --git a/examples/stm32n6/src/bin/blinky.rs b/examples/stm32n6/src/bin/blinky.rs index 764b8d6ef..a8baf16af 100644 --- a/examples/stm32n6/src/bin/blinky.rs +++ b/examples/stm32n6/src/bin/blinky.rs @@ -28,12 +28,7 @@ async fn main(spawner: Spawner) { info!("Hello World!"); let mut led = Output::new(p.PG10, Level::High, Speed::Low); - let button = ExtiInput::new( - p.PC13, - p.EXTI13, - Pull::Up, - Irqs::as_any::>(), - ); + let button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up, Irqs); spawner.spawn(button_task(button).unwrap()); diff --git a/examples/stm32u0/src/bin/button_exti.rs b/examples/stm32u0/src/bin/button_exti.rs index 52fdc39c5..9d54479da 100644 --- a/examples/stm32u0/src/bin/button_exti.rs +++ b/examples/stm32u0/src/bin/button_exti.rs @@ -18,12 +18,7 @@ async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let mut button = ExtiInput::new( - p.PC13, - p.EXTI13, - Pull::Up, - Irqs::as_any::>(), - ); + let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up, Irqs); info!("Press the USER button..."); diff --git a/examples/stm32wb/src/bin/button_exti.rs b/examples/stm32wb/src/bin/button_exti.rs index e2698450a..3c58eb556 100644 --- a/examples/stm32wb/src/bin/button_exti.rs +++ b/examples/stm32wb/src/bin/button_exti.rs @@ -18,12 +18,7 @@ async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let mut button = ExtiInput::new( - p.PC4, - p.EXTI4, - Pull::Up, - Irqs::as_any::>(), - ); + let mut button = ExtiInput::new(p.PC4, p.EXTI4, Pull::Up, Irqs); info!("Press the USER button..."); diff --git a/examples/stm32wba/src/bin/button_exti.rs b/examples/stm32wba/src/bin/button_exti.rs index 29159a3b3..d63290d42 100644 --- a/examples/stm32wba/src/bin/button_exti.rs +++ b/examples/stm32wba/src/bin/button_exti.rs @@ -18,12 +18,7 @@ async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let mut button = ExtiInput::new( - p.PC13, - p.EXTI13, - Pull::Up, - Irqs::as_any::>(), - ); + let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up, Irqs); info!("Press the USER button..."); diff --git a/examples/stm32wba6/src/bin/button_exti.rs b/examples/stm32wba6/src/bin/button_exti.rs index 29159a3b3..d63290d42 100644 --- a/examples/stm32wba6/src/bin/button_exti.rs +++ b/examples/stm32wba6/src/bin/button_exti.rs @@ -18,12 +18,7 @@ async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let mut button = ExtiInput::new( - p.PC13, - p.EXTI13, - Pull::Up, - Irqs::as_any::>(), - ); + let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up, Irqs); info!("Press the USER button..."); diff --git a/examples/stm32wl/src/bin/button_exti.rs b/examples/stm32wl/src/bin/button_exti.rs index c22de0322..2bb39c709 100644 --- a/examples/stm32wl/src/bin/button_exti.rs +++ b/examples/stm32wl/src/bin/button_exti.rs @@ -23,12 +23,7 @@ async fn main(_spawner: Spawner) { let p = embassy_stm32::init_primary(Default::default(), &SHARED_DATA); info!("Hello World!"); - let mut button = ExtiInput::new( - p.PA0, - p.EXTI0, - Pull::Up, - Irqs::as_any::>(), - ); + let mut button = ExtiInput::new(p.PA0, p.EXTI0, Pull::Up, Irqs); info!("Press the USER button..."); diff --git a/examples/stm32wle5/src/bin/button_exti.rs b/examples/stm32wle5/src/bin/button_exti.rs index 538801990..f248b6147 100644 --- a/examples/stm32wle5/src/bin/button_exti.rs +++ b/examples/stm32wle5/src/bin/button_exti.rs @@ -69,12 +69,7 @@ async fn async_main(_spawner: Spawner) { info!("Hello World!"); - let mut button = ExtiInput::new( - p.PA0, - p.EXTI0, - Pull::Up, - Irqs::as_any::>(), - ); + let mut button = ExtiInput::new(p.PA0, p.EXTI0, Pull::Up, Irqs); info!("Press the USER button..."); -- cgit From b877b0dc6b5fe4541a45e6b43ed9d82131608aee Mon Sep 17 00:00:00 2001 From: WillaWillNot Date: Sat, 22 Nov 2025 18:18:04 -0500 Subject: Build script now injects EXTI2 => EXTI2_TSC peripheral/interrupt mapping if it's not present in the PAC, removed macro magic in exti that was working around this omission --- embassy-stm32/CHANGELOG.md | 2 +- embassy-stm32/build.rs | 21 +++++++++++++++++---- embassy-stm32/src/exti.rs | 18 ++++-------------- 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/embassy-stm32/CHANGELOG.md b/embassy-stm32/CHANGELOG.md index 0f8113863..a66b2d437 100644 --- a/embassy-stm32/CHANGELOG.md +++ b/embassy-stm32/CHANGELOG.md @@ -77,7 +77,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - feat: stm32/flash: add async support for h7 family - feat: exti brought in line with other drivers' interrupt rebinding system ([#4922](https://github.com/embassy-rs/embassy/pull/4922)) - removal: ExtiInput no longer accepts AnyPin/AnyChannel; AnyChannel removed entirely -- change: build script now generates `unimpl_tsc` cfg option when a chip has a TSC peripheral but no driver +- fix: build script ensures EXTI2_TSC is listed as the IRQ of EXTI2 even if the PAC doesn't - feat: stm32/lcd: added implementation ## 0.4.0 - 2025-08-26 diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 3d0b13fe2..109571e8f 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -56,16 +56,12 @@ fn main() { eprintln!("chip: {chip_name}"); - cfgs.declare("unimpl_tsc"); for p in METADATA.peripherals { if let Some(r) = &p.registers { cfgs.enable(r.kind); foreach_version_cfg(&mut cfgs, r.kind, r.version, |cfgs, cfg_name| { cfgs.enable(cfg_name); }); - } else if p.name == "TSC" { - //Even if the registers are missing, EXTI needs to know if TSC is present in silicon to know whether the EXTI2 interrupt is shadowed by EXTI2_TSC - cfgs.enable("unimpl_tsc") } } @@ -357,8 +353,13 @@ fn main() { // ======== // Generate interrupt declarations + let mut exti2_tsc_shared_int_present: Option = None; let mut irqs = Vec::new(); for irq in METADATA.interrupts { + // The PAC doesn't ensure this is listed as the IRQ of EXTI2, so we must do so + if irq.name == "EXTI2_TSC" { + exti2_tsc_shared_int_present = Some(irq.clone()) + } irqs.push(format_ident!("{}", irq.name)); } @@ -1816,7 +1817,19 @@ fn main() { for p in METADATA.peripherals { let mut pt = TokenStream::new(); + let mut exti2_tsc_injected = false; + if let Some(ref irq) = exti2_tsc_shared_int_present + && p.name == "EXTI" + { + exti2_tsc_injected = true; + let iname = format_ident!("{}", irq.name); + let sname = format_ident!("{}", "EXTI2"); + pt.extend(quote!(pub type #sname = crate::interrupt::typelevel::#iname;)); + } for irq in p.interrupts { + if exti2_tsc_injected && irq.signal == "EXTI2" { + continue; + } let iname = format_ident!("{}", irq.interrupt); let sname = format_ident!("{}", irq.signal); pt.extend(quote!(pub type #sname = crate::interrupt::typelevel::#iname;)); diff --git a/embassy-stm32/src/exti.rs b/embassy-stm32/src/exti.rs index 57217034e..7b7896d46 100644 --- a/embassy-stm32/src/exti.rs +++ b/embassy-stm32/src/exti.rs @@ -395,40 +395,30 @@ pub struct AnyChannel { macro_rules! impl_exti { ($type:ident, $number:expr) => { - impl_exti!(@inner $type, $number, crate::_generated::peripheral_interrupts::EXTI::$type); - }; - ($type:ident, $number:expr, @tsc) => { - impl_exti!(@inner $type, $number, crate::_generated::peripheral_interrupts::TSC::GLOBAL); - }; - (@inner $type:ident, $number:expr, $irq:path) => { impl SealedChannel for crate::peripherals::$type {} impl Channel for crate::peripherals::$type { fn number(&self) -> PinNumber { $number } fn irq(&self) -> InterruptEnum { - <$irq>::IRQ + crate::_generated::peripheral_interrupts::EXTI::$type::IRQ } - type IRQ = $irq; + type IRQ = crate::_generated::peripheral_interrupts::EXTI::$type; } //Still here to surface deprecation messages to the user - remove when removing AnyChannel #[allow(deprecated)] impl From for AnyChannel { fn from(_val: crate::peripherals::$type) -> Self { - Self { - number: $number, + Self { number: $number } } - }} + } }; } impl_exti!(EXTI0, 0); impl_exti!(EXTI1, 1); -#[cfg(not(any(tsc, unimpl_tsc)))] impl_exti!(EXTI2, 2); -#[cfg(any(tsc, unimpl_tsc))] -impl_exti!(EXTI2, 2, @tsc); impl_exti!(EXTI3, 3); impl_exti!(EXTI4, 4); impl_exti!(EXTI5, 5); -- cgit