use core::sync::atomic::{compiler_fence, Ordering};
pub use qingke::interrupt::Priority;
use crate::pac::interrupt::Interrupt as InterruptEnum;
use crate::pac::__EXTERNAL_INTERRUPTS as _;
pub unsafe trait InterruptNumber: Copy {
const MAX_INTERRUPT_NUMBER: u8;
fn number(self) -> u8;
fn from_number(value: u8) -> Result<Self, u8>;
}
unsafe impl InterruptNumber for InterruptEnum {
const MAX_INTERRUPT_NUMBER: u8 = 35;
fn number(self) -> u8 {
self as u8
}
fn from_number(value: u8) -> Result<Self, u8> {
InterruptEnum::try_from(value).map_err(|_| value)
}
}
mod sealed {
pub trait Interrupt {}
}
pub trait Interrupt: sealed::Interrupt {
const IRQ: InterruptEnum;
#[inline]
unsafe fn enable() {
Self::IRQ.enable()
}
#[inline]
fn disable() {
Self::IRQ.disable()
}
#[inline]
fn pend() {
Self::IRQ.pend()
}
#[inline]
fn unpend() {
Self::IRQ.unpend()
}
#[inline]
fn get_priority() -> crate::interrupt::Priority {
Self::IRQ.get_priority()
}
#[inline]
fn set_priority(prio: crate::interrupt::Priority) {
Self::IRQ.set_priority(prio)
}
}
macro_rules! impl_irqs {
($($irqs:ident),* $(,)?) => {
$(
#[allow(non_camel_case_types)]
#[doc=stringify!($irqs)]
#[doc=" typelevel interrupt."]
pub enum $irqs {}
impl sealed::Interrupt for $irqs{}
impl Interrupt for $irqs {
const IRQ: InterruptEnum = InterruptEnum::$irqs;
}
)*
}
}
impl_irqs!(
TMR0, GPIOA, GPIOB, SPI0, BLEL, BLEB, USB, TMR1, TMR2, UART0, UART1, UART2, UART3, RTC, I2C, ADC,
);
pub unsafe trait InterruptExt: InterruptNumber + Copy {
#[inline]
unsafe fn enable(self) {
qingke::pfic::enable_interrupt(self.number())
}
#[inline]
fn disable(self) {
unsafe { qingke::pfic::disable_interrupt(self.number()) }
}
#[inline]
fn is_active(self) -> bool {
qingke::pfic::is_active(self.number())
}
#[inline]
fn pend(self) {
unsafe { qingke::pfic::pend_interrupt(self.number()) }
}
#[inline]
fn unpend(self) {
unsafe { qingke::pfic::unpend_interrupt(self.number()) }
}
#[inline]
fn get_priority(self) -> Priority {
qingke::pfic::get_priority(self.number()).into()
}
#[inline]
fn set_priority(self, prio: Priority) {
unsafe { qingke::pfic::set_priority(self.number(), prio.into()) }
}
}
const PRIO_MASK: u8 = 0xf0;
unsafe impl<T: InterruptNumber + Copy> InterruptExt for T {}