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 timer = match family {
Family::Stm32mp2 => quote! { TIM2 },
Family::Imx9 => quote! { LPIT1 },
};
let bringup = quote! {
#hal::timer_driver::bringup(__p.#timer);
::consortium_runtime_mcu::log::trace!("consortium controller init: time driver up");
};
let isr = quote! {
#[#hal::interrupt]
fn #timer() {
#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,
}
}