summaryrefslogtreecommitdiff
path: root/nuttx
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-02-19 23:07:58 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-02-19 23:07:58 +0000
commitb5a0fbcbe0a71eb6ce04227f38647a85cd725466 (patch)
treef8e5739d3c84e16baaa9beb9f5f2afa2e08d6bf6 /nuttx
parentebb647ce35e507d5e408ab220d65c1f12ce5539b (diff)
downloadpx4-nuttx-b5a0fbcbe0a71eb6ce04227f38647a85cd725466.tar.gz
px4-nuttx-b5a0fbcbe0a71eb6ce04227f38647a85cd725466.tar.bz2
px4-nuttx-b5a0fbcbe0a71eb6ce04227f38647a85cd725466.zip
Add HID parser from LUFA
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3303 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx')
-rwxr-xr-xnuttx/COPYING26
-rw-r--r--nuttx/ChangeLog4
-rw-r--r--nuttx/Documentation/NuttX.html12
-rw-r--r--nuttx/drivers/usbhost/Make.defs2
-rw-r--r--nuttx/drivers/usbhost/hid_parser.c529
-rwxr-xr-xnuttx/include/nuttx/usb/hid.h101
-rw-r--r--nuttx/include/nuttx/usb/hid_parser.h342
7 files changed, 970 insertions, 46 deletions
diff --git a/nuttx/COPYING b/nuttx/COPYING
index e5e6238ad..3f85e869e 100755
--- a/nuttx/COPYING
+++ b/nuttx/COPYING
@@ -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:
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index cf5527d58..cdb664034 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -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.
diff --git a/nuttx/Documentation/NuttX.html b/nuttx/Documentation/NuttX.html
index 2e02a0f61..5ce0d0b1a 100644
--- a/nuttx/Documentation/NuttX.html
+++ b/nuttx/Documentation/NuttX.html
@@ -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;
diff --git a/nuttx/drivers/usbhost/Make.defs b/nuttx/drivers/usbhost/Make.defs
index 6fcca4b59..531ff983d 100644
--- a/nuttx/drivers/usbhost/Make.defs
+++ b/nuttx/drivers/usbhost/Make.defs
@@ -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
diff --git a/nuttx/drivers/usbhost/hid_parser.c b/nuttx/drivers/usbhost/hid_parser.c
new file mode 100644
index 000000000..269aa73de
--- /dev/null
+++ b/nuttx/drivers/usbhost/hid_parser.c
@@ -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;
+}
diff --git a/nuttx/include/nuttx/usb/hid.h b/nuttx/include/nuttx/usb/hid.h
index 81e515b82..e5bea9c32 100755
--- a/nuttx/include/nuttx/usb/hid.h
+++ b/nuttx/include/nuttx/usb/hid.h
@@ -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) */
diff --git a/nuttx/include/nuttx/usb/hid_parser.h b/nuttx/include/nuttx/usb/hid_parser.h
new file mode 100644
index 000000000..23cbf390c
--- /dev/null
+++ b/nuttx/include/nuttx/usb/hid_parser.h
@@ -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 */