aboutsummaryrefslogtreecommitdiffstats
path: root/LUFA/Drivers
diff options
context:
space:
mode:
authorDean Camera <dean@fourwalledcubicle.com>2009-09-09 08:34:24 +0000
committerDean Camera <dean@fourwalledcubicle.com>2009-09-09 08:34:24 +0000
commit524decdeb3a0a4c7adbeb4af906556e7bc6dd77c (patch)
tree3d3e83df9e11a61b2710d334c82609b0f3c89b4d /LUFA/Drivers
parent331929833da3e48ac9c43dce90487490d7a77af1 (diff)
downloadlufa-524decdeb3a0a4c7adbeb4af906556e7bc6dd77c.tar.gz
lufa-524decdeb3a0a4c7adbeb4af906556e7bc6dd77c.tar.bz2
lufa-524decdeb3a0a4c7adbeb4af906556e7bc6dd77c.zip
Change HID report parser so that it can calculate and record the sizes (IN, OUT and FEATURE) of each report within the device, by report ID. This will be required in host mode, so that the host can determine how many bytes of data must be read in for each report.
Add to MouseHostWithParser and KeyboardHostWithParser demos to print out the report sizes when a valid device is connected.
Diffstat (limited to 'LUFA/Drivers')
-rw-r--r--LUFA/Drivers/USB/Class/Host/HIDParser.c55
-rw-r--r--LUFA/Drivers/USB/Class/Host/HIDParser.h31
2 files changed, 66 insertions, 20 deletions
diff --git a/LUFA/Drivers/USB/Class/Host/HIDParser.c b/LUFA/Drivers/USB/Class/Host/HIDParser.c
index 5174b59f9..4293a3d98 100644
--- a/LUFA/Drivers/USB/Class/Host/HIDParser.c
+++ b/LUFA/Drivers/USB/Class/Host/HIDParser.c
@@ -38,19 +38,19 @@ uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID
HID_StateTable_t StateTable[HID_STATETABLE_STACK_DEPTH];
HID_StateTable_t* CurrStateTable = &StateTable[0];
HID_CollectionPath_t* CurrCollectionPath = NULL;
+ HID_ReportSizeInfo_t* CurrReportIDInfo = &ParserData->ReportIDSizes[0];
uint16_t UsageStack[HID_USAGE_STACK_DEPTH];
uint8_t UsageStackSize = 0;
- uint16_t BitOffsetIn = 0;
- uint16_t BitOffsetOut = 0;
- uint16_t BitOffsetFeature = 0;
- ParserData->TotalReportItems = 0;
- ParserData->UsingMultipleReports = false;
+ ParserData->TotalReportItems = 0;
+ ParserData->TotalDeviceReports = 1;
+ ParserData->UsingReportIDs = false;
for (uint8_t CurrCollection = 0; CurrCollection < HID_MAX_COLLECTIONS; CurrCollection++)
ParserData->CollectionPaths[CurrCollection].Parent = NULL;
- memset(&StateTable[0], 0x00, sizeof(HID_StateTable_t));
+ memset(CurrStateTable, 0x00, sizeof(HID_StateTable_t));
+ memset(CurrReportIDInfo, 0x00, sizeof(HID_ReportSizeInfo_t));
while (ReportSize)
{
@@ -126,10 +126,33 @@ uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID
break;
case (TYPE_GLOBAL | TAG_GLOBAL_REPORTID):
CurrStateTable->ReportID = ReportItemData;
- ParserData->UsingMultipleReports = true;
- BitOffsetIn = 0;
- BitOffsetOut = 0;
- BitOffsetFeature = 0;
+
+ if (ParserData->UsingReportIDs)
+ {
+ CurrReportIDInfo = NULL;
+
+ for (uint8_t i = 0; i < ParserData->TotalDeviceReports; i++)
+ {
+ if (ParserData->ReportIDSizes[i].ReportID == CurrStateTable->ReportID)
+ {
+ CurrReportIDInfo = &ParserData->ReportIDSizes[i];
+ break;
+ }
+ }
+
+ if (CurrReportIDInfo == NULL)
+ {
+ if (ParserData->TotalDeviceReports++ > HID_MAX_REPORT_IDS)
+ return HID_PARSE_InsufficientReportIDItems;
+
+ CurrReportIDInfo = &ParserData->ReportIDSizes[ParserData->TotalDeviceReports - 1];
+ memset(CurrReportIDInfo, 0x00, sizeof(HID_ReportSizeInfo_t));
+ }
+ }
+
+ ParserData->UsingReportIDs = true;
+
+ CurrReportIDInfo->ReportID = CurrStateTable->ReportID;
break;
case (TYPE_LOCAL | TAG_LOCAL_USAGE):
if (UsageStackSize == HID_USAGE_STACK_DEPTH)
@@ -223,21 +246,21 @@ uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID
{
case TAG_MAIN_INPUT:
NewReportItem.ItemType = REPORT_ITEM_TYPE_In;
- NewReportItem.BitOffset = BitOffsetIn;
+ NewReportItem.BitOffset = CurrReportIDInfo->BitsIn;
- BitOffsetIn += CurrStateTable->Attributes.BitSize;
+ CurrReportIDInfo->BitsIn += CurrStateTable->Attributes.BitSize;
break;
case TAG_MAIN_OUTPUT:
NewReportItem.ItemType = REPORT_ITEM_TYPE_Out;
- NewReportItem.BitOffset = BitOffsetOut;
+ NewReportItem.BitOffset = CurrReportIDInfo->BitsOut;
- BitOffsetOut += CurrStateTable->Attributes.BitSize;
+ CurrReportIDInfo->BitsOut += CurrStateTable->Attributes.BitSize;
break;
case TAG_MAIN_FEATURE:
NewReportItem.ItemType = REPORT_ITEM_TYPE_Feature;
- NewReportItem.BitOffset = BitOffsetFeature;
+ NewReportItem.BitOffset = CurrReportIDInfo->BitsFeature;
- BitOffsetFeature += CurrStateTable->Attributes.BitSize;
+ CurrReportIDInfo->BitsFeature += CurrStateTable->Attributes.BitSize;
break;
}
diff --git a/LUFA/Drivers/USB/Class/Host/HIDParser.h b/LUFA/Drivers/USB/Class/Host/HIDParser.h
index 8d3fbf212..d9adae34d 100644
--- a/LUFA/Drivers/USB/Class/Host/HIDParser.h
+++ b/LUFA/Drivers/USB/Class/Host/HIDParser.h
@@ -107,10 +107,21 @@
* in the report item descriptor and stored in the user HID Report Info structure. A large value allows
* for more report items to be stored, but consumes more memory. By default this is set to 20 items,
* but this can be overridden by defining HID_MAX_REPORTITEMS to another value in the user project
- * makefile, passing the define to the compiler using the -D compiler switch.
+ * makefile, and passing the define to the compiler using the -D compiler switch.
*/
#define HID_MAX_REPORTITEMS 20
#endif
+
+ #if !defined(HID_MAX_REPORT_IDS) || defined(__DOXYGEN__)
+ /** Constant indicating the maximum number of unique report IDs that can be processed in the report item
+ * descriptor for the report size information array in the user HID Report Info structure. A large value
+ * allows for more report ID report sizes to be stored, but consumes more memory. By default this is set
+ * to 5 items, but this can be overridden by defining HID_MAX_REPORT_IDS to another value in the user project
+ * makefile, and passing the define to the compiler using the -D compiler switch. Note that IN, OUT and FEATURE
+ * items sharing the same report ID consume only one size item in the array.
+ */
+ #define HID_MAX_REPORT_IDS 5
+ #endif
/* Public Interface - May be used in end-application: */
/* Enums: */
@@ -132,6 +143,7 @@
HID_PARSE_UnexpectedEndCollection = 4, /**< An END COLLECTION item found without matching COLLECTION item. */
HID_PARSE_InsufficientCollectionPaths = 5, /**< More than \ref HID_MAX_COLLECTIONS collections in the report. */
HID_PARSE_UsageStackOverflow = 6, /**< More than \ref HID_USAGE_STACK_DEPTH usages listed in a row. */
+ HID_PARSE_InsufficientReportIDItems = 7, /**< More than \ref HID_MAX_REPORT_IDS report IDs in the device. */
};
/* Type Defines: */
@@ -191,6 +203,15 @@
uint32_t Value; /**< Current value of the report item. */
} HID_ReportItem_t;
+
+ /** Type define for a report item size information structure */
+ typedef struct
+ {
+ uint8_t ReportID; /** Report ID of the report within the HID interface */
+ uint8_t BitsIn; /** Total number of IN data bits in the current report ID */
+ uint8_t BitsOut; /** Total number of OUT data bits in the current report ID */
+ uint8_t BitsFeature; /** Total number of FEATURE data bits in the current report ID */
+ } HID_ReportSizeInfo_t;
/** Type define for a complete processed HID report, including all report item data and collections. */
typedef struct
@@ -204,9 +225,11 @@
HID_CollectionPath_t CollectionPaths[HID_MAX_COLLECTIONS]; /**< All collection items, referenced
* by the report items.
*/
- bool UsingMultipleReports; /**< Indicates if the device has at least one REPORT ID
- * element in its HID report descriptor.
- */
+ uint8_t TotalDeviceReports; /** Number of reports within the HID interface */
+ HID_ReportSizeInfo_t ReportIDSizes[HID_MAX_REPORT_IDS]; /** Report sizes for each report in the interface */
+ bool UsingReportIDs; /**< Indicates if the device has at least one REPORT ID
+ * element in its HID report descriptor.
+ */
} HID_ReportInfo_t;
/* Function Prototypes: */