Skip to main content

autd3_rs/
firmware_version.rs

1use core::fmt;
2
3use autd3_cpu_wire::params::{FUNC_EMULATOR_BIT, VERSION_NUM_MAJOR, VERSION_NUM_MINOR};
4
5#[derive(Clone, Copy, Debug, PartialEq, Eq)]
6pub struct Version {
7    pub major: u8,
8    pub minor: u8,
9    pub patch: u8,
10}
11
12impl Version {
13    pub const UNKNOWN: Self = Self {
14        major: 0,
15        minor: 0,
16        patch: 0,
17    };
18
19    #[must_use]
20    pub const fn is_unknown(self) -> bool {
21        self.major == 0 && self.minor == 0 && self.patch == 0
22    }
23
24    #[must_use]
25    pub const fn series(self) -> (u8, u8) {
26        (self.major, self.minor)
27    }
28}
29
30impl fmt::Display for Version {
31    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32        write!(f, "{}.{}.{}", self.major, self.minor, self.patch)
33    }
34}
35
36#[derive(Clone, Copy, Debug, PartialEq, Eq)]
37pub struct FirmwareVersion {
38    pub cpu: Version,
39    pub fpga: Version,
40    pub(crate) function_bits: u8,
41}
42
43impl FirmwareVersion {
44    pub const SUPPORTED_SERIES: (u8, u8) = (VERSION_NUM_MAJOR, VERSION_NUM_MINOR);
45
46    #[must_use]
47    pub const fn is_emulator(&self) -> bool {
48        self.function_bits & (1 << FUNC_EMULATOR_BIT) != 0
49    }
50
51    #[must_use]
52    pub const fn is_supported(&self) -> bool {
53        !self.fpga.is_unknown() && is_supported_series(self.cpu) && is_supported_series(self.fpga)
54    }
55}
56
57const fn is_supported_series(version: Version) -> bool {
58    version.major == FirmwareVersion::SUPPORTED_SERIES.0
59        && version.minor == FirmwareVersion::SUPPORTED_SERIES.1
60}
61
62impl fmt::Display for FirmwareVersion {
63    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64        write!(f, "CPU: {}, FPGA: ", self.cpu)?;
65        if self.fpga.is_unknown() {
66            f.write_str("unknown")?;
67        } else {
68            write!(f, "{}", self.fpga)?;
69        }
70        if self.is_emulator() {
71            f.write_str(" [Emulator]")?;
72        }
73        Ok(())
74    }
75}
76
77#[cfg(test)]
78mod tests {
79    use super::*;
80
81    const V: Version = Version {
82        major: 4,
83        minor: 5,
84        patch: 6,
85    };
86
87    #[test]
88    fn is_emulator() {
89        assert!(
90            FirmwareVersion {
91                cpu: V,
92                fpga: V,
93                function_bits: 1 << 7,
94            }
95            .is_emulator()
96        );
97        assert!(
98            !FirmwareVersion {
99                cpu: V,
100                fpga: V,
101                function_bits: 0x7F,
102            }
103            .is_emulator()
104        );
105    }
106
107    #[test]
108    fn display_appends_emulator_suffix() {
109        assert_eq!(
110            FirmwareVersion {
111                cpu: Version {
112                    major: 1,
113                    minor: 2,
114                    patch: 3,
115                },
116                fpga: V,
117                function_bits: 1 << 7,
118            }
119            .to_string(),
120            "CPU: 1.2.3, FPGA: 4.5.6 [Emulator]"
121        );
122    }
123
124    #[test]
125    fn display_without_emulator_bit_has_no_suffix() {
126        assert_eq!(
127            FirmwareVersion {
128                cpu: Version {
129                    major: 1,
130                    minor: 2,
131                    patch: 3,
132                },
133                fpga: V,
134                function_bits: 0,
135            }
136            .to_string(),
137            "CPU: 1.2.3, FPGA: 4.5.6"
138        );
139    }
140
141    #[test]
142    fn display_unknown_fpga_with_emulator_bit() {
143        assert_eq!(
144            FirmwareVersion {
145                cpu: Version {
146                    major: 1,
147                    minor: 2,
148                    patch: 3,
149                },
150                fpga: Version::UNKNOWN,
151                function_bits: 1 << 7,
152            }
153            .to_string(),
154            "CPU: 1.2.3, FPGA: unknown [Emulator]"
155        );
156    }
157}