12
12
13
13
#include <USB.h>
14
14
15
+ /** Buffer to hold the previously generated HID report, for comparison purposes inside the HID class driver. */
16
+ static u8 openinput_hid_report_buff [sizeof (struct oi_report_t )];
17
+ static u8 mouse_hid_report_buff [sizeof (struct mouse_report )];
18
+ static u8 keyboard_hid_report_buff [sizeof (struct keyboard_report )];
19
+
20
+ static u8 new_oi_report ;
21
+ static struct oi_report_t oi_report ;
22
+ static u8 oi_report_size ;
23
+
24
+ static u8 new_mouse_report ;
25
+ static struct mouse_report mouse_report ;
26
+ static u8 mouse_report_size ;
27
+
28
+ static u8 new_keyboard_report ;
29
+ static struct keyboard_report keyboard_report ;
30
+ static u8 keyboard_report_size ;
31
+
15
32
static struct protocol_config_t protocol_config ;
16
33
17
- void usb_attach_protocol_config (struct protocol_config_t config )
18
- {
19
- protocol_config = config ;
20
- }
34
+ /** LUFA HID Class driver interface configuration and state information. This structure is
35
+ * passed to all HID Class driver functions, so that multiple instances of the same class
36
+ * within a device can be differentiated from one another.
37
+ */
38
+ USB_ClassInfo_HID_Device_t openinput_hid_interface = {
39
+ .Config =
40
+ {
41
+ .InterfaceNumber = 0 ,
42
+ .ReportINEndpoint =
43
+ {
44
+ .Address = 0x81 ,
45
+ .Size = 64 ,
46
+ .Banks = 1 ,
47
+ },
48
+ .PrevReportINBuffer = openinput_hid_report_buff ,
49
+ .PrevReportINBufferSize = sizeof (openinput_hid_report_buff ),
50
+ },
51
+ };
52
+
53
+ USB_ClassInfo_HID_Device_t mouse_hid_interface = {
54
+ .Config =
55
+ {
56
+ .InterfaceNumber = 1 ,
57
+ .ReportINEndpoint =
58
+ {
59
+ .Address = 0x83 ,
60
+ .Size = 64 ,
61
+ .Banks = 1 ,
62
+ },
63
+ .PrevReportINBuffer = mouse_hid_report_buff ,
64
+ .PrevReportINBufferSize = sizeof (mouse_hid_report_buff ),
65
+ },
66
+ };
67
+
68
+ USB_ClassInfo_HID_Device_t keyboard_hid_interface = {
69
+ .Config =
70
+ {
71
+ .InterfaceNumber = 2 ,
72
+ .ReportINEndpoint =
73
+ {
74
+ .Address = 0x84 ,
75
+ .Size = 64 ,
76
+ .Banks = 1 ,
77
+ },
78
+ .PrevReportINBuffer = keyboard_hid_report_buff ,
79
+ .PrevReportINBufferSize = sizeof (keyboard_hid_report_buff ),
80
+ },
81
+ };
21
82
22
83
void usb_init ()
23
84
{
@@ -29,64 +90,30 @@ void usb_task()
29
90
{
30
91
USB_USBTask ();
31
92
32
- /* openinput IN */
33
- Endpoint_SelectEndpoint (0x81 );
34
-
35
- /* Check if Endpoint Ready for Read/Write */
36
- if (Endpoint_IsReadWriteAllowed ()) {
37
- /* Write Report Data */
38
- // Endpoint_Write_Stream_LE(&report_data, sizeof(report_data), NULL);
39
-
40
- /* Finalize the stream transfer to send the last packet */
41
- // Endpoint_ClearIN();
42
- }
43
-
44
- /* openinput OUT */
45
- Endpoint_SelectEndpoint (0x02 );
46
-
47
- /* Check if Endpoint Ready for Read/Write */
48
- if (Endpoint_IsReadWriteAllowed ()) {
49
- /* Write Report Data */
50
- // Keyboard_ProcessLEDReport(Endpoint_Read_8());
51
-
52
- /* Handshake the OUT Endpoint - clear endpoint and ready for next report */
53
- Endpoint_ClearOUT ();
54
- }
55
-
56
- /* mouse IN */
57
- Endpoint_SelectEndpoint (0x83 );
58
-
59
- /* Check if Endpoint Ready for Read/Write */
60
- if (Endpoint_IsReadWriteAllowed ()) {
61
- /* Write Report Data */
62
- // Endpoint_Write_Stream_LE(&report_data, sizeof(report_data), NULL);
63
-
64
- /* Finalize the stream transfer to send the last packet */
65
- // Endpoint_ClearIN();
66
- }
67
-
68
- /* keyboard IN */
69
- Endpoint_SelectEndpoint (0x84 );
70
-
71
- /* Check if Endpoint Ready for Read/Write */
72
- if (Endpoint_IsReadWriteAllowed ()) {
73
- /* Write Report Data */
74
- // Endpoint_Write_Stream_LE(&report_data, sizeof(report_data), NULL);
75
-
76
- /* Finalize the stream transfer to send the last packet */
77
- // Endpoint_ClearIN();
78
- }
79
-
80
- /* keyboard OUT */
81
- Endpoint_SelectEndpoint (0x05 );
93
+ HID_Device_USBTask (& openinput_hid_interface );
94
+ HID_Device_USBTask (& mouse_hid_interface );
95
+ HID_Device_USBTask (& keyboard_hid_interface );
96
+ }
82
97
83
- /* Check if Endpoint Ready for Read/Write */
84
- if ( Endpoint_IsReadWriteAllowed ()) {
85
- /* Write Report Data */
86
- // Keyboard_ProcessLEDReport(Endpoint_Read_8());
98
+ void usb_attach_protocol_config ( struct protocol_config_t config )
99
+ {
100
+ protocol_config = config ;
101
+ }
87
102
88
- /* Handshake the OUT Endpoint - clear endpoint and ready for next report */
89
- Endpoint_ClearOUT ();
103
+ void usb_write_descriptor (u8 interface , u8 * report_data , u16 report_size )
104
+ {
105
+ if (interface == openinput_hid_interface .Config .InterfaceNumber ) {
106
+ memcpy (& oi_report , report_data , report_size );
107
+ oi_report_size = report_size ;
108
+ new_oi_report = 1 ;
109
+ } else if (interface == mouse_hid_interface .Config .InterfaceNumber ) {
110
+ memcpy (& mouse_report , report_data , report_size );
111
+ mouse_report_size = report_size ;
112
+ new_mouse_report = 1 ;
113
+ } else if (interface == keyboard_hid_interface .Config .InterfaceNumber ) {
114
+ memcpy (& keyboard_report , report_data , report_size );
115
+ keyboard_report_size = report_size ;
116
+ new_keyboard_report = 1 ;
90
117
}
91
118
}
92
119
@@ -104,90 +131,79 @@ void EVENT_USB_Device_Disconnect(void)
104
131
{
105
132
}
106
133
107
- struct oi_report_t oi_rep ;
108
- struct mouse_report mouse_rep ;
109
- struct keyboard_report keyb_rep ;
134
+ /** Event handler for the library USB Configuration Changed event. */
135
+ void EVENT_USB_Device_ConfigurationChanged (void )
136
+ {
137
+ HID_Device_ConfigureEndpoints (& openinput_hid_interface );
138
+ HID_Device_ConfigureEndpoints (& mouse_hid_interface );
139
+ HID_Device_ConfigureEndpoints (& keyboard_hid_interface );
140
+ }
110
141
111
- /** Event handler for the USB_ControlRequest event. This is used to catch and process control requests sent to
112
- * the device from the USB host before passing along unhandled control requests to the library for processing
113
- * internally.
142
+ /** HID class driver callback function for the creation of HID reports to the host.
143
+ *
144
+ * \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced
145
+ * \param[in,out] ReportID Report ID requested by the host if non-zero, otherwise callback should set to the generated report ID
146
+ * \param[in] ReportType Type of the report to create, either HID_REPORT_ITEM_In or HID_REPORT_ITEM_Feature
147
+ * \param[out] ReportData Pointer to a buffer where the created report should be stored
148
+ * \param[out] ReportSize Number of bytes written in the report (or zero if no report is to be sent)
149
+ *
150
+ * \return Boolean \c true to force the sending of the report, \c false to let the library determine if it needs to be sent
114
151
*/
115
- void EVENT_USB_Device_ControlRequest (void )
152
+ bool CALLBACK_HID_Device_CreateHIDReport (
153
+ USB_ClassInfo_HID_Device_t * const HIDInterfaceInfo ,
154
+ uint8_t * const ReportID ,
155
+ const uint8_t ReportType ,
156
+ void * ReportData ,
157
+ uint16_t * const ReportSize )
116
158
{
117
- struct oi_report_t oi_report ;
118
- uint8_t * ReportData ;
119
- uint8_t ReportSize ;
120
-
121
- /* Handle HID Class specific requests */
122
- switch (USB_ControlRequest .bRequest ) {
123
- case HID_REQ_GetReport :
124
- if (USB_ControlRequest .bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE )) {
125
- Endpoint_ClearSETUP ();
126
-
127
- // /* Determine if it is the mouse or the keyboard data that is being requested */
128
- // if (USB_ControlRequest.wIndex == 0) { // openinput
129
- // ReportData = (uint8_t *) &oi_rep;
130
- // ReportSize = sizeof(struct oi_report_t);
131
- // } else if (USB_ControlRequest.wIndex == 1) { // mouse
132
- // ReportData = (uint8_t *) &mouse_rep;
133
- // ReportSize = sizeof(struct mouse_report);
134
- // } else if (USB_ControlRequest.wIndex == 2) { // keyboard
135
- // ReportData = (uint8_t *) &keyb_rep;
136
- // ReportSize = sizeof(struct keyboard_report);
137
- // }
138
-
139
- // /* Write the report data to the control endpoint */
140
- // Endpoint_Write_Control_Stream_LE(ReportData, ReportSize);
141
- Endpoint_ClearOUT ();
142
- }
143
-
144
- break ;
145
- case HID_REQ_SetReport :
146
- if (USB_ControlRequest .bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE )) {
147
- Endpoint_ClearSETUP ();
148
-
149
- /* Wait until the report has been sent by the host */
150
- while (!(Endpoint_IsOUTReceived ())) {
151
- if (USB_DeviceState == DEVICE_STATE_Unattached )
152
- return ;
153
- }
154
-
155
- // if (USB_ControlRequest.wIndex == 0) {
156
- // // for (size_t i = 0; i < USB_ControlRequest.wLength; i++)
157
- // // {
158
- // // ((uint8_t *)(&oi_report))[i] = Endpoint_Read_8();
159
- // // }
160
- // // protocol_dispatch(protocol_config, (uint8_t *)(&oi_report), USB_ControlRequest.wLength);
161
-
162
- // } else if (USB_ControlRequest.wIndex == 2) {
163
- // /* Read in the LED report from the host */
164
- // uint8_t LEDStatus = Endpoint_Read_8();
165
- // }
166
-
167
- /* Read in the LED report from the host */
168
- uint8_t LEDStatus = Endpoint_Read_8 ();
169
-
170
- Endpoint_ClearOUT ();
171
- Endpoint_ClearStatusStage ();
172
- }
173
-
174
- break ;
159
+ /* Determine which interface must have its report generated */
160
+ if (HIDInterfaceInfo == & openinput_hid_interface ) {
161
+ if (new_oi_report == 1 ) {
162
+ memcpy (ReportData , & oi_report , oi_report_size );
163
+ * ReportSize = oi_report_size ;
164
+ new_oi_report = 0 ;
165
+ return true;
166
+ } else {
167
+ return false;
168
+ }
169
+ } else if (HIDInterfaceInfo == & mouse_hid_interface ) {
170
+ if (new_mouse_report == 1 ) {
171
+ memcpy (ReportData , & mouse_report , mouse_report_size );
172
+ * ReportSize = mouse_report_size ;
173
+ new_mouse_report = 0 ;
174
+ return true;
175
+ } else {
176
+ return false;
177
+ }
178
+ } else if (HIDInterfaceInfo == & keyboard_hid_interface ) {
179
+ if (new_keyboard_report == 1 ) {
180
+ memcpy (ReportData , & keyboard_report , keyboard_report_size );
181
+ * ReportSize = keyboard_report_size ;
182
+ new_keyboard_report = 0 ;
183
+ return true;
184
+ } else {
185
+ return false;
186
+ }
175
187
}
176
188
}
177
189
178
- /** Event handler for the USB_ConfigurationChanged event. This is fired when the host sets the current configuration
179
- * of the USB device after enumeration, and configures the keyboard and mouse device endpoints.
190
+ /** HID class driver callback function for the processing of HID reports from the host.
191
+ *
192
+ * \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced
193
+ * \param[in] ReportID Report ID of the received report from the host
194
+ * \param[in] ReportType The type of report that the host has sent, either HID_REPORT_ITEM_Out or HID_REPORT_ITEM_Feature
195
+ * \param[in] ReportData Pointer to a buffer where the received report has been stored
196
+ * \param[in] ReportSize Size in bytes of the received HID report
180
197
*/
181
- void EVENT_USB_Device_ConfigurationChanged (void )
198
+ void CALLBACK_HID_Device_ProcessHIDReport (
199
+ USB_ClassInfo_HID_Device_t * const HIDInterfaceInfo ,
200
+ const uint8_t ReportID ,
201
+ const uint8_t ReportType ,
202
+ const void * ReportData ,
203
+ const uint16_t ReportSize )
182
204
{
183
- /* Setup Openinput Report Endpoints */
184
- Endpoint_ConfigureEndpoint (0x81 , EP_TYPE_INTERRUPT , 0x40 , 1 ); // IN
185
- Endpoint_ConfigureEndpoint (0x02 , EP_TYPE_INTERRUPT , 0x40 , 1 ); // OUT
186
-
187
- /* Setup Mouse HID Report Endpoint */
188
- Endpoint_ConfigureEndpoint (0x83 , EP_TYPE_INTERRUPT , 0x40 , 1 ); // IN
189
-
190
- /* Setup Keyboard HID Report Endpoints */
191
- Endpoint_ConfigureEndpoint (0x84 , EP_TYPE_INTERRUPT , 0x40 , 1 ); // IN
192
- Endpoint_ConfigureEndpoint (0x05 , EP_TYPE_INTERRUPT , 0x40 , 1 ); // OUT
205
+ if (HIDInterfaceInfo == & openinput_hid_interface ) {
206
+ } else if (HIDInterfaceInfo == & keyboard_hid_interface ) {
207
+ protocol_dispatch (protocol_config , (u8 * ) ReportData , ReportSize );
208
+ }
193
209
}
0 commit comments