for (;;)\r
{\r
CheckJoystickMovement();\r
- \r
+ \r
/* Must throw away unused bytes from the host, or it will lock up while waiting for the device */\r
while (CDC_Device_BytesReceived(&VirtualSerial_CDC_Interface))\r
CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface);\r
\r
.ReportINEndpointNumber = GENERIC_IN_EPNUM,\r
.ReportINEndpointSize = GENERIC_EPSIZE,\r
- \r
- .ReportINBufferSize = GENERIC_REPORT_SIZE,\r
},\r
};\r
\r
\r
.ReportINEndpointNumber = JOYSTICK_EPNUM,\r
.ReportINEndpointSize = JOYSTICK_EPSIZE,\r
- \r
- .ReportINBufferSize = sizeof(USB_JoystickReport_Data_t),\r
},\r
};\r
\r
\r
.ReportINEndpointNumber = KEYBOARD_EPNUM,\r
.ReportINEndpointSize = KEYBOARD_EPSIZE,\r
-\r
- .ReportINBufferSize = sizeof(USB_KeyboardReport_Data_t),\r
},\r
};\r
\r
\r
.ReportINEndpointNumber = KEYBOARD_IN_EPNUM,\r
.ReportINEndpointSize = HID_EPSIZE,\r
- \r
- .ReportINBufferSize = sizeof(USB_KeyboardReport_Data_t),\r
},\r
};\r
\r
\r
.ReportINEndpointNumber = MOUSE_IN_EPNUM,\r
.ReportINEndpointSize = HID_EPSIZE,\r
-\r
- .ReportINBufferSize = sizeof(USB_MouseReport_Data_t),\r
},\r
\r
.State =\r
\r
.ReportINEndpointNumber = MOUSE_EPNUM,\r
.ReportINEndpointSize = MOUSE_EPSIZE,\r
-\r
- .ReportINBufferSize = sizeof(USB_MouseReport_Data_t),\r
},\r
};\r
\r
{\r
Endpoint_ClearSETUP(); \r
\r
- uint8_t ReportINData[HIDInterfaceInfo->Config.ReportINBufferSize];\r
+ uint8_t ReportINData[HID_MAX_REPORT_SIZE];\r
uint16_t ReportINSize;\r
uint8_t ReportID = (USB_ControlRequest.wValue & 0xFF);\r
\r
\r
void HID_Device_USBTask(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo)\r
{\r
+ static uint8_t PreviousReportINData[HID_MAX_REPORT_SIZE];\r
+\r
if (USB_DeviceState != DEVICE_STATE_Configured)\r
return;\r
\r
Endpoint_SelectEndpoint(HIDInterfaceInfo->Config.ReportINEndpointNumber);\r
\r
- if (Endpoint_IsReadWriteAllowed() &&\r
- !(HIDInterfaceInfo->State.IdleCount && HIDInterfaceInfo->State.IdleMSRemaining))\r
+ if (Endpoint_IsReadWriteAllowed())\r
{\r
- if (HIDInterfaceInfo->State.IdleCount && !(HIDInterfaceInfo->State.IdleMSRemaining))\r
- HIDInterfaceInfo->State.IdleMSRemaining = HIDInterfaceInfo->State.IdleCount;\r
-\r
- uint8_t ReportINData[HIDInterfaceInfo->Config.ReportINBufferSize];\r
- uint16_t ReportINSize;\r
+ uint8_t ReportINData[HID_MAX_REPORT_SIZE];\r
uint8_t ReportID = 0;\r
+ uint16_t ReportINSize;\r
\r
memset(ReportINData, 0, sizeof(ReportINData));\r
\r
- ReportINSize = CALLBACK_HID_Device_CreateHIDReport(HIDInterfaceInfo, &ReportID, ReportINData);\r
+ ReportINSize = CALLBACK_HID_Device_CreateHIDReport(HIDInterfaceInfo, &ReportID, ReportINData);\r
\r
- if (ReportINSize)\r
+ bool StatesChanged = (memcmp(ReportINData, PreviousReportINData, ReportINSize) != 0);\r
+ bool IdlePeriodElapsed = (HIDInterfaceInfo->State.IdleCount && !(HIDInterfaceInfo->State.IdleMSRemaining));\r
+ \r
+ memcpy(PreviousReportINData, ReportINData, ReportINSize);\r
+\r
+ if (ReportINSize && (StatesChanged || IdlePeriodElapsed))\r
{\r
+ HIDInterfaceInfo->State.IdleMSRemaining = HIDInterfaceInfo->State.IdleCount;\r
+\r
if (ReportID)\r
Endpoint_Write_Stream_LE(&ReportID, sizeof(ReportID), NO_STREAM_CALLBACK);\r
\r
#endif\r
\r
/* Public Interface - May be used in end-application: */\r
+ /* Macros: */\r
+ #if !defined(HID_MAX_REPORT_SIZE)\r
+ /** Maximum size of an IN report which can be generated by the device and sent to the host, in bytes.\r
+ *\r
+ * \note If larger reports than the default specified here are to be generated by the device, this\r
+ * value can be overridden by defining this token to the required value in the project makefile\r
+ * and passing it to the compiler via the -D switch.\r
+ */\r
+ #define HID_MAX_REPORT_SIZE 16\r
+ #endif\r
+ \r
/* Type Defines: */\r
/** Class state structure. An instance of this structure should be made for each HID interface\r
* within the user application, and passed to each of the HID class driver functions as the\r
uint8_t InterfaceNumber; /**< Interface number of the HID interface within the device */\r
\r
uint8_t ReportINEndpointNumber; /**< Endpoint number of the HID interface's IN report endpoint */\r
- uint16_t ReportINEndpointSize; /**< Size in bytes of the HID interface's IN report endpoint */\r
- \r
- uint8_t ReportINBufferSize; /**< Size of the largest possible report to send to the host, for\r
- * buffer allocation purposes\r
- */\r
+ uint16_t ReportINEndpointSize; /**< Size in bytes of the HID interface's IN report endpoint */ \r
} Config; /**< Config data for the USB class interface within the device. All elements in this section\r
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.\r
*/ \r
struct\r
{\r
bool UsingReportProtocol; /**< Indicates if the HID interface is set to Boot or Report protocol mode */\r
- uint16_t IdleCount; /**< Report idle period, in ms, set by the host */\r
- uint16_t IdleMSRemaining; /**< Total number of ms remaining before the idle period elapsed - this should be\r
+ uint16_t IdleCount; /**< Report idle period, in mS, set by the host */\r
+ uint16_t IdleMSRemaining; /**< Total number of mS remaining before the idle period elapsed - this should be\r
* decremented by the user application if non-zero each millisecond */ \r
} State; /**< State data for the USB class interface within the device. All elements in this section\r
* are reset to their defaults when the interface is enumerated.\r
\r
.ReportINEndpointNumber = KEYBOARD_EPNUM,\r
.ReportINEndpointSize = KEYBOARD_EPSIZE,\r
- \r
- .ReportINBufferSize = sizeof(USB_KeyboardReport_Data_t),\r
},\r
};\r
\r