Add to MouseHostWithParser and KeyboardHostWithParser demos to print out the report sizes when a valid device is connected.
break; \r
}\r
\r
+ printf("Total Reports: %d\r\n", HIDReportInfo.TotalDeviceReports);\r
+\r
+ for (uint8_t i = 0; i < HIDReportInfo.TotalDeviceReports; i++)\r
+ {\r
+ HID_ReportSizeInfo_t* CurrReportIDInfo = &HIDReportInfo.ReportIDSizes[i];\r
+ \r
+ /* Print out the byte sizes of each report within the device */\r
+ printf_P(PSTR(" + Report ID %d - In: %d bytes, Out: %d bytes, Feature: %d bytes\r\n"),\r
+ CurrReportIDInfo->ReportID,\r
+ ((CurrReportIDInfo->BitsIn >> 3) + (CurrReportIDInfo->BitsIn & 0x07)),\r
+ ((CurrReportIDInfo->BitsOut >> 3) + (CurrReportIDInfo->BitsOut & 0x07)),\r
+ ((CurrReportIDInfo->BitsFeature >> 3) + (CurrReportIDInfo->BitsFeature & 0x07)));\r
+ }\r
+\r
puts_P(PSTR("Keyboard Enumerated.\r\n"));\r
\r
USB_HostState = HOST_STATE_Configured;\r
USB_HostState = HOST_STATE_WaitForDeviceRemoval;\r
break;\r
}\r
+ \r
+ printf("Total Reports: %d\r\n", HIDReportInfo.TotalDeviceReports);\r
+\r
+ for (uint8_t i = 0; i < HIDReportInfo.TotalDeviceReports; i++)\r
+ {\r
+ HID_ReportSizeInfo_t* CurrReportIDInfo = &HIDReportInfo.ReportIDSizes[i];\r
+\r
+ /* Print out the byte sizes of each report within the device */\r
+ printf_P(PSTR(" + Report ID %d - In: %d bytes, Out: %d bytes, Feature: %d bytes\r\n"),\r
+ CurrReportIDInfo->ReportID,\r
+ ((CurrReportIDInfo->BitsIn >> 3) + (CurrReportIDInfo->BitsIn & 0x07)),\r
+ ((CurrReportIDInfo->BitsOut >> 3) + (CurrReportIDInfo->BitsOut & 0x07)),\r
+ ((CurrReportIDInfo->BitsFeature >> 3) + (CurrReportIDInfo->BitsFeature & 0x07)));\r
+ }\r
\r
puts_P(PSTR("Mouse Enumerated.\r\n"));\r
\r
/* Select and unfreeze mouse data pipe */\r
Pipe_SelectPipe(MOUSE_DATAPIPE); \r
Pipe_Unfreeze();\r
-\r
+ \r
/* Check to see if a packet has been received */\r
if (Pipe_IsINReceived())\r
{\r
HID_StateTable_t StateTable[HID_STATETABLE_STACK_DEPTH];\r
HID_StateTable_t* CurrStateTable = &StateTable[0];\r
HID_CollectionPath_t* CurrCollectionPath = NULL;\r
+ HID_ReportSizeInfo_t* CurrReportIDInfo = &ParserData->ReportIDSizes[0]; \r
uint16_t UsageStack[HID_USAGE_STACK_DEPTH];\r
uint8_t UsageStackSize = 0;\r
- uint16_t BitOffsetIn = 0;\r
- uint16_t BitOffsetOut = 0;\r
- uint16_t BitOffsetFeature = 0;\r
\r
- ParserData->TotalReportItems = 0;\r
- ParserData->UsingMultipleReports = false;\r
+ ParserData->TotalReportItems = 0;\r
+ ParserData->TotalDeviceReports = 1;\r
+ ParserData->UsingReportIDs = false;\r
\r
for (uint8_t CurrCollection = 0; CurrCollection < HID_MAX_COLLECTIONS; CurrCollection++)\r
ParserData->CollectionPaths[CurrCollection].Parent = NULL;\r
\r
- memset(&StateTable[0], 0x00, sizeof(HID_StateTable_t));\r
+ memset(CurrStateTable, 0x00, sizeof(HID_StateTable_t));\r
+ memset(CurrReportIDInfo, 0x00, sizeof(HID_ReportSizeInfo_t));\r
\r
while (ReportSize)\r
{\r
break;\r
case (TYPE_GLOBAL | TAG_GLOBAL_REPORTID):\r
CurrStateTable->ReportID = ReportItemData;\r
- ParserData->UsingMultipleReports = true;\r
- BitOffsetIn = 0;\r
- BitOffsetOut = 0;\r
- BitOffsetFeature = 0;\r
+\r
+ if (ParserData->UsingReportIDs)\r
+ {\r
+ CurrReportIDInfo = NULL;\r
+\r
+ for (uint8_t i = 0; i < ParserData->TotalDeviceReports; i++)\r
+ {\r
+ if (ParserData->ReportIDSizes[i].ReportID == CurrStateTable->ReportID)\r
+ {\r
+ CurrReportIDInfo = &ParserData->ReportIDSizes[i];\r
+ break;\r
+ }\r
+ }\r
+ \r
+ if (CurrReportIDInfo == NULL)\r
+ {\r
+ if (ParserData->TotalDeviceReports++ > HID_MAX_REPORT_IDS)\r
+ return HID_PARSE_InsufficientReportIDItems;\r
+ \r
+ CurrReportIDInfo = &ParserData->ReportIDSizes[ParserData->TotalDeviceReports - 1];\r
+ memset(CurrReportIDInfo, 0x00, sizeof(HID_ReportSizeInfo_t));\r
+ }\r
+ }\r
+\r
+ ParserData->UsingReportIDs = true; \r
+\r
+ CurrReportIDInfo->ReportID = CurrStateTable->ReportID;\r
break;\r
case (TYPE_LOCAL | TAG_LOCAL_USAGE):\r
if (UsageStackSize == HID_USAGE_STACK_DEPTH)\r
{\r
case TAG_MAIN_INPUT:\r
NewReportItem.ItemType = REPORT_ITEM_TYPE_In;\r
- NewReportItem.BitOffset = BitOffsetIn;\r
+ NewReportItem.BitOffset = CurrReportIDInfo->BitsIn;\r
\r
- BitOffsetIn += CurrStateTable->Attributes.BitSize;\r
+ CurrReportIDInfo->BitsIn += CurrStateTable->Attributes.BitSize;\r
break;\r
case TAG_MAIN_OUTPUT:\r
NewReportItem.ItemType = REPORT_ITEM_TYPE_Out;\r
- NewReportItem.BitOffset = BitOffsetOut;\r
+ NewReportItem.BitOffset = CurrReportIDInfo->BitsOut;\r
\r
- BitOffsetOut += CurrStateTable->Attributes.BitSize;\r
+ CurrReportIDInfo->BitsOut += CurrStateTable->Attributes.BitSize;\r
break;\r
case TAG_MAIN_FEATURE:\r
NewReportItem.ItemType = REPORT_ITEM_TYPE_Feature; \r
- NewReportItem.BitOffset = BitOffsetFeature;\r
+ NewReportItem.BitOffset = CurrReportIDInfo->BitsFeature;\r
\r
- BitOffsetFeature += CurrStateTable->Attributes.BitSize;\r
+ CurrReportIDInfo->BitsFeature += CurrStateTable->Attributes.BitSize;\r
break;\r
}\r
\r
* in the report item descriptor and stored in the user HID Report Info structure. A large value allows\r
* for more report items to be stored, but consumes more memory. By default this is set to 20 items, \r
* but this can be overridden by defining HID_MAX_REPORTITEMS to another value in the user project\r
- * makefile, passing the define to the compiler using the -D compiler switch.\r
+ * makefile, and passing the define to the compiler using the -D compiler switch.\r
*/\r
#define HID_MAX_REPORTITEMS 20\r
#endif\r
+ \r
+ #if !defined(HID_MAX_REPORT_IDS) || defined(__DOXYGEN__)\r
+ /** Constant indicating the maximum number of unique report IDs that can be processed in the report item\r
+ * descriptor for the report size information array in the user HID Report Info structure. A large value\r
+ * allows for more report ID report sizes to be stored, but consumes more memory. By default this is set\r
+ * to 5 items, but this can be overridden by defining HID_MAX_REPORT_IDS to another value in the user project\r
+ * makefile, and passing the define to the compiler using the -D compiler switch. Note that IN, OUT and FEATURE\r
+ * items sharing the same report ID consume only one size item in the array.\r
+ */\r
+ #define HID_MAX_REPORT_IDS 5\r
+ #endif\r
\r
/* Public Interface - May be used in end-application: */\r
/* Enums: */\r
HID_PARSE_UnexpectedEndCollection = 4, /**< An END COLLECTION item found without matching COLLECTION item. */\r
HID_PARSE_InsufficientCollectionPaths = 5, /**< More than \ref HID_MAX_COLLECTIONS collections in the report. */\r
HID_PARSE_UsageStackOverflow = 6, /**< More than \ref HID_USAGE_STACK_DEPTH usages listed in a row. */\r
+ HID_PARSE_InsufficientReportIDItems = 7, /**< More than \ref HID_MAX_REPORT_IDS report IDs in the device. */\r
};\r
\r
/* Type Defines: */ \r
\r
uint32_t Value; /**< Current value of the report item. */\r
} HID_ReportItem_t;\r
+ \r
+ /** Type define for a report item size information structure */\r
+ typedef struct\r
+ {\r
+ uint8_t ReportID; /** Report ID of the report within the HID interface */\r
+ uint8_t BitsIn; /** Total number of IN data bits in the current report ID */\r
+ uint8_t BitsOut; /** Total number of OUT data bits in the current report ID */\r
+ uint8_t BitsFeature; /** Total number of FEATURE data bits in the current report ID */\r
+ } HID_ReportSizeInfo_t;\r
\r
/** Type define for a complete processed HID report, including all report item data and collections. */\r
typedef struct\r
HID_CollectionPath_t CollectionPaths[HID_MAX_COLLECTIONS]; /**< All collection items, referenced\r
* by the report items.\r
*/\r
- bool UsingMultipleReports; /**< Indicates if the device has at least one REPORT ID\r
- * element in its HID report descriptor.\r
- */\r
+ uint8_t TotalDeviceReports; /** Number of reports within the HID interface */\r
+ HID_ReportSizeInfo_t ReportIDSizes[HID_MAX_REPORT_IDS]; /** Report sizes for each report in the interface */\r
+ bool UsingReportIDs; /**< Indicates if the device has at least one REPORT ID\r
+ * element in its HID report descriptor.\r
+ */\r
} HID_ReportInfo_t;\r
\r
/* Function Prototypes: */\r
* - The Benito Programmer project now has its own unique VID/PID pair allocated from the Atmel donated LUFA VID/PID pool\r
* - Add in new invalid event hook check targets to project makefiles to produce compilation errors when invalid event names\r
* are used in a project\r
+ * - The HID Report Parser now gives information on the total length of each report within a HID interface\r
*\r
* <b>Fixed:</b>\r
* - Fixed possible lockup in the CDC device class driver, when the host sends data that is a multiple of the\r
* If a item has a multiple count (i.e. a REPORT COUNT of more than 1), each item in the report count is placed separately in the\r
* processed HID report table. If not defined, this defaults to the value indicated in the HID.h file documentation.\r
*\r
+ * <b>HID_MAX_REPORT_IDS</b> - ( \ref Group_HIDParser ) \n\r
+ * HID reports may contain several report IDs, to logically distinguish grouped device data from one another - for example, a combination\r
+ * keyboard and mouse might use report IDs to seperate the keyboard reports from the mouse reports. In order to determine the size of each\r
+ * report, and thus know how many bytes must be read or written, the size of each report (IN, OUT and FEATURE) must be calculated and\r
+ * stored. This token may be defined to a non-zero 8-bit value to set the maximum number of report IDs in a device which can be processed\r
+ * and their sizes calculated/stored into the resultant processed report structure. If not defined, this defaults to the value indicated in\r
+ * the HID.h file documentation.\r
*\r
* \section Sec_SummaryUSBTokens USB Driver Related Tokens\r
* This section describes compile tokens which affect USB driver stack as a whole in the LUFA library.\r