autd3-rs 0.9.0

Core async client library for the AUTD3 phased-array kit.
Documentation
use super::params::CPU_VERSION_V12_1;

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Version {
    pub major: u8,
    pub minor: u8,
}

impl core::fmt::Display for Version {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        let (major, minor) = (self.major, self.minor);
        match major {
            0 => write!(f, "older than legacy-v0.4"),
            0x01..=0x06 => write!(f, "legacy-v0.{}", major + 3),
            0x0A..=0x15 => write!(f, "legacy-v1.{}", major - 0x0A),
            0x80..=0x89 => write!(f, "legacy-v2.{}.{}", major - 0x80, minor),
            0x8A => write!(f, "legacy-v3.0.{minor}"),
            0x8B..=0x8C => write!(f, "legacy-v4.{}.{}", major - 0x8B, minor),
            0x8D..=0x8E => write!(f, "legacy-v5.{}.{}", major - 0x8D, minor),
            0x8F..=0x90 => write!(f, "legacy-v6.{}.{}", major - 0x8F, minor),
            0x91 => write!(f, "legacy-v7.0.{minor}"),
            0x92 => write!(f, "legacy-v8.0.{minor}"),
            0xA0..=0xA1 => write!(f, "legacy-v9.{}.{}", major - 0xA0, minor),
            0xA2 => write!(f, "legacy-v10.0.{minor}"),
            0xA3 => write!(f, "legacy-v11.0.{minor}"),
            0xA4..=0xA5 => write!(f, "legacy-v12.{}.{}", major - 0xA4, minor),
            _ => write!(f, "unknown legacy version ({major})"),
        }
    }
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct FirmwareVersion {
    pub idx: usize,
    pub cpu: Version,
    pub fpga: Version,
    pub function_bits: u8,
}

impl FirmwareVersion {
    pub const ENABLED_EMULATOR_BIT: u8 = 1 << 7;

    pub const SUPPORTED_CPU_MAJOR: u8 = CPU_VERSION_V12_1;

    #[must_use]
    pub const fn is_emulator(&self) -> bool {
        (self.function_bits & Self::ENABLED_EMULATOR_BIT) == Self::ENABLED_EMULATOR_BIT
    }

    #[must_use]
    pub const fn is_supported(&self) -> bool {
        self.cpu.major == Self::SUPPORTED_CPU_MAJOR
    }
}

impl core::fmt::Display for FirmwareVersion {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        write!(f, "{}: CPU = {}, FPGA = {}", self.idx, self.cpu, self.fpga)?;
        if self.is_emulator() {
            write!(f, " [Emulator]")?;
        }
        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    fn v(major: u8) -> String {
        Version { major, minor: 0 }.to_string()
    }

    #[test]
    fn version_map_matches_legacy_sdk() {
        assert_eq!(v(0), "older than legacy-v0.4");
        assert_eq!(v(1), "legacy-v0.4");
        assert_eq!(v(6), "legacy-v0.9");
        assert_eq!(v(7), "unknown legacy version (7)");
        assert_eq!(v(10), "legacy-v1.0");
        assert_eq!(v(21), "legacy-v1.11");
        assert_eq!(v(128), "legacy-v2.0.0");
        assert_eq!(v(137), "legacy-v2.9.0");
        assert_eq!(v(138), "legacy-v3.0.0");
        assert_eq!(v(139), "legacy-v4.0.0");
        assert_eq!(v(140), "legacy-v4.1.0");
        assert_eq!(v(141), "legacy-v5.0.0");
        assert_eq!(v(142), "legacy-v5.1.0");
        assert_eq!(v(143), "legacy-v6.0.0");
        assert_eq!(v(144), "legacy-v6.1.0");
        assert_eq!(v(145), "legacy-v7.0.0");
        assert_eq!(v(146), "legacy-v8.0.0");
        assert_eq!(v(147), "unknown legacy version (147)");
        assert_eq!(v(160), "legacy-v9.0.0");
        assert_eq!(v(161), "legacy-v9.1.0");
        assert_eq!(v(162), "legacy-v10.0.0");
        assert_eq!(v(163), "legacy-v11.0.0");
        assert_eq!(v(164), "legacy-v12.0.0");
        assert_eq!(v(165), "legacy-v12.1.0");
    }

    #[test]
    fn only_0xa5_is_supported() {
        let mk = |major| FirmwareVersion {
            idx: 0,
            cpu: Version { major, minor: 0 },
            fpga: Version { major, minor: 0 },
            function_bits: 0,
        };
        assert!(mk(0xA5).is_supported());
        assert!(!mk(0xA4).is_supported());
        assert!(!mk(0xA3).is_supported());
    }

    #[test]
    fn display_reports_both_cores_and_emulator_bit() {
        let mut fw = FirmwareVersion {
            idx: 2,
            cpu: Version {
                major: 0xA5,
                minor: 0,
            },
            fpga: Version {
                major: 0xA5,
                minor: 1,
            },
            function_bits: 0,
        };
        assert_eq!(
            fw.to_string(),
            "2: CPU = legacy-v12.1.0, FPGA = legacy-v12.1.1"
        );
        fw.function_bits = FirmwareVersion::ENABLED_EMULATOR_BIT;
        assert!(fw.is_emulator());
        assert_eq!(
            fw.to_string(),
            "2: CPU = legacy-v12.1.0, FPGA = legacy-v12.1.1 [Emulator]"
        );
    }
}