aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2023-02-26 22:42:22 +0100
committerDario Nieuwenhuis <[email protected]>2023-03-06 00:17:51 +0100
commit42c13c8c3d9514866c2842009f76e88e8cb01b22 (patch)
tree88fff15dd26e850f6ca41a9fec0e591466c08101
parenta054891263cbd17315cdf85ecdcc6359313063bc (diff)
nrf: add new interrupt binding traits and macro.
-rw-r--r--embassy-cortex-m/src/interrupt.rs30
-rw-r--r--embassy-nrf/src/lib.rs33
2 files changed, 59 insertions, 4 deletions
diff --git a/embassy-cortex-m/src/interrupt.rs b/embassy-cortex-m/src/interrupt.rs
index ead9d52fe..3a82726df 100644
--- a/embassy-cortex-m/src/interrupt.rs
+++ b/embassy-cortex-m/src/interrupt.rs
@@ -13,6 +13,36 @@ pub mod _export {
13 pub use embassy_macros::{cortex_m_interrupt as interrupt, cortex_m_interrupt_declare as declare}; 13 pub use embassy_macros::{cortex_m_interrupt as interrupt, cortex_m_interrupt_declare as declare};
14} 14}
15 15
16/// Interrupt handler trait.
17///
18/// Drivers that need to handle interrupts implement this trait.
19/// The user must ensure `on_interrupt()` is called every time the interrupt fires.
20/// Drivers must use use [`Binding`] to assert at compile time that the user has done so.
21pub trait Handler<I: Interrupt> {
22 /// Interrupt handler function.
23 ///
24 /// Must be called every time the `I` interrupt fires, synchronously from
25 /// the interrupt handler context.
26 ///
27 /// # Safety
28 ///
29 /// This function must ONLY be called from the interrupt handler for `I`.
30 unsafe fn on_interrupt();
31}
32
33/// Compile-time assertion that an interrupt has been bound to a handler.
34///
35/// For the vast majority of cases, you should use the `bind_interrupts!`
36/// macro instead of writing `unsafe impl`s of this trait.
37///
38/// # Safety
39///
40/// By implementing this trait, you are asserting that you have arranged for `H::on_interrupt()`
41/// to be called every time the `I` interrupt fires.
42///
43/// This allows drivers to check bindings at compile-time.
44pub unsafe trait Binding<I: Interrupt, H: Handler<I>> {}
45
16/// Implementation detail, do not use outside embassy crates. 46/// Implementation detail, do not use outside embassy crates.
17#[doc(hidden)] 47#[doc(hidden)]
18pub struct DynHandler { 48pub struct DynHandler {
diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs
index 3c5db5c7c..446b1f41a 100644
--- a/embassy-nrf/src/lib.rs
+++ b/embassy-nrf/src/lib.rs
@@ -95,14 +95,39 @@ pub mod wdt;
95#[cfg_attr(feature = "_nrf9160", path = "chips/nrf9160.rs")] 95#[cfg_attr(feature = "_nrf9160", path = "chips/nrf9160.rs")]
96mod chip; 96mod chip;
97 97
98pub use chip::EASY_DMA_SIZE;
99
100pub mod interrupt { 98pub mod interrupt {
101 //! nRF interrupts for cortex-m devices. 99 //! Interrupt definitions and macros to bind them.
102 pub use cortex_m::interrupt::{CriticalSection, Mutex}; 100 pub use cortex_m::interrupt::{CriticalSection, Mutex};
103 pub use embassy_cortex_m::interrupt::*; 101 pub use embassy_cortex_m::interrupt::*;
104 102
105 pub use crate::chip::irqs::*; 103 pub use crate::chip::irqs::*;
104
105 /// Macro to bind interrupts to handlers.
106 ///
107 /// This defines the right interrupt handlers, and creates a unit struct (like `struct Irqs;`)
108 /// and implements the right [`Binding`]s for it. You can pass this struct to drivers to
109 /// prove at compile-time that the right interrupts have been bound.
110 // developer note: this macro can't be in `embassy-cortex-m` due to the use of `$crate`.
111 #[macro_export]
112 macro_rules! bind_interrupts {
113 ($vis:vis struct $name:ident { $($irq:ident => $($handler:ty),*;)* }) => {
114 $vis struct $name;
115
116 $(
117 #[allow(non_snake_case)]
118 #[no_mangle]
119 unsafe extern "C" fn $irq() {
120 $(
121 <$handler as $crate::interrupt::Handler<$crate::interrupt::$irq>>::on_interrupt();
122 )*
123 }
124
125 $(
126 unsafe impl $crate::interrupt::Binding<$crate::interrupt::$irq, $handler> for $name {}
127 )*
128 )*
129 };
130 }
106} 131}
107 132
108// Reexports 133// Reexports
@@ -111,7 +136,7 @@ pub mod interrupt {
111pub use chip::pac; 136pub use chip::pac;
112#[cfg(not(feature = "unstable-pac"))] 137#[cfg(not(feature = "unstable-pac"))]
113pub(crate) use chip::pac; 138pub(crate) use chip::pac;
114pub use chip::{peripherals, Peripherals}; 139pub use chip::{peripherals, Peripherals, EASY_DMA_SIZE};
115pub use embassy_cortex_m::executor; 140pub use embassy_cortex_m::executor;
116pub use embassy_cortex_m::interrupt::_export::interrupt; 141pub use embassy_cortex_m::interrupt::_export::interrupt;
117pub use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; 142pub use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};