Make HID device class driver ignore the previous HID report comparison buffer when...
authorDean Camera <dean@fourwalledcubicle.com>
Mon, 26 Oct 2009 11:44:36 +0000 (11:44 +0000)
committerDean Camera <dean@fourwalledcubicle.com>
Mon, 26 Oct 2009 11:44:36 +0000 (11:44 +0000)
Demos/Device/ClassDriver/MassStorageKeyboard/MassStorageKeyboard.c
LUFA/Drivers/USB/Class/Device/HID.c
LUFA/Drivers/USB/Class/Device/HID.h

index fc7d136..033bc56 100644 (file)
 /** Buffer to hold the previously generated Keyboard HID report, for comparison purposes inside the HID class driver. */\r
 uint8_t PrevKeyboardHIDReportBuffer[sizeof(USB_KeyboardReport_Data_t)];\r
 \r
+/** LUFA HID Class driver interface configuration and state information. This structure is\r
+ *  passed to all HID Class driver functions, so that multiple instances of the same class\r
+ *  within a device can be differentiated from one another.\r
+ */\r
+USB_ClassInfo_HID_Device_t Keyboard_HID_Interface =\r
+       {\r
+               .Config =\r
+                       {\r
+                               .InterfaceNumber         = 1,\r
+\r
+                               .ReportINEndpointNumber  = KEYBOARD_EPNUM,\r
+                               .ReportINEndpointSize    = KEYBOARD_EPSIZE,\r
+\r
+                               .PrevReportINBuffer      = PrevKeyboardHIDReportBuffer,\r
+                               .PrevReportINBufferSize  = sizeof(PrevKeyboardHIDReportBuffer),\r
+                       },\r
+    };\r
+       \r
 /** LUFA Mass Storage Class driver interface configuration and state information. This structure is\r
  *  passed to all Mass Storage Class driver functions, so that multiple instances of the same class\r
  *  within a device can be differentiated from one another.\r
@@ -60,24 +78,6 @@ USB_ClassInfo_MS_Device_t Disk_MS_Interface =
                        },\r
        };\r
 \r
-/** LUFA HID Class driver interface configuration and state information. This structure is\r
- *  passed to all HID Class driver functions, so that multiple instances of the same class\r
- *  within a device can be differentiated from one another.\r
- */\r
-USB_ClassInfo_HID_Device_t Keyboard_HID_Interface =\r
-       {\r
-               .Config =\r
-                       {\r
-                               .InterfaceNumber         = 1,\r
-\r
-                               .ReportINEndpointNumber  = KEYBOARD_EPNUM,\r
-                               .ReportINEndpointSize    = KEYBOARD_EPSIZE,\r
-\r
-                               .PrevReportINBuffer      = PrevKeyboardHIDReportBuffer,\r
-                               .PrevReportINBufferSize  = sizeof(PrevKeyboardHIDReportBuffer),\r
-                       },\r
-    };\r
-\r
 /** Main program entry point. This routine contains the overall program flow, including initial\r
  *  setup of all components and the main program loop.\r
  */\r
index 403d494..26f5697 100644 (file)
@@ -157,12 +157,15 @@ void HID_Device_USBTask(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo)
 \r
                memset(ReportINData, 0, sizeof(ReportINData));\r
 \r
-               bool ForceSend = CALLBACK_HID_Device_CreateHIDReport(HIDInterfaceInfo, &ReportID, ReportINData, &ReportINSize);\r
-\r
-               bool StatesChanged     = (memcmp(ReportINData, HIDInterfaceInfo->Config.PrevReportINBuffer, ReportINSize) != 0);\r
+               bool ForceSend         = CALLBACK_HID_Device_CreateHIDReport(HIDInterfaceInfo, &ReportID, ReportINData, &ReportINSize);\r
+               bool StatesChanged     = false;\r
                bool IdlePeriodElapsed = (HIDInterfaceInfo->State.IdleCount && !(HIDInterfaceInfo->State.IdleMSRemaining));\r
                \r
-               memcpy(HIDInterfaceInfo->Config.PrevReportINBuffer, ReportINData, ReportINSize);\r
+               if (HIDInterfaceInfo->Config.PrevReportINBuffer != NULL)\r
+               {\r
+                       StatesChanged = (memcmp(ReportINData, HIDInterfaceInfo->Config.PrevReportINBuffer, ReportINSize) != 0);\r
+                       memcpy(HIDInterfaceInfo->Config.PrevReportINBuffer, ReportINData, ReportINSize);\r
+               }\r
 \r
                if (ReportINSize && (ForceSend || StatesChanged || IdlePeriodElapsed))\r
                {\r
index dee892d..4865a12 100644 (file)
                                        void*    PrevReportINBuffer; /** Pointer to a buffer where the previously created HID input report can be\r
                                                                      *  stored by the driver, for comparison purposes to detect report changes that\r
                                                                      *  must be sent immediately to the host. This should point to a buffer big enough\r
-                                                                     *  to hold the largest HID input report sent from the HID interface.\r
+                                                                     *  to hold the largest HID input report sent from the HID interface. If this is set\r
+                                                                                                 *  to NULL, it is up to the user to force transfers when needed in the \r
+                                                                                                 *  \ref CALLBACK_HID_Device_CreateHIDReport() callback function.\r
+                                                                                                 *\r
+                                                                                                 *  \note Due to the single buffer, the internal driver can only correctly compare\r
+                                                                                                 *        subsequent reports with identical report IDs. In multiple report devices,\r
+                                                                                                 *        this buffer should be set to NULL and the decision to send reports made\r
+                                                                                                 *        by the user application instead.\r
                                                                      */\r
                                        uint8_t  PrevReportINBufferSize; /** Size in bytes of the given input report buffer. This is used to create a\r
                                                                          *  second buffer of the same size within the driver so that subsequent reports\r