[tasks.pacgen] script_runner = "@rust" script = ''' //! ```cargo //! [dependencies] //! anyhow = "1" //! glob = "0.3" //! regex = "1" //! quote = "1" //! proc-macro2 = "1" //! serde = "1" //! serde_yaml = "=0.9.34-deprecated" //! svd-parser = { git = "https://github.com/Dirbaio/svd.git", rev = "8426f3bb40dd2391e26cd087a0d6510fe21fdcbc", features = ["derive-from", "expand"] } //! chiptool = { git = "https://github.com/embassy-rs/chiptool.git", rev = "63e36008ecbc1b68e49160703e256e2db7e40b89" } //! ``` use std::collections::HashMap; use anyhow::{Context, Result}; use glob::glob; use quote::quote; const SVDS_DIR: &str = "./svds"; const TRANSFORMS_DIR: &str = "./transforms"; const CRATE_DIR: &str = "."; #[derive(Debug, serde::Deserialize)] struct Config { includes: Option>, transforms: Option>, } impl Config { fn from_file>(path: P) -> Result { serde_yaml::from_slice(&std::fs::read(path)?).context("unable to read config") } fn apply(&self, ir: &mut chiptool::ir::IR) -> Result<()> { if let Some(includes) = &self.includes { for include in includes { let c = Self::from_file(&format!("{}/{}", TRANSFORMS_DIR, include))?; c.apply(ir)?; } } if let Some(transforms) = &self.transforms { for transform in transforms { transform.run(ir)?; } } Ok(()) } } fn main() -> Result<()> { let devices: Vec<_> = glob(&format!("{}/*.svd", SVDS_DIR))? .map(|p| { p.unwrap() .file_stem() .unwrap() .to_string_lossy() .to_string() }) .collect(); let mut configs = HashMap::new(); for d in &devices { configs.insert( d.clone(), Config::from_file(&format!("{}/{}.yaml", TRANSFORMS_DIR, d))?, ); } std::fs::create_dir_all(CRATE_DIR)?; std::fs::write( &format!("{}/src/common.rs", CRATE_DIR), chiptool::generate::COMMON_MODULE, )?; let svd_parser_config = svd_parser::Config::default(); let render_opts = chiptool::generate::Options { common_module: chiptool::generate::CommonModule::External(quote!(crate::common)), }; for device in &devices { let svd = svd_parser::parse_with_config( std::fs::read_to_string(&format!("{}/{}.svd", SVDS_DIR, device))?.as_ref(), &svd_parser_config, )?; let mut ir = chiptool::svd2ir::convert_svd(&svd)?; configs[device].apply(&mut ir)?; std::fs::create_dir_all(&format!("{}/src/{}", CRATE_DIR, device.to_lowercase()))?; let items = chiptool::generate::render(&mut ir, &render_opts)?; let path = format!("{}/src/{}/chip.rs", CRATE_DIR, device.to_lowercase()); std::fs::write(&path, items.to_string())?; std::process::Command::new("rustfmt").arg(&path).output()?; let items = chiptool::generate::render_device_x(&ir, &ir.devices.values().next().unwrap())?; let path = format!("{}/src/{}/device.x", CRATE_DIR, device.to_lowercase()); std::fs::write(&path, items.to_string())?; } Ok(()) } '''