use std::{env, fs::File, io::Write, path::PathBuf};
type Error = Box<dyn std::error::Error>;
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<bool, Error> {
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(())
}