9
0
Fork 0

Add HID parser from LUFA

git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@3303 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
patacongo 2011-02-19 23:07:58 +00:00
parent b8945cd913
commit 435459ad2f
7 changed files with 970 additions and 46 deletions

View File

@ -61,6 +61,32 @@ IGMP support, if enabled in uIP, adds additional logic by Steve Reynolds:
Copyright (c) 2002 CITEL Technologies Ltd.
All rights reserved.
The HID Parser in drivers/usbhost
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Adapted from the LUFA Library (MIT license):
Copyright 2011 Dean Camera (dean [at] fourwalledcubicle [dot] com)
dean [at] fourwalledcubicle [dot] com, www.lufa-lib.org
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
Certain functions in the NuttX C-library derive from other BSD-compatible
sources:

View File

@ -1460,6 +1460,8 @@
* The NuttX repository has been converted to SVN and can now be found here
http://nuttx.svn.sourceforge.net/viewvc/nuttx/
* configs/mbed/hidkbd -- Added USB host support for the mbed LPC1768 board; add
a USB host HID keyboard configuraion.
a USB host HID keyboard configuraion.
* drivers/usbhost/hid_parser.c -- Leverages the LUFA HID parser written by
Dean Camera.

View File

@ -8,7 +8,7 @@
<tr align="center" bgcolor="#e4e4e4">
<td>
<h1><big><font color="#3c34ec"><i>NuttX RTOS</i></font></big></h1>
<p>Last Updated: February 15, 2011</p>
<p>Last Updated: February 19, 2011</p>
</td>
</tr>
</table>
@ -2032,12 +2032,14 @@ nuttx-5.18 2011-xx-xx Gregory Nutt &lt;spudmonkey@racsa.co.cr&gt;
* examplex/wlan, configs/olimex-lpc1766stk/wlan, drivers/usbhost/usbhost_rtl8187.c,
Add infrastructure to support RTL18187 wireless USB.
* configs/nucleus2g -- backed out USB host changes... wrong board.
* Renamed arc/hc/include/mc9s12ne64 and src/mc9s12ne64 -- m9s12. That name is
shorter and more general.
* Renamed arc/hc/include/mc9s12ne64 and src/mc9s12ne64 -- m9s12. That name is
shorter and more general.
* The NuttX repository has been converted to SVN and can now be found here
http://nuttx.svn.sourceforge.net/viewvc/nuttx/
* configs/mbed/hidkbd -- Added USB host support for the mbed LPC1768 board; add
a USB host HID keyboard configuraion.
* configs/mbed/hidkbd -- Added USB host support for the mbed LPC1768 board; add
a USB host HID keyboard configuraion.
* drivers/usbhost/hid_parser.c -- Leverages the LUFA HID parser written by
Dean Camera.
pascal-2.1 2011-xx-xx Gregory Nutt &lt;spudmonkey@racsa.co.cr&gt;

View File

@ -34,7 +34,7 @@
############################################################################
USBHOST_ASRCS =
USBHOST_CSRCS =
USBHOST_CSRCS = hid_parser.c
ifeq ($(CONFIG_USBHOST),y)
USBHOST_CSRCS += usbhost_registry.c usbhost_registerclass.c usbhost_findclass.c

View File

