hid_report/global_items.rs
1use crate::{__data_to_signed, __data_to_unsigned, macros::*};
2use alloc::vec::Vec;
3use std::fmt::Display;
4
5__impls_for_short_items! {
6 /// Unsigned integer specifying the current Usage Page.
7 ///
8 /// Since a usage are 32 bit values, Usage
9 /// Page items can be used to conserve space in a
10 /// report descriptor by setting the high order 16 bits
11 /// of a subsequent usages. Any usage that follows
12 /// which is defines 16 bits or less is interpreted as a
13 /// Usage ID and concatenated with the Usage Page
14 /// to form a 32 bit Usage.
15 ///
16 /// # Data (Little Endian)
17 ///
18 /// * 0x00: Undefined
19 /// * 0x01: Generic Desktop
20 /// * 0x02: Simulation Controls
21 /// * 0x03: VR Controls
22 /// * 0x04: Sport Controls
23 /// * 0x05: Game Controls
24 /// * 0x06: Generic Device Controls
25 /// * 0x07: Keyboard/Keypad
26 /// * 0x08: LED
27 /// * 0x09: Button
28 /// * 0x0A: Ordinal
29 /// * 0x0B: Telephony Device
30 /// * 0x0C: Consumer
31 /// * 0x0D: Digitizer
32 /// * 0x0E: Haptics
33 /// * 0x0F: PID
34 /// * 0x10: Unicode
35 /// * 0x12: Eye and Head Trackers
36 /// * 0x14: Auxiliary Display
37 /// * 0x20: Sensors
38 /// * 0x40: Medical Instrument
39 /// * 0x41: Braille Display
40 /// * 0x59: Lighting And Illumination
41 /// * 0x80-0x83: Monitor
42 /// * 0x84-0x87: Power
43 /// * 0x8C: Bar Code Scanner
44 /// * 0x8D: Scale
45 /// * 0x8E: Magnetic Stripe Reading
46 /// * 0x8F: Reserved Point of Sale
47 /// * 0x90: Camera Control
48 /// * 0x91: Arcade
49 /// * 0x92: Gaming Device
50 /// * 0xF1D0: FIDO Alliance
51 /// * 0xFF00-x0FFFF: Vendor Defined
52 /// * Other: Reserved
53 UsagePage: 0b0000_0100;
54 /// Extent value in logical units. This is the
55 /// minimum value that a variable or array item will
56 /// report.
57 ///
58 /// For example, a mouse reporting x
59 /// position values from 0 to 128 would have a
60 /// Logical Minimum of 0 and a [Logical Maximum](LogicalMaximum)
61 /// of 128.
62 LogicalMinimum: 0b0001_0100;
63 /// Extent value in logical units. This is the
64 /// maximum value that a variable or array item will
65 /// report.
66 ///
67 /// For example, a mouse reporting x
68 /// position values from 0 to 128 would have a
69 /// [Logical Minimum](LogicalMinimum) of 0 and a Logical Maximum
70 /// of 128.
71 LogicalMaximum: 0b0010_0100;
72 /// Minimum value for the physical extent of a variable item.
73 /// This represents the [Logical Minimum](LogicalMinimum)
74 /// with units applied to it.
75 PhysicalMinimum: 0b0011_0100;
76 /// Maximum value for the physical extent of a variable item.
77 /// This represents the [Logical Maximum](LogicalMaximum)
78 /// with units applied to it.
79 PhysicalMaximum: 0b0100_0100;
80 /// Value of the unit exponent in base 10.
81 ///
82 /// # Data (Little Endian)
83 ///
84 /// * 0x0: 0
85 /// * 0x1: 1
86 /// * 0x2: 2
87 /// * 0x3: 3
88 /// * 0x4: 4
89 /// * 0x5: 5
90 /// * 0x6: 6
91 /// * 0x7: 7
92 /// * 0x8: -8
93 /// * 0x9: -7
94 /// * 0xA: -6
95 /// * 0xB: -5
96 /// * 0xC: -4
97 /// * 0xD: -3
98 /// * 0xE: -2
99 /// * 0xF: -1
100 UnitExponent: 0b0101_0100;
101 /// Unit values.
102 ///
103 /// # Data (Little Endian)
104 ///
105 /// The Unit item qualifies value in the unit of [nibbles](https://en.wikipedia.org/wiki/Nibble).
106 /// i.e., bit 3-0 is the nibble 0, bit 7-4 is the nibble 1, and so on.
107 ///
108 /// | Nibble | System | 0 | 1 | 2 | 3 | 4 |
109 /// | --- | --- | --- | --- | --- | --- | --- |
110 /// | 0 | System | None | SI Linear | SI Rotation | English Linear | English Rotation |
111 /// | 1 | Length | None | Centimeter | Radians | Inch | Degrees |
112 /// | 2 | Mass | None | Gram | Gram | Slug | Slug |
113 /// | 3 | Time | None | Seconds | Seconds | Seconds | Seconds |
114 /// | 4 | Temperature | None | Kelvin | Kelvin | Fahrenheit | Fahrenheit |
115 /// | 5 | Current | None | Ampere | Ampere | Ampere | Ampere |
116 /// | 6 | Luminous Intensity | None | Candela | Candela | Candela | Candela |
117 ///
118 /// Codes 0x5-0xE are reserved; code 0xF is vendor-defined.
119 Unit: 0b0110_0100;
120 /// Unsigned integer specifying the size of the report
121 /// fields in bits.
122 ///
123 /// This allows the parser to build an
124 /// item map for the report handler to use.
125 ReportSize: 0b0111_0100;
126 /// Unsigned value that specifies the Report ID.
127 ///
128 /// If a Report ID tag is used anywhere in Report
129 /// descriptor, all data reports for the device are
130 /// preceded by a single byte ID field. All items
131 /// succeeding the first Report ID tag but preceding
132 /// a second Report ID tag are included in a report
133 /// prefixed by a 1-byte ID. All items succeeding the
134 /// second but preceding a third Report ID tag are
135 /// included in a second report prefixed by a second
136 /// ID, and so on.
137 ///
138 /// This Report ID value indicates the prefix added
139 /// to a particular report. For example, a Report
140 /// descriptor could define a 3-byte report with a
141 /// Report ID of `01`. This device would generate a
142 /// 4-byte data report in which the first byte is `01`.
143 /// The device may also generate other reports, each
144 /// with a unique ID. This allows the host to
145 /// distinguish different types of reports arriving
146 /// over a single interrupt in pipe. And allows the
147 /// device to distinguish different types of reports
148 /// arriving over a single interrupt out pipe. Report
149 /// ID zero is reserved and should not be used.
150 ReportId: 0b1000_0100;
151 /// Unsigned integer specifying the number of data
152 /// fields for the item; determines how many fields
153 /// are included in the report for this particular item
154 /// (and consequently how many bits are added to
155 /// the report).
156 ReportCount: 0b1001_0100;
157 /// Places a copy of the global item state table on the stack.
158 Push: 0b1010_0100;
159 /// Replaces the item state table with the top structure from the stack.
160 Pop: 0b1011_0100;
161}
162
163impl Display for UsagePage {
164 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
165 match self.data().len() {
166 0 => write!(f, "Usage Page"),
167 1.. => write!(
168 f,
169 "Usage Page ({})",
170 match __data_to_unsigned(self.data()) {
171 0x00 => "Undefined",
172 0x01 => "Generic Desktop",
173 0x02 => "Simulation Controls",
174 0x03 => "VR Controls",
175 0x04 => "Sport Controls",
176 0x05 => "Game Controls",
177 0x06 => "Generic Device Controls",
178 0x07 => "Keyboard/Keypad",
179 0x08 => "LED",
180 0x09 => "Button",
181 0x0A => "Ordinal",
182 0x0B => "Telephony Device",
183 0x0C => "Consumer",
184 0x0D => "Digitizers",
185 0x0E => "Haptics",
186 0x0F => "Physical Input Device",
187 0x10 => "Unicode",
188 0x11 => "SoC",
189 0x12 => "Eye and Head Trackers",
190 0x14 => "Auxiliary Display",
191 0x20 => "Sensors",
192 0x40 => "Medical Instrument",
193 0x41 => "Braille Display",
194 0x59 => "Lighting And Illumination",
195 0x80 => "Monitor",
196 0x81 => "Monitor Enumerated",
197 0x82 => "VESA Virtual Controls",
198 0x84 => "Power",
199 0x85 => "Battery System",
200 0x8C => "Bar Code Scanner",
201 0x8D => "Scale",
202 0x8E => "Magnetic Stripe Reading",
203 0x90 => "Camera Control",
204 0x91 => "Arcade",
205 0x92 => "Gaming Device",
206 0xF1D0 => "FIDO Alliance",
207 0xFF00..=0xFFFF => "Vendor Defined",
208 _ => "Reserved",
209 }
210 ),
211 }
212 }
213}
214
215impl Display for LogicalMinimum {
216 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
217 match self.data().len() {
218 0 => write!(f, "Logical Minimum"),
219 1.. => write!(f, "Logical Minimum ({})", __data_to_signed(self.data())),
220 }
221 }
222}
223
224impl Display for LogicalMaximum {
225 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
226 match self.data().len() {
227 0 => write!(f, "Logical Maximum"),
228 1.. => write!(f, "Logical Maximum ({})", __data_to_signed(self.data())),
229 }
230 }
231}
232
233impl Display for PhysicalMinimum {
234 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
235 match self.data().len() {
236 0 => write!(f, "Physical Minimum"),
237 1.. => write!(f, "Physical Minimum ({})", __data_to_signed(self.data())),
238 }
239 }
240}
241
242impl Display for PhysicalMaximum {
243 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
244 match self.data().len() {
245 0 => write!(f, "Physical Maximum"),
246 1.. => write!(f, "Physical Maximum ({})", __data_to_signed(self.data())),
247 }
248 }
249}
250
251impl Display for UnitExponent {
252 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
253 match self.data().len() {
254 0 => write!(f, "Unit Exponent"),
255 1.. => match __data_to_signed(self.data()) {
256 exp @ 0..=7 => write!(f, "Unit Exponent {exp}"),
257 exp @ 8..=15 => write!(f, "Unit Exponent {}", exp - 16),
258 _ => write!(f, "Unit Exponent"),
259 },
260 }
261 }
262}
263
264impl Display for Unit {
265 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
266 let mut units = Vec::new();
267 if let [byte, ..] = self.data() {
268 let system = byte & 0x0F;
269 let length = (byte & 0xF0) >> 4;
270 match system {
271 1 => units.push("System: SI Linear"),
272 2 => units.push("System: SI Rotation"),
273 3 => units.push("System: English Linear"),
274 4 => units.push("System: English Rotation"),
275 5..=0xE => units.push("System: Reserved"),
276 0xF => units.push("System: Vendor Defined"),
277 _ => unreachable!(),
278 }
279 match length {
280 1 => units.push("Length: Centimeter"),
281 2 => units.push("Length: Radians"),
282 3 => units.push("Length: Inch"),
283 4 => units.push("Length: Degrees"),
284 5..=0xE => units.push("Length: Reserved"),
285 0xF => units.push("Length: Vendor Defined"),
286 _ => unreachable!(),
287 }
288 }
289 if let [_, byte, ..] = self.data() {
290 let mass = byte & 0x0F;
291 let time = (byte & 0xF0) >> 4;
292 match mass {
293 1 | 2 => units.push("Mass: Gram"),
294 3 | 4 => units.push("Mass: Slug"),
295 5..=0xE => units.push("Mass: Reserved"),
296 0xF => units.push("Mass: Vendor Defined"),
297 _ => unreachable!(),
298 }
299 match time {
300 1..=4 => units.push("Time: Seconds"),
301 5..=0xE => units.push("Time: Reserved"),
302 0xF => units.push("Time: Vendor Defined"),
303 _ => unreachable!(),
304 }
305 }
306 if let [_, _, byte, ..] = self.data() {
307 let temperature = byte & 0x0F;
308 let current = (byte & 0xF0) >> 4;
309 match temperature {
310 1 | 2 => units.push("Temperature: Kelvin"),
311 3 | 4 => units.push("Temperature: Fahrenheit"),
312 5..=0xE => units.push("Temperature: Reserved"),
313 0xF => units.push("Temperature: Vendor Defined"),
314 _ => unreachable!(),
315 }
316 match current {
317 1..=4 => units.push("Current: Ampere"),
318 5..=0xE => units.push("Current: Reserved"),
319 0xF => units.push("Current: Vendor Defined"),
320 _ => unreachable!(),
321 }
322 }
323 if let [_, _, _, byte, ..] = self.data() {
324 let luminous_intensity = byte & 0x0F;
325 match luminous_intensity {
326 1..=4 => units.push("Luminous Intensity: Candela"),
327 5..=0xE => units.push("Luminous Intensity: Reserved"),
328 0xF => units.push("Luminous Intensity: Vendor Defined"),
329 _ => unreachable!(),
330 }
331 }
332 if units.is_empty() {
333 write!(f, "Unit")
334 } else {
335 write!(f, "Unit({})", units.join(", "))
336 }
337 }
338}
339
340impl Display for ReportSize {
341 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
342 match self.data().len() {
343 0 => write!(f, "Report Size"),
344 1.. => write!(f, "Report Size ({})", __data_to_unsigned(self.data())),
345 }
346 }
347}
348
349impl Display for ReportId {
350 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
351 match self.data().len() {
352 0 => write!(f, "Report ID"),
353 1.. => write!(f, "Report ID ({})", __data_to_unsigned(self.data())),
354 }
355 }
356}
357
358impl Display for ReportCount {
359 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
360 match self.data().len() {
361 0 => write!(f, "Report Count"),
362 1.. => write!(f, "Report Count ({})", __data_to_unsigned(self.data())),
363 }
364 }
365}
366
367impl Display for Push {
368 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
369 write!(f, "Push")
370 }
371}
372
373impl Display for Pop {
374 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
375 write!(f, "Pop")
376 }
377}