diff --git a/Demos/Host/ClassDriver/KeyboardHostWithParser/KeyboardHostWithParser.c b/Demos/Host/ClassDriver/KeyboardHostWithParser/KeyboardHostWithParser.c index d87c0e72c3..d89807461c 100644 --- a/Demos/Host/ClassDriver/KeyboardHostWithParser/KeyboardHostWithParser.c +++ b/Demos/Host/ClassDriver/KeyboardHostWithParser/KeyboardHostWithParser.c @@ -120,7 +120,7 @@ int main(void) case HOST_STATE_Configured: if (HID_Host_IsReportReceived(&Keyboard_HID_Interface)) { - uint8_t KeyboardReport[50]; + uint8_t KeyboardReport[Keyboard_HID_Interface.State.LargestReportSize]; HID_Host_ReceiveReport(&Keyboard_HID_Interface, &KeyboardReport); for (uint8_t ReportNumber = 0; ReportNumber < HIDReportInfo.TotalReportItems; ReportNumber++) diff --git a/Demos/Host/ClassDriver/MouseHostWithParser/MouseHostWithParser.c b/Demos/Host/ClassDriver/MouseHostWithParser/MouseHostWithParser.c index 8133c87438..c33b2ebde8 100644 --- a/Demos/Host/ClassDriver/MouseHostWithParser/MouseHostWithParser.c +++ b/Demos/Host/ClassDriver/MouseHostWithParser/MouseHostWithParser.c @@ -120,7 +120,7 @@ int main(void) case HOST_STATE_Configured: if (HID_Host_IsReportReceived(&Mouse_HID_Interface)) { - uint8_t MouseReport[50]; + uint8_t MouseReport[Keyboard_HID_Interface.State.LargestReportSize]; HID_Host_ReceiveReport(&Mouse_HID_Interface, &MouseReport); uint8_t LEDMask = LEDS_NO_LEDS; diff --git a/LUFA/Drivers/USB/Class/Host/HID.c b/LUFA/Drivers/USB/Class/Host/HID.c index 87d37933e6..b420a5b919 100644 --- a/LUFA/Drivers/USB/Class/Host/HID.c +++ b/LUFA/Drivers/USB/Class/Host/HID.c @@ -101,6 +101,7 @@ uint8_t HID_Host_ConfigurePipes(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo } } + HIDInterfaceInfo->State.LargestReportSize = 8; HIDInterfaceInfo->State.IsActive = true; return HID_ENUMERROR_NoError; } @@ -288,6 +289,7 @@ uint8_t USB_HID_Host_SetBootProtocol(USB_ClassInfo_HID_Host_t* const HIDInterfac if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful) return ErrorCode; + HIDInterfaceInfo->State.LargestReportSize = 8; HIDInterfaceInfo->State.UsingBootProtocol = true; return HOST_SENDCONTROL_Successful; @@ -339,6 +341,9 @@ uint8_t USB_HID_Host_SetReportProtocol(USB_ClassInfo_HID_Host_t* const HIDInterf return HID_ERROR_LOGICAL | ErrorCode; } + uint8_t LargestReportSizeBits = HIDInterfaceInfo->Config.HIDParserData->LargestReportSizeBits; + HIDInterfaceInfo->State.LargestReportSize = (LargestReportSizeBits >> 3) + ((LargestReportSizeBits & 0x07) != 0); + return 0; } diff --git a/LUFA/Drivers/USB/Class/Host/HID.h b/LUFA/Drivers/USB/Class/Host/HID.h index 8f80ea8c21..5526990adc 100644 --- a/LUFA/Drivers/USB/Class/Host/HID.h +++ b/LUFA/Drivers/USB/Class/Host/HID.h @@ -101,6 +101,8 @@ */ bool UsingBootProtocol; /**< Indicates that the interface is currently initialised in Boot Protocol mode */ uint16_t HIDReportSize; /**< Size in bytes of the HID report descriptor in the device */ + + uint8_t LargestReportSize; /**< Largest report the device will send, in bytes */ } State; /**< State data for the USB class interface within the device. All elements in this section * may be set to initial values, but may also be ignored to default to sane values when * the interface is enumerated. diff --git a/LUFA/Drivers/USB/Class/Host/HIDParser.c b/LUFA/Drivers/USB/Class/Host/HIDParser.c index b302a94b47..450f6afb03 100644 --- a/LUFA/Drivers/USB/Class/Host/HIDParser.c +++ b/LUFA/Drivers/USB/Class/Host/HIDParser.c @@ -241,29 +241,36 @@ uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID { NewReportItem.Attributes.Usage.Usage = 0; } - + + uint8_t ReportSizeIndex = 0; + switch (HIDReportItem & TAG_MASK) { case TAG_MAIN_INPUT: NewReportItem.ItemType = REPORT_ITEM_TYPE_In; NewReportItem.BitOffset = CurrReportIDInfo->ReportSizeBits[REPORT_ITEM_TYPE_In]; - CurrReportIDInfo->ReportSizeBits[REPORT_ITEM_TYPE_In] += CurrStateTable->Attributes.BitSize; + ReportSizeIndex = REPORT_ITEM_TYPE_In; break; case TAG_MAIN_OUTPUT: NewReportItem.ItemType = REPORT_ITEM_TYPE_Out; NewReportItem.BitOffset = CurrReportIDInfo->ReportSizeBits[REPORT_ITEM_TYPE_Out]; - CurrReportIDInfo->ReportSizeBits[REPORT_ITEM_TYPE_Out] += CurrStateTable->Attributes.BitSize; + ReportSizeIndex = REPORT_ITEM_TYPE_Out; break; case TAG_MAIN_FEATURE: NewReportItem.ItemType = REPORT_ITEM_TYPE_Feature; NewReportItem.BitOffset = CurrReportIDInfo->ReportSizeBits[REPORT_ITEM_TYPE_Feature]; - CurrReportIDInfo->ReportSizeBits[REPORT_ITEM_TYPE_Feature] += CurrStateTable->Attributes.BitSize; + ReportSizeIndex = REPORT_ITEM_TYPE_Feature; break; } + + CurrReportIDInfo->ReportSizeBits[ReportSizeIndex] += CurrStateTable->Attributes.BitSize; + if (ParserData->LargestReportSizeBits < CurrReportIDInfo->ReportSizeBits[ReportSizeIndex]) + ParserData->LargestReportSizeBits = CurrReportIDInfo->ReportSizeBits[ReportSizeIndex]; + if (!(ReportItemData & IOF_CONSTANT) && CALLBACK_HIDParser_FilterHIDReportItem(&CurrStateTable->Attributes)) { if (ParserData->TotalReportItems == HID_MAX_REPORTITEMS) diff --git a/LUFA/Drivers/USB/Class/Host/HIDParser.h b/LUFA/Drivers/USB/Class/Host/HIDParser.h index f2cd35b88d..2ee3f7032d 100644 --- a/LUFA/Drivers/USB/Class/Host/HIDParser.h +++ b/LUFA/Drivers/USB/Class/Host/HIDParser.h @@ -225,8 +225,9 @@ HID_CollectionPath_t CollectionPaths[HID_MAX_COLLECTIONS]; /**< All collection items, referenced * by the report items. */ - 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 */ + 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 */ + uint16_t LargestReportSizeBits; /**< Largest report that the attached device will generate, in bits */ bool UsingReportIDs; /**< Indicates if the device has at least one REPORT ID * element in its HID report descriptor. */ diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt index c8fe5b8333..18b609080d 100644 --- a/LUFA/ManPages/ChangeLog.txt +++ b/LUFA/ManPages/ChangeLog.txt @@ -68,7 +68,7 @@ * - Re-add in missing flip, flip-ee, dfu and dfu-ee targets to project makefiles (thanks to Opendous Inc.) * - Fix allowable F_CPU values comment in project makefiles to more accurately reflect the allowable values on the USB AVRs * - Fixed DFU and CDC class bootloaders on the series 2 USB AVRs, corrected invalid signatures, added support for the new - * ATMEGAxxx2 series 2 variant AVRs to the DFU bootloader + * ATMEGAxx2 series 2 variant AVRs to the DFU bootloader * - Fixed Low Level USBtoSerial demo not storing received characters (thanks to Michael Cooper) * - Fixed MIDI Device Class driver not sending/receiving MIDI packets of the correct size (thanks to Thomas Bleeker) * diff --git a/LUFA/ManPages/CompileTimeTokens.txt b/LUFA/ManPages/CompileTimeTokens.txt index 8213c678b4..3619ec44ab 100644 --- a/LUFA/ManPages/CompileTimeTokens.txt +++ b/LUFA/ManPages/CompileTimeTokens.txt @@ -23,27 +23,27 @@ * \section Sec_SummaryUSBClassTokens USB Class Driver Related Tokens * This section describes compile tokens which affect USB class-specific drivers in the LUFA library. * - * HID_STATETABLE_STACK_DEPTH - ( \ref Group_HIDParser ) \n + * HID_STATETABLE_STACK_DEPTH=x - ( \ref Group_HIDParser ) \n * HID reports may contain PUSH and POP elements, to store and retrieve the current HID state table onto a stack. This * allows for reports to save the state table before modifying it slightly for a data item, and then restore the previous * state table in a compact manner. This token may be defined to a non-zero 8-bit value to give the maximum depth of the state * table stack. If not defined, this defaults to the value indicated in the HID.h file documentation. * - * HID_USAGE_STACK_DEPTH - ( \ref Group_HIDParser ) \n + * HID_USAGE_STACK_DEPTH=x - ( \ref Group_HIDParser ) \n * HID reports generally contain many USAGE elements, which are assigned to INPUT, OUTPUT and FEATURE items in succession * when multiple items are defined at once (via REPORT COUNT elements). This allows for several items to be defined with * different usages in a compact manner. This token may be defined to a non-zero 8-bit value to set the maximum depth of the * usage stack, indicating the maximum number of USAGE items which can be stored temporarily until the next INPUT, OUTPUT * and FEATURE item. If not defined, this defaults to the value indicated in the HID.h file documentation. * - * HID_MAX_COLLECTIONS - ( \ref Group_HIDParser ) \n + * HID_MAX_COLLECTIONS=x - ( \ref Group_HIDParser ) \n * HID reports generally contain several COLLECTION elements, used to group related data items together. Collection information * is stored separately in the processed usage structure (and referred to by the data elements in the structure) to save space. * This token may be defined to a non-zero 8-bit value to set the maximum number of COLLECTION items which can be processed by the * parser into the resultant processed report structure. If not defined, this defaults to the value indicated in the HID.h file * documentation. * - * HID_MAX_REPORTITEMS - ( \ref Group_HIDParser ) \n + * HID_MAX_REPORTITEMS=x - ( \ref Group_HIDParser ) \n * All HID reports contain one or more INPUT, OUTPUT and/or FEATURE items describing the data which can be sent to and from the HID * device. Each item has associated usages, bit offsets in the item reports and other associated data indicating the manner in which * the report data should be interpreted by the host. This token may be defined to a non-zero 8-bit value to set the maximum number of @@ -51,7 +51,7 @@ * 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 * processed HID report table. If not defined, this defaults to the value indicated in the HID.h file documentation. * - * HID_MAX_REPORT_IDS - ( \ref Group_HIDParser ) \n + * HID_MAX_REPORT_IDS=x - ( \ref Group_HIDParser ) \n * HID reports may contain several report IDs, to logically distinguish grouped device data from one another - for example, a combination * keyboard and mouse might use report IDs to seperate the keyboard reports from the mouse reports. In order to determine the size of each * 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 @@ -78,7 +78,7 @@ * allocated resources (such as drivers, COM Port number allocations) to be preserved. This is not needed in many apps, and so the * code that performs this task can be disabled by defining this option and passing it to the compiler via the -D switch. * - * FIXED_CONTROL_ENDPOINT_SIZE - ( \ref Group_EndpointManagement ) \n + * FIXED_CONTROL_ENDPOINT_SIZE=x - ( \ref Group_EndpointManagement ) \n * By default, the library determines the size of the control endpoint (when in device mode) by reading the device descriptor. * Normally this reduces the amount of configuration required for the library, allows the value to change dynamically (if * descriptors are stored in EEPROM or RAM rather than flash memory) and reduces code maintenance. However, this token can be @@ -99,7 +99,7 @@ * reserved for application use. When defined, the corresponding GPIOR register should not be used within the user application except * implicitly via the library APIs. * - * FIXED_NUM_CONFIGURATIONS - ( \ref Group_Device ) \n + * FIXED_NUM_CONFIGURATIONS=x - ( \ref Group_Device ) \n * By default, the library determines the number of configurations a USB device supports by reading the device descriptor. This reduces * the amount of configuration required to set up the library, and allows the value to change dynamically (if descriptors are stored in * EEPROM or RAM rather than flash memory) and reduces code maintenance. However, this value may be fixed via this token in the project @@ -125,18 +125,18 @@ * used, bytes are sent or recevied in groups of 8 bytes at a time increasing performance at the expense of a larger flash memory consumption * due to the extra code required to deal with byte alignment. * - * USB_HOST_TIMEOUT_MS - ( \ref Group_Host ) \n + * USB_HOST_TIMEOUT_MS=x - ( \ref Group_Host ) \n * When a control transfer is initiated in host mode to an attached device, a timeout is used to abort the transfer if the attached * device fails to respond within the timeout period. This token may be defined to a non-zero 16-bit value to set the timeout period for * control transfers, specified in milliseconds. If not defined, the default value specified in Host.h is used instead. * - * HOST_DEVICE_SETTLE_DELAY_MS - ( \ref Group_Host ) \n + * HOST_DEVICE_SETTLE_DELAY_MS=x - ( \ref Group_Host ) \n * Some devices require a delay of up to 5 seconds after they are connected to VBUS before the enumeration process can be started, or * they will fail to enumerate correctly. By placing a delay before the enumeration process, it can be ensured that the bus has settled * back to a known idle state before communications occur with the device. This token may be defined to a 16-bit value to set the device * settle period, specified in milliseconds. If not defined, the default value specified in Host.h is used instead. * - * USE_STATIC_OPTIONS - ( \ref Group_USBManagement ) \n + * USE_STATIC_OPTIONS=x - ( \ref Group_USBManagement ) \n * By default, the USB_Init() function accepts dynamic options at runtime to alter the library behaviour, including whether the USB pad * voltage regulator is enabled, and the device speed when in device mode. By defining this token to a mask comprised of the USB options * mask defines usually passed as the Options parameter to USB_Init(), the resulting compiled binary can be decreased in size by removing @@ -152,7 +152,7 @@ * USB_HOST_ONLY - ( \ref Group_USBManagement ) \n * Same as USB_DEVICE_ONLY, except the library is fixed to USB host mode rather than USB device mode. Not available on some USB AVR models. * - * USB_STREAM_TIMEOUT_MS - ( \ref Group_USBManagement ) \n + * USB_STREAM_TIMEOUT_MS=x - ( \ref Group_USBManagement ) \n * When endpoint and/or pipe stream functions are used, by default there is a timeout between each transfer which the connected device or host * must satisfy, or the stream function aborts the remaining data transfer. This token may be defined to a non-zero 16-bit value to set the timeout * period for stream transfers, specified in milliseconds. If not defined, the default value specified in LowLevel.h is used instead. diff --git a/LUFA/ManPages/FutureChanges.txt b/LUFA/ManPages/FutureChanges.txt index 425dcb5510..c5fcbc5862 100644 --- a/LUFA/ManPages/FutureChanges.txt +++ b/LUFA/ManPages/FutureChanges.txt @@ -11,8 +11,8 @@ * If you have an item to add to this list, please contact the library author via email, the LUFA mailing list, * or post your suggestion as an enhancement request to the project bug tracker. * - * Targeted for This Release: - * - Finish HID Host Mode Class Driver, add demo summaries + * Targeted for This Release (SVN Development Only): + * - N/A * * Targeted for Future Releases: * - Add hub support to match Atmel's stack @@ -20,10 +20,11 @@ * - Remake AVRStudio project files * - Add detailed overviews of how each demo works * - Master LUFA include file rather than per-module includes - * - Add multiple-report HID device demo to the library - * - Add dual role Mouse Host/Keyboard Device demo to the library - * - Add Mouse/CDC dual class device demo to the library * - Change makefiles to allow for absolute LUFA location to be used + * - Make new demos + * -# Multiple-report HID device + * -# Dual Role Mouse Host/Keyboard Device + * -# Mouse/CDC Dual ClassDevice * - Port LUFA to other architectures * -# AVR32 UC3B series microcontrollers * -# Atmel ARM7 series microcontrollers