@ -0,0 +1,529 @@
/****************************************************************************
* drivers/usbhost/hid_parser.c
*
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
*
* Adapted from the LUFA Library:
*
* Copyright 2011 Dean Camera (dean [at] fourwalledcubicle [dot] com)
* dean [at] fourwalledcubicle [dot] com, www.lufa-lib.org
*
* Permission to use, copy, modify, distribute, and sell this
* software and its documentation for any purpose is hereby granted
* without fee, provided that the above copyright notice appear in
* all copies and that both that the copyright notice and this
* permission notice and warranty disclaimer appear in supporting
* documentation, and that the name of the author not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
*
* The author disclaim all warranties with regard to this
* software, including all implied warranties of merchantability
* and fitness. In no event shall the author be liable for any
* special, indirect or consequential damages or any damages
* whatsoever resulting from loss of use, data or profits, whether
* in an action of contract, negligence or other tortious action,
* arising out of or in connection with the use or performance of
* this software.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/usb/hid.h>
#include <nuttx/usb/hid_parser.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
struct hid_state_s
{
struct hid_rptitem_attributes_s attrib;
uint8_t rptcount;
uint8_t id;
};
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: hid_parsereport
*
* Description:
* Function to process a given HID report returned from an attached device,
* and store it into a given struct hid_rptinfo_s structure.
*
* Input Parameters:
* report Buffer containing the device's HID report table.
* rptlen Size in bytes of the HID report table.
* filter Callback function to decide if an item should be retained
* rptinfo Pointer to a struct hid_rptinfo_s instance for the parser output.
*
* Returned Value:
* Zero on success, otherwise a negated errno value.
****************************************************************************/
int hid_parsereport(FAR const uint8_t *report, int rptlen,
hid_rptfilter_t filter, FAR struct hid_rptinfo_s *rptinfo)
{
struct hid_state_s state[HID_STATETABLE_STACK_DEPTH];
struct hid_state_s *currstate = &state[0];
struct hid_collectionpath_s *collectionpath = NULL;
struct hid_rptsizeinfo_s *rptidinfo = &rptinfo->rptsize[0];
uint16_t usage[HID_USAGE_STACK_DEPTH];
uint8_t nusage = 0;
struct hid_range_s usage_range = { 0, 0 };
int i;
DEBUGASSERT(report && filter && rptinfo);
memset(rptinfo, 0x00, sizeof(struct hid_rptinfo_s));
memset(currstate, 0x00, sizeof(struct hid_state_s));
memset(rptidinfo, 0x00, sizeof(struct hid_rptsizeinfo_s));
rptinfo->nreports = 1;
while (rptlen > 0)
{
uint8_t item = *report;
uint32_t data = 0;
report++;
rptlen--;
switch (item & USBHID_RPTITEM_SIZE_MASK)
{
case USBHID_RPTITEM_SIZE_4: /* 4 bytes of little endian data follow */
data = (uint32_t)(*report++);
data |= (uint32_t)(*report++) << 8;
data |= (uint32_t)(*report++) << 16;
data |= (uint32_t)(*report++) << 24;
rptlen -= 4;
break;
case USBHID_RPTITEM_SIZE_2: /* 2 bytes of little endian data follow */
data = (uint32_t)(*report++);
data |= (uint32_t)(*report++) << 8;
rptlen -= 2;
break;
case USBHID_RPTITEM_SIZE_1: /* 1 byte of data follows */
data = (uint32_t)(*report++);
rptlen -= 1;
break;
case USBHID_RPTITEM_SIZE_0: /* No data follows */
default:
break;
}
switch (item & ~USBHID_RPTITEM_SIZE_MASK)
{
case USBHID_GLOBAL_PUSH_PREFIX:
if (currstate == &state[HID_STATETABLE_STACK_DEPTH - 1])
{
return -E2BIG;
}
memcpy((currstate + 1),
currstate, sizeof(struct hid_rptitem_s));
currstate++;
break;
case USBHID_GLOBAL_POP_PREFIX:
if (currstate == &state[0])
{
return -EINVAL; /* Pop without push? */
}
currstate--;
break;
case USBHID_GLOBAL_USAGEPAGE_PREFIX:
if ((item & USBHID_RPTITEM_SIZE_MASK) == USBHID_RPTITEM_SIZE_4)
{
currstate->attrib.usage.page = (data >> 16);
}
currstate->attrib.usage.page = data;
break;
case USBHID_GLOBAL_LOGICALMIN_PREFIX:
currstate->attrib.logical.min = data;
break;
case USBHID_GLOBAL_LOGICALMAX_PREFIX:
currstate->attrib.logical.max = data;
break;
case USBHID_GLOBAL_PHYSICALMIN_PREFIX:
currstate->attrib.physical.min = data;
break;
case USBHID_GLOBAL_PHYSMICALAX_PREFIX:
currstate->attrib.physical.max = data;
break;
case USBHID_GLOBAL_UNITEXP_PREFIX:
currstate->attrib.unit.exponent = data;
break;
case USBHID_GLOBAL_UNIT_PREFIX:
currstate->attrib.unit.type = data;
break;
case USBHID_GLOBAL_REPORTSIZE_PREFIX:
currstate->attrib.bitsize = data;
break;
case USBHID_GLOBAL_REPORTCOUNT_PREFIX:
currstate->rptcount = data;
break;
case USBHID_GLOBAL_REPORTID_PREFIX:
currstate->id = data;
if (rptinfo->haverptid)
{
rptidinfo = NULL;
for (i = 0; i < rptinfo->nreports; i++)
{
if (rptinfo->rptsize[i].id == currstate->id)
{
rptidinfo = &rptinfo->rptsize[i];
break;
}
}
if (rptidinfo == NULL)
{
if (rptinfo->nreports == HID_MAX_REPORT_IDS)
{
return -EINVAL;
}
rptidinfo = &rptinfo->rptsize[rptinfo->nreports++];
memset(rptidinfo, 0x00, sizeof(struct hid_rptsizeinfo_s));
}
}
rptinfo->haverptid = true;
rptidinfo->id = currstate->id;
break;
case USBHID_LOCAL_USAGE_PREFIX:
if (nusage == HID_USAGE_STACK_DEPTH)
{
return -E2BIG;
}
usage[nusage++] = data;
break;
case USBHID_LOCAL_USAGEMIN_PREFIX:
usage_range.min = data;
break;
case USBHID_LOCAL_USAGEMAX_PREFIX:
usage_range.max = data;
break;
case USBHID_MAIN_COLLECTION_PREFIX:
if (collectionpath == NULL)
{
collectionpath = &rptinfo->collectionpaths[0];
}
else
{
struct hid_collectionpath_s *ParentCollectionPath = collectionpath;
collectionpath = &rptinfo->collectionpaths[1];
while (collectionpath->parent != NULL)
{
if (collectionpath == &rptinfo->collectionpaths[HID_MAX_COLLECTIONS - 1])
{
return -EINVAL;
}
collectionpath++;
}
collectionpath->parent = ParentCollectionPath;
}
collectionpath->type = data;
collectionpath->usage.page = currstate->attrib.usage.page;
if (nusage)
{
collectionpath->usage.usage = usage[0];
for (i = 0; i < nusage; i++)
usage[i] = usage[i + 1];
nusage--;
}
else if (usage_range.min <= usage_range.max)
{
collectionpath->usage.usage = usage_range.min++;
}
break;
case USBHID_MAIN_ENDCOLLECTION_PREFIX:
if (collectionpath == NULL)
{
return -EINVAL;
}
collectionpath = collectionpath->parent;
break;
case USBHID_MAIN_INPUT_PREFIX:
case USBHID_MAIN_OUTPUT_PREFIX:
case USBHID_MAIN_FEATURE_PREFIX:
{
int itemno;
for (itemno = 0; itemno < currstate->rptcount; itemno++)
{
struct hid_rptitem_s newitem;
uint8_t tag;
memcpy(&newitem.attrib, &currstate->attrib,
sizeof(struct hid_rptitem_attributes_s));
newitem.flags = data;
newitem.collectionpath = collectionpath;
newitem.id = currstate->id;
if (nusage)
{
newitem.attrib.usage.usage = usage[0];
for (i = 0; i < nusage; i++)
{
usage[i] = usage[i + 1];
}
nusage--;
}
else if (usage_range.min <= usage_range.max)
{
newitem.attrib.usage.usage = usage_range.min++;
}
tag = (item & ~USBHID_RPTITEM_SIZE_MASK);
if (tag == USBHID_MAIN_INPUT_PREFIX)
{
newitem.type = USBHID_REPORTTYPE_INPUT;
}
else if (tag == USBHID_MAIN_OUTPUT_PREFIX)
{
newitem.type = USBHID_REPORTTYPE_OUTPUT;
}
else
{
newitem.type = USBHID_REPORTTYPE_FEATURE;
}
newitem.bitoffset = rptidinfo->size[newitem.type];
rptidinfo->size[newitem.type] += currstate->attrib.bitsize;
/* Accumulate the maximum report size */
if (rptinfo->maxrptsize < newitem.bitoffset)
{
rptinfo->maxrptsize = newitem.bitoffset;
}
if ((data & USBHID_MAIN_CONSTANT) == 0 && filter(&newitem))
{
if (rptinfo->nitems == HID_MAX_REPORTITEMS)
{
return -EINVAL;
}
memcpy(&rptinfo->items[rptinfo->nitems],
&newitem, sizeof(struct hid_rptitem_s));
rptinfo->nitems++;
}
}
}
break;
}
if ((item & USBHID_RPTITEM_TYPE_MASK) == USBHID_RPTITEM_TYPE_MAIN)
{
usage_range.min = 0;
usage_range.max = 0;
nusage = 0;
}
}
if (!(rptinfo->nitems))
{
return -ENOENT;
}
return OK;
}
/****************************************************************************
* Name: hid_getitem
*
* Description:
* 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 struct hid_rptitem_s
* structure.
*
* When called on a report with an item that exists in that report, this
* copies the report item's Value to it's previous element for easy
* checking to see if an item's value has changed before processing a
* report. If the given item does not exist in the report, the function
* does not modify the report item's data.
*
* Input Parameters
* report Buffer containing an IN or FEATURE report from an attached
* device.
* item Pointer to the report item of interest in a struct hid_rptinfo_s
* item array.
*
* Returned Value:
* Zero on success, otherwise a negated errno value.
*
****************************************************************************/
int hid_getitem(FAR const uint8_t *report, FAR struct hid_rptitem_s *item)
{
uint16_t remaining = item->attrib.bitsize;
uint16_t offset = item->bitoffset;
uint32_t mask = (1 << 0);
if (item->id)
{
if (item->id != report[0])
{
return -ENOENT;
}
report++;
}
item->previous = item->value;
item->value = 0;
while (remaining--)
{
if (report[offset >> 3] & (1 << (offset & 7)))
{
item->value |= mask;
}
offset++;
mask <<= 1;
}
return OK;
}
/****************************************************************************
* Name: hid_putitem
*
* Desription:
* Retrieves the given report item's value out of the Value member of the
* report item's struct hid_rptitem_s structure and places it into the correct
* position in the HID report 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
* previous 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.
*
* Input Parameters:
* report Buffer holding the current OUT or FEATURE report data.
* item Pointer to the report item of interest in a struct hid_rptinfo_s
* item array.
*
****************************************************************************/
#if 0 /* Not needed by host */
void hid_putitem(FAR uint8_t *report, struct hid_rptitem_s *item)
{
uint16_t remaining = item->attrib.bitsize;
uint16_t offset = item->bitoffset;
uint32_t mask = (1 << 0);
if (item->id)
{
report[0] = item->id;
report++;
}
item->previous = item->value;
while (remaining--)
{
if (item->value & (1 << (offset & 7)))
{
report[offset >> 3] |= mask;
}
offset++;
mask <<= 1;
}
}
#endif
/****************************************************************************
* Name: hid_reportsize
*
* Description:
* Retrieves the size of a given HID report in bytes from it's Report ID.
*
* InputParameters:
* rptinfo Pointer to a struct hid_rptinfo_s instance containing the parser output.
* id Report ID of the report whose size is to be retrieved.
* rpttype Type of the report whose size is to be determined, a valued from the
* HID_ReportItemTypes_t enum.
*
* Size of the report in bytes, or 0 if the report does not exist.
*
****************************************************************************/
size_t hid_reportsize(FAR struct hid_rptinfo_s *rptinfo, uint8_t id, uint8_t rpttype)
{
int i;
for (i = 0; i < HID_MAX_REPORT_IDS; i++)
{
size_t size = rptinfo->rptsize[i].size[rpttype];
if (rptinfo->rptsize[i].id == id)
{
return ((size >> 3) + ((size & 0x07) ? 1 : 0));
}
}
return 0;
}

