add interrupt channels, waker
This commit is contained in:
parent
56db0e1c61
commit
b5e0116f76
@ -307,6 +307,55 @@ compile_error!(
|
|||||||
pub use stm32f4xx_hal as hal;
|
pub use stm32f4xx_hal as hal;
|
||||||
pub use stm32f4xx_hal::stm32 as pac;
|
pub use stm32f4xx_hal::stm32 as pac;
|
||||||
|
|
||||||
|
/// Creates a new interrupt waking a [`Waker`].
|
||||||
|
///
|
||||||
|
/// As this interrupt will be declared in this macro, it can't be used for anything else.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// This macro is useful for implementing [`Future::poll`]:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
|
/// if self.is_ready() {
|
||||||
|
/// Poll::Ready(())
|
||||||
|
/// } else {
|
||||||
|
/// waker_interrupt!(TIM2, cx.waker().clone());
|
||||||
|
/// Poll::Pending
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// [`Waker`]: core::task::Waker
|
||||||
|
/// [`Future::poll`]: core::future::Future::poll
|
||||||
|
macro_rules! waker_interrupt {
|
||||||
|
($INT:ident, $waker:expr) => {{
|
||||||
|
use core::sync::atomic::{self, Ordering};
|
||||||
|
use stm32f4xx_hal::pac::{interrupt, Interrupt, NVIC};
|
||||||
|
|
||||||
|
static mut WAKER: Option<Waker> = None;
|
||||||
|
|
||||||
|
#[interrupt]
|
||||||
|
fn $INT() {
|
||||||
|
// Safety: This context is disabled while the lower priority context accesses WAKER
|
||||||
|
if let Some(waker) = unsafe { WAKER.as_ref() } {
|
||||||
|
waker.wake_by_ref();
|
||||||
|
|
||||||
|
NVIC::mask(Interrupt::$INT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NVIC::mask(Interrupt::$INT);
|
||||||
|
atomic::compiler_fence(Ordering::Acquire);
|
||||||
|
// Safety: The other relevant context, the interrupt, is disabled
|
||||||
|
unsafe { WAKER = Some($waker) }
|
||||||
|
NVIC::unpend(Interrupt::$INT);
|
||||||
|
atomic::compiler_fence(Ordering::Release);
|
||||||
|
// Safety: This is the end of a mask-based critical section
|
||||||
|
unsafe { NVIC::unmask(Interrupt::$INT) }
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
// This mod MUST go first, so that the others see its macros.
|
// This mod MUST go first, so that the others see its macros.
|
||||||
pub(crate) mod fmt;
|
pub(crate) mod fmt;
|
||||||
|
|
||||||
|
@ -554,13 +554,12 @@ pub trait Instance: Deref<Target = uarte0::RegisterBlock> + Sized + private::Sea
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[interrupt]
|
#[interrupt]
|
||||||
unsafe fn UARTE0_UART0() {
|
unsafe fn DMA2_CHANNEL2() {
|
||||||
interrupt::free(|cs| UARTE0::get_state(cs).as_mut().unwrap().on_interrupt());
|
interrupt::free(|cs| UARTE0::get_state(cs).as_mut().unwrap().on_interrupt());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "52833", feature = "52840", feature = "9160"))]
|
|
||||||
#[interrupt]
|
#[interrupt]
|
||||||
unsafe fn UARTE1() {
|
unsafe fn DMA2_CHANNEL7() {
|
||||||
interrupt::free(|cs| UARTE1::get_state(cs).as_mut().unwrap().on_interrupt());
|
interrupt::free(|cs| UARTE1::get_state(cs).as_mut().unwrap().on_interrupt());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user