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