1use core::convert::TryFrom;
2
3#[derive(Copy, Clone, Debug)]
5pub struct Error {
6 repr: Repr,
7}
8
9#[derive(Copy, Clone, Debug)]
10enum Repr {
11 Device(Status),
12 Simple(ErrorKind),
13}
14
15impl From<ErrorKind> for Error {
16 fn from(kind: ErrorKind) -> Error {
17 Error {
18 repr: Repr::Simple(kind),
19 }
20 }
21}
22
23impl From<Status> for Error {
24 fn from(status: Status) -> Error {
25 Error {
26 repr: Repr::Device(status),
27 }
28 }
29}
30
31impl core::fmt::Display for Error {
32 fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
33 match &self.repr {
34 Repr::Device(status) => write!(fmt, "{}", status),
35 Repr::Simple(kind) => write!(fmt, "{}", kind),
36 }
37 }
38}
39
40#[derive(Copy, Clone, Debug)]
41pub enum Status {
42 CheckmacVerifyFailed = 0x01,
44 Execution = 0x0F,
47 Parse = 0x03,
49 Crc = 0xFF,
52 Unknown = 0xD5,
54 Ecc = 0x05,
56 SelfTest = 0x07,
59 HealthTest = 0x08,
61}
62
63impl TryFrom<u8> for Status {
64 type Error = ();
65
66 fn try_from(value: u8) -> Result<Self, Self::Error> {
67 match value {
68 0x00 => Err(()),
69 0x01 => Ok(Self::CheckmacVerifyFailed),
70 0x0F => Ok(Self::Execution),
71 0x03 => Ok(Self::Parse),
72 0xFF => Ok(Self::Crc),
73 0x05 => Ok(Self::Ecc),
74 0x07 => Ok(Self::SelfTest),
75 0x08 => Ok(Self::HealthTest),
76 _ => Ok(Self::Unknown),
77 }
78 }
79}
80
81impl core::fmt::Display for Status {
82 fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
83 match self {
84 Self::CheckmacVerifyFailed => write!(fmt, "checkmac or verify failed"),
85 Self::Crc => write!(
86 fmt,
87 "bad crc found (command not properly received by device) or other comm error"
88 ),
89 Self::Ecc => write!(
90 fmt,
91 "computation error during ECC processing causing invalid results"
92 ),
93 Self::Execution => write!(fmt, "chip can't execute the command"),
94 Self::HealthTest => write!(fmt, "random number generator health test error"),
95 Self::Parse => write!(
96 fmt,
97 "command received byte length, opcode or parameter was illegal"
98 ),
99 Self::SelfTest => write!(fmt, "chip is in self test failure mode"),
100 Self::Unknown => write!(fmt, "response contains unknown non-zero status byte"),
101 }
102 }
103}
104
105#[derive(Copy, Clone, Debug)]
107pub enum ErrorKind {
108 AssertFailure = 0xF6,
110 BadOpcode = 0xF2,
112 BadParam = 0xE2,
114 CommFail = 0xF0,
116 ConfigZoneLocked = 0x01,
117 DataZoneLocked = 0x04,
118 FuncFail = 0xE0,
120 InvalidId = 0xE3,
122 InvalidSize = 0xE4,
124 NotLocked = 0xF8,
126 ResyncWithWakeup = 0xE8,
128 RxCrcError = 0xE5,
130 RxFail = 0xE6,
132 SmallBuffer = 0xED,
134 Timeout = 0xF1,
136 TooManyCommRetries = 0xEC,
139 TxFail = 0xF7,
141 Unimplemented = 0xF5,
143 UseFlagsConsumed = 0xFC,
145 WakeFailed = 0xD0,
147}
148
149impl core::fmt::Display for ErrorKind {
150 fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
151 match self {
152 Self::AssertFailure => write!(fmt, "failed run-time consistency check"),
153 Self::BadOpcode => write!(fmt, "opcode is not supported by the device"),
154 Self::BadParam => write!(fmt, "bad argument (out of range, null pointer, etc.)"),
155 Self::CommFail => write!(fmt, "communication with device failed"),
156 Self::ConfigZoneLocked => write!(fmt, "config zone is locked"),
157 Self::DataZoneLocked => write!(fmt, "data zone is locked"),
158 Self::FuncFail => write!(
159 fmt,
160 "function could not execute due to incorrect condition / state"
161 ),
162 Self::InvalidId => write!(fmt, "invalid device id, id not set"),
163 Self::InvalidSize => write!(
164 fmt,
165 "count value is out of range or greater than buffer size"
166 ),
167 Self::NotLocked => write!(fmt, "required zone was not locked"),
168 Self::ResyncWithWakeup => write!(
169 fmt,
170 "re-synchronization succeeded, but only after generating a Wake-up"
171 ),
172 Self::RxCrcError => write!(fmt, "crc error in data received from device"),
173 Self::RxFail => write!(
174 fmt,
175 "timed out while waiting for response. Number of bytes received is > 0"
176 ),
177 Self::SmallBuffer => write!(fmt, "supplied buffer is too small for data required"),
178 Self::Timeout => write!(fmt, "timed out while waiting for response"),
179 Self::TooManyCommRetries => {
180 write!(
181 fmt,
182 "device did not respond too many times, indicating no device present"
183 )
184 }
185 Self::TxFail => write!(fmt, "failed to write"),
186 Self::Unimplemented => write!(
187 fmt,
188 "function or some element of it hasn't been implemented yet"
189 ),
190 Self::UseFlagsConsumed => {
191 write!(fmt, "use flags on the device indicates its consumed fully")
192 }
193 Self::WakeFailed => write!(fmt, "device did not respond to wake call as expected"),
194 }
195 }
196}