Skip to main content

autd3_cpu_wire/
error.rs

1crate::wire_enum! {
2    pub enum Error {
3        None = 0x00,
4        UnknownCmd = 0x01,
5        InvalidPayload = 0x02,
6        InvalidSilencerSetting = 0x04,
7        InvalidTransitionMode = 0x05,
8        MissTransitionTime = 0x06,
9        FpgaTimeout = 0x07,
10        SyncNotReady = 0x08,
11        InvalidSync0Cycle = 0x09,
12        UpdateNotStarted = 0x0A,
13        UpdateImageInvalid = 0x0B,
14        UpdateFlash = 0x0C,
15        UpdateNotCommitted = 0x0D,
16        UpdateNothingToConfirm = 0x0E,
17        UpdateUnsupported = 0x0F,
18        FpgaUpdateInProgress = 0x10,
19        FpgaReconfigFailed = 0x11,
20        UpdateActivating = 0x12,
21    }
22}
23
24impl Error {
25    #[must_use]
26    pub const fn describe(self) -> &'static str {
27        match self {
28            Self::None => "no error",
29            Self::UnknownCmd => "unknown command (device firmware may be out of date)",
30            Self::InvalidPayload => "invalid payload",
31            Self::InvalidSilencerSetting => "invalid silencer setting",
32            Self::InvalidTransitionMode => "invalid transition mode for the target loop behavior",
33            Self::MissTransitionTime => "sys-time transition is too close to now (would be missed)",
34            Self::FpgaTimeout => "FPGA did not acknowledge a register update in time",
35            Self::SyncNotReady => "EtherCAT DC is not configured (no SYNC0 time available)",
36            Self::InvalidSync0Cycle => {
37                "invalid Sync0 cycle time (master's DC config missing or not a multiple of 500us)"
38            }
39            Self::UpdateNotStarted => "firmware update session is not open (UpdateBegin required)",
40            Self::UpdateImageInvalid => "firmware image CRC32 mismatch after write-back",
41            Self::UpdateFlash => "serial flash erase/program/read failed",
42            Self::UpdateNotCommitted => "no committed firmware image to activate",
43            Self::UpdateNothingToConfirm => {
44                "the running firmware image is unknown or was overwritten; nothing to confirm"
45            }
46            Self::UpdateUnsupported => {
47                "the running FPGA image cannot write its configuration flash (flash it once via JTAG)"
48            }
49            Self::FpgaUpdateInProgress => {
50                "an FPGA update is in progress; output commands are rejected until the FPGA reboots"
51            }
52            Self::FpgaReconfigFailed => {
53                "the FPGA did not reconfigure after the update was activated (the new image boots at the next power cycle)"
54            }
55            Self::UpdateActivating => {
56                "a firmware activation is pending; the device reboots within 100 ms"
57            }
58        }
59    }
60}
61
62#[must_use]
63pub fn describe_device_error(code: u8) -> &'static str {
64    match Error::from_u8(code) {
65        Some(e) => e.describe(),
66        None => "unknown error code",
67    }
68}
69
70#[cfg(test)]
71mod tests {
72    use super::*;
73
74    #[test]
75    fn error_round_trips() {
76        for raw in 0u8..=0xFF {
77            match Error::from_u8(raw) {
78                Some(e) => {
79                    assert_eq!(e.as_u8(), raw);
80                    assert_eq!(Error::try_from(raw), Ok(e));
81                }
82                None => assert_eq!(Error::try_from(raw), Err(raw)),
83            }
84        }
85    }
86
87    #[test]
88    fn unknown_code_describes_generically() {
89        assert_eq!(describe_device_error(0xFF), "unknown error code");
90    }
91}