#[macro_export]
macro_rules! adapt_serial {
($name:ident) => {
pub struct $name<T>(pub T);
impl<T> embedded_io::ErrorType for $name<T>
where
T: $crate::compat::serial_compat::SerialCompat,
{
type Error = T::Error;
}
impl<T> embedded_io::Write for $name<T>
where
T: $crate::compat::serial_compat::SerialCompat,
{
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
for &b in buf {
self.0.write(&[b])?;
}
Ok(buf.len())
}
fn flush(&mut self) -> Result<(), Self::Error> {
self.0.flush()
}
}
impl<T> core::fmt::Write for $name<T>
where
T: $crate::compat::serial_compat::SerialCompat,
{
fn write_str(&mut self, s: &str) -> core::fmt::Result {
for &b in s.as_bytes() {
self.0.write(&[b]).map_err(|_| core::fmt::Error)?;
}
self.0.flush().map_err(|_| core::fmt::Error)?;
Ok(())
}
}
};
}
#[macro_export]
macro_rules! write_hex {
($dst:expr, $data:expr) => {
for &b in $data {
let _ = core::write!($dst, "{:02X} ", b);
}
};
}
#[macro_export]
macro_rules! write_bin {
($dst:expr, $data:expr) => {
for &b in $data {
let _ = core::write!($dst, "{:08b} ", b);
}
};
}
#[macro_export]
macro_rules! measure_cycles {
($expr:expr, $timer:expr) => {{
let start = $timer.now();
let result = $expr;
let elapsed = $timer.now().wrapping_sub(start);
(result, elapsed)
}};
}
#[macro_export]
macro_rules! loop_with_delay {
($delay:expr, $delay_ms:expr, $body:block) => {
loop {
$body
$delay.delay_ms($delay_ms);
}
};
}
#[macro_export]
macro_rules! assert_log {
($cond:expr, $logger:expr, $($arg:tt)*) => {
if !$cond {
let _ = core::write!($logger, "ASSERT FAILED: ");
let _ = core::writeln!($logger, $($arg)*);
}
};
}
#[macro_export]
macro_rules! quick_diag {
($serial:expr, $i2c:expr, $ctrl_byte:expr, $timer:expr, $test_expr:expr) => {{
quick_diag!(@inner $serial, $i2c, $ctrl_byte);
let (_result, cycles) = $crate::measure_cycles!($test_expr, $timer);
let _ = core::writeln!($serial, "Test expression cycles: {}", cycles);
let _ = core::writeln!($serial, "=== Quick Diagnostic Complete ===");
}};
($serial:expr, $i2c:expr) => {{
quick_diag!(@inner $serial, $i2c, 0x00);
let _ = core::writeln!($serial, "=== Quick Diagnostic Complete ===");
}};
(@inner $serial:expr, $i2c:expr, $ctrl_byte:expr) => {{
let _ = core::writeln!($serial, "=== Quick Diagnostic Start ===");
if let Err(e) = $crate::scanner::scan_i2c($i2c, $serial, $ctrl_byte) {
let _ = core::writeln!($serial, "[error] I2C Scan failed: {}", e);
}
}};
}