nrf: add new interrupt binding traits and macro.
This commit is contained in:
parent
a054891263
commit
42c13c8c3d
@ -13,6 +13,36 @@ pub mod _export {
|
|||||||
pub use embassy_macros::{cortex_m_interrupt as interrupt, cortex_m_interrupt_declare as declare};
|
pub use embassy_macros::{cortex_m_interrupt as interrupt, cortex_m_interrupt_declare as declare};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Interrupt handler trait.
|
||||||
|
///
|
||||||
|
/// Drivers that need to handle interrupts implement this trait.
|
||||||
|
/// The user must ensure `on_interrupt()` is called every time the interrupt fires.
|
||||||
|
/// Drivers must use use [`Binding`] to assert at compile time that the user has done so.
|
||||||
|
pub trait Handler<I: Interrupt> {
|
||||||
|
/// Interrupt handler function.
|
||||||
|
///
|
||||||
|
/// Must be called every time the `I` interrupt fires, synchronously from
|
||||||
|
/// the interrupt handler context.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// This function must ONLY be called from the interrupt handler for `I`.
|
||||||
|
unsafe fn on_interrupt();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Compile-time assertion that an interrupt has been bound to a handler.
|
||||||
|
///
|
||||||
|
/// For the vast majority of cases, you should use the `bind_interrupts!`
|
||||||
|
/// macro instead of writing `unsafe impl`s of this trait.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// By implementing this trait, you are asserting that you have arranged for `H::on_interrupt()`
|
||||||
|
/// to be called every time the `I` interrupt fires.
|
||||||
|
///
|
||||||
|
/// This allows drivers to check bindings at compile-time.
|
||||||
|
pub unsafe trait Binding<I: Interrupt, H: Handler<I>> {}
|
||||||
|
|
||||||
/// Implementation detail, do not use outside embassy crates.
|
/// Implementation detail, do not use outside embassy crates.
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub struct DynHandler {
|
pub struct DynHandler {
|
||||||
|
@ -95,14 +95,39 @@ pub mod wdt;
|
|||||||
#[cfg_attr(feature = "_nrf9160", path = "chips/nrf9160.rs")]
|
#[cfg_attr(feature = "_nrf9160", path = "chips/nrf9160.rs")]
|
||||||
mod chip;
|
mod chip;
|
||||||
|
|
||||||
pub use chip::EASY_DMA_SIZE;
|
|
||||||
|
|
||||||
pub mod interrupt {
|
pub mod interrupt {
|
||||||
//! nRF interrupts for cortex-m devices.
|
//! Interrupt definitions and macros to bind them.
|
||||||
pub use cortex_m::interrupt::{CriticalSection, Mutex};
|
pub use cortex_m::interrupt::{CriticalSection, Mutex};
|
||||||
pub use embassy_cortex_m::interrupt::*;
|
pub use embassy_cortex_m::interrupt::*;
|
||||||
|
|
||||||
pub use crate::chip::irqs::*;
|
pub use crate::chip::irqs::*;
|
||||||
|
|
||||||
|
/// 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
|
||||||
|
/// prove at compile-time that the right interrupts have been bound.
|
||||||
|
// developer note: this macro can't be in `embassy-cortex-m` due to the use of `$crate`.
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! bind_interrupts {
|
||||||
|
($vis:vis struct $name:ident { $($irq:ident => $($handler:ty),*;)* }) => {
|
||||||
|
$vis struct $name;
|
||||||
|
|
||||||
|
$(
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[no_mangle]
|
||||||
|
unsafe extern "C" fn $irq() {
|
||||||
|
$(
|
||||||
|
<$handler as $crate::interrupt::Handler<$crate::interrupt::$irq>>::on_interrupt();
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
|
||||||
|
$(
|
||||||
|
unsafe impl $crate::interrupt::Binding<$crate::interrupt::$irq, $handler> for $name {}
|
||||||
|
)*
|
||||||
|
)*
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reexports
|
// Reexports
|
||||||
@ -111,7 +136,7 @@ pub mod interrupt {
|
|||||||
pub use chip::pac;
|
pub use chip::pac;
|
||||||
#[cfg(not(feature = "unstable-pac"))]
|
#[cfg(not(feature = "unstable-pac"))]
|
||||||
pub(crate) use chip::pac;
|
pub(crate) use chip::pac;
|
||||||
pub use chip::{peripherals, Peripherals};
|
pub use chip::{peripherals, Peripherals, EASY_DMA_SIZE};
|
||||||
pub use embassy_cortex_m::executor;
|
pub use embassy_cortex_m::executor;
|
||||||
pub use embassy_cortex_m::interrupt::_export::interrupt;
|
pub use embassy_cortex_m::interrupt::_export::interrupt;
|
||||||
pub use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
|
pub use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
|
||||||
|
Loading…
Reference in New Issue
Block a user