pub use bare_metal::{CriticalSection, Mutex, Nr};
#[cfg(cortex_m)]
use core::arch::asm;
#[cfg(cortex_m)]
use core::sync::atomic::{Ordering, compiler_fence};
use cortex_m_macros::asm_cfg;
pub unsafe trait InterruptNumber: Copy {
fn number(self) -> u16;
}
unsafe impl<T: Nr + Copy> InterruptNumber for T {
#[inline]
fn number(self) -> u16 {
self.nr() as u16
}
}
#[inline]
#[asm_cfg(cortex_m)]
pub fn disable() {
unsafe { asm!("cpsid i", options(nomem, nostack, preserves_flags)) };
compiler_fence(Ordering::SeqCst);
}
#[inline]
#[asm_cfg(cortex_m)]
pub unsafe fn enable() {
compiler_fence(Ordering::SeqCst);
unsafe { asm!("cpsie i", options(nomem, nostack, preserves_flags)) };
}
#[cfg(cortex_m)]
#[inline]
pub fn free<F, R>(f: F) -> R
where
F: FnOnce(&CriticalSection) -> R,
{
let primask = crate::register::primask::read_raw();
disable();
let r = f(&unsafe { CriticalSection::new() });
unsafe {
crate::register::primask::write_raw(primask);
}
r
}
#[cfg(not(cortex_m))]
#[inline]
pub fn free<F, R>(_: F) -> R
where
F: FnOnce(&CriticalSection) -> R,
{
panic!("cortex_m::interrupt::free() is only functional on cortex-m platforms");
}