WIP owned irqs
This commit is contained in:
@ -98,3 +98,65 @@ pub fn task(args: TokenStream, item: TokenStream) -> TokenStream {
|
||||
};
|
||||
result.into()
|
||||
}
|
||||
|
||||
#[proc_macro]
|
||||
pub fn interrupt_declare(item: TokenStream) -> TokenStream {
|
||||
let name = syn::parse_macro_input!(item as syn::Ident);
|
||||
let name = format_ident!("{}", name);
|
||||
let name_interrupt = format_ident!("{}Interrupt", name);
|
||||
let name_handler = format!("__EMBASSY_{}_HANDLER", name);
|
||||
|
||||
let result = quote! {
|
||||
#[allow(non_camel_case_types)]
|
||||
pub struct #name_interrupt(());
|
||||
unsafe impl OwnedInterrupt for #name_interrupt {
|
||||
type Priority = Priority;
|
||||
fn number(&self) -> u8 {
|
||||
Interrupt::#name as u8
|
||||
}
|
||||
unsafe fn __handler(&self) -> &'static ::core::sync::atomic::AtomicPtr<u32> {
|
||||
#[export_name = #name_handler]
|
||||
static HANDLER: ::core::sync::atomic::AtomicPtr<u32> = ::core::sync::atomic::AtomicPtr::new(::core::ptr::null_mut());
|
||||
&HANDLER
|
||||
}
|
||||
}
|
||||
};
|
||||
result.into()
|
||||
}
|
||||
|
||||
#[proc_macro]
|
||||
pub fn interrupt_take(item: TokenStream) -> TokenStream {
|
||||
let name = syn::parse_macro_input!(item as syn::Ident);
|
||||
let name = format!("{}", name);
|
||||
let name_interrupt = format_ident!("{}Interrupt", name);
|
||||
let name_handler = format!("__EMBASSY_{}_HANDLER", name);
|
||||
|
||||
let result = quote! {
|
||||
{
|
||||
#[allow(non_snake_case)]
|
||||
#[export_name = #name]
|
||||
pub unsafe extern "C" fn trampoline() {
|
||||
extern "C" {
|
||||
#[link_name = #name_handler]
|
||||
static HANDLER: ::core::sync::atomic::AtomicPtr<u32>;
|
||||
}
|
||||
|
||||
let p = HANDLER.load(::core::sync::atomic::Ordering::Acquire);
|
||||
if !p.is_null() {
|
||||
let f: fn() = ::core::mem::transmute(p);
|
||||
f()
|
||||
}
|
||||
}
|
||||
|
||||
static TAKEN: ::core::sync::atomic::AtomicBool = ::core::sync::atomic::AtomicBool::new(false);
|
||||
|
||||
if TAKEN.compare_and_swap(false, true, ::core::sync::atomic::Ordering::AcqRel) {
|
||||
panic!("IRQ Already taken");
|
||||
}
|
||||
|
||||
let irq: interrupt::#name_interrupt = unsafe { ::core::mem::transmute(()) };
|
||||
irq
|
||||
}
|
||||
};
|
||||
result.into()
|
||||
}
|
||||
|
Reference in New Issue
Block a user