Commit 2919aeea authored by Dean Camera's avatar Dean Camera
Browse files

Fixed HID Parser not distributing the Usage Min and Usage Max values across an...

Fixed HID Parser not distributing the Usage Min and Usage Max values across an array of report items.

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.
parent f338ddcb
...@@ -282,7 +282,7 @@ void ProcessJoystickReport(uint8_t* JoystickReport) ...@@ -282,7 +282,7 @@ void ProcessJoystickReport(uint8_t* JoystickReport)
if (!(FoundData)) if (!(FoundData))
continue; 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 */ /* Determine if the report is for the X or Y delta movement */
if (ReportItem->Attributes.Usage.Usage == USAGE_X) if (ReportItem->Attributes.Usage.Usage == USAGE_X)
......
...@@ -280,7 +280,7 @@ void ProcessMouseReport(uint8_t* MouseReport) ...@@ -280,7 +280,7 @@ void ProcessMouseReport(uint8_t* MouseReport)
if (!(USB_GetHIDReportItemInfo(MouseReport, ReportItem))) if (!(USB_GetHIDReportItemInfo(MouseReport, ReportItem)))
continue; continue;
int16_t WheelDelta = (int16_t)(ReportItem->Value << (16 - ReportItem->Attributes.BitSize)); int16_t WheelDelta = HID_ALIGN_DATA(ReportItem, int16_t);
if (WheelDelta) if (WheelDelta)
LEDMask = (LEDS_LED1 | LEDS_LED2 | ((WheelDelta > 0) ? LEDS_LED3 : LEDS_LED4)); LEDMask = (LEDS_LED1 | LEDS_LED2 | ((WheelDelta > 0) ? LEDS_LED3 : LEDS_LED4));
......
...@@ -41,6 +41,7 @@ uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID ...@@ -41,6 +41,7 @@ uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID
HID_ReportSizeInfo_t* CurrReportIDInfo = &ParserData->ReportIDSizes[0]; HID_ReportSizeInfo_t* CurrReportIDInfo = &ParserData->ReportIDSizes[0];
uint16_t UsageList[HID_USAGE_STACK_DEPTH]; 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(ParserData, 0x00, sizeof(HID_ReportInfo_t));
memset(CurrStateTable, 0x00, sizeof(HID_StateTable_t)); memset(CurrStateTable, 0x00, sizeof(HID_StateTable_t));
...@@ -157,10 +158,10 @@ uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID ...@@ -157,10 +158,10 @@ uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID
UsageList[UsageListSize++] = ReportItemData; UsageList[UsageListSize++] = ReportItemData;
break; break;
case (TYPE_LOCAL | TAG_LOCAL_USAGEMIN): case (TYPE_LOCAL | TAG_LOCAL_USAGEMIN):
CurrStateTable->Attributes.Usage.MinMax.Minimum = ReportItemData; UsageMinMax.Minimum = ReportItemData;
break; break;
case (TYPE_LOCAL | TAG_LOCAL_USAGEMAX): case (TYPE_LOCAL | TAG_LOCAL_USAGEMAX):
CurrStateTable->Attributes.Usage.MinMax.Maximum = ReportItemData; UsageMinMax.Maximum = ReportItemData;
break; break;
case (TYPE_MAIN | TAG_MAIN_COLLECTION): case (TYPE_MAIN | TAG_MAIN_COLLECTION):
if (CurrCollectionPath == NULL) if (CurrCollectionPath == NULL)
...@@ -196,6 +197,10 @@ uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID ...@@ -196,6 +197,10 @@ uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID
UsageListSize--; UsageListSize--;
} }
else if (UsageMinMax.Minimum <= UsageMinMax.Maximum)
{
CurrCollectionPath->Usage.Usage = UsageMinMax.Minimum++;
}
break; break;
case (TYPE_MAIN | TAG_MAIN_ENDCOLLECTION): case (TYPE_MAIN | TAG_MAIN_ENDCOLLECTION):
...@@ -228,6 +233,10 @@ uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID ...@@ -228,6 +233,10 @@ uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID
UsageListSize--; UsageListSize--;
} }
else if (UsageMinMax.Minimum <= UsageMinMax.Maximum)
{
CurrCollectionPath->Usage.Usage = UsageMinMax.Minimum++;
}
uint8_t ItemTag = (HIDReportItem & TAG_MASK); uint8_t ItemTag = (HIDReportItem & TAG_MASK);
...@@ -262,8 +271,8 @@ uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID ...@@ -262,8 +271,8 @@ uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID
if ((HIDReportItem & TYPE_MASK) == TYPE_MAIN) if ((HIDReportItem & TYPE_MASK) == TYPE_MAIN)
{ {
CurrStateTable->Attributes.Usage.MinMax.Minimum = 0; UsageMinMax.Minimum = 0;
CurrStateTable->Attributes.Usage.MinMax.Maximum = 0; UsageMinMax.Maximum = 0;
UsageListSize = 0; UsageListSize = 0;
} }
} }
...@@ -280,6 +289,7 @@ bool USB_GetHIDReportItemInfo(const uint8_t* ReportData, HID_ReportItem_t* const ...@@ -280,6 +289,7 @@ bool USB_GetHIDReportItemInfo(const uint8_t* ReportData, HID_ReportItem_t* const
uint16_t CurrentBit = ReportItem->BitOffset; uint16_t CurrentBit = ReportItem->BitOffset;
uint32_t BitMask = (1 << 0); uint32_t BitMask = (1 << 0);
ReportItem->PreviousValue = ReportItem->Value;
ReportItem->Value = 0; ReportItem->Value = 0;
if (ReportItem->ReportID) if (ReportItem->ReportID)
...@@ -314,6 +324,8 @@ void USB_SetHIDReportItemInfo(uint8_t* ReportData, const HID_ReportItem_t* Repor ...@@ -314,6 +324,8 @@ void USB_SetHIDReportItemInfo(uint8_t* ReportData, const HID_ReportItem_t* Repor
ReportData++; ReportData++;
} }
ReportItem->PreviousValue = ReportItem->Value;
while (DataBitsRem--) while (DataBitsRem--)
{ {
if (ReportItem->Value & (1 << (CurrentBit % 8))) if (ReportItem->Value & (1 << (CurrentBit % 8)))
......
...@@ -71,7 +71,7 @@ ...@@ -71,7 +71,7 @@
extern "C" { extern "C" {
#endif #endif
/* Preprocessor checks and defines: */ /* Macros: */
#if !defined(HID_STATETABLE_STACK_DEPTH) || defined(__DOXYGEN__) #if !defined(HID_STATETABLE_STACK_DEPTH) || defined(__DOXYGEN__)
/** Constant indicating the maximum stack depth of the state table. A larger state table /** 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 * allows for more PUSH/POP report items to be nested, but consumes more memory. By default
...@@ -124,6 +124,17 @@ ...@@ -124,6 +124,17 @@
#define HID_MAX_REPORT_IDS 10 #define HID_MAX_REPORT_IDS 10
#endif #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: */ /* Public Interface - May be used in end-application: */
/* Enums: */ /* Enums: */
/** Enum for the possible error codes in the return value of the \ref USB_ProcessHIDReport() function */ /** Enum for the possible error codes in the return value of the \ref USB_ProcessHIDReport() function */
...@@ -160,7 +171,6 @@ ...@@ -160,7 +171,6 @@
{ {
uint16_t Page; /**< Usage page of the report item. */ uint16_t Page; /**< Usage page of the report item. */
uint16_t Usage; /**< Usage 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; } HID_Usage_t;
/** Type define for a COLLECTION object. Contains the collection attributes and a reference to the /** Type define for a COLLECTION object. Contains the collection attributes and a reference to the
...@@ -196,6 +206,7 @@ ...@@ -196,6 +206,7 @@
HID_ReportItem_Attributes_t Attributes; /**< Report item attributes. */ HID_ReportItem_Attributes_t Attributes; /**< Report item attributes. */
uint32_t Value; /**< Current value of the report item. */ uint32_t Value; /**< Current value of the report item. */
uint32_t PreviousValue; /**< Previous value of the report item. */
} HID_ReportItem_t; } HID_ReportItem_t;
/** Type define for a report item size information structure */ /** Type define for a report item size information structure */
...@@ -243,6 +254,9 @@ ...@@ -243,6 +254,9 @@
/** Extracts the given report item's value out of the given HID report and places it into the Value /** 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. * 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] 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 * \param[in,out] ReportItem Pointer to the report item of interest in a \ref HID_ReportInfo_t ReportItem array
* *
...@@ -256,6 +270,9 @@ ...@@ -256,6 +270,9 @@
* buffer. The report buffer is assumed to have the appropriate bits cleared before calling * 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). * 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. * 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 * \param[out] ReportData Buffer holding the current OUT or FEATURE report data
......
...@@ -19,6 +19,8 @@ ...@@ -19,6 +19,8 @@
* - Added PDI programming support for XMEGA devices to the AVRISP programmer project * - 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 * - 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 * 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
* *
* <b>Changed:</b> * <b>Changed:</b>
* - Removed code in the Keyboard demos to send zeroed reports between two reports with differing numbers of keycodes * - Removed code in the Keyboard demos to send zeroed reports between two reports with differing numbers of keycodes
...@@ -45,6 +47,7 @@ ...@@ -45,6 +47,7 @@
* - Fixed misnamed Pipe_SetPipeToken() macro for setting a pipe's direction * - Fixed misnamed Pipe_SetPipeToken() macro for setting a pipe's direction
* - Fixed CDCHost failing on devices with bidirectional endpoints * - Fixed CDCHost failing on devices with bidirectional endpoints
* - Fixed USB driver failing to define the PLL prescaler mask for the ATMEGA8U2 and ATMEGA16U2 * - 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 * \section Sec_ChangeLog091122 Version 091122
* *
......
...@@ -17,6 +17,9 @@ ...@@ -17,6 +17,9 @@
* now named \ref SImage_Host_USBTask() and \ref SImage_Host_ConfigurePipes() respectively. * 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 * - 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. * 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.
* *
* <b>Device Mode</b> * <b>Device Mode</b>
* - The CALLBACK_HID_Device_CreateHIDReport() HID Device Class driver callback now has a new ReportType parameter to * - The CALLBACK_HID_Device_CreateHIDReport() HID Device Class driver callback now has a new ReportType parameter to
......
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
#include "V2Protocol.h" #include "V2Protocol.h"
/* Preprocessor Checks: */ /* Preprocessor Checks: */
#if BOARD == BOARD_XPLAIN #if (BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1)
#undef ENABLE_ISP_PROTOCOL #undef ENABLE_ISP_PROTOCOL
#if !defined(ENABLE_PDI_PROTOCOL) #if !defined(ENABLE_PDI_PROTOCOL)
......
...@@ -48,7 +48,7 @@ ...@@ -48,7 +48,7 @@
#include "V2ProtocolParams.h" #include "V2ProtocolParams.h"
/* Preprocessor Checks: */ /* Preprocessor Checks: */
#if BOARD == BOARD_XPLAIN #if (BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1)
#undef ENABLE_ISP_PROTOCOL #undef ENABLE_ISP_PROTOCOL
#if !defined(ENABLE_PDI_PROTOCOL) #if !defined(ENABLE_PDI_PROTOCOL)
......
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
#include "PDITarget.h" #include "PDITarget.h"
/* Preprocessor Checks: */ /* Preprocessor Checks: */
#if BOARD == BOARD_XPLAIN #if (BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1)
#undef ENABLE_ISP_PROTOCOL #undef ENABLE_ISP_PROTOCOL
#if !defined(ENABLE_PDI_PROTOCOL) #if !defined(ENABLE_PDI_PROTOCOL)
......
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
/** Writes a given byte to the attached XMEGA device, using a RS232 frame via software through the /** Writes a given byte to the attached XMEGA device, using a RS232 frame via software through the
* PDI interface. * 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) void PDITarget_SendByte(uint8_t Byte)
{ {
......
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
#include <LUFA/Common/Common.h> #include <LUFA/Common/Common.h>
/* Preprocessor Checks: */ /* Preprocessor Checks: */
#if BOARD == BOARD_XPLAIN #if (BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1)
#undef ENABLE_ISP_PROTOCOL #undef ENABLE_ISP_PROTOCOL
#if !defined(ENABLE_PDI_PROTOCOL) #if !defined(ENABLE_PDI_PROTOCOL)
......
...@@ -47,7 +47,7 @@ ...@@ -47,7 +47,7 @@
#include "PDIProtocol.h" #include "PDIProtocol.h"
/* Preprocessor Checks: */ /* Preprocessor Checks: */
#if BOARD == BOARD_XPLAIN #if (BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1)
#undef ENABLE_ISP_PROTOCOL #undef ENABLE_ISP_PROTOCOL
#if !defined(ENABLE_PDI_PROTOCOL) #if !defined(ENABLE_PDI_PROTOCOL)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment