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.
pull/1469/head
Dean Camera 15 years ago
parent f338ddcb87
commit 2919aeeaab

@ -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)
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));

@ -40,7 +40,8 @@ uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID
HID_CollectionPath_t* CurrCollectionPath = NULL; HID_CollectionPath_t* CurrCollectionPath = NULL;
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
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
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
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,9 +271,9 @@ 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
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
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 @@
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 @@
#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 @@
{ {
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 @@
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 @@
/** 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 @@
* 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 @@
* - 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 @@
* - 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 @@
* 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 @@
#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 @@
#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 @@
#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 @@
/** 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 @@
#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 @@
#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)

Loading…
Cancel
Save