pub use crate::interrupt::*;
use crate::typelevel::Sealed;
use atsamd_hal_macros::hal_cfg;
pub trait SingleInterruptSource: Sealed {}
pub trait MultipleInterruptSources: Sealed {}
macro_rules! declare_interrupts {
($($(#[$cfg:meta])* $irqs:ident),* $(,)?) => {
$(
$(#[$cfg])*
#[allow(non_camel_case_types)]
#[doc=stringify!($irqs)]
#[doc=" typelevel interrupt."]
pub enum $irqs {}
$(#[$cfg])*
impl $crate::typelevel::Sealed for $irqs{}
$(#[$cfg])*
impl $crate::async_hal::interrupts::Interrupt for $irqs {
const IRQ: crate::pac::Interrupt = crate::pac::Interrupt::$irqs;
}
$(#[$cfg])*
impl $crate::async_hal::interrupts::SingleInterruptSource for $irqs {}
)*
}
}
#[allow(unused_macros)]
macro_rules! declare_multiple_interrupts {
($(#[$cfg:meta])* $name:ident: [ $($irq:ident),+ $(,)? ]) => {
::paste::paste! {
$(#[$cfg])*
pub enum $name {}
$(#[$cfg])*
impl $crate::typelevel::Sealed for $name {}
$(#[$cfg])*
impl $crate::async_hal::interrupts::InterruptSource for $name {
unsafe fn enable() {
unsafe {
$($crate::pac::Interrupt::$irq.enable();)+
}
}
fn disable() {
$($crate::pac::Interrupt::$irq.disable();)+
}
fn unpend() {
$($crate::pac::Interrupt::$irq.unpend();)+
}
fn set_priority(prio: $crate::async_hal::interrupts::Priority){
$($crate::pac::Interrupt::$irq.set_priority(prio);)+
}
}
$(#[$cfg])*
impl $crate::async_hal::interrupts::MultipleInterruptSources for $name {}
}
};
}
#[cfg(feature = "dma")]
#[hal_cfg("dmac-d5x")]
declare_multiple_interrupts!(DMAC: [DMAC_0, DMAC_1, DMAC_2, DMAC_OTHER]);
#[cfg(feature = "dma")]
#[hal_cfg(any("dmac-d11", "dmac-d21"))]
declare_interrupts!(DMAC);
#[hal_cfg(any("sercom0-d11", "sercom0-d21"))]
declare_interrupts!(SERCOM0);
#[hal_cfg(any("sercom1-d11", "sercom1-d21"))]
declare_interrupts!(SERCOM1);
#[hal_cfg(any("sercom2-d11", "sercom2-d21"))]
declare_interrupts!(SERCOM2);
#[hal_cfg("sercom3-d21")]
declare_interrupts!(SERCOM3);
#[hal_cfg("sercom4-d21")]
declare_interrupts!(SERCOM4);
#[hal_cfg("sercom5-d21")]
declare_interrupts!(SERCOM5);
#[hal_cfg("sercom0-d5x")]
declare_multiple_interrupts!(SERCOM0: [SERCOM0_0, SERCOM0_1, SERCOM0_2, SERCOM0_OTHER ]);
#[hal_cfg("sercom1-d5x")]
declare_multiple_interrupts!(SERCOM1: [SERCOM1_0, SERCOM1_1, SERCOM1_2, SERCOM1_OTHER ]);
#[hal_cfg("sercom2-d5x")]
declare_multiple_interrupts!(SERCOM2: [SERCOM0_2, SERCOM2_1, SERCOM2_2, SERCOM2_OTHER ]);
#[hal_cfg("sercom3-d5x")]
declare_multiple_interrupts!(SERCOM3: [SERCOM3_0, SERCOM3_1, SERCOM3_2, SERCOM3_OTHER ]);
#[hal_cfg("sercom4-d5x")]
declare_multiple_interrupts!(SERCOM4: [SERCOM4_0, SERCOM4_1, SERCOM4_2, SERCOM4_OTHER ]);
#[hal_cfg("sercom5-d5x")]
declare_multiple_interrupts!(SERCOM5: [SERCOM5_0, SERCOM5_1, SERCOM5_2, SERCOM5_OTHER ]);
#[hal_cfg("sercom6-d5x")]
declare_multiple_interrupts!(SERCOM6: [SERCOM6_0, SERCOM6_1, SERCOM6_2, SERCOM6_OTHER ]);
#[hal_cfg("sercom7-d5x")]
declare_multiple_interrupts!(SERCOM7: [SERCOM7_0, SERCOM7_1, SERCOM7_2, SERCOM7_OTHER ]);
#[hal_cfg("tc0")]
declare_interrupts!(TC0);
#[hal_cfg("tc1")]
declare_interrupts!(TC1);
#[hal_cfg("tc2")]
declare_interrupts!(TC2);
#[hal_cfg("tc3")]
declare_interrupts!(TC3);
#[hal_cfg("tc4")]
declare_interrupts!(TC4);
#[hal_cfg("tc5")]
declare_interrupts!(TC5);
#[hal_cfg("tc6")]
declare_interrupts!(TC6);
#[hal_cfg("tc7")]
declare_interrupts!(TC7);
#[hal_cfg(any("eic-d11", "eic-d21"))]
declare_interrupts!(EIC);
#[hal_cfg("eic-d5x")]
seq_macro::seq!(N in 0..= 15 {
paste::paste! {
declare_interrupts! {
EIC_EXTINT_~N
}
}
});
#[hal_cfg("adc-d5x")]
declare_multiple_interrupts!(ADC0: [ADC0_RESRDY, ADC0_OTHER]);
#[hal_cfg("adc-d5x")]
declare_multiple_interrupts!(ADC1: [ADC1_RESRDY, ADC1_OTHER]);
#[hal_cfg(any("adc-d11", "adc-d21"))]
declare_interrupts!(ADC);
pub trait InterruptSource: crate::typelevel::Sealed {
unsafe fn enable();
fn disable();
fn unpend();
fn set_priority(prio: Priority);
}
impl<T: Interrupt> InterruptSource for T {
unsafe fn enable() {
unsafe {
Self::enable();
}
}
fn disable() {
Self::disable();
}
fn unpend() {
Self::unpend();
}
fn set_priority(prio: Priority) {
Self::set_priority(prio);
}
}
pub trait Interrupt: crate::typelevel::Sealed {
const IRQ: crate::pac::Interrupt;
#[inline]
unsafe fn enable() {
unsafe { Self::IRQ.enable() }
}
#[inline]
fn disable() {
Self::IRQ.disable()
}
#[inline]
fn is_enabled() -> bool {
Self::IRQ.is_enabled()
}
#[inline]
fn is_pending() -> bool {
Self::IRQ.is_pending()
}
#[inline]
fn pend() {
Self::IRQ.pend()
}
#[inline]
fn unpend() {
Self::IRQ.unpend()
}
#[inline]
fn get_priority() -> Priority {
Self::IRQ.get_priority()
}
#[inline]
fn set_priority(prio: Priority) {
Self::IRQ.set_priority(prio)
}
#[inline]
fn set_priority_with_cs(cs: critical_section::CriticalSection, prio: Priority) {
Self::IRQ.set_priority_with_cs(cs, prio)
}
}
pub trait Handler<I: InterruptSource>: Sealed {
unsafe fn on_interrupt();
}
pub unsafe trait Binding<I: InterruptSource, H: Handler<I>> {}