View File

@ -165,40 +165,63 @@
#define USBHID_COUNTRY_YUGOSLAVIA 0x34 /* Yugoslavia */
#define USBHID_COUNTRY_TURKISHF 0x35 /* Turkish-F */
/* HID report items */
#define USBHID_RPTITEM_SIZE_MASK 0x03
# define USBHID_RPTITEM_SIZE_0 0x00 /* No data follows */
# define USBHID_RPTITEM_SIZE_1 0x01 /* 1 byte of data follows */
# define USBHID_RPTITEM_SIZE_2 0x02 /* 2 bytes of data follow */
# define USBHID_RPTITEM_SIZE_4 0x03 /* 4 bytes of data follow */
#define USBHID_RPTITEM_TYPE_MASK 0x0c
# define USBHID_RPTITEM_TYPE_MAIN 0x00
# define USBHID_RPTITEM_TYPE_GLOBAL 0x04
# define USBHID_RPTITEM_TYPE_LOCAL 0x08
#define USBHID_RPTITEM_TAG_MASK 0xf0
/* Main Items (HID 6.2.2.4) */
#define USBHID_MAIN_SIZE(pfx) ((pfx) & 3)
#define USBHID_MAIN_CONSTANT (1 << 0) /* Constant(1) vs Data(0) */
#define USBHID_MAIN_VARIABLE (1 << 1) /* Variable(1) vs Array(0) */
#define USBHID_MAIN_RELATIVE (1 << 2) /* Relative(1) vs Absolute(0) */
#define USBHID_MAIN_WRAP (1 << 3) /* Wrap(1) vs No Wrap(0) */
#define USBHID_MAIN_NONLINEAR (1 << 4) /* Non Linear(1) vs Linear(0) */
#define USBHID_MAIN_NOPREFERRED (1 << 5) /* No Preferred (1) vs Preferred State(0) */
#define USBHID_MAIN_NULLSTATE (1 << 6) /* Null state(1) vs No Null position(0) */
#define USBHID_MAIN_VOLATILE (1 << 7) /* Volatile(1) vs Non volatile(0) */
#define USBHID_MAIN_BUFFEREDBYTES (1 << 8) /* Buffered Bytes(1) vs Bit Field(0) */
#define USBHID_MAIN_SIZE(pfx) ((pfx) & USBHID_RPTITEM_SIZE_MASK)
#define USBHID_MAIN_INPUT_PREFIX 0x80
#define USBHID_MAIN_INPUT_CONSTANT (1 << 0) /* Constant(1) vs Data(0) */
#define USBHID_MAIN_INPUT_VARIABLE (1 << 1) /* Variable(1) vs Array(0) */
#define USBHID_MAIN_INPUT_RELATIVE (1 << 2) /* Relative(1) vs Absolute(0) */
#define USBHID_MAIN_INPUT_WRAP (1 << 3) /* Wrap(1) vs No Wrap(0) */
#define USBHID_MAIN_INPUT_NONLINEAR (1 << 4) /* Non Linear(1) vs Linear(0) */
#define USBHID_MAIN_INPUT_NOPREFERRED (1 << 5) /* No Preferred (1) vs Preferred State(0) */
#define USBHID_MAIN_INPUT_NULLSTATE (1 << 6) /* Null state(1) vs No Null position(0) */
#define USBHID_MAIN_INPUT_BUFFEREDBYTES (1 << 8) /* Buffered Bytes(1) vs Bit Field(0) */
#define USBHID_MAIN_INPUT_CONSTANT USBHID_MAIN_CONSTANT
#define USBHID_MAIN_INPUT_VARIABLE USBHID_MAIN_VARIABLE
#define USBHID_MAIN_INPUT_RELATIVE USBHID_MAIN_RELATIVE
#define USBHID_MAIN_INPUT_WRAP USBHID_MAIN_WRAP
#define USBHID_MAIN_INPUT_NONLINEAR USBHID_MAIN_NONLINEAR
#define USBHID_MAIN_INPUT_NOPREFERRED USBHID_MAIN_NOPREFERRED
#define USBHID_MAIN_INPUT_NULLSTATE USBHID_MAIN_NULLSTATE
#define USBHID_MAIN_INPUT_BUFFEREDBYTES USBHID_MAIN_BUFFEREDBYTES
#define USBHID_MAIN_OUTPUT_PREFIX 0x90
#define USBHID_MAIN_OUTPUT_CONSTANT (1 << 0) /* Constant(1) vs Data(0) */
#define USBHID_MAIN_OUTPUT_VARIABLE (1 << 1) /* Variable(1) vs Array(0) */
#define USBHID_MAIN_OUTPUT_RELATIVE (1 << 2) /* Relative(1) vs Absolute(0) */
#define USBHID_MAIN_OUTPUT_WRAP (1 << 3) /* Wrap(1) vs No Wrap(0) */
#define USBHID_MAIN_OUTPUT_NONLINEAR (1 << 4) /* Non Linear(1) vs Linear(0) */
#define USBHID_MAIN_OUTPUT_NOPREFERRED (1 << 5) /* No Preferred (1) vs Preferred State(0) */
#define USBHID_MAIN_OUTPUT_NULLSTATE (1 << 6) /* Null state(1) vs No Null position(0) */
#define USBHID_MAIN_OUTPUT_VOLATILE (1 << 7) /* Volatile(1) vs Non volatile(0) */
#define USBHID_MAIN_OUTPUT_BUFFEREDBYTES (1 << 8) /* Buffered Bytes(1) vs Bit Field(0) */
#define USBHID_MAIN_OUTPUT_CONSTANT USBHID_MAIN_CONSTANT
#define USBHID_MAIN_OUTPUT_VARIABLE USBHID_MAIN_VARIABLE
#define USBHID_MAIN_OUTPUT_RELATIVE USBHID_MAIN_RELATIVE
#define USBHID_MAIN_OUTPUT_WRAP USBHID_MAIN_WRAP
#define USBHID_MAIN_OUTPUT_NONLINEAR USBHID_MAIN_NONLINEAR
#define USBHID_MAIN_OUTPUT_NOPREFERRED USBHID_MAIN_NOPREFERRED
#define USBHID_MAIN_OUTPUT_NULLSTATE USBHID_MAIN_NULLSTATE
#define USBHID_MAIN_OUTPUT_VOLATILE USBHID_MAIN_VOLATILE
#define USBHID_MAIN_OUTPUT_BUFFEREDBYTES USBHID_MAIN_BUFFEREDBYTES
#define USBHID_MAIN_FEATURE_PREFIX 0xb0
#define USBHID_MAIN_FEATURE_CONSTANT (1 << 0) /* Constant(1) vs Data(0) */
#define USBHID_MAIN_FEATURE_VARIABLE (1 << 1) /* Variable(1) vs Array(0) */
#define USBHID_MAIN_FEATURE_RELATIVE (1 << 2) /* Relative(1) vs Absolute(0) */
#define USBHID_MAIN_FEATURE_WRAP (1 << 3) /* Wrap(1) vs No Wrap(0) */
#define USBHID_MAIN_FEATURE_NONLINEAR (1 << 4) /* Non Linear(1) vs Linear(0) */
#define USBHID_MAIN_FEATURE_NOPREFERRED (1 << 5) /* No Preferred (1) vs Preferred State(0) */
#define USBHID_MAIN_FEATURE_NULLSTATE (1 << 6) /* Null state(1) vs No Null position(0) */
#define USBHID_MAIN_FEATURE_VOLATILE (1 << 7) /* Volatile(1) vs Non volatile(0) */
#define USBHID_MAIN_FEATURE_BUFFEREDBYTES (1 << 8) /* Buffered Bytes(1) vs Bit Field(0) */
#define USBHID_MAIN_FEATURE_CONSTANT USBHID_MAIN_CONSTANT
#define USBHID_MAIN_FEATURE_VARIABLE USBHID_MAIN_VARIABLE
#define USBHID_MAIN_FEATURE_RELATIVE USBHID_MAIN_RELATIVE
#define USBHID_MAIN_FEATURE_WRAP USBHID_MAIN_WRAP
#define USBHID_MAIN_FEATURE_NONLINEAR USBHID_MAIN_NONLINEAR
#define USBHID_MAIN_FEATURE_NOPREFERRED USBHID_MAIN_NOPREFERRED
#define USBHID_MAIN_FEATURE_NULLSTATE USBHID_MAIN_NULLSTATE
#define USBHID_MAIN_FEATURE_VOLATILE USBHID_MAIN_VOLATILE
#define USBHID_MAIN_FEATURE_BUFFEREDBYTES USBHID_MAIN_BUFFEREDBYTES
#define USBHID_MAIN_COLLECTION_PREFIX 0xa0
#define USBHID_MAIN_COLLECTION_PHYSICAL 0x00 /* Physical (group of axes) */
@ -213,7 +236,7 @@
/* Global Items (HID 6.2.2.7) */
#define USBHID_GLOBAL_SIZE(pfx) ((pfx) & 3)
#define USBHID_GLOBAL_SIZE(pfx) ((pfx) & USBHID_RPTITEM_SIZE_MASK)
#define USBHID_GLOBAL_USAGEPAGE_PREFIX 0x04 /* Usage Page */
#define USBHID_GLOBAL_LOGICALMIN_PREFIX 0x14 /* Logical Minimum */
#define USBHID_GLOBAL_LOGICALMAX_PREFIX 0x24 /* Logical Maximum */
@ -229,17 +252,17 @@
/* Local Items (HID 6.2.2.8) */
#define USBHID_LOCAL_SIZE(pfx) ((pfx) & 3)
#define USBHID_LOCAL_USAGE 0x08 /* Usage */
#define USBHID_LOCAL_USAGEMIN 0x18 /* Usage Minimum */
#define USBHID_LOCAL_USAGEMAX 0x28 /* Usage Maximum */
#define USBHID_LOCAL_DESIGNATORIDX 0x38 /* Designator Index */
#define USBHID_LOCAL_DESIGNATORMIN 0x48 /* Designator Minimum */
#define USBHID_LOCAL_DESIGNATORMAX 0x58 /* Designator Maximum */
#define USBHID_LOCAL_STRINGIDX 0x78 /* String Index */
#define USBHID_LOCAL_STRINGMIN 0x88 /* String Minimum */
#define USBHID_LOCAL_STRINGMAX 0x98 /* xx */
#define USBHID_LOCAL_DELIMITER 0xa8 /*Delimiter */
#define USBHID_LOCAL_SIZE(pfx) ((pfx) & USBHID_RPTITEM_SIZE_MASK)
#define USBHID_LOCAL_USAGE_PREFIX 0x08 /* Usage */
#define USBHID_LOCAL_USAGEMIN_PREFIX 0x18 /* Usage Minimum */
#define USBHID_LOCAL_USAGEMAX_PREFIX 0x28 /* Usage Maximum */
#define USBHID_LOCAL_DESIGNATORIDX_PREFIX 0x38 /* Designator Index */
#define USBHID_LOCAL_DESIGNATORMIN_PREFIX 0x48 /* Designator Minimum */
#define USBHID_LOCAL_DESIGNATORMAX_PREFIX 0x58 /* Designator Maximum */
#define USBHID_LOCAL_STRINGIDX_PREFIX 0x78 /* String Index */
#define USBHID_LOCAL_STRINGMIN_PREFIX 0x88 /* String Minimum */
#define USBHID_LOCAL_STRINGMAX_PREFIX 0x98 /* xx */
#define USBHID_LOCAL_DELIMITER_PREFIX 0xa8 /*Delimiter */
/* Modifier Keys (HID 8.3) */

