Skip to main content

usbd_hid/
descriptor.rs

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