use proc_macro2::TokenStream;
use quote::quote;
use syn::parse_str;
#[derive(Clone, Copy)]
enum Family {
Stm32mp2,
Imx9,
}
impl Family {
fn from_hal_crate(hal_crate: &str) -> Option<Self> {
if hal_crate.contains("stm32mp2") {
Some(Family::Stm32mp2)
} else if hal_crate.contains("imx9") {
Some(Family::Imx9)
} else {
None
}
}
}
pub struct TimeDriverCodegen {
pub timestamp: TokenStream,
pub isr: TokenStream,
pub bringup: TokenStream,
}
impl TimeDriverCodegen {
fn empty() -> Self {
Self {
timestamp: quote! {},
isr: quote! {},
bringup: quote! {},
}
}
}
pub fn time_driver_codegen(hal_crate: &str, enabled: bool, dbg_present: bool) -> TimeDriverCodegen {
if !enabled {
return TimeDriverCodegen::empty();
}
let Some(family) = Family::from_hal_crate(hal_crate) else {
return TimeDriverCodegen::empty();
};
let hal: syn::Path = parse_str(hal_crate).expect("hal_crate must be a valid path");
let bringup = quote! {
unsafe {
#hal::timer_driver::bringup();
}
::consortium_runtime_mcu::log::trace!("consortium controller init: time driver up");
};
let isr = match family {
Family::Stm32mp2 => quote! {
#[cfg(target_arch = "arm")]
#[#hal::interrupt]
fn TIM2() {
#hal::timer_driver::on_timer_interrupt();
}
},
Family::Imx9 => quote! {
#[cfg(target_arch = "arm")]
#[unsafe(no_mangle)]
extern "C" fn LPIT1_IRQHandler() {
#hal::timer_driver::on_timer_interrupt();
}
},
};
let timestamp = if dbg_present {
quote! {
#[cfg(target_arch = "arm")]
defmt::timestamp!("{=u32}", {
use ::core::sync::atomic::{AtomicU32, Ordering};
static COUNT: AtomicU32 = AtomicU32::new(0);
COUNT.fetch_add(1, Ordering::Relaxed)
});
}
} else {
quote! {}
};
TimeDriverCodegen {
timestamp,
isr,
bringup,
}
}