@@ -3,15 +3,140 @@ use core::{future::Future, sync::atomic::Ordering};
33
44use embassy_usb:: class:: hid:: ReadError ;
55use embassy_usb:: driver:: EndpointError ;
6+ use serde:: Serialize ;
7+ use usbd_hid:: descriptor:: generator_prelude:: * ;
68use usbd_hid:: descriptor:: { AsInputReport , MediaKeyboardReport , MouseReport , SystemControlReport } ;
79
810use crate :: CONNECTION_STATE ;
911use crate :: channel:: KEYBOARD_REPORT_CHANNEL ;
10- use crate :: descriptor:: KeyboardReport ;
1112use crate :: state:: ConnectionState ;
1213#[ cfg( not( feature = "_no_usb" ) ) ]
1314use crate :: usb:: USB_REMOTE_WAKEUP ;
1415
16+ /// KeyboardReport describes a report and its companion descriptor that can be
17+ /// used to send keyboard button presses to a host and receive the status of the
18+ /// keyboard LEDs.
19+ #[ gen_hid_descriptor(
20+ ( collection = APPLICATION , usage_page = GENERIC_DESKTOP , usage = KEYBOARD ) = {
21+ ( usage_page = KEYBOARD , usage_min = 0xE0 , usage_max = 0xE7 ) = {
22+ #[ packed_bits = 8 ] #[ item_settings( data, variable, absolute) ] modifier=input;
23+ } ;
24+ ( logical_min = 0 , ) = {
25+ #[ item_settings( constant, variable, absolute) ] reserved=input;
26+ } ;
27+ ( usage_page = LEDS , usage_min = 0x01 , usage_max = 0x05 ) = {
28+ #[ packed_bits = 5 ] #[ item_settings( data, variable, absolute) ] leds=output;
29+ } ;
30+ ( usage_page = KEYBOARD , usage_min = 0x00 , usage_max = 0xDD ) = {
31+ #[ item_settings( data, array, absolute) ] keycodes=input;
32+ } ;
33+ }
34+ ) ]
35+ #[ allow( dead_code) ]
36+ #[ derive( Default ) ]
37+ #[ cfg_attr( feature = "defmt" , derive( defmt:: Format ) ) ]
38+ pub struct KeyboardReport {
39+ pub modifier : u8 , // ModifierCombination
40+ pub reserved : u8 ,
41+ pub leds : u8 , // LedIndicator
42+ pub keycodes : [ u8 ; 6 ] ,
43+ }
44+
45+ #[ gen_hid_descriptor(
46+ ( collection = APPLICATION , usage_page = 0xFF60 , usage = 0x61 ) = {
47+ ( usage = 0x62 , logical_min = 0x0 ) = {
48+ #[ item_settings( data, variable, absolute) ] input_data=input;
49+ } ;
50+ ( usage = 0x63 , logical_min = 0x0 ) = {
51+ #[ item_settings( data, variable, absolute) ] output_data=output;
52+ } ;
53+ }
54+ ) ]
55+ #[ derive( Default ) ]
56+ pub struct ViaReport {
57+ pub ( crate ) input_data : [ u8 ; 32 ] ,
58+ pub ( crate ) output_data : [ u8 ; 32 ] ,
59+ }
60+
61+ /// Predefined report ids for composite hid report.
62+ /// Should be same with `#[gen_hid_descriptor]`
63+ /// DO NOT EDIT
64+ #[ repr( u8 ) ]
65+ #[ derive( Debug , Copy , Clone , Default , PartialEq , Eq , PartialOrd , Ord , Serialize ) ]
66+
67+ pub enum CompositeReportType {
68+ #[ default]
69+ None = 0x00 ,
70+ Mouse = 0x01 ,
71+ Media = 0x02 ,
72+ System = 0x03 ,
73+ }
74+
75+ impl CompositeReportType {
76+ fn from_u8 ( report_id : u8 ) -> Self {
77+ match report_id {
78+ 0x01 => Self :: Mouse ,
79+ 0x02 => Self :: Media ,
80+ 0x03 => Self :: System ,
81+ _ => Self :: None ,
82+ }
83+ }
84+ }
85+
86+ /// A composite hid report which contains mouse, consumer, system reports.
87+ /// Report id is used to distinguish from them.
88+ #[ gen_hid_descriptor(
89+ ( collection = APPLICATION , usage_page = GENERIC_DESKTOP , usage = MOUSE ) = {
90+ ( collection = PHYSICAL , usage = POINTER ) = {
91+ ( report_id = 0x01 , ) = {
92+ ( usage_page = BUTTON , usage_min = BUTTON_1 , usage_max = BUTTON_8 ) = {
93+ #[ packed_bits = 8 ] #[ item_settings( data, variable, absolute) ] buttons=input;
94+ } ;
95+ ( usage_page = GENERIC_DESKTOP , ) = {
96+ ( usage = X , ) = {
97+ #[ item_settings( data, variable, relative) ] x=input;
98+ } ;
99+ ( usage = Y , ) = {
100+ #[ item_settings( data, variable, relative) ] y=input;
101+ } ;
102+ ( usage = WHEEL , ) = {
103+ #[ item_settings( data, variable, relative) ] wheel=input;
104+ } ;
105+ } ;
106+ ( usage_page = CONSUMER , ) = {
107+ ( usage = AC_PAN , ) = {
108+ #[ item_settings( data, variable, relative) ] pan=input;
109+ } ;
110+ } ;
111+ } ;
112+ } ;
113+ } ,
114+ ( collection = APPLICATION , usage_page = CONSUMER , usage = CONSUMER_CONTROL ) = {
115+ ( report_id = 0x02 , ) = {
116+ ( usage_page = CONSUMER , usage_min = 0x00 , usage_max = 0x514 ) = {
117+ #[ item_settings( data, array, absolute, not_null) ] media_usage_id=input;
118+ }
119+ } ;
120+ } ,
121+ ( collection = APPLICATION , usage_page = GENERIC_DESKTOP , usage = SYSTEM_CONTROL ) = {
122+ ( report_id = 0x03 , ) = {
123+ ( usage_min = 0x81 , usage_max = 0xB7 , logical_min = 1 ) = {
124+ #[ item_settings( data, array, absolute, not_null) ] system_usage_id=input;
125+ } ;
126+ } ;
127+ }
128+ ) ]
129+ #[ derive( Default , Serialize ) ]
130+ pub struct CompositeReport {
131+ pub ( crate ) buttons : u8 , // MouseButtons
132+ pub ( crate ) x : i8 ,
133+ pub ( crate ) y : i8 ,
134+ pub ( crate ) wheel : i8 , // Scroll down (negative) or up (positive) this many units
135+ pub ( crate ) pan : i8 , // Scroll left (negative) or right (positive) this many units
136+ pub ( crate ) media_usage_id : u16 ,
137+ pub ( crate ) system_usage_id : u8 ,
138+ }
139+
15140#[ derive( Debug , Clone ) ]
16141pub enum Report {
17142 /// Normal keyboard hid report
0 commit comments