View File

@ -0,0 +1,342 @@
/****************************************************************************
* include/nuttx/usb/hid_parser.h
*
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
*
* Adapted from the LUFA Library:
*
* Copyright 2011 Dean Camera (dean [at] fourwalledcubicle [dot] com)
* dean [at] fourwalledcubicle [dot] com, www.lufa-lib.org
*
* Permission to use, copy, modify, distribute, and sell this
* software and its documentation for any purpose is hereby granted
* without fee, provided that the above copyright notice appear in
* all copies and that both that the copyright notice and this
* permission notice and warranty disclaimer appear in supporting
* documentation, and that the name of the author not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
*
* The author disclaim all warranties with regard to this
* software, including all implied warranties of merchantability
* and fitness. In no event shall the author be liable for any
* special, indirect or consequential damages or any damages
* whatsoever resulting from loss of use, data or profits, whether
* in an action of contract, negligence or other tortious action,
* arising out of or in connection with the use or performance of
* this software.
*
****************************************************************************/
#ifndef __INCLUDE_NUTTX_USB_HID_PARSER_H
#define __INCLUDE_NUTTX_USB_HID_PARSER_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <string.h>
#include <stdbool.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Configuration ************************************************************/
/* HID_STATETABLE_STACK_DEPTH
* 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 this is set to 2 levels (allowing non-
* nested PUSH items) but this can be overridden by defining
* HID_STATETABLE_STACK_DEPTH in the Nuttx config file.
*
* HID_USAGE_STACK_DEPTH
* Constant indicating the maximum stack depth of the usage table. A larger
* usage table allows for more USAGE items to be indicated sequentially for
* REPORT COUNT entries of more than one, but requires more stack space. By
* default this is set to 8 levels (allowing for a report item with a count
* of 8) but this can be overridden by defining HID_USAGE_STACK_DEPTH to
* in the Nuttx config file.
*
* HID_MAX_COLLECTIONS
* Constant indicating the maximum number of COLLECTION items (nested or
* unnested) that can be processed in the report item descriptor. A large
* value allows for more COLLECTION items to be processed, but consumes
* more memory. By default this is set to 10 collections, but this can be
* overridden by defining HID_MAX_COLLECTIONS in the Nuttx config file.
*
* Constant indicating the maximum number of report items (IN, OUT or
* FEATURE) that can be processed 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 in the Nuttx config file.
*
* 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 10 items, but this can be overridden by defining
* HID_MAX_REPORT_IDS in the Nuttx config file. Note that IN, OUT and FEATURE
* items sharing the same report ID consume only one size item in the array.
*/
#ifndef HID_STATETABLE_STACK_DEPTH
# define HID_STATETABLE_STACK_DEPTH 2
#endif
#ifndef HID_USAGE_STACK_DEPTH
# define HID_USAGE_STACK_DEPTH 8
#endif
#ifndef HID_MAX_COLLECTIONS
# define HID_MAX_COLLECTIONS 10
#endif
#ifndef HID_MAX_REPORTITEMS
# define HID_MAX_REPORTITEMS 20
#endif
#ifndef HID_MAX_REPORT_IDS
# define HID_MAX_REPORT_IDS 10
#endif
/****************************************************************************
* Public Types
****************************************************************************/
/* HID Parser Report Item Min/Max Structure. Type define for an attribute
* with both minimum and maximum values (e.g. Logical Min/Max).
*/
struct hid_range_s
{
uint32_t min; /* Minimum value for the attribute. */
uint32_t max; /* Maximum value for the attribute. */
};
/* HID Parser Report Item Unit Structure. Type define for the Unit attributes
* of a report item.
*/
struct hid_unit_t
{
uint32_t type; /* Unit type (refer to HID specifications for details). */
uint8_t exponent; /* Unit exponent (refer to HID specifications for details). */
};
/* HID Parser Report Item Usage Structure. Type define for the Usage
* attributes of a report item.
*/
struct hid_usage_t
{
uint16_t page; /* Usage page of the report item. */
uint16_t usage; /* Usage of the report item. */
};
/* HID Parser Report Item Collection Path Structure. Type define for a
* COLLECTION object. Contains the collection attributes and a reference to
* the parent collection if any.
*/
struct hid_collectionpath_s
{
uint8_t type; /* Collection type (e.g. "Generic Desktop"). */
struct hid_usage_t usage; /* Collection usage. */
struct hid_collectionpath_s *parent; /* Reference to parent collection, or NULL if root collection. */
};
/* HID Parser Report Item Attributes Structure. Type define for all the data
* attributes of a report item, except flags.
*/
struct hid_rptitem_attributes_s
{
uint8_t bitsize; /* Size in bits of the report item's data. */
struct hid_usage_t usage; /* Usage of the report item. */
struct hid_unit_t unit; /* Unit type and exponent of the report item. */
struct hid_range_s logical; /* Logical minimum and maximum of the report item. */
struct hid_range_s physical; /* Physical minimum and maximum of the report item. */
};
/* HID Parser Report Item Details Structure. Type define for a report item
* (IN, OUT or FEATURE) layout attributes and other details.
*/
struct hid_rptitem_s
{
uint16_t bitoffset; /* Bit offset in the IN, OUT or FEATURE report of the item. */
uint8_t type; /* Report item type, a value in HID_ReportItemTypes_t. */
uint16_t flags; /* Item data flags, a mask of HID_IOF_* constants. */
uint8_t id; /* Report ID this item belongs to, or 0x00 if device has only one report */
struct hid_collectionpath_s *collectionpath; /* Collection path of the item. */
struct hid_rptitem_attributes_s attrib; /* Report item attributes. */
uint32_t value; /* Current value of the report item */
uint32_t previous; /* Previous value of the report item. */
};
/* HID Parser Report Size Structure. Type define for a report item size
* information structure, to retain the size of a device's reports by ID.
*/
struct hid_rptsizeinfo_s
{
uint8_t id; /* Report ID of the report within the HID interface. */
uint16_t size[3]; /* Number of bits in each report type for the given Report ID */
};
/* HID Parser State Structure. Type define for a complete processed HID
* report, including all report item data and collections.
*/
struct hid_rptinfo_s
{
/* nitems is the number of report items stored in the report items array (rptitems[]). */
uint8_t nitems;
struct hid_rptitem_s items[HID_MAX_REPORTITEMS];
/* All collection items, referenced by the report items. */
struct hid_collectionpath_s collectionpaths[HID_MAX_COLLECTIONS];
uint8_t nreports; /* Number of reports within the HID interface */
struct hid_rptsizeinfo_s rptsize[HID_MAX_REPORT_IDS]; /* Report sizes for each report in the interface */
uint16_t maxrptsize; /* Largest report that the attached device will generate, in bits */
bool haverptid; /* Device has at least one REPORT ID in its HID report. */
};
/* Callback routine for the HID Report Parser. This callback must be
* implemented by the user code when the parser is used, to determine what
* report IN, OUT and FEATURE item's information is stored into the user
* struct hid_rptinfo_s structure. This can be used to filter only those
* items the application will be using, so that no RAM is wasted storing
* the attributes for report items which will never be referenced by the
* application.
*
* Input Parameters:
* item Pointer to the current report item for user checking.
*
* Returned value:
* Boolean true if the item should be stored into the struct hid_rptinfo_s
* structure, false if it should be ignored.
*/
typedef bool (*hid_rptfilter_t)(FAR struct hid_rptitem_s *item);
/****************************************************************************
* Public Function Protoypes
****************************************************************************/
#undef EXTERN
#if defined(__cplusplus)
# define EXTERN extern "C"
extern "C" {
#else
# define EXTERN extern
#endif
/****************************************************************************
* Name: hid_parsereport
*
* Description:
* Function to process a given HID report returned from an attached device,
* and store it into a given struct hid_rptinfo_s structure.
*
* Input Parameters:
* report Buffer containing the device's HID report table.
* rptlen Size in bytes of the HID report table.
* filter Callback function to decide if an item should be retained
* rptinfo Pointer to a struct hid_rptinfo_s instance for the parser output.
*
* Returned Value:
* Zero on success, otherwise a negated errno value.
****************************************************************************/
EXTERN int hid_parsereport(FAR const uint8_t *report, int rptlen,
hid_rptfilter_t filter,
FAR struct hid_rptinfo_s *rptinfo);
/****************************************************************************
* Name: hid_getitem
*
* Description:
* 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 struct hid_rptitem_s
* structure.
*
* When called on a report with an item that exists in that report, this
* copies the report item's Value to it's previous element for easy
* checking to see if an item's value has changed before processing a
* report. If the given item does not exist in the report, the function
* does not modify the report item's data.
*
* Input Parameters
* report Buffer containing an IN or FEATURE report from an attached
* device.
* item Pointer to the report item of interest in a struct hid_rptinfo_s
* item array.
*
* Returned Value:
* Zero on success, otherwise a negated errno value.
*
****************************************************************************/
EXTERN int hid_getitem(FAR const uint8_t *report, FAR struct hid_rptitem_s *item);
/****************************************************************************
* Name: hid_putitem
*
* Desription:
* Retrieves the given report item's value out of the value member of the
* report item's struct hid_rptitem_s structure and places it into the correct
* position in the HID report 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
* previous 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.
*
* Input Parameters:
* report Buffer holding the current OUT or FEATURE report data.
* item Pointer to the report item of interest in a struct hid_rptinfo_s
* item array.
*
****************************************************************************/
#if 0 /* Not needed by host */
EXTERN void hid_putitem(FAR uint8_t *report, FAR struct hid_rptitem_s *item);
#endif
/****************************************************************************
* Name: hid_reportsize
*
* Description:
* Retrieves the size of a given HID report in bytes from it's Report ID.
*
* InputParameters:
* rptinfo Pointer to a struct hid_rptinfo_s instance containing the parser output.
* id Report ID of the report whose size is to be retrieved.
* rpttype Type of the report whose size is to be determined, a valued from the
* HID_ReportItemTypes_t enum.
*
* Size of the report in bytes, or 0 if the report does not exist.
*
****************************************************************************/
EXTERN size_t hid_reportsize(FAR struct hid_rptinfo_s *rptinfo,
uint8_t id, uint8_t rpttype);
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __INCLUDE_NUTTX_USB_HID_PARSER_H */