Skip to main content

rfid_silion_compat/
codes.rs

1//! Protocol code definitions used across command building and response parsing.
2//!
3//! This module groups enums and constants for command codes, status codes,
4//! region identifiers, and antenna-related options.
5
6use std::fmt;
7
8/// Command codes defined by the Silion protocol documentation.
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10#[repr(u8)]
11pub enum CommandCode {
12    /// 0x01
13    WriteFlash = 0x01,
14    /// 0x02
15    ReadFlash = 0x02,
16    /// 0x03
17    GetVersion = 0x03,
18    /// 0x04
19    BootFirmware = 0x04,
20    /// 0x06
21    SetBaudRate = 0x06,
22    /// 0x08
23    VerifyFirmware = 0x08,
24    /// 0x09
25    BootBootloader = 0x09,
26    /// 0x0C
27    GetRunPhase = 0x0C,
28    /// 0x10
29    GetSerialNumber = 0x10,
30    /// 0x21
31    SingleTagInventory = 0x21,
32    /// 0x22
33    SynchronousInventory = 0x22,
34    /// 0x23
35    WriteTagEpc = 0x23,
36    /// 0x24
37    WriteTagData = 0x24,
38    /// 0x25
39    LockTag = 0x25,
40    /// 0x26
41    KillTag = 0x26,
42    /// 0x28
43    ReadTagData = 0x28,
44    /// 0x29
45    GetTagBuffer = 0x29,
46    /// 0x61
47    GetAntennaPorts = 0x61,
48    /// 0x63
49    GetCurrentTagProtocol = 0x63,
50    /// 0x65
51    GetFrequencyHopping = 0x65,
52    /// 0x66
53    GetGpi = 0x66,
54    /// 0x67
55    GetCurrentRegion = 0x67,
56    /// 0x6A
57    GetReaderConfiguration = 0x6A,
58    /// 0x6B
59    GetProtocolConfiguration = 0x6B,
60    /// 0x71
61    GetAvailableRegions = 0x71,
62    /// 0x72
63    GetCurrentTemperature = 0x72,
64    /// 0x91
65    SetAntennaPorts = 0x91,
66    /// 0x93
67    SetCurrentTagProtocol = 0x93,
68    /// 0x95
69    SetFrequencyHopping = 0x95,
70    /// 0x96
71    SetGpo = 0x96,
72    /// 0x97
73    SetCurrentRegion = 0x97,
74    /// 0x9A
75    SetReaderConfiguration = 0x9A,
76    /// 0x9B
77    SetProtocolConfiguration = 0x9B,
78    /// 0xAA, Asynchronous inventory command family.
79    AsynchronousInventory = 0xAA,
80}
81
82impl CommandCode {
83    /// Return the raw 8-bit command code.
84    pub const fn as_u8(self) -> u8 {
85        self as u8
86    }
87}
88
89/// Region code values documented for Set/Get Current Region commands.
90#[derive(Debug, Clone, Copy, PartialEq, Eq)]
91#[repr(u8)]
92pub enum RegionCode {
93    /// North America (902-928 MHz), code `0x01`.
94    NorthAmerica = 0x01,
95    /// China 1 (920-925 MHz), code `0x06`.
96    China1 = 0x06,
97    /// Europe (865-867 MHz), code `0x08`.
98    Europe = 0x08,
99    /// China 2 (840-845 MHz), code `0x0A`.
100    China2 = 0x0A,
101    /// Full Frequency Band (840-960 MHz), code `0xFF`.
102    FullFrequencyBand = 0xFF,
103}
104
105impl RegionCode {
106    /// Convert a raw 8-bit region code to the documented enum if known.
107    pub const fn from_u8(raw: u8) -> Option<Self> {
108        match raw {
109            0x01 => Some(Self::NorthAmerica),
110            0x06 => Some(Self::China1),
111            0x08 => Some(Self::Europe),
112            0x0A => Some(Self::China2),
113            0xFF => Some(Self::FullFrequencyBand),
114            _ => None,
115        }
116    }
117
118    /// Return the raw region code byte.
119    pub const fn as_u8(self) -> u8 {
120        self as u8
121    }
122}
123
124impl From<RegionCode> for u8 {
125    fn from(value: RegionCode) -> Self {
126        value as u8
127    }
128}
129
130impl fmt::Display for RegionCode {
131    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
132        let name = match self {
133            Self::NorthAmerica => "North America",
134            Self::China1 => "China 1",
135            Self::Europe => "Europe",
136            Self::China2 => "China 2",
137            Self::FullFrequencyBand => "Full Frequency Band",
138        };
139        f.write_str(name)
140    }
141}
142
143/// Option values documented for Get Antenna Ports (`0x61`).
144#[derive(Debug, Clone, Copy, PartialEq, Eq)]
145#[repr(u8)]
146pub enum AntennaPortsOption {
147    /// `0x00`: get the single TX/RX pair used for tag access operations.
148    AccessPair = 0x00,
149    /// `0x02`: get the TX/RX pairs used for inventory operations.
150    InventoryPairs = 0x02,
151    /// `0x03`: get read/write power settings for each logical antenna.
152    Power = 0x03,
153    /// `0x04`: get read/write power plus settling time for each logical antenna.
154    PowerAndSettling = 0x04,
155    /// `0x05`: get antenna connection state bytes.
156    ConnectionStates = 0x05,
157}
158
159impl AntennaPortsOption {
160    /// Convert a raw 8-bit option code to the documented enum if known.
161    pub const fn from_u8(raw: u8) -> Option<Self> {
162        match raw {
163            0x00 => Some(Self::AccessPair),
164            0x02 => Some(Self::InventoryPairs),
165            0x03 => Some(Self::Power),
166            0x04 => Some(Self::PowerAndSettling),
167            0x05 => Some(Self::ConnectionStates),
168            _ => None,
169        }
170    }
171
172    /// Return the raw antenna ports option byte.
173    pub const fn as_u8(self) -> u8 {
174        self as u8
175    }
176}
177
178impl From<AntennaPortsOption> for u8 {
179    fn from(value: AntennaPortsOption) -> Self {
180        value as u8
181    }
182}
183
184/// Reader status code values from the documentation.
185#[derive(Debug, Clone, Copy, PartialEq, Eq)]
186#[repr(u16)]
187pub enum StatusCode {
188    /// 0x0000
189    Success = 0x0000,
190    /// 0x0100
191    DataLengthMismatch = 0x0100,
192    /// 0x0101
193    UnavailableCommand = 0x0101,
194    /// 0x0105
195    UnavailableParameter = 0x0105,
196    /// 0x010A
197    UnavailableBaudRate = 0x010A,
198    /// 0x010B
199    UnavailableRegion = 0x010B,
200    /// 0x0200
201    AppFirmwareCrcError = 0x0200,
202    /// 0x0302
203    FlashWriteFailed = 0x0302,
204    /// 0x0400
205    NoTagFound = 0x0400,
206    /// 0x0402
207    ProtocolUnavailable = 0x0402,
208    /// 0x040A
209    GeneralTagError = 0x040A,
210    /// 0x040B
211    ReadLengthOutOfLimit = 0x040B,
212    /// 0x040C
213    UnavailableKillPassword = 0x040C,
214    /// 0x0420
215    Gen2ProtocolError = 0x0420,
216    /// 0x0423
217    MemoryOverrunBadPc = 0x0423,
218    /// 0x0424
219    MemoryLocked = 0x0424,
220    /// 0x042B
221    InsufficientPower = 0x042B,
222    /// 0x042F
223    NonSpecificError = 0x042F,
224    /// 0x0430
225    UnknownTagError = 0x0430,
226    /// 0x0500
227    UnavailableFrequency = 0x0500,
228    /// 0x0504
229    TemperatureOverrun = 0x0504,
230    /// 0x0505
231    HighReturnLoss = 0x0505,
232    /// 0x7F00
233    UnknownSeriousError = 0x7F00,
234    /// 0xFF01
235    InitTimerFlashGpioError = 0xFF01,
236    /// 0xFF02
237    OemInitFailed = 0xFF02,
238    /// 0xFF03
239    CommandInterfaceInitFailed = 0xFF03,
240    /// 0xFF04
241    MacRegisterRwInitFailed = 0xFF04,
242    /// 0xFF05
243    MacRegisterInitFailed = 0xFF05,
244    /// 0xFF06
245    R2000Arm7InterfaceInitFailed = 0xFF06,
246    /// 0xFF07
247    R2000Arm7DetectFailed1 = 0xFF07,
248    /// 0xFF08
249    R2000Arm7DetectFailed2 = 0xFF08,
250    /// 0xFF09
251    GpioConfigError = 0xFF09,
252    /// 0xFF0A
253    R2000RegisterInitFailed = 0xFF0A,
254    /// 0xFF0B
255    EpcProtocolInitFailed = 0xFF0B,
256    /// 0xFF0C
257    OemMacMappingInitFailed = 0xFF0C,
258    /// 0xFF0D
259    SerialInitFailed = 0xFF0D,
260    /// 0xFF0E
261    AppMainHandlerInterfaceError = 0xFF0E,
262}
263
264impl StatusCode {
265    /// Convert raw 16-bit status to enum if known.
266    pub const fn from_u16(raw: u16) -> Option<Self> {
267        match raw {
268            0x0000 => Some(Self::Success),
269            0x0100 => Some(Self::DataLengthMismatch),
270            0x0101 => Some(Self::UnavailableCommand),
271            0x0105 => Some(Self::UnavailableParameter),
272            0x010A => Some(Self::UnavailableBaudRate),
273            0x010B => Some(Self::UnavailableRegion),
274            0x0200 => Some(Self::AppFirmwareCrcError),
275            0x0302 => Some(Self::FlashWriteFailed),
276            0x0400 => Some(Self::NoTagFound),
277            0x0402 => Some(Self::ProtocolUnavailable),
278            0x040A => Some(Self::GeneralTagError),
279            0x040B => Some(Self::ReadLengthOutOfLimit),
280            0x040C => Some(Self::UnavailableKillPassword),
281            0x0420 => Some(Self::Gen2ProtocolError),
282            0x0423 => Some(Self::MemoryOverrunBadPc),
283            0x0424 => Some(Self::MemoryLocked),
284            0x042B => Some(Self::InsufficientPower),
285            0x042F => Some(Self::NonSpecificError),
286            0x0430 => Some(Self::UnknownTagError),
287            0x0500 => Some(Self::UnavailableFrequency),
288            0x0504 => Some(Self::TemperatureOverrun),
289            0x0505 => Some(Self::HighReturnLoss),
290            0x7F00 => Some(Self::UnknownSeriousError),
291            0xFF01 => Some(Self::InitTimerFlashGpioError),
292            0xFF02 => Some(Self::OemInitFailed),
293            0xFF03 => Some(Self::CommandInterfaceInitFailed),
294            0xFF04 => Some(Self::MacRegisterRwInitFailed),
295            0xFF05 => Some(Self::MacRegisterInitFailed),
296            0xFF06 => Some(Self::R2000Arm7InterfaceInitFailed),
297            0xFF07 => Some(Self::R2000Arm7DetectFailed1),
298            0xFF08 => Some(Self::R2000Arm7DetectFailed2),
299            0xFF09 => Some(Self::GpioConfigError),
300            0xFF0A => Some(Self::R2000RegisterInitFailed),
301            0xFF0B => Some(Self::EpcProtocolInitFailed),
302            0xFF0C => Some(Self::OemMacMappingInitFailed),
303            0xFF0D => Some(Self::SerialInitFailed),
304            0xFF0E => Some(Self::AppMainHandlerInterfaceError),
305            _ => None,
306        }
307    }
308}