1212
1313#include <USB.h>
1414
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+
1532static struct protocol_config_t protocol_config ;
1633
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+ };
2182
2283void usb_init ()
2384{
@@ -29,64 +90,30 @@ void usb_task()
2990{
3091 USB_USBTask ();
3192
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+ }
8297
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+ }
87102
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 ;
90117 }
91118}
92119
@@ -104,90 +131,79 @@ void EVENT_USB_Device_Disconnect(void)
104131{
105132}
106133
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+ }
110141
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
114151 */
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 )
116158{
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+ }
175187 }
176188}
177189
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
180197 */
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 )
182204{
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+ }
193209}
0 commit comments