use std::{env, fs::File, io::Write, path::PathBuf}; type Error = Box; const CHECKED_ENV_VARS: &[&str] = &[ "IMXRT_LOG_USB_BULK_MPS", "IMXRT_LOG_USB_SPEED", "IMXRT_LOG_BUFFER_SIZE", ]; fn handle_usb_speed(file: &mut dyn Write) -> Result { let speed = env::var("IMXRT_LOG_USB_SPEED").unwrap_or_else(|_| "HIGH".into()); let is_high_speed = if speed.to_uppercase() == "HIGH" { true } else if speed == "FULL" { false } else { return Err( format!("Unsupported USB speed '{speed}'. Select either 'HIGH' or 'LOW'.").into(), ); }; let speed = if is_high_speed { "High" } else { "LowFull" }; writeln!(file, "\t#[cfg(feature = \"usbd\")]")?; writeln!( file, "\tpub const USB_SPEED: ::imxrt_usbd::Speed = ::imxrt_usbd::Speed::{speed};" )?; Ok(is_high_speed) } fn handle_usb_bulk_speed_mps(file: &mut dyn Write, is_high_speed: bool) -> Result<(), Error> { const ALLOWED_MPS: &[usize] = &[8, 16, 32, 64, 512]; let mps = env::var("IMXRT_LOG_USB_BULK_MPS").unwrap_or_else(|_| "512".into()); let mps: usize = mps.parse().map_err(|err| -> Error { format!("{err:?} when trying to parse IMXRT_LOG_USB_BULK_MPS={mps}").into() })?; if !ALLOWED_MPS.contains(&mps) { return Err(format!("Unsupported bulk MPS '{mps}'. Select on of {ALLOWED_MPS:?}").into()); } if !is_high_speed && mps == 512 { return Err("Bulk MPS of 512 does not work with full-speed USB devices. Either pick a different MPS, or configure a high-speed USB device".into()); } else if is_high_speed && mps != 512 { return Err("High-speed USB devices must use a 512 byte MPS.".into()); } writeln!(file, "\t#[cfg(feature = \"usbd\")]")?; writeln!(file, "\tpub const USB_BULK_MPS: usize = {mps};")?; Ok(()) } fn handle_buffer_size(file: &mut dyn Write) -> Result<(), Error> { let buffer_size = env::var("IMXRT_LOG_BUFFER_SIZE").unwrap_or_else(|_| "1024".into()); let buffer_size: usize = buffer_size.parse().map_err(|err| -> Error { format!("{err:?} when trying to parse IMXRT_LOG_BUFFER_SIZE={buffer_size}").into() })?; if !buffer_size.is_power_of_two() { return Err(format!("Buffer size '{buffer_size}' must be a power of two.").into()); } writeln!(file, "\tpub const BUFFER_SIZE: usize = {buffer_size};")?; Ok(()) } fn main() -> Result<(), Error> { for env_var in CHECKED_ENV_VARS { println!("cargo:rerun-if-env-changed={env_var}"); } let out = PathBuf::from(env::var("OUT_DIR")?); let mut cfg = File::create(out.join("config.rs"))?; writeln!(&mut cfg, "/// Auto-generated by build.rs.\nmod config {{")?; handle_buffer_size(&mut cfg)?; let is_high_speed = handle_usb_speed(&mut cfg)?; handle_usb_bulk_speed_mps(&mut cfg, is_high_speed)?; writeln!(&mut cfg, "}}")?; Ok(()) }