diff --git a/Demos/Host/LowLevel/JoystickHostWithParser/JoystickHostWithParser.c b/Demos/Host/LowLevel/JoystickHostWithParser/JoystickHostWithParser.c index eee9343d38..04f4d2476b 100644 --- a/Demos/Host/LowLevel/JoystickHostWithParser/JoystickHostWithParser.c +++ b/Demos/Host/LowLevel/JoystickHostWithParser/JoystickHostWithParser.c @@ -282,7 +282,7 @@ void ProcessJoystickReport(uint8_t* JoystickReport) if (!(FoundData)) continue; - int16_t DeltaMovement = (int16_t)(ReportItem->Value << (16 - ReportItem->Attributes.BitSize)); + int16_t DeltaMovement = HID_ALIGN_DATA(ReportItem, int16_t); /* Determine if the report is for the X or Y delta movement */ if (ReportItem->Attributes.Usage.Usage == USAGE_X) diff --git a/Demos/Host/LowLevel/MouseHostWithParser/MouseHostWithParser.c b/Demos/Host/LowLevel/MouseHostWithParser/MouseHostWithParser.c index d84e2d3ceb..c29d4debd2 100644 --- a/Demos/Host/LowLevel/MouseHostWithParser/MouseHostWithParser.c +++ b/Demos/Host/LowLevel/MouseHostWithParser/MouseHostWithParser.c @@ -280,7 +280,7 @@ void ProcessMouseReport(uint8_t* MouseReport) if (!(USB_GetHIDReportItemInfo(MouseReport, ReportItem))) continue; - int16_t WheelDelta = (int16_t)(ReportItem->Value << (16 - ReportItem->Attributes.BitSize)); + int16_t WheelDelta = HID_ALIGN_DATA(ReportItem, int16_t); if (WheelDelta) LEDMask = (LEDS_LED1 | LEDS_LED2 | ((WheelDelta > 0) ? LEDS_LED3 : LEDS_LED4)); diff --git a/LUFA/Drivers/USB/Class/Host/HIDParser.c b/LUFA/Drivers/USB/Class/Host/HIDParser.c index 81062b1c88..71598b036c 100644 --- a/LUFA/Drivers/USB/Class/Host/HIDParser.c +++ b/LUFA/Drivers/USB/Class/Host/HIDParser.c @@ -40,7 +40,8 @@ uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID HID_CollectionPath_t* CurrCollectionPath = NULL; HID_ReportSizeInfo_t* CurrReportIDInfo = &ParserData->ReportIDSizes[0]; uint16_t UsageList[HID_USAGE_STACK_DEPTH]; - uint8_t UsageListSize = 0; + uint8_t UsageListSize = 0; + HID_MinMax_t UsageMinMax = {0, 0}; memset(ParserData, 0x00, sizeof(HID_ReportInfo_t)); memset(CurrStateTable, 0x00, sizeof(HID_StateTable_t)); @@ -157,10 +158,10 @@ uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID UsageList[UsageListSize++] = ReportItemData; break; case (TYPE_LOCAL | TAG_LOCAL_USAGEMIN): - CurrStateTable->Attributes.Usage.MinMax.Minimum = ReportItemData; + UsageMinMax.Minimum = ReportItemData; break; case (TYPE_LOCAL | TAG_LOCAL_USAGEMAX): - CurrStateTable->Attributes.Usage.MinMax.Maximum = ReportItemData; + UsageMinMax.Maximum = ReportItemData; break; case (TYPE_MAIN | TAG_MAIN_COLLECTION): if (CurrCollectionPath == NULL) @@ -196,6 +197,10 @@ uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID UsageListSize--; } + else if (UsageMinMax.Minimum <= UsageMinMax.Maximum) + { + CurrCollectionPath->Usage.Usage = UsageMinMax.Minimum++; + } break; case (TYPE_MAIN | TAG_MAIN_ENDCOLLECTION): @@ -228,7 +233,11 @@ uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID UsageListSize--; } - + else if (UsageMinMax.Minimum <= UsageMinMax.Maximum) + { + CurrCollectionPath->Usage.Usage = UsageMinMax.Minimum++; + } + uint8_t ItemTag = (HIDReportItem & TAG_MASK); if (ItemTag == TAG_MAIN_INPUT) @@ -262,9 +271,9 @@ uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID if ((HIDReportItem & TYPE_MASK) == TYPE_MAIN) { - CurrStateTable->Attributes.Usage.MinMax.Minimum = 0; - CurrStateTable->Attributes.Usage.MinMax.Maximum = 0; - UsageListSize = 0; + UsageMinMax.Minimum = 0; + UsageMinMax.Maximum = 0; + UsageListSize = 0; } } @@ -280,6 +289,7 @@ bool USB_GetHIDReportItemInfo(const uint8_t* ReportData, HID_ReportItem_t* const uint16_t CurrentBit = ReportItem->BitOffset; uint32_t BitMask = (1 << 0); + ReportItem->PreviousValue = ReportItem->Value; ReportItem->Value = 0; if (ReportItem->ReportID) @@ -314,6 +324,8 @@ void USB_SetHIDReportItemInfo(uint8_t* ReportData, const HID_ReportItem_t* Repor ReportData++; } + ReportItem->PreviousValue = ReportItem->Value; + while (DataBitsRem--) { if (ReportItem->Value & (1 << (CurrentBit % 8))) diff --git a/LUFA/Drivers/USB/Class/Host/HIDParser.h b/LUFA/Drivers/USB/Class/Host/HIDParser.h index b04714739c..e1f4cb3c26 100644 --- a/LUFA/Drivers/USB/Class/Host/HIDParser.h +++ b/LUFA/Drivers/USB/Class/Host/HIDParser.h @@ -71,7 +71,7 @@ extern "C" { #endif - /* Preprocessor checks and defines: */ + /* Macros: */ #if !defined(HID_STATETABLE_STACK_DEPTH) || defined(__DOXYGEN__) /** Constant indicating the maximum stack depth of the state table. A larger state table * allows for more PUSH/POP report items to be nested, but consumes more memory. By default @@ -124,6 +124,17 @@ #define HID_MAX_REPORT_IDS 10 #endif + /** Returns the value a given HID report item (once its value has been fetched via \ref USB_GetHIDReportItemInfo()) + * left-aligned to the given data type. This allows for signed data to be interpreted correctly, by shifting the data + * leftwards until the data's sign bit is in the correct position. + * + * \param[in] reportitem HID Report Item whose retrieved value is to be aligned + * \param[in] type Data type to align the HID report item's value to + * + * \return Left-aligned data of the given report item's pre-retrived value for the given datatype + */ + #define HID_ALIGN_DATA(reportitem, type) ((type)(reportitem->Value << (sizeof(type) - reportitem->Attributes.BitSize))) + /* Public Interface - May be used in end-application: */ /* Enums: */ /** Enum for the possible error codes in the return value of the \ref USB_ProcessHIDReport() function */ @@ -160,7 +171,6 @@ { uint16_t Page; /**< Usage page of the report item. */ uint16_t Usage; /**< Usage of the report item. */ - HID_MinMax_t MinMax; /**< Usage minimum and maximum of the report item. */ } HID_Usage_t; /** Type define for a COLLECTION object. Contains the collection attributes and a reference to the @@ -196,6 +206,7 @@ HID_ReportItem_Attributes_t Attributes; /**< Report item attributes. */ uint32_t Value; /**< Current value of the report item. */ + uint32_t PreviousValue; /**< Previous value of the report item. */ } HID_ReportItem_t; /** Type define for a report item size information structure */ @@ -243,6 +254,9 @@ /** Extracts the given report item's value out of the given HID report and places it into the Value * member of the report item's \ref HID_ReportItem_t structure. * + * When called, this copies the report item's Value element to it's PreviousValue element for easy + * checking to see if an item's value has changed before processing a report. + * * \param[in] ReportData Buffer containing an IN or FEATURE report from an attached device * \param[in,out] ReportItem Pointer to the report item of interest in a \ref HID_ReportInfo_t ReportItem array * @@ -256,6 +270,9 @@ * buffer. The report buffer is assumed to have the appropriate bits cleared before calling * this function (i.e., the buffer should be explicitly cleared before report values are added). * + * When called, this copies the report item's Value element to it's PreviousValue element for easy + * checking to see if an item's value has changed before sending a report. + * * If the device has multiple HID reports, the first byte in the report is set to the report ID of the given item. * * \param[out] ReportData Buffer holding the current OUT or FEATURE report data diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt index f0d0478940..4fc4424b54 100644 --- a/LUFA/ManPages/ChangeLog.txt +++ b/LUFA/ManPages/ChangeLog.txt @@ -19,6 +19,8 @@ * - Added PDI programming support for XMEGA devices to the AVRISP programmer project * - Added support for the XPLAIN board Dataflash, with new XPLAIN_REV1 board target for the different dataflash used * on the first revision boards compared to the one mounted on later revisions + * - Added new HID_ALIGN_DATA() macro to return the pre-retrieved value of a HID report item, left-aligned to a given datatype + * - Added new PreviousValue to the HID Report Parser report item structure, for easy monitoring of previous report item values * * Changed: * - Removed code in the Keyboard demos to send zeroed reports between two reports with differing numbers of keycodes @@ -45,6 +47,7 @@ * - Fixed misnamed Pipe_SetPipeToken() macro for setting a pipe's direction * - Fixed CDCHost failing on devices with bidirectional endpoints * - Fixed USB driver failing to define the PLL prescaler mask for the ATMEGA8U2 and ATMEGA16U2 + * - Fixed HID Parser not distributing the Usage Min and Usage Max values across an array of report items * * \section Sec_ChangeLog091122 Version 091122 * diff --git a/LUFA/ManPages/MigrationInformation.txt b/LUFA/ManPages/MigrationInformation.txt index be0952f286..378744ee57 100644 --- a/LUFA/ManPages/MigrationInformation.txt +++ b/LUFA/ManPages/MigrationInformation.txt @@ -17,6 +17,9 @@ * now named \ref SImage_Host_USBTask() and \ref SImage_Host_ConfigurePipes() respectively. * - The HOST_SENDCONTROL_DeviceDisconnect enum value has been renamed to \ref HOST_SENDCONTROL_DeviceDisconnected to be in * line with the rest of the library error codes. + * - The HID Parser item usages no longer contain seperate minimum and maximum values, as this was a violation of the HID + * specification. Instead, the values are distributed evenly across each item as its usage value, to ensure that all items + * can be distinguished from oneanother. * * Device Mode * - The CALLBACK_HID_Device_CreateHIDReport() HID Device Class driver callback now has a new ReportType parameter to diff --git a/Projects/AVRISP/Lib/ISPProtocol.h b/Projects/AVRISP/Lib/ISPProtocol.h index 247933e397..2f39b44468 100644 --- a/Projects/AVRISP/Lib/ISPProtocol.h +++ b/Projects/AVRISP/Lib/ISPProtocol.h @@ -42,7 +42,7 @@ #include "V2Protocol.h" /* Preprocessor Checks: */ - #if BOARD == BOARD_XPLAIN + #if (BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1) #undef ENABLE_ISP_PROTOCOL #if !defined(ENABLE_PDI_PROTOCOL) diff --git a/Projects/AVRISP/Lib/ISPTarget.h b/Projects/AVRISP/Lib/ISPTarget.h index da5bd30d19..bf884ae263 100644 --- a/Projects/AVRISP/Lib/ISPTarget.h +++ b/Projects/AVRISP/Lib/ISPTarget.h @@ -48,7 +48,7 @@ #include "V2ProtocolParams.h" /* Preprocessor Checks: */ - #if BOARD == BOARD_XPLAIN + #if (BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1) #undef ENABLE_ISP_PROTOCOL #if !defined(ENABLE_PDI_PROTOCOL) diff --git a/Projects/AVRISP/Lib/PDIProtocol.h b/Projects/AVRISP/Lib/PDIProtocol.h index bbbfda50a7..9511bc8781 100644 --- a/Projects/AVRISP/Lib/PDIProtocol.h +++ b/Projects/AVRISP/Lib/PDIProtocol.h @@ -44,7 +44,7 @@ #include "PDITarget.h" /* Preprocessor Checks: */ - #if BOARD == BOARD_XPLAIN + #if (BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1) #undef ENABLE_ISP_PROTOCOL #if !defined(ENABLE_PDI_PROTOCOL) diff --git a/Projects/AVRISP/Lib/PDITarget.c b/Projects/AVRISP/Lib/PDITarget.c index d1dfa15111..98d4bded48 100644 --- a/Projects/AVRISP/Lib/PDITarget.c +++ b/Projects/AVRISP/Lib/PDITarget.c @@ -41,7 +41,7 @@ /** Writes a given byte to the attached XMEGA device, using a RS232 frame via software through the * PDI interface. * - * \param Byte Byte to send to the attached device + * \param[in] Byte Byte to send to the attached device */ void PDITarget_SendByte(uint8_t Byte) { diff --git a/Projects/AVRISP/Lib/PDITarget.h b/Projects/AVRISP/Lib/PDITarget.h index 0ecc70a262..294d1a98b8 100644 --- a/Projects/AVRISP/Lib/PDITarget.h +++ b/Projects/AVRISP/Lib/PDITarget.h @@ -43,7 +43,7 @@ #include /* Preprocessor Checks: */ - #if BOARD == BOARD_XPLAIN + #if (BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1) #undef ENABLE_ISP_PROTOCOL #if !defined(ENABLE_PDI_PROTOCOL) diff --git a/Projects/AVRISP/Lib/V2Protocol.h b/Projects/AVRISP/Lib/V2Protocol.h index 8a0ac2f7d5..d40f951f9a 100644 --- a/Projects/AVRISP/Lib/V2Protocol.h +++ b/Projects/AVRISP/Lib/V2Protocol.h @@ -47,7 +47,7 @@ #include "PDIProtocol.h" /* Preprocessor Checks: */ - #if BOARD == BOARD_XPLAIN + #if (BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1) #undef ENABLE_ISP_PROTOCOL #if !defined(ENABLE_PDI_PROTOCOL)