aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWillaWillNot <[email protected]>2025-11-20 16:24:15 -0500
committerWillaWillNot <[email protected]>2025-11-21 16:36:15 -0500
commit623623a25f213f76de932eaf4458c3120823d205 (patch)
treea1039bcdb29488180f4fe669f16ac0b33370404e
parentde4d7f56473df58d9b3fa8ec4917ab86550005ae (diff)
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
-rw-r--r--docs/examples/layer-by-layer/blinky-async/src/main.rs16
-rw-r--r--docs/pages/faq.adoc6
-rw-r--r--docs/pages/layer_by_layer.adoc2
-rw-r--r--embassy-hal-internal/CHANGELOG.md2
-rw-r--r--embassy-hal-internal/src/interrupt.rs5
-rw-r--r--embassy-stm32/CHANGELOG.md3
-rw-r--r--embassy-stm32/build.rs4
-rw-r--r--embassy-stm32/src/exti.rs53
-rw-r--r--embassy-stm32/src/lib.rs15
-rw-r--r--examples/boot/application/stm32f3/src/bin/a.rs16
-rw-r--r--examples/boot/application/stm32f7/src/bin/a.rs16
-rw-r--r--examples/boot/application/stm32h7/src/bin/a.rs16
-rw-r--r--examples/boot/application/stm32l0/src/bin/a.rs16
-rw-r--r--examples/boot/application/stm32l1/src/bin/a.rs16
-rw-r--r--examples/boot/application/stm32l4/src/bin/a.rs16
-rw-r--r--examples/boot/application/stm32wl/src/bin/a.rs16
-rw-r--r--examples/stm32c0/src/bin/button_exti.rs16
-rw-r--r--examples/stm32f0/src/bin/button_controlled_blink.rs16
-rw-r--r--examples/stm32f0/src/bin/button_exti.rs16
-rw-r--r--examples/stm32f3/src/bin/button_events.rs16
-rw-r--r--examples/stm32f3/src/bin/button_exti.rs16
-rw-r--r--examples/stm32f4/src/bin/button_exti.rs16
-rw-r--r--examples/stm32f4/src/bin/eth_w5500.rs12
-rw-r--r--examples/stm32f4/src/bin/usb_hid_keyboard.rs12
-rw-r--r--examples/stm32f7/src/bin/button_exti.rs16
-rw-r--r--examples/stm32g0/src/bin/button_exti.rs16
-rw-r--r--examples/stm32g4/src/bin/button_exti.rs16
-rw-r--r--examples/stm32h5/src/bin/button_exti.rs16
-rw-r--r--examples/stm32h7/src/bin/button_exti.rs16
-rw-r--r--examples/stm32h7rs/src/bin/button_exti.rs16
-rw-r--r--examples/stm32l0/src/bin/button_exti.rs16
-rw-r--r--examples/stm32l4/src/bin/button_exti.rs16
-rw-r--r--examples/stm32l5/src/bin/button_exti.rs16
-rw-r--r--examples/stm32n6/src/bin/blinky.rs16
-rw-r--r--examples/stm32u0/src/bin/button_exti.rs16
-rw-r--r--examples/stm32wb/src/bin/button_exti.rs16
-rw-r--r--examples/stm32wba/src/bin/button_exti.rs16
-rw-r--r--examples/stm32wba6/src/bin/button_exti.rs16
-rw-r--r--examples/stm32wl/src/bin/button_exti.rs16
-rw-r--r--examples/stm32wle5/src/bin/button_exti.rs16
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 @@
2#![no_main] 2#![no_main]
3 3
4use embassy_executor::Spawner; 4use embassy_executor::Spawner;
5use embassy_stm32::exti::ExtiInput; 5use embassy_stm32::bind_interrupts;
6use embassy_stm32::exti::{self, ExtiInput};
6use embassy_stm32::gpio::{Level, Output, Pull, Speed}; 7use embassy_stm32::gpio::{Level, Output, Pull, Speed};
8use embassy_stm32::interrupt;
7use {defmt_rtt as _, panic_probe as _}; 9use {defmt_rtt as _, panic_probe as _};
8 10
11bind_interrupts!(
12 pub struct Irqs{
13 EXTI15_10 => exti::InterruptHandler<interrupt::typelevel::EXTI15_10 >;
14});
15
9#[embassy_executor::main] 16#[embassy_executor::main]
10async fn main(_spawner: Spawner) { 17async fn main(_spawner: Spawner) {
11 let p = embassy_stm32::init(Default::default()); 18 let p = embassy_stm32::init(Default::default());
12 let mut led = Output::new(p.PB14, Level::Low, Speed::VeryHigh); 19 let mut led = Output::new(p.PB14, Level::Low, Speed::VeryHigh);
13 let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up); 20 let mut button = ExtiInput::new(
21 p.PC13,
22 p.EXTI13,
23 Pull::Up,
24 Irqs::as_any::<interrupt::typelevel::EXTI15_10, exti::InterruptHandler<interrupt::typelevel::EXTI15_10>>(),
25 );
14 26
15 loop { 27 loop {
16 button.wait_for_any_edge().await; 28 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
171 171
172== Can I use manual ISRs alongside Embassy? 172== Can I use manual ISRs alongside Embassy?
173 173
174Yes! 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]. 174Yes! 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.
175
176You 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].
177
178Or 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.
175 179
176== How can I measure resource usage (CPU, RAM, etc.)? 180== How can I measure resource usage (CPU, RAM, etc.)?
177 181
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
76* The peripheral initialization is done by the main macro, and is handed to the main task. 76* The peripheral initialization is done by the main macro, and is handed to the main task.
77* Before checking the button state, the application is awaiting a transition in the pin state (low -> high or high -> low). 77* Before checking the button state, the application is awaiting a transition in the pin state (low -> high or high -> low).
78 78
79When `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. 79When `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.
80 80
81The 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. 81The 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.
82 82
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
8<!-- next-header --> 8<!-- next-header -->
9## Unreleased - ReleaseDate 9## Unreleased - ReleaseDate
10 10
11- feat: type erasure from Binding to AnyBinding, so that drivers accepting type erased peripheral arguments can still check bindings
12
11## 0.1.1 - 2025-08-15 13## 0.1.1 - 2025-08-15
12 14
13- First release with changelog. 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 {
170 /// Driver which defined the Handler. Always User for user-defined handlers. 170 /// Driver which defined the Handler. Always User for user-defined handlers.
171 #[derive(Copy, Clone)] 171 #[derive(Copy, Clone)]
172 pub enum HandlerType { 172 pub enum HandlerType {
173 /// Defined in user code, or otherwise has not had its SOURCE_ID overridden.
173 User, 174 User,
175 /// Defined somewhere within Embassy.
174 Embassy(PrivateHandlerType), 176 Embassy(PrivateHandlerType),
177 /// Defined by the [embassy-stm32::exti] module.
175 EmbassyStm32Exti(PrivateHandlerType), 178 EmbassyStm32Exti(PrivateHandlerType),
176 } 179 }
177 180
@@ -184,9 +187,11 @@ macro_rules! interrupt_mod {
184 handler_source: HandlerType, 187 handler_source: HandlerType,
185 } 188 }
186 impl AnyBinding { 189 impl AnyBinding {
190 /// Get the IRQ (vector number) of the interrupt.
187 pub const fn irq(&self) -> super::Interrupt { 191 pub const fn irq(&self) -> super::Interrupt {
188 self.irq 192 self.irq
189 } 193 }
194 /// Get the source of the handler bound to the interrupt.
190 pub const fn source(&self) -> HandlerType { 195 pub const fn source(&self) -> HandlerType {
191 self.handler_source 196 self.handler_source
192 } 197 }
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
71- fix: fixing channel numbers on vbat and vddcore for adc on adc 71- fix: fixing channel numbers on vbat and vddcore for adc on adc
72- adc: adding disable to vbat 72- adc: adding disable to vbat
73- feat: stm32/flash: add async support for h7 family 73- feat: stm32/flash: add async support for h7 family
74- feat: exti brought in line with other drivers' interrupt rebinding system
75- feat: bind_interrupts generates convenience method for type erasing to AnyBinding
76- fix: exti2 now usable as a normal exti on chips with touch sensing
74 77
75## 0.4.0 - 2025-08-26 78## 0.4.0 - 2025-08-26
76 79
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() {
56 56
57 eprintln!("chip: {chip_name}"); 57 eprintln!("chip: {chip_name}");
58 58
59 cfgs.declare("unimpl_tsc");
59 for p in METADATA.peripherals { 60 for p in METADATA.peripherals {
60 if let Some(r) = &p.registers { 61 if let Some(r) = &p.registers {
61 cfgs.enable(r.kind); 62 cfgs.enable(r.kind);
62 foreach_version_cfg(&mut cfgs, r.kind, r.version, |cfgs, cfg_name| { 63 foreach_version_cfg(&mut cfgs, r.kind, r.version, |cfgs, cfg_name| {
63 cfgs.enable(cfg_name); 64 cfgs.enable(cfg_name);
64 }); 65 });
66 } else if p.name == "TSC" {
67 //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
68 cfgs.enable("unimpl_tsc")
65 } 69 }
66 } 70 }
67 71
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;
11 11
12use crate::gpio::{AnyPin, Input, Level, Pin as GpioPin, PinNumber, Pull}; 12use crate::gpio::{AnyPin, Input, Level, Pin as GpioPin, PinNumber, Pull};
13use crate::interrupt::Interrupt as InterruptEnum; 13use crate::interrupt::Interrupt as InterruptEnum;
14use crate::interrupt::typelevel::{AnyBinding, HandlerType, Interrupt as InterruptType, PrivateHandlerType}; 14use crate::interrupt::typelevel::{AnyBinding, Handler, HandlerType, Interrupt as InterruptType, PrivateHandlerType};
15use crate::pac::EXTI; 15use crate::pac::EXTI;
16use crate::pac::exti::regs::Lines; 16use crate::pac::exti::regs::Lines;
17use crate::{Peri, pac, peripherals}; 17use crate::{Peri, pac};
18 18
19const EXTI_COUNT: usize = 16; 19const EXTI_COUNT: usize = 16;
20static EXTI_WAKERS: [AtomicWaker; EXTI_COUNT] = [const { AtomicWaker::new() }; EXTI_COUNT]; 20static EXTI_WAKERS: [AtomicWaker; EXTI_COUNT] = [const { AtomicWaker::new() }; EXTI_COUNT];
@@ -109,10 +109,12 @@ impl<'d> Unpin for ExtiInput<'d> {}
109impl<'d> ExtiInput<'d> { 109impl<'d> ExtiInput<'d> {
110 /// Create an EXTI input. 110 /// Create an EXTI input.
111 /// 111 ///
112 /// The interrupt [Binding] must be type-erased to [AnyBinding] via [Binding::into_any()] in order
113 /// to support type-erased [AnyChannel] arguments.
114 ///
115 /// The Binding must bind the Channel's IRQ to [InterruptHandler]. 112 /// The Binding must bind the Channel's IRQ to [InterruptHandler].
113 ///
114 /// The interrupt [Binding](crate::interrupt::typelevel::Binding) must be type-erased to [AnyBinding]
115 /// via [into_any()](crate::interrupt::typelevel::Binding::into_any()), in order to support type-erased
116 /// [AnyChannel] arguments. [bind_interrupts](crate::bind_interrupts) also generates a convenience
117 /// method as_any() for type erasure that doesn't need a trait object.
116 pub fn new<T: GpioPin>(pin: Peri<'d, T>, ch: Peri<'d, T::ExtiChannel>, pull: Pull, binding: AnyBinding) -> Self { 118 pub fn new<T: GpioPin>(pin: Peri<'d, T>, ch: Peri<'d, T::ExtiChannel>, pull: Pull, binding: AnyBinding) -> Self {
117 // Needed if using AnyPin+AnyChannel. 119 // Needed if using AnyPin+AnyChannel.
118 assert_eq!(pin.pin(), ch.number()); 120 assert_eq!(pin.pin(), ch.number());
@@ -354,18 +356,17 @@ macro_rules! foreach_exti_irq {
354 356
355///EXTI interrupt handler. All EXTI interrupt vectors should be bound to this handler. 357///EXTI interrupt handler. All EXTI interrupt vectors should be bound to this handler.
356/// 358///
357/// It is generic over the [Interrupt](crate::interrupt::typelevel::Interrupt) rather 359/// It is generic over the [Interrupt](InterruptType) rather
358/// than the [Instance](crate::exti::Instance) because it should not be bound multiple 360/// than the [Channel] because it should not be bound multiple
359/// times to the same vector on chips which multiplex multiple EXTI interrupts into one vector. 361/// times to the same vector on chips which multiplex multiple EXTI interrupts into one vector.
360// 362//
361// It technically doesn't need to be generic at all, except to satisfy the generic argument 363// It technically doesn't need to be generic at all, except to satisfy the generic argument
362// of [Handler](crate::interrupt::typelevel::Handler). All EXTI interrupts eventually 364// of [Handler]. All EXTI interrupts eventually land in the same on_irq() function.
363// land in the same on_irq() function.
364pub struct InterruptHandler<T: crate::interrupt::typelevel::Interrupt> { 365pub struct InterruptHandler<T: crate::interrupt::typelevel::Interrupt> {
365 _phantom: PhantomData<T>, 366 _phantom: PhantomData<T>,
366} 367}
367 368
368impl<T: crate::interrupt::typelevel::Interrupt> crate::interrupt::typelevel::Handler<T> for InterruptHandler<T> { 369impl<T: InterruptType> Handler<T> for InterruptHandler<T> {
369 const SOURCE_ID: HandlerType = HandlerType::EmbassyStm32Exti(PrivateHandlerType::new()); 370 const SOURCE_ID: HandlerType = HandlerType::EmbassyStm32Exti(PrivateHandlerType::new());
370 unsafe fn on_interrupt() { 371 unsafe fn on_interrupt() {
371 on_irq() 372 on_irq()
@@ -377,10 +378,15 @@ trait SealedChannel {}
377/// EXTI channel trait. 378/// EXTI channel trait.
378#[allow(private_bounds)] 379#[allow(private_bounds)]
379pub trait Channel: PeripheralType + SealedChannel + Sized { 380pub trait Channel: PeripheralType + SealedChannel + Sized {
380 /// Get the EXTI channel number. 381 /// EXTI channel number.
381 fn number(&self) -> PinNumber; 382 fn number(&self) -> PinNumber;
382 /// Get the EXTI IRQ, which may be the same for multiple channels 383 /// [Enum-level Interrupt](InterruptEnum), which may be the same for multiple channels.
383 fn irq(&self) -> InterruptEnum; 384 fn irq(&self) -> InterruptEnum;
385 /// [Type-level Interrupt](InterruptType), which may be the same for multiple channels.
386 /// Unavailable on type-erased [AnyChannel], where it is defined as the unit type.
387 /// has no trait bound, so mostly only useful for doc reference (e.g. while writing
388 /// [bind_interrupts](crate::bind_interrupts) invocation.) Use irq() for programmatic access.
389 type INTERRUPT;
384} 390}
385 391
386/// Type-erased EXTI channel. 392/// Type-erased EXTI channel.
@@ -400,24 +406,32 @@ impl Channel for AnyChannel {
400 fn irq(&self) -> InterruptEnum { 406 fn irq(&self) -> InterruptEnum {
401 self.irq 407 self.irq
402 } 408 }
409 type INTERRUPT = bool;
403} 410}
404 411
405macro_rules! impl_exti { 412macro_rules! impl_exti {
406 ($type:ident, $number:expr) => { 413 ($type:ident, $number:expr) => {
407 impl SealedChannel for peripherals::$type {} 414 impl_exti!(@inner $type, $number, crate::_generated::peripheral_interrupts::EXTI::$type);
408 impl Channel for peripherals::$type { 415 };
416 ($type:ident, $number:expr, @tsc) => {
417 impl_exti!(@inner $type, $number, crate::_generated::peripheral_interrupts::TSC::GLOBAL);
418 };
419 (@inner $type:ident, $number:expr, $irq:path) => {
420 impl SealedChannel for crate::peripherals::$type {}
421 impl Channel for crate::peripherals::$type {
409 fn number(&self) -> PinNumber { 422 fn number(&self) -> PinNumber {
410 $number 423 $number
411 } 424 }
412 fn irq(&self) -> InterruptEnum { 425 fn irq(&self) -> InterruptEnum {
413 crate::_generated::peripheral_interrupts::EXTI::$type::IRQ 426 <$irq>::IRQ
414 } 427 }
428 type INTERRUPT = $irq;
415 } 429 }
416 impl From<peripherals::$type> for AnyChannel { 430 impl From<crate::peripherals::$type> for AnyChannel {
417 fn from(_val: peripherals::$type) -> Self { 431 fn from(_val: crate::peripherals::$type) -> Self {
418 Self { 432 Self {
419 number: $number, 433 number: $number,
420 irq: crate::_generated::peripheral_interrupts::EXTI::$type::IRQ, 434 irq: <$irq>::IRQ,
421 } 435 }
422 } 436 }
423 } 437 }
@@ -426,7 +440,10 @@ macro_rules! impl_exti {
426 440
427impl_exti!(EXTI0, 0); 441impl_exti!(EXTI0, 0);
428impl_exti!(EXTI1, 1); 442impl_exti!(EXTI1, 1);
443#[cfg(not(any(tsc, unimpl_tsc)))]
429impl_exti!(EXTI2, 2); 444impl_exti!(EXTI2, 2);
445#[cfg(any(tsc, unimpl_tsc))]
446impl_exti!(EXTI2, 2, @tsc);
430impl_exti!(EXTI3, 3); 447impl_exti!(EXTI3, 3);
431impl_exti!(EXTI4, 4); 448impl_exti!(EXTI4, 4);
432impl_exti!(EXTI5, 5); 449impl_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;
151/// Macro to bind interrupts to handlers. 151/// Macro to bind interrupts to handlers.
152/// 152///
153/// This defines the right interrupt handlers, and creates a unit struct (like `struct Irqs;`) 153/// This defines the right interrupt handlers, and creates a unit struct (like `struct Irqs;`)
154/// and implements the right [`Binding`]s for it. You can pass this struct to drivers to 154/// and implements the right [`Binding`](crate::interrupt::typelevel::Binding)s for it. You can pass this struct to drivers to
155/// prove at compile-time that the right interrupts have been bound. 155/// prove at compile-time that the right interrupts have been bound.
156/// 156///
157/// Example of how to bind one interrupt: 157/// Example of how to bind one interrupt:
@@ -195,6 +195,19 @@ macro_rules! bind_interrupts {
195 $(#[$outer])* 195 $(#[$outer])*
196 $vis struct $name; 196 $vis struct $name;
197 197
198 impl $name {
199 #[doc = r"Convenience method to call Binding::into_any(). Unlike the trait method, can be called with a turbofish."]
200 pub fn as_any<
201 I: $crate::interrupt::typelevel::Interrupt,
202 H: $crate::interrupt::typelevel::Handler<I>
203 >() -> $crate::interrupt::typelevel::AnyBinding
204 where
205 Self: $crate::interrupt::typelevel::Binding<I, H>
206 {
207 <Self as $crate::interrupt::typelevel::Binding<I, H>>::into_any()
208 }
209 }
210
198 $( 211 $(
199 #[allow(non_snake_case)] 212 #[allow(non_snake_case)]
200 #[unsafe(no_mangle)] 213 #[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::*;
6use embassy_boot_stm32::{AlignedBuffer, FirmwareUpdater, FirmwareUpdaterConfig}; 6use embassy_boot_stm32::{AlignedBuffer, FirmwareUpdater, FirmwareUpdaterConfig};
7use embassy_embedded_hal::adapter::BlockingAsync; 7use embassy_embedded_hal::adapter::BlockingAsync;
8use embassy_executor::Spawner; 8use embassy_executor::Spawner;
9use embassy_stm32::exti::ExtiInput; 9use embassy_stm32::bind_interrupts;
10use embassy_stm32::exti::{self, ExtiInput};
10use embassy_stm32::flash::{Flash, WRITE_SIZE}; 11use embassy_stm32::flash::{Flash, WRITE_SIZE};
11use embassy_stm32::gpio::{Level, Output, Pull, Speed}; 12use embassy_stm32::gpio::{Level, Output, Pull, Speed};
13use embassy_stm32::interrupt;
12use embassy_sync::mutex::Mutex; 14use embassy_sync::mutex::Mutex;
13use panic_reset as _; 15use panic_reset as _;
14 16
17bind_interrupts!(
18 pub struct Irqs{
19 EXTI15_10 => exti::InterruptHandler<interrupt::typelevel::EXTI15_10>;
20});
21
15#[cfg(feature = "skip-include")] 22#[cfg(feature = "skip-include")]
16static APP_B: &[u8] = &[0, 1, 2, 3]; 23static APP_B: &[u8] = &[0, 1, 2, 3];
17#[cfg(not(feature = "skip-include"))] 24#[cfg(not(feature = "skip-include"))]
@@ -23,7 +30,12 @@ async fn main(_spawner: Spawner) {
23 let flash = Flash::new_blocking(p.FLASH); 30 let flash = Flash::new_blocking(p.FLASH);
24 let flash = Mutex::new(BlockingAsync::new(flash)); 31 let flash = Mutex::new(BlockingAsync::new(flash));
25 32
26 let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up); 33 let mut button = ExtiInput::new(
34 p.PC13,
35 p.EXTI13,
36 Pull::Up,
37 Irqs::as_any::<interrupt::typelevel::EXTI15_10, exti::InterruptHandler<interrupt::typelevel::EXTI15_10>>(),
38 );
27 39
28 let mut led = Output::new(p.PA5, Level::Low, Speed::Low); 40 let mut led = Output::new(p.PA5, Level::Low, Speed::Low);
29 led.set_high(); 41 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;
7use defmt_rtt::*; 7use defmt_rtt::*;
8use embassy_boot_stm32::{AlignedBuffer, BlockingFirmwareUpdater, FirmwareUpdaterConfig}; 8use embassy_boot_stm32::{AlignedBuffer, BlockingFirmwareUpdater, FirmwareUpdaterConfig};
9use embassy_executor::Spawner; 9use embassy_executor::Spawner;
10use embassy_stm32::exti::ExtiInput; 10use embassy_stm32::bind_interrupts;
11use embassy_stm32::exti::{self, ExtiInput};
11use embassy_stm32::flash::{Flash, WRITE_SIZE}; 12use embassy_stm32::flash::{Flash, WRITE_SIZE};
12use embassy_stm32::gpio::{Level, Output, Pull, Speed}; 13use embassy_stm32::gpio::{Level, Output, Pull, Speed};
14use embassy_stm32::interrupt;
13use embassy_sync::blocking_mutex::Mutex; 15use embassy_sync::blocking_mutex::Mutex;
14use embedded_storage::nor_flash::NorFlash; 16use embedded_storage::nor_flash::NorFlash;
15use panic_reset as _; 17use panic_reset as _;
@@ -19,13 +21,23 @@ static APP_B: &[u8] = &[0, 1, 2, 3];
19#[cfg(not(feature = "skip-include"))] 21#[cfg(not(feature = "skip-include"))]
20static APP_B: &[u8] = include_bytes!("../../b.bin"); 22static APP_B: &[u8] = include_bytes!("../../b.bin");
21 23
24bind_interrupts!(
25 pub struct Irqs{
26 EXTI15_10 => exti::InterruptHandler<interrupt::typelevel::EXTI15_10>;
27});
28
22#[embassy_executor::main] 29#[embassy_executor::main]
23async fn main(_spawner: Spawner) { 30async fn main(_spawner: Spawner) {
24 let p = embassy_stm32::init(Default::default()); 31 let p = embassy_stm32::init(Default::default());
25 let flash = Flash::new_blocking(p.FLASH); 32 let flash = Flash::new_blocking(p.FLASH);
26 let flash = Mutex::new(RefCell::new(flash)); 33 let flash = Mutex::new(RefCell::new(flash));
27 34
28 let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down); 35 let mut button = ExtiInput::new(
36 p.PC13,
37 p.EXTI13,
38 Pull::Down,
39 Irqs::as_any::<interrupt::typelevel::EXTI15_10, exti::InterruptHandler<interrupt::typelevel::EXTI15_10>>(),
40 );
29 41
30 let mut led = Output::new(p.PB7, Level::Low, Speed::Low); 42 let mut led = Output::new(p.PB7, Level::Low, Speed::Low);
31 led.set_high(); 43 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;
7use defmt_rtt::*; 7use defmt_rtt::*;
8use embassy_boot_stm32::{AlignedBuffer, BlockingFirmwareUpdater, FirmwareUpdaterConfig}; 8use embassy_boot_stm32::{AlignedBuffer, BlockingFirmwareUpdater, FirmwareUpdaterConfig};
9use embassy_executor::Spawner; 9use embassy_executor::Spawner;
10use embassy_stm32::exti::ExtiInput; 10use embassy_stm32::bind_interrupts;
11use embassy_stm32::exti::{self, ExtiInput};
11use embassy_stm32::flash::{Flash, WRITE_SIZE}; 12use embassy_stm32::flash::{Flash, WRITE_SIZE};
12use embassy_stm32::gpio::{Level, Output, Pull, Speed}; 13use embassy_stm32::gpio::{Level, Output, Pull, Speed};
14use embassy_stm32::interrupt;
13use embassy_sync::blocking_mutex::Mutex; 15use embassy_sync::blocking_mutex::Mutex;
14use embedded_storage::nor_flash::NorFlash; 16use embedded_storage::nor_flash::NorFlash;
15use panic_reset as _; 17use panic_reset as _;
16 18
19bind_interrupts!(
20 pub struct Irqs{
21 EXTI15_10 => exti::InterruptHandler<interrupt::typelevel::EXTI15_10>;
22});
23
17#[cfg(feature = "skip-include")] 24#[cfg(feature = "skip-include")]
18static APP_B: &[u8] = &[0, 1, 2, 3]; 25static APP_B: &[u8] = &[0, 1, 2, 3];
19#[cfg(not(feature = "skip-include"))] 26#[cfg(not(feature = "skip-include"))]
@@ -25,7 +32,12 @@ async fn main(_spawner: Spawner) {
25 let flash = Flash::new_blocking(p.FLASH); 32 let flash = Flash::new_blocking(p.FLASH);
26 let flash = Mutex::new(RefCell::new(flash)); 33 let flash = Mutex::new(RefCell::new(flash));
27 34
28 let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down); 35 let mut button = ExtiInput::new(
36 p.PC13,
37 p.EXTI13,
38 Pull::Down,
39 Irqs::as_any::<interrupt::typelevel::EXTI15_10, exti::InterruptHandler<interrupt::typelevel::EXTI15_10>>(),
40 );
29 41
30 let mut led = Output::new(p.PB14, Level::Low, Speed::Low); 42 let mut led = Output::new(p.PB14, Level::Low, Speed::Low);
31 led.set_high(); 43 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::*;
6use embassy_boot_stm32::{AlignedBuffer, FirmwareUpdater, FirmwareUpdaterConfig}; 6use embassy_boot_stm32::{AlignedBuffer, FirmwareUpdater, FirmwareUpdaterConfig};
7use embassy_embedded_hal::adapter::BlockingAsync; 7use embassy_embedded_hal::adapter::BlockingAsync;
8use embassy_executor::Spawner; 8use embassy_executor::Spawner;
9use embassy_stm32::exti::ExtiInput; 9use embassy_stm32::bind_interrupts;
10use embassy_stm32::exti::{self, ExtiInput};
10use embassy_stm32::flash::{Flash, WRITE_SIZE}; 11use embassy_stm32::flash::{Flash, WRITE_SIZE};
11use embassy_stm32::gpio::{Level, Output, Pull, Speed}; 12use embassy_stm32::gpio::{Level, Output, Pull, Speed};
13use embassy_stm32::interrupt;
12use embassy_sync::mutex::Mutex; 14use embassy_sync::mutex::Mutex;
13use embassy_time::Timer; 15use embassy_time::Timer;
14use panic_reset as _; 16use panic_reset as _;
15 17
18bind_interrupts!(
19 pub struct Irqs{
20 EXTI2_3 => exti::InterruptHandler<interrupt::typelevel::EXTI2_3>;
21});
22
16#[cfg(feature = "skip-include")] 23#[cfg(feature = "skip-include")]
17static APP_B: &[u8] = &[0, 1, 2, 3]; 24static APP_B: &[u8] = &[0, 1, 2, 3];
18#[cfg(not(feature = "skip-include"))] 25#[cfg(not(feature = "skip-include"))]
@@ -24,7 +31,12 @@ async fn main(_spawner: Spawner) {
24 let flash = Flash::new_blocking(p.FLASH); 31 let flash = Flash::new_blocking(p.FLASH);
25 let flash = Mutex::new(BlockingAsync::new(flash)); 32 let flash = Mutex::new(BlockingAsync::new(flash));
26 33
27 let mut button = ExtiInput::new(p.PB2, p.EXTI2, Pull::Up); 34 let mut button = ExtiInput::new(
35 p.PB2,
36 p.EXTI2,
37 Pull::Up,
38 Irqs::as_any::<interrupt::typelevel::EXTI2_3, exti::InterruptHandler<interrupt::typelevel::EXTI2_3>>(),
39 );
28 40
29 let mut led = Output::new(p.PB5, Level::Low, Speed::Low); 41 let mut led = Output::new(p.PB5, Level::Low, Speed::Low);
30 42
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::*;
6use embassy_boot_stm32::{AlignedBuffer, FirmwareUpdater, FirmwareUpdaterConfig}; 6use embassy_boot_stm32::{AlignedBuffer, FirmwareUpdater, FirmwareUpdaterConfig};
7use embassy_embedded_hal::adapter::BlockingAsync; 7use embassy_embedded_hal::adapter::BlockingAsync;
8use embassy_executor::Spawner; 8use embassy_executor::Spawner;
9use embassy_stm32::exti::ExtiInput; 9use embassy_stm32::bind_interrupts;
10use embassy_stm32::exti::{self, ExtiInput};
10use embassy_stm32::flash::{Flash, WRITE_SIZE}; 11use embassy_stm32::flash::{Flash, WRITE_SIZE};
11use embassy_stm32::gpio::{Level, Output, Pull, Speed}; 12use embassy_stm32::gpio::{Level, Output, Pull, Speed};
13use embassy_stm32::interrupt;
12use embassy_sync::mutex::Mutex; 14use embassy_sync::mutex::Mutex;
13use embassy_time::Timer; 15use embassy_time::Timer;
14use panic_reset as _; 16use panic_reset as _;
@@ -18,6 +20,11 @@ static APP_B: &[u8] = &[0, 1, 2, 3];
18#[cfg(not(feature = "skip-include"))] 20#[cfg(not(feature = "skip-include"))]
19static APP_B: &[u8] = include_bytes!("../../b.bin"); 21static APP_B: &[u8] = include_bytes!("../../b.bin");
20 22
23bind_interrupts!(
24 pub struct Irqs{
25 EXTI2 => exti::InterruptHandler<interrupt::typelevel::EXTI2>;
26});
27
21#[embassy_executor::main] 28#[embassy_executor::main]
22async fn main(_spawner: Spawner) { 29async fn main(_spawner: Spawner) {
23 let p = embassy_stm32::init(Default::default()); 30 let p = embassy_stm32::init(Default::default());
@@ -26,7 +33,12 @@ async fn main(_spawner: Spawner) {
26 33
27 let mut button = ExtiInput::new(p.PB2, p.EXTI2, Pull::Up); 34 let mut button = ExtiInput::new(p.PB2, p.EXTI2, Pull::Up);
28 35
29 let mut led = Output::new(p.PB5, Level::Low, Speed::Low); 36 let mut led = Output::new(
37 p.PB5,
38 Level::Low,
39 Speed::Low,
40 Irqs::as_any::<interrupt::typelevel::EXTI2, exti::InterruptHandler<interrupt::typelevel::EXTI2>>(),
41 );
30 42
31 led.set_high(); 43 led.set_high();
32 44
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::*;
6use embassy_boot_stm32::{AlignedBuffer, FirmwareUpdater, FirmwareUpdaterConfig}; 6use embassy_boot_stm32::{AlignedBuffer, FirmwareUpdater, FirmwareUpdaterConfig};
7use embassy_embedded_hal::adapter::BlockingAsync; 7use embassy_embedded_hal::adapter::BlockingAsync;
8use embassy_executor::Spawner; 8use embassy_executor::Spawner;
9use embassy_stm32::exti::ExtiInput; 9use embassy_stm32::bind_interrupts;
10use embassy_stm32::exti::{self, ExtiInput};
10use embassy_stm32::flash::{Flash, WRITE_SIZE}; 11use embassy_stm32::flash::{Flash, WRITE_SIZE};
11use embassy_stm32::gpio::{Level, Output, Pull, Speed}; 12use embassy_stm32::gpio::{Level, Output, Pull, Speed};
13use embassy_stm32::interrupt;
12use embassy_sync::mutex::Mutex; 14use embassy_sync::mutex::Mutex;
13use panic_reset as _; 15use panic_reset as _;
14 16
@@ -17,13 +19,23 @@ static APP_B: &[u8] = &[0, 1, 2, 3];
17#[cfg(not(feature = "skip-include"))] 19#[cfg(not(feature = "skip-include"))]
18static APP_B: &[u8] = include_bytes!("../../b.bin"); 20static APP_B: &[u8] = include_bytes!("../../b.bin");
19 21
22bind_interrupts!(
23 pub struct Irqs{
24 EXTI15_10 => exti::InterruptHandler<interrupt::typelevel::EXTI15_10>;
25});
26
20#[embassy_executor::main] 27#[embassy_executor::main]
21async fn main(_spawner: Spawner) { 28async fn main(_spawner: Spawner) {
22 let p = embassy_stm32::init(Default::default()); 29 let p = embassy_stm32::init(Default::default());
23 let flash = Flash::new_blocking(p.FLASH); 30 let flash = Flash::new_blocking(p.FLASH);
24 let flash = Mutex::new(BlockingAsync::new(flash)); 31 let flash = Mutex::new(BlockingAsync::new(flash));
25 32
26 let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up); 33 let mut button = ExtiInput::new(
34 p.PC13,
35 p.EXTI13,
36 Pull::Up,
37 Irqs::as_any::<interrupt::typelevel::EXTI15_10, exti::InterruptHandler<interrupt::typelevel::EXTI15_10>>(),
38 );
27 39
28 let mut led = Output::new(p.PB14, Level::Low, Speed::Low); 40 let mut led = Output::new(p.PB14, Level::Low, Speed::Low);
29 led.set_high(); 41 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};
9use embassy_embedded_hal::adapter::BlockingAsync; 9use embassy_embedded_hal::adapter::BlockingAsync;
10use embassy_executor::Spawner; 10use embassy_executor::Spawner;
11use embassy_stm32::SharedData; 11use embassy_stm32::SharedData;
12use embassy_stm32::exti::ExtiInput; 12use embassy_stm32::bind_interrupts;
13use embassy_stm32::exti::{self, ExtiInput};
13use embassy_stm32::flash::{Flash, WRITE_SIZE}; 14use embassy_stm32::flash::{Flash, WRITE_SIZE};
14use embassy_stm32::gpio::{Level, Output, Pull, Speed}; 15use embassy_stm32::gpio::{Level, Output, Pull, Speed};
16use embassy_stm32::interrupt;
15use embassy_sync::mutex::Mutex; 17use embassy_sync::mutex::Mutex;
16use panic_reset as _; 18use panic_reset as _;
17 19
@@ -20,6 +22,11 @@ static APP_B: &[u8] = &[0, 1, 2, 3];
20#[cfg(not(feature = "skip-include"))] 22#[cfg(not(feature = "skip-include"))]
21static APP_B: &[u8] = include_bytes!("../../b.bin"); 23static APP_B: &[u8] = include_bytes!("../../b.bin");
22 24
25bind_interrupts!(
26 pub struct Irqs{
27 EXTEXTI0I2_3 => exti::InterruptHandler<interrupt::typelevel::EXTI0>;
28});
29
23#[unsafe(link_section = ".shared_data")] 30#[unsafe(link_section = ".shared_data")]
24static SHARED_DATA: MaybeUninit<SharedData> = MaybeUninit::uninit(); 31static SHARED_DATA: MaybeUninit<SharedData> = MaybeUninit::uninit();
25 32
@@ -29,7 +36,12 @@ async fn main(_spawner: Spawner) {
29 let flash = Flash::new_blocking(p.FLASH); 36 let flash = Flash::new_blocking(p.FLASH);
30 let flash = Mutex::new(BlockingAsync::new(flash)); 37 let flash = Mutex::new(BlockingAsync::new(flash));
31 38
32 let mut button = ExtiInput::new(p.PA0, p.EXTI0, Pull::Up); 39 let mut button = ExtiInput::new(
40 p.PA0,
41 p.EXTI0,
42 Pull::Up,
43 Irqs::as_any::<interrupt::typelevel::EXTI0, exti::InterruptHandler<interrupt::typelevel::EXTI0>>(),
44 );
33 45
34 let mut led = Output::new(p.PB9, Level::Low, Speed::Low); 46 let mut led = Output::new(p.PB9, Level::Low, Speed::Low);
35 led.set_high(); 47 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 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::exti::ExtiInput; 6use embassy_stm32::bind_interrupts;
7use embassy_stm32::exti::{self, ExtiInput};
7use embassy_stm32::gpio::Pull; 8use embassy_stm32::gpio::Pull;
9use embassy_stm32::interrupt;
8use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
9 11
12bind_interrupts!(
13 pub struct Irqs{
14 EXTI4_15 => exti::InterruptHandler<interrupt::typelevel::EXTI4_15>;
15});
16
10#[embassy_executor::main] 17#[embassy_executor::main]
11async fn main(_spawner: Spawner) { 18async fn main(_spawner: Spawner) {
12 let p = embassy_stm32::init(Default::default()); 19 let p = embassy_stm32::init(Default::default());
13 info!("Hello World!"); 20 info!("Hello World!");
14 21
15 let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up); 22 let mut button = ExtiInput::new(
23 p.PC13,
24 p.EXTI13,
25 Pull::Up,
26 Irqs::as_any::<interrupt::typelevel::EXTI4_15, exti::InterruptHandler<interrupt::typelevel::EXTI4_15>>(),
27 );
16 28
17 info!("Press the USER button..."); 29 info!("Press the USER button...");
18 30
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};
8use defmt::info; 8use defmt::info;
9use embassy_executor::Spawner; 9use embassy_executor::Spawner;
10use embassy_stm32::Peri; 10use embassy_stm32::Peri;
11use embassy_stm32::exti::ExtiInput; 11use embassy_stm32::bind_interrupts;
12use embassy_stm32::exti::{self, ExtiInput};
12use embassy_stm32::gpio::{AnyPin, Level, Output, Pull, Speed}; 13use embassy_stm32::gpio::{AnyPin, Level, Output, Pull, Speed};
14use embassy_stm32::interrupt;
13use embassy_time::Timer; 15use embassy_time::Timer;
14use {defmt_rtt as _, panic_probe as _}; 16use {defmt_rtt as _, panic_probe as _};
15 17
16static BLINK_MS: AtomicU32 = AtomicU32::new(0); 18static BLINK_MS: AtomicU32 = AtomicU32::new(0);
17 19
20bind_interrupts!(
21 pub struct Irqs{
22 EXTI4_15 => exti::InterruptHandler<interrupt::typelevel::EXTI4_15>;
23});
24
18#[embassy_executor::task] 25#[embassy_executor::task]
19async fn led_task(led: Peri<'static, AnyPin>) { 26async fn led_task(led: Peri<'static, AnyPin>) {
20 // Configure the LED pin as a push pull output and obtain handler. 27 // Configure the LED pin as a push pull output and obtain handler.
@@ -37,7 +44,12 @@ async fn main(spawner: Spawner) {
37 44
38 // Configure the button pin and obtain handler. 45 // Configure the button pin and obtain handler.
39 // On the Nucleo F091RC there is a button connected to pin PC13. 46 // On the Nucleo F091RC there is a button connected to pin PC13.
40 let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::None); 47 let mut button = ExtiInput::new(
48 p.PC13,
49 p.EXTI13,
50 Pull::None,
51 Irqs::as_any::<interrupt::typelevel::EXTI4_15, exti::InterruptHandler<interrupt::typelevel::EXTI4_15>>(),
52 );
41 53
42 // Create and initialize a delay variable to manage delay loop 54 // Create and initialize a delay variable to manage delay loop
43 let mut del_var = 2000; 55 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 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::exti::ExtiInput; 6use embassy_stm32::bind_interrupts;
7use embassy_stm32::exti::{self, ExtiInput};
7use embassy_stm32::gpio::Pull; 8use embassy_stm32::gpio::Pull;
9use embassy_stm32::interrupt;
8use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
9 11
12bind_interrupts!(
13 pub struct Irqs{
14 EXTI4_15 => exti::InterruptHandler<interrupt::typelevel::EXTI4_15>;
15});
16
10#[embassy_executor::main] 17#[embassy_executor::main]
11async fn main(_spawner: Spawner) { 18async fn main(_spawner: Spawner) {
12 // Initialize and create handle for devicer peripherals 19 // Initialize and create handle for devicer peripherals
13 let p = embassy_stm32::init(Default::default()); 20 let p = embassy_stm32::init(Default::default());
14 // Configure the button pin and obtain handler. 21 // Configure the button pin and obtain handler.
15 // On the Nucleo F091RC there is a button connected to pin PC13. 22 // On the Nucleo F091RC there is a button connected to pin PC13.
16 let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down); 23 let mut button = ExtiInput::new(
24 p.PC13,
25 p.EXTI13,
26 Pull::Down,
27 Irqs::as_any::<interrupt::typelevel::EXTI4_15, exti::InterruptHandler<interrupt::typelevel::EXTI4_15>>(),
28 );
17 29
18 info!("Press the USER button..."); 30 info!("Press the USER button...");
19 loop { 31 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 @@
11 11
12use defmt::*; 12use defmt::*;
13use embassy_executor::Spawner; 13use embassy_executor::Spawner;
14use embassy_stm32::exti::ExtiInput; 14use embassy_stm32::bind_interrupts;
15use embassy_stm32::exti::{self, ExtiInput};
15use embassy_stm32::gpio::{Level, Output, Pull, Speed}; 16use embassy_stm32::gpio::{Level, Output, Pull, Speed};
17use embassy_stm32::interrupt;
16use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; 18use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
17use embassy_sync::channel::Channel; 19use embassy_sync::channel::Channel;
18use embassy_time::{Duration, Timer, with_timeout}; 20use embassy_time::{Duration, Timer, with_timeout};
19use {defmt_rtt as _, panic_probe as _}; 21use {defmt_rtt as _, panic_probe as _};
20 22
23bind_interrupts!(
24 pub struct Irqs{
25 EXTI0 => exti::InterruptHandler<interrupt::typelevel::EXTI0>;
26});
27
21struct Leds<'a> { 28struct Leds<'a> {
22 leds: [Output<'a>; 8], 29 leds: [Output<'a>; 8],
23 direction: i8, 30 direction: i8,
@@ -99,7 +106,12 @@ static CHANNEL: Channel<ThreadModeRawMutex, ButtonEvent, 4> = Channel::new();
99#[embassy_executor::main] 106#[embassy_executor::main]
100async fn main(spawner: Spawner) { 107async fn main(spawner: Spawner) {
101 let p = embassy_stm32::init(Default::default()); 108 let p = embassy_stm32::init(Default::default());
102 let button = ExtiInput::new(p.PA0, p.EXTI0, Pull::Down); 109 let button = ExtiInput::new(
110 p.PA0,
111 p.EXTI0,
112 Pull::Down,
113 Irqs::as_any::<interrupt::typelevel::EXTI0, exti::InterruptHandler<interrupt::typelevel::EXTI0>>(),
114 );
103 info!("Press the USER button..."); 115 info!("Press the USER button...");
104 let leds = [ 116 let leds = [
105 Output::new(p.PE9, Level::Low, Speed::Low), 117 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 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::exti::ExtiInput; 6use embassy_stm32::bind_interrupts;
7use embassy_stm32::exti::{self, ExtiInput};
7use embassy_stm32::gpio::Pull; 8use embassy_stm32::gpio::Pull;
9use embassy_stm32::interrupt;
8use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
9 11
12bind_interrupts!(
13 pub struct Irqs{
14 EXTI0 => exti::InterruptHandler<interrupt::typelevel::EXTI0>;
15});
16
10#[embassy_executor::main] 17#[embassy_executor::main]
11async fn main(_spawner: Spawner) { 18async fn main(_spawner: Spawner) {
12 let p = embassy_stm32::init(Default::default()); 19 let p = embassy_stm32::init(Default::default());
13 info!("Hello World!"); 20 info!("Hello World!");
14 21
15 let mut button = ExtiInput::new(p.PA0, p.EXTI0, Pull::Down); 22 let mut button = ExtiInput::new(
23 p.PA0,
24 p.EXTI0,
25 Pull::Down,
26 Irqs::as_any::<interrupt::typelevel::EXTI0, exti::InterruptHandler<interrupt::typelevel::EXTI0>>(),
27 );
16 28
17 info!("Press the USER button..."); 29 info!("Press the USER button...");
18 30
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 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::exti::ExtiInput; 6use embassy_stm32::bind_interrupts;
7use embassy_stm32::exti::{self, ExtiInput};
7use embassy_stm32::gpio::Pull; 8use embassy_stm32::gpio::Pull;
9use embassy_stm32::interrupt;
8use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
9 11
12bind_interrupts!(
13 pub struct Irqs{
14 EXTI15_10 => exti::InterruptHandler<interrupt::typelevel::EXTI15_10>;
15});
16
10#[embassy_executor::main] 17#[embassy_executor::main]
11async fn main(_spawner: Spawner) { 18async fn main(_spawner: Spawner) {
12 let p = embassy_stm32::init(Default::default()); 19 let p = embassy_stm32::init(Default::default());
13 info!("Hello World!"); 20 info!("Hello World!");
14 21
15 let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down); 22 let mut button = ExtiInput::new(
23 p.PC13,
24 p.EXTI13,
25 Pull::Down,
26 Irqs::as_any::<interrupt::typelevel::EXTI15_10, exti::InterruptHandler<interrupt::typelevel::EXTI15_10>>(),
27 );
16 28
17 info!("Press the USER button..."); 29 info!("Press the USER button...");
18 30
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;
7use embassy_net::{Ipv4Address, StackResources}; 7use embassy_net::{Ipv4Address, StackResources};
8use embassy_net_wiznet::chip::W5500; 8use embassy_net_wiznet::chip::W5500;
9use embassy_net_wiznet::{Device, Runner, State}; 9use embassy_net_wiznet::{Device, Runner, State};
10use embassy_stm32::exti::ExtiInput; 10use embassy_stm32::bind_interrupts;
11use embassy_stm32::exti::{self, ExtiInput};
11use embassy_stm32::gpio::{Level, Output, Pull, Speed}; 12use embassy_stm32::gpio::{Level, Output, Pull, Speed};
13use embassy_stm32::interrupt;
12use embassy_stm32::mode::Async; 14use embassy_stm32::mode::Async;
13use embassy_stm32::rng::Rng; 15use embassy_stm32::rng::Rng;
14use embassy_stm32::spi::Spi; 16use embassy_stm32::spi::Spi;
@@ -23,6 +25,7 @@ use {defmt_rtt as _, panic_probe as _};
23 25
24bind_interrupts!(struct Irqs { 26bind_interrupts!(struct Irqs {
25 HASH_RNG => rng::InterruptHandler<peripherals::RNG>; 27 HASH_RNG => rng::InterruptHandler<peripherals::RNG>;
28 EXTI0 => exti::InterruptHandler<interrupt::typelevel::EXTI0>;
26}); 29});
27 30
28type EthernetSPI = ExclusiveDevice<Spi<'static, Async, Master>, Output<'static>, Delay>; 31type EthernetSPI = ExclusiveDevice<Spi<'static, Async, Master>, Output<'static>, Delay>;
@@ -75,7 +78,12 @@ async fn main(spawner: Spawner) -> ! {
75 let cs = Output::new(p.PA4, Level::High, Speed::VeryHigh); 78 let cs = Output::new(p.PA4, Level::High, Speed::VeryHigh);
76 let spi = unwrap!(ExclusiveDevice::new(spi, cs, Delay)); 79 let spi = unwrap!(ExclusiveDevice::new(spi, cs, Delay));
77 80
78 let w5500_int = ExtiInput::new(p.PB0, p.EXTI0, Pull::Up); 81 let w5500_int = ExtiInput::new(
82 p.PB0,
83 p.EXTI0,
84 Pull::Up,
85 Irqs::as_any::<interrupt::typelevel::EXTI0, exti::InterruptHandler<interrupt::typelevel::EXTI0>>(),
86 );
79 let w5500_reset = Output::new(p.PB1, Level::High, Speed::VeryHigh); 87 let w5500_reset = Output::new(p.PB1, Level::High, Speed::VeryHigh);
80 88
81 let mac_addr = [0x02, 234, 3, 4, 82, 231]; 89 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};
6use defmt::*; 6use defmt::*;
7use embassy_executor::Spawner; 7use embassy_executor::Spawner;
8use embassy_futures::join::join; 8use embassy_futures::join::join;
9use embassy_stm32::exti::ExtiInput; 9use embassy_stm32::bind_interrupts;
10use embassy_stm32::exti::{self, ExtiInput};
10use embassy_stm32::gpio::Pull; 11use embassy_stm32::gpio::Pull;
12use embassy_stm32::interrupt;
11use embassy_stm32::time::Hertz; 13use embassy_stm32::time::Hertz;
12use embassy_stm32::usb::Driver; 14use embassy_stm32::usb::Driver;
13use embassy_stm32::{Config, bind_interrupts, peripherals, usb}; 15use embassy_stm32::{Config, bind_interrupts, peripherals, usb};
@@ -21,6 +23,7 @@ use {defmt_rtt as _, panic_probe as _};
21 23
22bind_interrupts!(struct Irqs { 24bind_interrupts!(struct Irqs {
23 OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; 25 OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>;
26 EXTI15_10 => exti::InterruptHandler<interrupt::typelevel::EXTI15_10>;
24}); 27});
25 28
26static HID_PROTOCOL_MODE: AtomicU8 = AtomicU8::new(HidProtocolMode::Boot as u8); 29static HID_PROTOCOL_MODE: AtomicU8 = AtomicU8::new(HidProtocolMode::Boot as u8);
@@ -123,7 +126,12 @@ async fn main(_spawner: Spawner) {
123 126
124 let (reader, mut writer) = hid.split(); 127 let (reader, mut writer) = hid.split();
125 128
126 let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down); 129 let mut button = ExtiInput::new(
130 p.PC13,
131 p.EXTI13,
132 Pull::Down,
133 Irqs::as_any::<interrupt::typelevel::EXTI15_10, exti::InterruptHandler<interrupt::typelevel::EXTI15_10>>(),
134 );
127 135
128 // Do stuff with the class! 136 // Do stuff with the class!
129 let in_fut = async { 137 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 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::exti::ExtiInput; 6use embassy_stm32::bind_interrupts;
7use embassy_stm32::exti::{self, ExtiInput};
7use embassy_stm32::gpio::Pull; 8use embassy_stm32::gpio::Pull;
9use embassy_stm32::interrupt;
8use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
9 11
12bind_interrupts!(
13 pub struct Irqs{
14 EXTI15_10 => exti::InterruptHandler<interrupt::typelevel::EXTI15_10>;
15});
16
10#[embassy_executor::main] 17#[embassy_executor::main]
11async fn main(_spawner: Spawner) { 18async fn main(_spawner: Spawner) {
12 let p = embassy_stm32::init(Default::default()); 19 let p = embassy_stm32::init(Default::default());
13 info!("Hello World!"); 20 info!("Hello World!");
14 21
15 let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down); 22 let mut button = ExtiInput::new(
23 p.PC13,
24 p.EXTI13,
25 Pull::Down,
26 Irqs::as_any::<interrupt::typelevel::EXTI15_10, exti::InterruptHandler<interrupt::typelevel::EXTI15_10>>(),
27 );
16 28
17 info!("Press the USER button..."); 29 info!("Press the USER button...");
18 30
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 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::exti::ExtiInput; 6use embassy_stm32::bind_interrupts;
7use embassy_stm32::exti::{self, ExtiInput};
7use embassy_stm32::gpio::Pull; 8use embassy_stm32::gpio::Pull;
9use embassy_stm32::interrupt;
8use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
9 11
12bind_interrupts!(
13 pub struct Irqs{
14 EXTI4_15 => exti::InterruptHandler<interrupt::typelevel::EXTI4_15>;
15});
16
10#[embassy_executor::main] 17#[embassy_executor::main]
11async fn main(_spawner: Spawner) { 18async fn main(_spawner: Spawner) {
12 let p = embassy_stm32::init(Default::default()); 19 let p = embassy_stm32::init(Default::default());
13 info!("Hello World!"); 20 info!("Hello World!");
14 21
15 let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up); 22 let mut button = ExtiInput::new(
23 p.PC13,
24 p.EXTI13,
25 Pull::Up,
26 Irqs::as_any::<interrupt::typelevel::EXTI4_15, exti::InterruptHandler<interrupt::typelevel::EXTI4_15>>(),
27 );
16 28
17 info!("Press the USER button..."); 29 info!("Press the USER button...");
18 30
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 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::exti::ExtiInput; 6use embassy_stm32::bind_interrupts;
7use embassy_stm32::exti::{self, ExtiInput};
7use embassy_stm32::gpio::Pull; 8use embassy_stm32::gpio::Pull;
9use embassy_stm32::interrupt;
8use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
9 11
12bind_interrupts!(
13 pub struct Irqs{
14 EXTI15_10 => exti::InterruptHandler<interrupt::typelevel::EXTI15_10>;
15});
16
10#[embassy_executor::main] 17#[embassy_executor::main]
11async fn main(_spawner: Spawner) { 18async fn main(_spawner: Spawner) {
12 let p = embassy_stm32::init(Default::default()); 19 let p = embassy_stm32::init(Default::default());
13 info!("Hello World!"); 20 info!("Hello World!");
14 21
15 let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down); 22 let mut button = ExtiInput::new(
23 p.PC13,
24 p.EXTI13,
25 Pull::Down,
26 Irqs::as_any::<interrupt::typelevel::EXTI15_10, exti::InterruptHandler<interrupt::typelevel::EXTI15_10>>(),
27 );
16 28
17 info!("Press the USER button..."); 29 info!("Press the USER button...");
18 30
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 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::exti::ExtiInput; 6use embassy_stm32::bind_interrupts;
7use embassy_stm32::exti::{self, ExtiInput};
7use embassy_stm32::gpio::Pull; 8use embassy_stm32::gpio::Pull;
9use embassy_stm32::interrupt;
8use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
9 11
12bind_interrupts!(
13 pub struct Irqs{
14 EXTI13 => exti::InterruptHandler<interrupt::typelevel::EXTI13>;
15});
16
10#[embassy_executor::main] 17#[embassy_executor::main]
11async fn main(_spawner: Spawner) { 18async fn main(_spawner: Spawner) {
12 let p = embassy_stm32::init(Default::default()); 19 let p = embassy_stm32::init(Default::default());
13 info!("Hello World!"); 20 info!("Hello World!");
14 21
15 let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down); 22 let mut button = ExtiInput::new(
23 p.PC13,
24 p.EXTI13,
25 Pull::Down,
26 Irqs::as_any::<interrupt::typelevel::EXTI13, exti::InterruptHandler<interrupt::typelevel::EXTI13>>(),
27 );
16 28
17 info!("Press the USER button..."); 29 info!("Press the USER button...");
18 30
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 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::exti::ExtiInput; 6use embassy_stm32::bind_interrupts;
7use embassy_stm32::exti::{self, ExtiInput};
7use embassy_stm32::gpio::Pull; 8use embassy_stm32::gpio::Pull;
9use embassy_stm32::interrupt;
8use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
9 11
12bind_interrupts!(
13 pub struct Irqs{
14 EXTI15_10 => exti::InterruptHandler<interrupt::typelevel::EXTI15_10>;
15});
16
10#[embassy_executor::main] 17#[embassy_executor::main]
11async fn main(_spawner: Spawner) { 18async fn main(_spawner: Spawner) {
12 let p = embassy_stm32::init(Default::default()); 19 let p = embassy_stm32::init(Default::default());
13 info!("Hello World!"); 20 info!("Hello World!");
14 21
15 let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down); 22 let mut button = ExtiInput::new(
23 p.PC13,
24 p.EXTI13,
25 Pull::Down,
26 Irqs::as_any::<interrupt::typelevel::EXTI15_10, exti::InterruptHandler<interrupt::typelevel::EXTI15_10>>(),
27 );
16 28
17 info!("Press the USER button..."); 29 info!("Press the USER button...");
18 30
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 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::exti::ExtiInput; 6use embassy_stm32::bind_interrupts;
7use embassy_stm32::exti::{self, ExtiInput};
7use embassy_stm32::gpio::Pull; 8use embassy_stm32::gpio::Pull;
9use embassy_stm32::interrupt;
8use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
9 11
12bind_interrupts!(
13 pub struct Irqs{
14 EXTI13 => exti::InterruptHandler<interrupt::typelevel::EXTI13>;
15});
16
10#[embassy_executor::main] 17#[embassy_executor::main]
11async fn main(_spawner: Spawner) { 18async fn main(_spawner: Spawner) {
12 let p = embassy_stm32::init(Default::default()); 19 let p = embassy_stm32::init(Default::default());
13 info!("Hello World!"); 20 info!("Hello World!");
14 21
15 let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up); 22 let mut button = ExtiInput::new(
23 p.PC13,
24 p.EXTI13,
25 Pull::Up,
26 Irqs::as_any::<interrupt::typelevel::EXTI13, exti::InterruptHandler<interrupt::typelevel::EXTI13>>(),
27 );
16 28
17 info!("Press the USER button..."); 29 info!("Press the USER button...");
18 30
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 @@
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::Config; 6use embassy_stm32::Config;
7use embassy_stm32::exti::ExtiInput; 7use embassy_stm32::bind_interrupts;
8use embassy_stm32::exti::{self, ExtiInput};
8use embassy_stm32::gpio::Pull; 9use embassy_stm32::gpio::Pull;
10use embassy_stm32::interrupt;
9use {defmt_rtt as _, panic_probe as _}; 11use {defmt_rtt as _, panic_probe as _};
10 12
13bind_interrupts!(
14 pub struct Irqs{
15 EXTI2_3 => exti::InterruptHandler<interrupt::typelevel::EXTI2_3>;
16});
17
11#[embassy_executor::main] 18#[embassy_executor::main]
12async fn main(_spawner: Spawner) { 19async fn main(_spawner: Spawner) {
13 let config = Config::default(); 20 let config = Config::default();
14 let p = embassy_stm32::init(config); 21 let p = embassy_stm32::init(config);
15 22
16 let mut button = ExtiInput::new(p.PB2, p.EXTI2, Pull::Up); 23 let mut button = ExtiInput::new(
24 p.PB2,
25 p.EXTI2,
26 Pull::Up,
27 Irqs::as_any::<interrupt::typelevel::EXTI2_3, exti::InterruptHandler<interrupt::typelevel::EXTI2_3>>(),
28 );
17 29
18 info!("Press the USER button..."); 30 info!("Press the USER button...");
19 31
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 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::exti::ExtiInput; 6use embassy_stm32::bind_interrupts;
7use embassy_stm32::exti::{self, ExtiInput};
7use embassy_stm32::gpio::Pull; 8use embassy_stm32::gpio::Pull;
9use embassy_stm32::interrupt;
8use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
9 11
12bind_interrupts!(
13 pub struct Irqs{
14 EXTI15_10 => exti::InterruptHandler<interrupt::typelevel::EXTI15_10>;
15});
16
10#[embassy_executor::main] 17#[embassy_executor::main]
11async fn main(_spawner: Spawner) { 18async fn main(_spawner: Spawner) {
12 let p = embassy_stm32::init(Default::default()); 19 let p = embassy_stm32::init(Default::default());
13 info!("Hello World!"); 20 info!("Hello World!");
14 21
15 let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up); 22 let mut button = ExtiInput::new(
23 p.PC13,
24 p.EXTI13,
25 Pull::Up,
26 Irqs::as_any::<interrupt::typelevel::EXTI15_10, exti::InterruptHandler<interrupt::typelevel::EXTI15_10>>(),
27 );
16 28
17 info!("Press the USER button..."); 29 info!("Press the USER button...");
18 30
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 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::exti::ExtiInput; 6use embassy_stm32::bind_interrupts;
7use embassy_stm32::exti::{self, ExtiInput};
7use embassy_stm32::gpio::Pull; 8use embassy_stm32::gpio::Pull;
9use embassy_stm32::interrupt;
8use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
9 11
12bind_interrupts!(
13 pub struct Irqs{
14 EXTI13 => exti::InterruptHandler<interrupt::typelevel::EXTI13>;
15});
16
10#[embassy_executor::main] 17#[embassy_executor::main]
11async fn main(_spawner: Spawner) { 18async fn main(_spawner: Spawner) {
12 let p = embassy_stm32::init(Default::default()); 19 let p = embassy_stm32::init(Default::default());
13 info!("Hello World!"); 20 info!("Hello World!");
14 21
15 let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down); 22 let mut button = ExtiInput::new(
23 p.PC13,
24 p.EXTI13,
25 Pull::Down,
26 Irqs::as_any::<interrupt::typelevel::EXTI13, exti::InterruptHandler<interrupt::typelevel::EXTI13>>(),
27 );
16 28
17 info!("Press the USER button..."); 29 info!("Press the USER button...");
18 30
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 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::exti::ExtiInput; 6use embassy_stm32::bind_interrupts;
7use embassy_stm32::exti::{self, ExtiInput};
7use embassy_stm32::gpio::{Level, Output, Pull, Speed}; 8use embassy_stm32::gpio::{Level, Output, Pull, Speed};
9use embassy_stm32::interrupt;
8use embassy_time::Timer; 10use embassy_time::Timer;
9use {defmt_rtt as _, panic_probe as _}; 11use {defmt_rtt as _, panic_probe as _};
10 12
13bind_interrupts!(
14 pub struct Irqs{
15 EXTI13 => exti::InterruptHandler<interrupt::typelevel::EXTI13>;
16});
17
11#[embassy_executor::task] 18#[embassy_executor::task]
12async fn button_task(mut p: ExtiInput<'static>) { 19async fn button_task(mut p: ExtiInput<'static>) {
13 loop { 20 loop {
@@ -22,7 +29,12 @@ async fn main(spawner: Spawner) {
22 info!("Hello World!"); 29 info!("Hello World!");
23 30
24 let mut led = Output::new(p.PG10, Level::High, Speed::Low); 31 let mut led = Output::new(p.PG10, Level::High, Speed::Low);
25 let button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up); 32 let button = ExtiInput::new(
33 p.PC13,
34 p.EXTI13,
35 Pull::Up,
36 Irqs::as_any::<interrupt::typelevel::EXTI13, exti::InterruptHandler<interrupt::typelevel::EXTI13>>(),
37 );
26 38
27 spawner.spawn(button_task(button).unwrap()); 39 spawner.spawn(button_task(button).unwrap());
28 40
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 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::exti::ExtiInput; 6use embassy_stm32::bind_interrupts;
7use embassy_stm32::exti::{self, ExtiInput};
7use embassy_stm32::gpio::Pull; 8use embassy_stm32::gpio::Pull;
9use embassy_stm32::interrupt;
8use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
9 11
12bind_interrupts!(
13 pub struct Irqs{
14 EXTI4_15 => exti::InterruptHandler<interrupt::typelevel::EXTI4_15>;
15});
16
10#[embassy_executor::main] 17#[embassy_executor::main]
11async fn main(_spawner: Spawner) { 18async fn main(_spawner: Spawner) {
12 let p = embassy_stm32::init(Default::default()); 19 let p = embassy_stm32::init(Default::default());
13 info!("Hello World!"); 20 info!("Hello World!");
14 21
15 let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up); 22 let mut button = ExtiInput::new(
23 p.PC13,
24 p.EXTI13,
25 Pull::Up,
26 Irqs::as_any::<interrupt::typelevel::EXTI4_15, exti::InterruptHandler<interrupt::typelevel::EXTI4_15>>(),
27 );
16 28
17 info!("Press the USER button..."); 29 info!("Press the USER button...");
18 30
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 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::exti::ExtiInput; 6use embassy_stm32::bind_interrupts;
7use embassy_stm32::exti::{self, ExtiInput};
7use embassy_stm32::gpio::Pull; 8use embassy_stm32::gpio::Pull;
9use embassy_stm32::interrupt;
8use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
9 11
12bind_interrupts!(
13 pub struct Irqs{
14 EXTI4 => exti::InterruptHandler<interrupt::typelevel::EXTI4>;
15});
16
10#[embassy_executor::main] 17#[embassy_executor::main]
11async fn main(_spawner: Spawner) { 18async fn main(_spawner: Spawner) {
12 let p = embassy_stm32::init(Default::default()); 19 let p = embassy_stm32::init(Default::default());
13 info!("Hello World!"); 20 info!("Hello World!");
14 21
15 let mut button = ExtiInput::new(p.PC4, p.EXTI4, Pull::Up); 22 let mut button = ExtiInput::new(
23 p.PC4,
24 p.EXTI4,
25 Pull::Up,
26 Irqs::as_any::<interrupt::typelevel::EXTI4, exti::InterruptHandler<interrupt::typelevel::EXTI4>>(),
27 );
16 28
17 info!("Press the USER button..."); 29 info!("Press the USER button...");
18 30
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 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::exti::ExtiInput; 6use embassy_stm32::bind_interrupts;
7use embassy_stm32::exti::{self, ExtiInput};
7use embassy_stm32::gpio::Pull; 8use embassy_stm32::gpio::Pull;
9use embassy_stm32::interrupt;
8use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
9 11
12bind_interrupts!(
13 pub struct Irqs{
14 EXTI13 => exti::InterruptHandler<interrupt::typelevel::EXTI13>;
15});
16
10#[embassy_executor::main] 17#[embassy_executor::main]
11async fn main(_spawner: Spawner) { 18async fn main(_spawner: Spawner) {
12 let p = embassy_stm32::init(Default::default()); 19 let p = embassy_stm32::init(Default::default());
13 info!("Hello World!"); 20 info!("Hello World!");
14 21
15 let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up); 22 let mut button = ExtiInput::new(
23 p.PC13,
24 p.EXTI13,
25 Pull::Up,
26 Irqs::as_any::<interrupt::typelevel::EXTI13, exti::InterruptHandler<interrupt::typelevel::EXTI13>>(),
27 );
16 28
17 info!("Press the USER button..."); 29 info!("Press the USER button...");
18 30
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 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::exti::ExtiInput; 6use embassy_stm32::bind_interrupts;
7use embassy_stm32::exti::{self, ExtiInput};
7use embassy_stm32::gpio::Pull; 8use embassy_stm32::gpio::Pull;
9use embassy_stm32::interrupt;
8use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
9 11
12bind_interrupts!(
13 pub struct Irqs{
14 EXTI13 => exti::InterruptHandler<interrupt::typelevel::EXTI13>;
15});
16
10#[embassy_executor::main] 17#[embassy_executor::main]
11async fn main(_spawner: Spawner) { 18async fn main(_spawner: Spawner) {
12 let p = embassy_stm32::init(Default::default()); 19 let p = embassy_stm32::init(Default::default());
13 info!("Hello World!"); 20 info!("Hello World!");
14 21
15 let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up); 22 let mut button = ExtiInput::new(
23 p.PC13,
24 p.EXTI13,
25 Pull::Up,
26 Irqs::as_any::<interrupt::typelevel::EXTI13, exti::InterruptHandler<interrupt::typelevel::EXTI13>>(),
27 );
16 28
17 info!("Press the USER button..."); 29 info!("Press the USER button...");
18 30
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;
6use defmt::*; 6use defmt::*;
7use embassy_executor::Spawner; 7use embassy_executor::Spawner;
8use embassy_stm32::SharedData; 8use embassy_stm32::SharedData;
9use embassy_stm32::exti::ExtiInput; 9use embassy_stm32::bind_interrupts;
10use embassy_stm32::exti::{self, ExtiInput};
10use embassy_stm32::gpio::Pull; 11use embassy_stm32::gpio::Pull;
12use embassy_stm32::interrupt;
11use {defmt_rtt as _, panic_probe as _}; 13use {defmt_rtt as _, panic_probe as _};
12 14
15bind_interrupts!(
16 pub struct Irqs{
17 EXTI0 => exti::InterruptHandler<interrupt::typelevel::EXTI0>;
18});
19
13#[unsafe(link_section = ".shared_data")] 20#[unsafe(link_section = ".shared_data")]
14static SHARED_DATA: MaybeUninit<SharedData> = MaybeUninit::uninit(); 21static SHARED_DATA: MaybeUninit<SharedData> = MaybeUninit::uninit();
15 22
@@ -18,7 +25,12 @@ async fn main(_spawner: Spawner) {
18 let p = embassy_stm32::init_primary(Default::default(), &SHARED_DATA); 25 let p = embassy_stm32::init_primary(Default::default(), &SHARED_DATA);
19 info!("Hello World!"); 26 info!("Hello World!");
20 27
21 let mut button = ExtiInput::new(p.PA0, p.EXTI0, Pull::Up); 28 let mut button = ExtiInput::new(
29 p.PA0,
30 p.EXTI0,
31 Pull::Up,
32 Irqs::as_any::<interrupt::typelevel::EXTI0, exti::InterruptHandler<interrupt::typelevel::EXTI0>>(),
33 );
22 34
23 info!("Press the USER button..."); 35 info!("Press the USER button...");
24 36
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::*;
5#[cfg(feature = "defmt-rtt")] 5#[cfg(feature = "defmt-rtt")]
6use defmt_rtt as _; 6use defmt_rtt as _;
7use embassy_executor::Spawner; 7use embassy_executor::Spawner;
8use embassy_stm32::exti::ExtiInput; 8use embassy_stm32::bind_interrupts;
9use embassy_stm32::exti::{self, ExtiInput};
9use embassy_stm32::gpio::Pull; 10use embassy_stm32::gpio::Pull;
11use embassy_stm32::interrupt;
10use embassy_stm32::low_power; 12use embassy_stm32::low_power;
11use panic_probe as _; 13use panic_probe as _;
12use static_cell::StaticCell; 14use static_cell::StaticCell;
13 15
16bind_interrupts!(
17 pub struct Irqs{
18 EXTI0 => exti::InterruptHandler<interrupt::typelevel::EXTI0>;
19});
20
14#[embassy_executor::main(executor = "low_power::Executor")] 21#[embassy_executor::main(executor = "low_power::Executor")]
15async fn async_main(_spawner: Spawner) { 22async fn async_main(_spawner: Spawner) {
16 let mut config = embassy_stm32::Config::default(); 23 let mut config = embassy_stm32::Config::default();
@@ -64,7 +71,12 @@ async fn async_main(_spawner: Spawner) {
64 71
65 info!("Hello World!"); 72 info!("Hello World!");
66 73
67 let mut button = ExtiInput::new(p.PA0, p.EXTI0, Pull::Up); 74 let mut button = ExtiInput::new(
75 p.PA0,
76 p.EXTI0,
77 Pull::Up,
78 Irqs::as_any::<interrupt::typelevel::EXTI0, exti::InterruptHandler<interrupt::typelevel::EXTI0>>(),
79 );
68 80
69 info!("Press the USER button..."); 81 info!("Press the USER button...");
70 82