usbd_hid/
descriptor.rs

1//! Implements generation of HID report descriptors as well as common reports
2extern crate serde;
3extern crate usbd_hid_macros;
4use serde::ser::{Serialize, SerializeTuple, Serializer};
5
6pub use usbd_hid_macros::gen_hid_descriptor;
7
8/// Report types where serialized HID report descriptors are available.
9pub trait SerializedDescriptor {
10    fn desc() -> &'static [u8];
11}
12
13/// Report types which serialize into input reports, ready for transmission.
14pub trait AsInputReport: Serialize {}
15
16/// Prelude for modules which use the `gen_hid_descriptor` macro.
17pub mod generator_prelude {
18    pub use crate::descriptor::{AsInputReport, SerializedDescriptor};
19    pub use serde::ser::{Serialize, SerializeTuple, Serializer};
20    pub use usbd_hid_macros::gen_hid_descriptor;
21}
22
23/// MouseReport describes a report and its companion descriptor than can be used
24/// to send mouse movements and button presses to a host.
25#[gen_hid_descriptor(
26    (collection = APPLICATION, usage_page = GENERIC_DESKTOP, usage = MOUSE) = {
27        (collection = PHYSICAL, usage = POINTER) = {
28            (usage_page = BUTTON, usage_min = BUTTON_1, usage_max = BUTTON_8) = {
29                #[packed_bits 8] #[item_settings data,variable,absolute] buttons=input;
30            };
31            (usage_page = GENERIC_DESKTOP,) = {
32                (usage = X,) = {
33                    #[item_settings data,variable,relative] x=input;
34                };
35                (usage = Y,) = {
36                    #[item_settings data,variable,relative] y=input;
37                };
38                (usage = WHEEL,) = {
39                    #[item_settings data,variable,relative] wheel=input;
40                };
41            };
42            (usage_page = CONSUMER,) = {
43                (usage = AC_PAN,) = {
44                    #[item_settings data,variable,relative] pan=input;
45                };
46            };
47        };
48    }
49)]
50#[allow(dead_code)]
51pub struct MouseReport {
52    pub buttons: u8,
53    pub x: i8,
54    pub y: i8,
55    pub wheel: i8, // Scroll down (negative) or up (positive) this many units
56    pub pan: i8,   // Scroll left (negative) or right (positive) this many units
57}
58
59/// KeyboardReport describes a report and its companion descriptor that can be
60/// used to send keyboard button presses to a host and receive the status of the
61/// keyboard LEDs.
62#[gen_hid_descriptor(
63    (collection = APPLICATION, usage_page = GENERIC_DESKTOP, usage = KEYBOARD) = {
64        (usage_page = KEYBOARD, usage_min = 0xE0, usage_max = 0xE7) = {
65            #[packed_bits 8] #[item_settings data,variable,absolute] modifier=input;
66        };
67        (usage_min = 0x00, usage_max = 0xFF) = {
68            #[item_settings constant,variable,absolute] reserved=input;
69        };
70        (usage_page = LEDS, usage_min = 0x01, usage_max = 0x05) = {
71            #[packed_bits 5] #[item_settings data,variable,absolute] leds=output;
72        };
73        (usage_page = KEYBOARD, usage_min = 0x00, usage_max = 0xDD) = {
74            #[item_settings data,array,absolute] keycodes=input;
75        };
76    }
77)]
78#[allow(dead_code)]
79pub struct KeyboardReport {
80    pub modifier: u8,
81    pub reserved: u8,
82    pub leds: u8,
83    pub keycodes: [u8; 6],
84}
85
86impl KeyboardReport {
87    pub const fn default() -> Self {
88        Self {
89            modifier: 0,
90            reserved: 0,
91            leds: 0,
92            keycodes: [0u8; 6],
93        }
94    }
95}
96
97/// KeyboardUsage describes the key codes to be used in implementing a USB keyboard.
98///
99/// The usage type of all key codes is Selectors, except for the modifier keys
100/// Keyboard Left Control to Keyboard Right GUI which are Dynamic Flags.
101///
102/// Reference: <https://usb.org/sites/default/files/hut1_3_0.pdf> (Section 10, page 88)
103#[repr(u8)]
104#[allow(unused)]
105#[non_exhaustive]
106#[derive(Copy, Debug, Clone, Eq, PartialEq)]
107#[cfg_attr(feature = "defmt", derive(defmt::Format))]
108pub enum KeyboardUsage {
109    // 0x00: Reserved
110    /// Keyboard ErrorRollOver (Footnote 1)
111    KeyboardErrorRollOver = 0x01,
112    /// Keyboard POSTFail (Footnote 1)
113    KeyboardPOSTFail = 0x02,
114    /// Keyboard ErrorUndefined (Footnote 1)
115    KeyboardErrorUndefined = 0x03,
116    /// Keyboard a and A (Footnote 2)
117    KeyboardAa = 0x04,
118    /// Keyboard b and B
119    KeyboardBb = 0x05,
120    /// Keyboard c and C (Footnote 2)
121    KeyboardCc = 0x06,
122    /// Keyboard d and D
123    KeyboardDd = 0x07,
124    /// Keyboard e and E
125    KeyboardEe = 0x08,
126    /// Keyboard f and F
127    KeyboardFf = 0x09,
128    /// Keyboard g and G
129    KeyboardGg = 0x0A,
130    /// Keyboard h and H
131    KeyboardHh = 0x0B,
132    /// Keyboard i and I
133    KeyboardIi = 0x0C,
134    /// Keyboard j and J
135    KeyboardJj = 0x0D,
136    /// Keyboard k and K
137    KeyboardKk = 0x0E,
138    /// Keyboard l and L
139    KeyboardLl = 0x0F,
140    /// Keyboard m and M (Footnote 2)
141    KeyboardMm = 0x10,
142    /// Keyboard n and N
143    KeyboardNn = 0x11,
144    /// Keyboard o and O (Footnote 2)
145    KeyboardOo = 0x12,
146    /// Keyboard p and P (Footnote 2)
147    KeyboardPp = 0x13,
148    /// Keyboard q and Q (Footnote 2)
149    KeyboardQq = 0x14,
150    /// Keyboard r and R
151    KeyboardRr = 0x15,
152    /// Keyboard s and S
153    KeyboardSs = 0x16,
154    /// Keyboard t and T
155    KeyboardTt = 0x17,
156    /// Keyboard u and U
157    KeyboardUu = 0x18,
158    /// Keyboard v and V
159    KeyboardVv = 0x19,
160    /// Keyboard w and W (Footnote 2)
161    KeyboardWw = 0x1A,
162    /// Keyboard x and X (Footnote 2)
163    KeyboardXx = 0x1B,
164    /// Keyboard y and Y (Footnote 2)
165    KeyboardYy = 0x1C,
166    /// Keyboard z and Z (Footnote 2)
167    KeyboardZz = 0x1D,
168    /// Keyboard 1 and ! (Footnote 2)
169    Keyboard1Exclamation = 0x1E,
170    /// Keyboard 2 and @ (Footnote 2)
171    Keyboard2At = 0x1F,
172    /// Keyboard 3 and # (Footnote 2)
173    Keyboard3Hash = 0x20,
174    /// Keyboard 4 and $ (Footnote 2)
175    Keyboard4Dollar = 0x21,
176    /// Keyboard 5 and % (Footnote 2)
177    Keyboard5Percent = 0x22,
178    /// Keyboard 6 and ^ (Footnote 2)
179    Keyboard6Caret = 0x23,
180    /// Keyboard 7 and & (Footnote 2)
181    Keyboard7Ampersand = 0x24,
182    /// Keyboard 8 and * (Footnote 2)
183    Keyboard8Asterisk = 0x25,
184    /// Keyboard 9 and ( (Footnote 2)
185    Keyboard9OpenParens = 0x26,
186    /// Keyboard 0 and ) (Footnote 2)
187    Keyboard0CloseParens = 0x27,
188    /// Keyboard Return (ENTER) (Footnote 3)
189    ///
190    ///  (Footnote 3): Keyboard Enter and Keypad Enter generate different Usage codes.
191    KeyboardEnter = 0x28,
192    /// Keyboard ESCAPE
193    KeyboardEscape = 0x29,
194    /// Keyboard DELETE (Backspace) (Footnote 4)
195    KeyboardBackspace = 0x2A,
196    /// Keyboard Tab
197    KeyboardTab = 0x2B,
198    /// Keyboard Spacebar
199    KeyboardSpacebar = 0x2C,
200    /// Keyboard - and _ (Footnote 2)
201    KeyboardDashUnderscore = 0x2D,
202    /// Keyboard = and + (Footnote 2)
203    KeyboardEqualPlus = 0x2E,
204    /// Keyboard [ and { (Footnote 2)
205    KeyboardOpenBracketBrace = 0x2F,
206    /// Keyboard ] and } (Footnote 2)
207    KeyboardCloseBracketBrace = 0x30,
208    /// Keyboard \ and |
209    KeyboardBackslashBar = 0x31,
210    /// Keyboard Non-US # and (Footnote 5)
211    KeyboardNonUSHash = 0x32,
212    /// Keyboard ; and : (Footnote 2)
213    KeyboardSemiColon = 0x33,
214    /// Keyboard ' and " (Footnote 2)
215    KeyboardSingleDoubleQuote = 0x34,
216    /// Keyboard ` and ~ (Footnote 2)
217    KeyboardBacktickTilde = 0x35,
218    /// Keyboard , and < (Footnote 2)
219    KeyboardCommaLess = 0x36,
220    /// Keyboard . and > (Footnote 2)
221    KeyboardPeriodGreater = 0x37,
222    /// Keyboard / and ? (Footnote 2)
223    KeyboardSlashQuestion = 0x38,
224    /// Keyboard Caps Lock (Footnote 6)
225    KeyboardCapsLock = 0x39,
226    /// Keyboard F1
227    KeyboardF1 = 0x3A,
228    /// Keyboard F2
229    KeyboardF2 = 0x3B,
230    /// Keyboard F3
231    KeyboardF3 = 0x3C,
232    /// Keyboard F4
233    KeyboardF4 = 0x3D,
234    /// Keyboard F5
235    KeyboardF5 = 0x3E,
236    /// Keyboard F6
237    KeyboardF6 = 0x3F,
238    /// Keyboard F7
239    KeyboardF7 = 0x40,
240    /// Keyboard F8
241    KeyboardF8 = 0x41,
242    /// Keyboard F9
243    KeyboardF9 = 0x42,
244    /// Keyboard F10
245    KeyboardF10 = 0x43,
246    /// Keyboard F11
247    KeyboardF11 = 0x44,
248    /// Keyboard F12
249    KeyboardF12 = 0x45,
250    /// Keyboard PrintScreen (Footnote 7)
251    KeyboardPrintScreen = 0x46,
252    /// Keyboard ScrollLock (Footnote 6)
253    KeyboardScrollLock = 0x47,
254    /// Keyboard Pause (Footnote 7)
255    KeyboardPause = 0x48,
256    /// Keyboard Insert (Footnote 7)
257    KeyboardInsert = 0x49,
258    /// Keyboard Home (Footnote 7)
259    KeyboardHome = 0x4A,
260    /// Keyboard PageUp (Footnote 7)
261    KeyboardPageUp = 0x4B,
262    /// Keyboard Delete Forward (Footnote 7) (Footnote 8)
263    KeyboardDelete = 0x4C,
264    /// Keyboard End (Footnote 7)
265    KeyboardEnd = 0x4D,
266    /// Keyboard PageDown (Footnote 7)
267    KeyboardPageDown = 0x4E,
268    /// Keyboard RightArrow (Footnote 7)
269    KeyboardRightArrow = 0x4F,
270    /// Keyboard LeftArrow (Footnote 7)
271    KeyboardLeftArrow = 0x50,
272    /// Keyboard DownArrow (Footnote 7)
273    KeyboardDownArrow = 0x51,
274    /// Keyboard UpArrow (Footnote 7)
275    KeyboardUpArrow = 0x52,
276    /// Keypad Num Lock and Clear (Footnote 6)
277    KeypadNumLock = 0x53,
278    /// Keypad / (Footnote 7)
279    KeypadDivide = 0x54,
280    /// Keypad *
281    KeypadMultiply = 0x55,
282    /// Keypad -
283    KeypadMinus = 0x56,
284    /// Keypad +
285    KeypadPlus = 0x57,
286    /// Keypad ENTER (Footnote 3)
287    KeypadEnter = 0x58,
288    /// Keypad 1 and End
289    Keypad1End = 0x59,
290    /// Keypad 2 and DownArrow
291    Keypad2DownArrow = 0x5A,
292    /// Keypad 3 and PageDown
293    Keypad3PageDown = 0x5B,
294    /// Keypad 4 and LeftArrow
295    Keypad4LeftArrow = 0x5C,
296    /// Keypad 5
297    Keypad5 = 0x5D,
298    /// Keypad 6 and RightArrow
299    Keypad6RightArrow = 0x5E,
300    /// Keypad 7 and Home
301    Keypad7Home = 0x5F,
302    /// Keypad 8 and UpArrow
303    Keypad8UpArrow = 0x60,
304    /// Keypad 9 and PageUp
305    Keypad9PageUp = 0x61,
306    /// Keypad 0 and Insert
307    Keypad0Insert = 0x62,
308    /// Keypad . and Delete
309    KeypadPeriodDelete = 0x63,
310    /// Keyboard Non-US \ and | (Footnote 9) (Footnote 10)
311    KeyboardNonUSSlash = 0x64,
312    /// Keyboard Application (Footnote 11)
313    KeyboardApplication = 0x65,
314    /// Keyboard Power (Footnote 1)
315    KeyboardPower = 0x66,
316    /// Keypad =
317    KeypadEqual = 0x67,
318    /// Keyboard F13
319    KeyboardF13 = 0x68,
320    /// Keyboard F14
321    KeyboardF14 = 0x69,
322    /// Keyboard F15
323    KeyboardF15 = 0x6A,
324    /// Keyboard F16
325    KeyboardF16 = 0x6B,
326    /// Keyboard F17
327    KeyboardF17 = 0x6C,
328    /// Keyboard F18
329    KeyboardF18 = 0x6D,
330    /// Keyboard F19
331    KeyboardF19 = 0x6E,
332    /// Keyboard F20
333    KeyboardF20 = 0x6F,
334    /// Keyboard F21
335    KeyboardF21 = 0x70,
336    /// Keyboard F22
337    KeyboardF22 = 0x71,
338    /// Keyboard F23
339    KeyboardF23 = 0x72,
340    /// Keyboard F24
341    KeyboardF24 = 0x73,
342    /// Keyboard Execute
343    KeyboardExecute = 0x74,
344    /// Keyboard Help
345    KeyboardHelp = 0x75,
346    /// Keyboard Menu
347    KeyboardMenu = 0x76,
348    /// Keyboard Select
349    KeyboardSelect = 0x77,
350    /// Keyboard Stop
351    KeyboardStop = 0x78,
352    /// Keyboard Again
353    KeyboardAgain = 0x79,
354    /// Keyboard Undo
355    KeyboardUndo = 0x7A,
356    /// Keyboard Cut
357    KeyboardCut = 0x7B,
358    /// Keyboard Copy
359    KeyboardCopy = 0x7C,
360    /// Keyboard Paste
361    KeyboardPaste = 0x7D,
362    /// Keyboard Find
363    KeyboardFind = 0x7E,
364    /// Keyboard Mute
365    KeyboardMute = 0x7F,
366    /// Keyboard Volume Up
367    KeyboardVolumeUp = 0x80,
368    /// Keyboard Volume Down
369    KeyboardVolumeDown = 0x81,
370    /// Keyboad Locking Caps Lock (Footnote 12)
371    KeyboardLockingCapsLock = 0x82,
372    /// Keyboad Locking Num Lock (Footnote 12)
373    KeyboardLockingNumLock = 0x83,
374    /// Keyboad Locking Scroll Lock (Footnote 12)
375    KeyboardLockingScrollLock = 0x84,
376    /// Keypad Comma (Footnote 13)
377    KeypadComma = 0x85,
378    /// Keypad Equal Sign (Footnote 14)
379    KeypadEqualSign = 0x86,
380    /// Keyboard International1 (Footnote 15) (Footnote 16)
381    KeyboardInternational1 = 0x87,
382    /// Keyboard International2 (Footnote 17)
383    KeyboardInternational2 = 0x88,
384    /// Keyboard International3 (Footnote 18)
385    KeyboardInternational3 = 0x89,
386    /// Keyboard International4 (Footnote 19)
387    KeyboardInternational4 = 0x8A,
388    /// Keyboard International5 (Footnote 20)
389    KeyboardInternational5 = 0x8B,
390    /// Keyboard International6 (Footnote 21)
391    KeyboardInternational6 = 0x8C,
392    /// Keyboard International7 (Footnote 22)
393    KeyboardInternational7 = 0x8D,
394    /// Keyboard International8 (Footnote 23)
395    KeyboardInternational8 = 0x8E,
396    /// Keyboard International9 (Footnote 23)
397    KeyboardInternational9 = 0x8F,
398    /// Keyboard LANG1 (Footnote 24)
399    KeyboardLANG1 = 0x90,
400    /// Keyboard LANG2 (Footnote 25)
401    KeyboardLANG2 = 0x91,
402    /// Keyboard LANG3 (Footnote 26)
403    KeyboardLANG3 = 0x92,
404    /// Keyboard LANG4 (Footnote 27)
405    KeyboardLANG4 = 0x93,
406    /// Keyboard LANG5 (Footnote 28)
407    KeyboardLANG5 = 0x94,
408    /// Keyboard LANG6 (Footnote 29)
409    KeyboardLANG6 = 0x95,
410    /// Keyboard LANG7 (Footnote 29)
411    KeyboardLANG7 = 0x96,
412    /// Keyboard LANG8 (Footnote 29)
413    KeyboardLANG8 = 0x97,
414    /// Keyboard LANG9 (Footnote 29)
415    KeyboardLANG9 = 0x98,
416    /// Keyboard Alternate Erase (Footnote 30)
417    KeyboardAlternateErase = 0x99,
418    /// Keyboard SysReq/Attention (Footnote 7)
419    KeyboardSysReqAttention = 0x9A,
420    /// Keyboard Cancel
421    KeyboardCancel = 0x9B,
422    /// Keyboard Clear
423    KeyboardClear = 0x9C,
424    /// Keyboard Prior
425    KeyboardPrior = 0x9D,
426    /// Keyboard Return
427    KeyboardReturn = 0x9E,
428    /// Keyboard Separator
429    KeyboardSeparator = 0x9F,
430    /// Keyboard Out
431    KeyboardOut = 0xA0,
432    /// Keyboard Oper
433    KeyboardOper = 0xA1,
434    /// Keyboard Clear/Again
435    KeyboardClearAgain = 0xA2,
436    /// Keyboard CrSel/Props
437    KeyboardCrSelProps = 0xA3,
438    /// Keyboard ExSel
439    KeyboardExSel = 0xA4,
440    // 0xA5-0xAF: Reserved
441    /// Keypad 00
442    Keypad00 = 0xB0,
443    /// Keypad 000
444    Keypad000 = 0xB1,
445    /// Thousands Separator (Footnote 31)
446    ThousandsSeparator = 0xB2,
447    /// Decimal Separator (Footnote 31)
448    DecimalSeparator = 0xB3,
449    /// Currency Unit (Footnote 32)
450    CurrencyUnit = 0xB4,
451    /// Currency Sub-unit (Footnote 32)
452    CurrencySubunit = 0xB5,
453    /// Keypad (
454    KeypadOpenParens = 0xB6,
455    /// Keypad )
456    KeypadCloseParens = 0xB7,
457    /// Keypad {
458    KeypadOpenBrace = 0xB8,
459    /// Keypad }
460    KeypadCloseBrace = 0xB9,
461    /// Keypad Tab
462    KeypadTab = 0xBA,
463    /// Keypad Backspace
464    KeypadBackspace = 0xBB,
465    /// Keypad A
466    KeypadA = 0xBC,
467    /// Keypad B
468    KeypadB = 0xBD,
469    /// Keypad C
470    KeypadC = 0xBE,
471    /// Keypad D
472    KeypadD = 0xBF,
473    /// Keypad E
474    KeypadE = 0xC0,
475    /// Keypad F
476    KeypadF = 0xC1,
477    /// Keypad XOR
478    KeypadBitwiseXor = 0xC2,
479    /// Keypad ^
480    KeypadLogicalXor = 0xC3,
481    /// Keypad %
482    KeypadModulo = 0xC4,
483    /// Keypad <
484    KeypadLeftShift = 0xC5,
485    /// Keypad >
486    KeypadRightShift = 0xC6,
487    /// Keypad &
488    KeypadBitwiseAnd = 0xC7,
489    /// Keypad &&
490    KeypadLogicalAnd = 0xC8,
491    /// Keypad |
492    KeypadBitwiseOr = 0xC9,
493    /// Keypad ||
494    KeypadLogicalOr = 0xCA,
495    /// Keypad :
496    KeypadColon = 0xCB,
497    /// Keypad #
498    KeypadHash = 0xCC,
499    /// Keypad Space
500    KeypadSpace = 0xCD,
501    /// Keypad @
502    KeypadAt = 0xCE,
503    /// Keypad !
504    KeypadExclamation = 0xCF,
505    /// Keypad Memory Store
506    KeypadMemoryStore = 0xD0,
507    /// Keypad Memory Recall
508    KeypadMemoryRecall = 0xD1,
509    /// Keypad Memory Clear
510    KeypadMemoryClear = 0xD2,
511    /// Keypad Memory Add
512    KeypadMemoryAdd = 0xD3,
513    /// Keypad Memory Subtract
514    KeypadMemorySubtract = 0xD4,
515    /// Keypad Memory Multiply
516    KeypadMemoryMultiply = 0xD5,
517    /// Keypad Memory Divice
518    KeypadMemoryDivide = 0xD6,
519    /// Keypad +/-
520    KeypadPositiveNegative = 0xD7,
521    /// Keypad Clear
522    KeypadClear = 0xD8,
523    /// Keypad Clear Entry
524    KeypadClearEntry = 0xD9,
525    /// Keypad Binary
526    KeypadBinary = 0xDA,
527    /// Keypad Octal
528    KeypadOctal = 0xDB,
529    /// Keypad Decimal
530    KeypadDecimal = 0xDC,
531    /// Keypad Hexadecimal
532    KeypadHexadecimal = 0xDD,
533    // 0xDE-0xDF: Reserved
534    /// Keyboard LeftControl
535    KeyboardLeftControl = 0xE0,
536    /// Keyboard LeftShift
537    KeyboardLeftShift = 0xE1,
538    /// Keyboard LeftAlt
539    KeyboardLeftAlt = 0xE2,
540    /// Keyboard LeftGUI (Footnote 11) (Footnote 33)
541    KeyboardLeftGUI = 0xE3,
542    /// Keyboard RightControl
543    KeyboardRightControl = 0xE4,
544    /// Keyboard RightShift
545    KeyboardRightShift = 0xE5,
546    /// Keyboard RightAlt
547    KeyboardRightAlt = 0xE6,
548    /// Keyboard RightGUI (Footnote 11) (Footnote 34)
549    KeyboardRightGUI = 0xE7,
550    /// Reserved keyboard values (used for all reserved / invalid values)
551    Reserved = 0xE8,
552    // 0xE8-0xFF: Reserved
553}
554
555impl From<u8> for KeyboardUsage {
556    fn from(k: u8) -> Self {
557        match k {
558            0x01 => Self::KeyboardErrorRollOver,
559            0x02 => Self::KeyboardPOSTFail,
560            0x03 => Self::KeyboardErrorUndefined,
561            0x04 => Self::KeyboardAa,
562            0x05 => Self::KeyboardBb,
563            0x06 => Self::KeyboardCc,
564            0x07 => Self::KeyboardDd,
565            0x08 => Self::KeyboardEe,
566            0x09 => Self::KeyboardFf,
567            0x0A => Self::KeyboardGg,
568            0x0B => Self::KeyboardHh,
569            0x0C => Self::KeyboardIi,
570            0x0D => Self::KeyboardJj,
571            0x0E => Self::KeyboardKk,
572            0x0F => Self::KeyboardLl,
573            0x10 => Self::KeyboardMm,
574            0x11 => Self::KeyboardNn,
575            0x12 => Self::KeyboardOo,
576            0x13 => Self::KeyboardPp,
577            0x14 => Self::KeyboardQq,
578            0x15 => Self::KeyboardRr,
579            0x16 => Self::KeyboardSs,
580            0x17 => Self::KeyboardTt,
581            0x18 => Self::KeyboardUu,
582            0x19 => Self::KeyboardVv,
583            0x1A => Self::KeyboardWw,
584            0x1B => Self::KeyboardXx,
585            0x1C => Self::KeyboardYy,
586            0x1D => Self::KeyboardZz,
587            0x1E => Self::Keyboard1Exclamation,
588            0x1F => Self::Keyboard2At,
589            0x20 => Self::Keyboard3Hash,
590            0x21 => Self::Keyboard4Dollar,
591            0x22 => Self::Keyboard5Percent,
592            0x23 => Self::Keyboard6Caret,
593            0x24 => Self::Keyboard7Ampersand,
594            0x25 => Self::Keyboard8Asterisk,
595            0x26 => Self::Keyboard9OpenParens,
596            0x27 => Self::Keyboard0CloseParens,
597            0x28 => Self::KeyboardEnter,
598            0x29 => Self::KeyboardEscape,
599            0x2A => Self::KeyboardBackspace,
600            0x2B => Self::KeyboardTab,
601            0x2C => Self::KeyboardSpacebar,
602            0x2D => Self::KeyboardDashUnderscore,
603            0x2E => Self::KeyboardEqualPlus,
604            0x2F => Self::KeyboardOpenBracketBrace,
605            0x30 => Self::KeyboardCloseBracketBrace,
606            0x31 => Self::KeyboardBackslashBar,
607            0x32 => Self::KeyboardNonUSHash,
608            0x33 => Self::KeyboardSemiColon,
609            0x34 => Self::KeyboardSingleDoubleQuote,
610            0x35 => Self::KeyboardBacktickTilde,
611            0x36 => Self::KeyboardCommaLess,
612            0x37 => Self::KeyboardPeriodGreater,
613            0x38 => Self::KeyboardSlashQuestion,
614            0x39 => Self::KeyboardCapsLock,
615            0x3A => Self::KeyboardF1,
616            0x3B => Self::KeyboardF2,
617            0x3C => Self::KeyboardF3,
618            0x3D => Self::KeyboardF4,
619            0x3E => Self::KeyboardF5,
620            0x3F => Self::KeyboardF6,
621            0x40 => Self::KeyboardF7,
622            0x41 => Self::KeyboardF8,
623            0x42 => Self::KeyboardF9,
624            0x43 => Self::KeyboardF10,
625            0x44 => Self::KeyboardF11,
626            0x45 => Self::KeyboardF12,
627            0x46 => Self::KeyboardPrintScreen,
628            0x47 => Self::KeyboardScrollLock,
629            0x48 => Self::KeyboardPause,
630            0x49 => Self::KeyboardInsert,
631            0x4A => Self::KeyboardHome,
632            0x4B => Self::KeyboardPageUp,
633            0x4C => Self::KeyboardDelete,
634            0x4D => Self::KeyboardEnd,
635            0x4E => Self::KeyboardPageDown,
636            0x4F => Self::KeyboardRightArrow,
637            0x50 => Self::KeyboardLeftArrow,
638            0x51 => Self::KeyboardDownArrow,
639            0x52 => Self::KeyboardUpArrow,
640            0x53 => Self::KeypadNumLock,
641            0x54 => Self::KeypadDivide,
642            0x55 => Self::KeypadMultiply,
643            0x56 => Self::KeypadMinus,
644            0x57 => Self::KeypadPlus,
645            0x58 => Self::KeypadEnter,
646            0x59 => Self::Keypad1End,
647            0x5A => Self::Keypad2DownArrow,
648            0x5B => Self::Keypad3PageDown,
649            0x5C => Self::Keypad4LeftArrow,
650            0x5D => Self::Keypad5,
651            0x5E => Self::Keypad6RightArrow,
652            0x5F => Self::Keypad7Home,
653            0x60 => Self::Keypad8UpArrow,
654            0x61 => Self::Keypad9PageUp,
655            0x62 => Self::Keypad0Insert,
656            0x63 => Self::KeypadPeriodDelete,
657            0x64 => Self::KeyboardNonUSSlash,
658            0x65 => Self::KeyboardApplication,
659            0x66 => Self::KeyboardPower,
660            0x67 => Self::KeypadEqual,
661            0x68 => Self::KeyboardF13,
662            0x69 => Self::KeyboardF14,
663            0x6A => Self::KeyboardF15,
664            0x6B => Self::KeyboardF16,
665            0x6C => Self::KeyboardF17,
666            0x6D => Self::KeyboardF18,
667            0x6E => Self::KeyboardF19,
668            0x6F => Self::KeyboardF20,
669            0x70 => Self::KeyboardF21,
670            0x71 => Self::KeyboardF22,
671            0x72 => Self::KeyboardF23,
672            0x73 => Self::KeyboardF24,
673            0x74 => Self::KeyboardExecute,
674            0x75 => Self::KeyboardHelp,
675            0x76 => Self::KeyboardMenu,
676            0x77 => Self::KeyboardSelect,
677            0x78 => Self::KeyboardStop,
678            0x79 => Self::KeyboardAgain,
679            0x7A => Self::KeyboardUndo,
680            0x7B => Self::KeyboardCut,
681            0x7C => Self::KeyboardCopy,
682            0x7D => Self::KeyboardPaste,
683            0x7E => Self::KeyboardFind,
684            0x7F => Self::KeyboardMute,
685            0x80 => Self::KeyboardVolumeUp,
686            0x81 => Self::KeyboardVolumeDown,
687            0x82 => Self::KeyboardLockingCapsLock,
688            0x83 => Self::KeyboardLockingNumLock,
689            0x84 => Self::KeyboardLockingScrollLock,
690            0x85 => Self::KeypadComma,
691            0x86 => Self::KeypadEqualSign,
692            0x87 => Self::KeyboardInternational1,
693            0x88 => Self::KeyboardInternational2,
694            0x89 => Self::KeyboardInternational3,
695            0x8A => Self::KeyboardInternational4,
696            0x8B => Self::KeyboardInternational5,
697            0x8C => Self::KeyboardInternational6,
698            0x8D => Self::KeyboardInternational7,
699            0x8E => Self::KeyboardInternational8,
700            0x8F => Self::KeyboardInternational9,
701            0x90 => Self::KeyboardLANG1,
702            0x91 => Self::KeyboardLANG2,
703            0x92 => Self::KeyboardLANG3,
704            0x93 => Self::KeyboardLANG4,
705            0x94 => Self::KeyboardLANG5,
706            0x95 => Self::KeyboardLANG6,
707            0x96 => Self::KeyboardLANG7,
708            0x97 => Self::KeyboardLANG8,
709            0x98 => Self::KeyboardLANG9,
710            0x99 => Self::KeyboardAlternateErase,
711            0x9A => Self::KeyboardSysReqAttention,
712            0x9B => Self::KeyboardCancel,
713            0x9C => Self::KeyboardClear,
714            0x9D => Self::KeyboardPrior,
715            0x9E => Self::KeyboardReturn,
716            0x9F => Self::KeyboardSeparator,
717            0xA0 => Self::KeyboardOut,
718            0xA1 => Self::KeyboardOper,
719            0xA2 => Self::KeyboardClearAgain,
720            0xA3 => Self::KeyboardCrSelProps,
721            0xA4 => Self::KeyboardExSel,
722            0xB0 => Self::Keypad00,
723            0xB1 => Self::Keypad000,
724            0xB2 => Self::ThousandsSeparator,
725            0xB3 => Self::DecimalSeparator,
726            0xB4 => Self::CurrencyUnit,
727            0xB5 => Self::CurrencySubunit,
728            0xB6 => Self::KeypadOpenParens,
729            0xB7 => Self::KeypadCloseParens,
730            0xB8 => Self::KeypadOpenBrace,
731            0xB9 => Self::KeypadCloseBrace,
732            0xBA => Self::KeypadTab,
733            0xBB => Self::KeypadBackspace,
734            0xBC => Self::KeypadA,
735            0xBD => Self::KeypadB,
736            0xBE => Self::KeypadC,
737            0xBF => Self::KeypadD,
738            0xC0 => Self::KeypadE,
739            0xC1 => Self::KeypadF,
740            0xC2 => Self::KeypadBitwiseXor,
741            0xC3 => Self::KeypadLogicalXor,
742            0xC4 => Self::KeypadModulo,
743            0xC5 => Self::KeypadLeftShift,
744            0xC6 => Self::KeypadRightShift,
745            0xC7 => Self::KeypadBitwiseAnd,
746            0xC8 => Self::KeypadLogicalAnd,
747            0xC9 => Self::KeypadBitwiseOr,
748            0xCA => Self::KeypadLogicalOr,
749            0xCB => Self::KeypadColon,
750            0xCC => Self::KeypadHash,
751            0xCD => Self::KeypadSpace,
752            0xCE => Self::KeypadAt,
753            0xCF => Self::KeypadExclamation,
754            0xD0 => Self::KeypadMemoryStore,
755            0xD1 => Self::KeypadMemoryRecall,
756            0xD2 => Self::KeypadMemoryClear,
757            0xD3 => Self::KeypadMemoryAdd,
758            0xD4 => Self::KeypadMemorySubtract,
759            0xD5 => Self::KeypadMemoryMultiply,
760            0xD6 => Self::KeypadMemoryDivide,
761            0xD7 => Self::KeypadPositiveNegative,
762            0xD8 => Self::KeypadClear,
763            0xD9 => Self::KeypadClearEntry,
764            0xDA => Self::KeypadBinary,
765            0xDB => Self::KeypadOctal,
766            0xDC => Self::KeypadDecimal,
767            0xDD => Self::KeypadHexadecimal,
768            0xE0 => Self::KeyboardLeftControl,
769            0xE1 => Self::KeyboardLeftShift,
770            0xE2 => Self::KeyboardLeftAlt,
771            0xE3 => Self::KeyboardLeftGUI,
772            0xE4 => Self::KeyboardRightControl,
773            0xE5 => Self::KeyboardRightShift,
774            0xE6 => Self::KeyboardRightAlt,
775            0xE7 => Self::KeyboardRightGUI,
776            _ => Self::Reserved,
777        }
778    }
779}
780
781/// MediaKeyboardReport describes a report and descriptor that can be used to
782/// send consumer control commands to the host.
783///
784/// This is commonly used for sending media player for keyboards with media player
785/// keys, but can be used for all sorts of Consumer Page functionality.
786///
787/// Reference: <https://usb.org/sites/default/files/hut1_2.pdf>
788///
789#[gen_hid_descriptor(
790    (collection = APPLICATION, usage_page = CONSUMER, usage = CONSUMER_CONTROL) = {
791        (usage_page = CONSUMER, usage_min = 0x00, usage_max = 0x514) = {
792            #[item_settings data,array,absolute,not_null] usage_id=input;
793        };
794    }
795)]
796#[allow(dead_code)]
797pub struct MediaKeyboardReport {
798    pub usage_id: u16,
799}
800
801/// Media player usage ids that can be used in MediaKeyboardReport
802#[non_exhaustive]
803#[repr(u16)]
804#[derive(Clone, Copy, Debug, PartialEq)]
805#[cfg_attr(feature = "defmt", derive(defmt::Format))]
806pub enum MediaKey {
807    Zero = 0x00,
808    Play = 0xB0,
809    Pause = 0xB1,
810    Record = 0xB2,
811    NextTrack = 0xB5,
812    PrevTrack = 0xB6,
813    Stop = 0xB7,
814    RandomPlay = 0xB9,
815    Repeat = 0xBC,
816    PlayPause = 0xCD,
817    Mute = 0xE2,
818    VolumeIncrement = 0xE9,
819    VolumeDecrement = 0xEA,
820    Reserved = 0xEB,
821}
822
823impl From<MediaKey> for u16 {
824    fn from(mk: MediaKey) -> u16 {
825        mk as u16
826    }
827}
828
829impl From<u8> for MediaKey {
830    fn from(k: u8) -> Self {
831        match k {
832            0x00 => Self::Zero,
833            0xB0 => Self::Play,
834            0xB1 => Self::Pause,
835            0xB2 => Self::Record,
836            0xB5 => Self::NextTrack,
837            0xB6 => Self::PrevTrack,
838            0xB7 => Self::Stop,
839            0xB9 => Self::RandomPlay,
840            0xBC => Self::Repeat,
841            0xCD => Self::PlayPause,
842            0xE2 => Self::Mute,
843            0xE9 => Self::VolumeIncrement,
844            0xEA => Self::VolumeDecrement,
845            _ => Self::Reserved,
846        }
847    }
848}
849
850impl From<u16> for MediaKey {
851    fn from(k: u16) -> Self {
852        (k as u8).into()
853    }
854}
855
856/// SystemControlReport describes a report and descriptor that can be used to
857/// send system control commands to the host.
858///
859/// This is commonly used to enter sleep mode, power down, hibernate, etc.
860///
861/// Reference: <https://usb.org/sites/default/files/hut1_2.pdf>
862///
863/// NOTE: For Windows compatibility usage_min should start at 0x81
864/// NOTE: For macOS scrollbar compatibility, logical minimum should start from 1
865///       (scrollbars disappear if logical_min is set to 0)
866#[gen_hid_descriptor(
867    (collection = APPLICATION, usage_page = GENERIC_DESKTOP, usage = SYSTEM_CONTROL) = {
868        (usage_min = 0x81, usage_max = 0xB7, logical_min = 1) = {
869            #[item_settings data,array,absolute,not_null] usage_id=input;
870        };
871    }
872)]
873#[allow(dead_code)]
874pub struct SystemControlReport {
875    pub usage_id: u8,
876}
877
878/// System control usage ids to use with SystemControlReport
879#[non_exhaustive]
880#[repr(u8)]
881#[derive(Clone, Copy, Debug, PartialEq)]
882#[cfg_attr(feature = "defmt", derive(defmt::Format))]
883pub enum SystemControlKey {
884    PowerDown = 0x81,
885    Sleep = 0x82,
886    WakeUp = 0x83,
887    ContextMenu = 0x84,
888    MainMenu = 0x85,
889    AppMenu = 0x86,
890    MenuHelp = 0x87,
891    MenuExit = 0x88,
892    MenuSelect = 0x89,
893    MenuRight = 0x8A,
894    MenuLeft = 0x8B,
895    MenuUp = 0x8C,
896    MenuDown = 0x8D,
897    ColdRestart = 0x8E,
898    WarmRestart = 0x8F,
899    DpadUp = 0x90,
900    DpadDown = 0x91,
901    DpadRight = 0x92,
902    DpadLeft = 0x93,
903    SystemFunctionShift = 0x97,
904    SystemFunctionShiftLock = 0x98,
905    SystemDismissNotification = 0x9A,
906    SystemDoNotDisturb = 0x9B,
907    Dock = 0xA0,
908    Undock = 0xA1,
909    Setup = 0xA2,
910    Break = 0xA3,
911    DebuggerBreak = 0xA4,
912    ApplicationBreak = 0xA5,
913    ApplicationDebuggerBreak = 0xA6,
914    SpeakerMute = 0xA7,
915    Hibernate = 0xA8,
916    DisplayInvert = 0xB0,
917    DisplayInternal = 0xB1,
918    DisplayExternal = 0xB2,
919    DisplayBoth = 0xB3,
920    DisplayDual = 0xB4,
921    DisplayToggleInternalExternal = 0xB5,
922    DisplaySwapPrimarySecondary = 0xB6,
923    DisplayLcdAutoscale = 0xB7,
924    // Use this reserved value to represent all reserved keys / invalid values
925    Reserved = 0xB8,
926}
927
928impl From<SystemControlKey> for u8 {
929    fn from(sck: SystemControlKey) -> u8 {
930        sck as u8
931    }
932}
933
934impl From<u8> for SystemControlKey {
935    fn from(k: u8) -> Self {
936        match k {
937            0x81 => Self::PowerDown,
938            0x82 => Self::Sleep,
939            0x83 => Self::WakeUp,
940            0x84 => Self::ContextMenu,
941            0x85 => Self::MainMenu,
942            0x86 => Self::AppMenu,
943            0x87 => Self::MenuHelp,
944            0x88 => Self::MenuExit,
945            0x89 => Self::MenuSelect,
946            0x8A => Self::MenuRight,
947            0x8B => Self::MenuLeft,
948            0x8C => Self::MenuUp,
949            0x8D => Self::MenuDown,
950            0x8E => Self::ColdRestart,
951            0x8F => Self::WarmRestart,
952            0x90 => Self::DpadUp,
953            0x91 => Self::DpadDown,
954            0x92 => Self::DpadRight,
955            0x93 => Self::DpadLeft,
956            0x97 => Self::SystemFunctionShift,
957            0x98 => Self::SystemFunctionShiftLock,
958            0x9A => Self::SystemDismissNotification,
959            0x9B => Self::SystemDoNotDisturb,
960            0xA0 => Self::Dock,
961            0xA1 => Self::Undock,
962            0xA2 => Self::Setup,
963            0xA3 => Self::Break,
964            0xA4 => Self::DebuggerBreak,
965            0xA5 => Self::ApplicationBreak,
966            0xA6 => Self::ApplicationDebuggerBreak,
967            0xA7 => Self::SpeakerMute,
968            0xA8 => Self::Hibernate,
969            0xB0 => Self::DisplayInvert,
970            0xB1 => Self::DisplayInternal,
971            0xB2 => Self::DisplayExternal,
972            0xB3 => Self::DisplayBoth,
973            0xB4 => Self::DisplayDual,
974            0xB5 => Self::DisplayToggleInternalExternal,
975            0xB6 => Self::DisplaySwapPrimarySecondary,
976            0xB7 => Self::DisplayLcdAutoscale,
977            _ => Self::Reserved,
978        }
979    }
980}
981
982/// CtapReport describes a report and its companion descriptor that can be
983/// used to present a FIDO-compatible authenticator device to the host.
984#[gen_hid_descriptor(
985    (collection = APPLICATION, usage_page = FIDO_ALLIANCE, usage = U2F_AUTHENTICATOR_DEVICE) = {
986        (usage = INPUT_REPORT_DATA, logical_min = 0x0) = {
987            #[item_settings data,variable,absolute] data_in=input;
988        };
989        (usage = OUTPUT_REPORT_DATA, logical_min = 0x0) = {
990            #[item_settings data,variable,absolute] data_out=output;
991        };
992    }
993)]
994#[allow(dead_code)]
995pub struct CtapReport {
996    pub data_in: [u8; 64],
997    pub data_out: [u8; 64],
998}