copied over all of the custom pcb stuff and switched connectors + added PWM headers to the power board

git-svn-id: https://robotics.mvla.net/svn/frc971/2013/trunk/src@4029 f308d9b7-e957-4cde-b6ac-9a88185e7312
diff --git a/gyro_board/src/usb/LPCUSB/USB_CDC.c b/gyro_board/src/usb/LPCUSB/USB_CDC.c
new file mode 100644
index 0000000..47d28db
--- /dev/null
+++ b/gyro_board/src/usb/LPCUSB/USB_CDC.c
@@ -0,0 +1,454 @@
+/*
+	LPCUSB, an USB device driver for LPC microcontrollers
+	Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
+
+	Redistribution and use in source and binary forms, with or without
+	modification, are permitted provided that the following conditions are met:
+
+	1. Redistributions of source code must retain the above copyright
+	   notice, this list of conditions and the following disclaimer.
+	2. Redistributions in binary form must reproduce the above copyright
+	   notice, this list of conditions and the following disclaimer in the
+	   documentation and/or other materials provided with the distribution.
+	3. The name of the author may not be used to endorse or promote products
+	   derived from this software without specific prior written permission.
+
+	THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+	IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+	OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+	IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+	INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+	NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+	DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+	THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+	(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+	THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+	Minimal implementation of a USB serial port, using the CDC class.
+	This example application simply echoes everything it receives right back
+	to the host.
+
+	Windows:
+	Extract the usbser.sys file from .cab file in C:\WINDOWS\Driver Cache\i386
+	and store it somewhere (C:\temp is a good place) along with the usbser.inf
+	file. Then plug in the LPC176x and direct windows to the usbser driver.
+	Windows then creates an extra COMx port that you can open in a terminal
+	program, like hyperterminal. [Note for FreeRTOS users - the required .inf
+	file is included in the project directory.]
+
+	Linux:
+	The device should be recognised automatically by the cdc_acm driver,
+	which creates a /dev/ttyACMx device file that acts just like a regular
+	serial port.
+
+*/
+
+#include "FreeRTOS.h"
+#include "queue.h"
+#include "task.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include "usbapi.h"
+#include "usbdebug.h"
+#include "usbstruct.h"
+
+#include "LPC17xx.h"
+
+#define usbMAX_SEND_BLOCK		( 20 / portTICK_RATE_MS )
+#define usbRXBUFFER_LEN			( 80 )
+#define usbTXBUFFER_LEN			( 600 )
+
+#define INCREMENT_ECHO_BY 0
+#define BAUD_RATE	115200
+
+#define INT_IN_EP		0x81
+#define BULK_OUT_EP		0x05
+#define BULK_IN_EP		0x82
+
+#define MAX_PACKET_SIZE	64
+
+#define LE_WORD(x)		((x)&0xFF),((x)>>8)
+
+// CDC definitions
+#define CS_INTERFACE			0x24
+#define CS_ENDPOINT				0x25
+
+#define	SET_LINE_CODING			0x20
+#define	GET_LINE_CODING			0x21
+#define	SET_CONTROL_LINE_STATE	0x22
+
+// data structure for GET_LINE_CODING / SET_LINE_CODING class requests
+typedef struct {
+	unsigned long		dwDTERate;
+	unsigned char		bCharFormat;
+	unsigned char		bParityType;
+	unsigned char		bDataBits;
+} TLineCoding;
+
+static TLineCoding LineCoding = {115200, 0, 0, 8};
+static unsigned char abBulkBuf[64];
+static unsigned char abClassReqData[8];
+
+static xQueueHandle xRxedChars = NULL, xCharsForTx = NULL;
+
+// forward declaration of interrupt handler
+void USBIntHandler(void);
+
+static const unsigned char abDescriptors[] = {
+
+// device descriptor
+	0x12,
+	DESC_DEVICE,
+	LE_WORD(0x0101),		// bcdUSB
+	0x02,				// bDeviceClass
+	0x00,				// bDeviceSubClass
+	0x00,				// bDeviceProtocol
+	MAX_PACKET_SIZE0,		// bMaxPacketSize
+	LE_WORD(0xFFFF),		// idVendor
+	LE_WORD(0x0005),		// idProduct
+	LE_WORD(0x0100),		// bcdDevice
+	0x01,				// iManufacturer
+	0x02,				// iProduct
+	0x03,				// iSerialNumber
+	0x01,				// bNumConfigurations
+
+// configuration descriptor
+	0x09,
+	DESC_CONFIGURATION,
+	LE_WORD(67),			// wTotalLength
+	0x02,				// bNumInterfaces
+	0x01,				// bConfigurationValue
+	0x00,				// iConfiguration
+	0xC0,				// bmAttributes
+	0x32,				// bMaxPower
+// control class interface
+	0x09,
+	DESC_INTERFACE,
+	0x00,				// bInterfaceNumber
+	0x00,				// bAlternateSetting
+	0x01,				// bNumEndPoints
+	0x02,				// bInterfaceClass
+	0x02,				// bInterfaceSubClass
+	0x01,				// bInterfaceProtocol, linux requires value of 1 for the cdc_acm module
+	0x00,				// iInterface
+// header functional descriptor
+	0x05,
+	CS_INTERFACE,
+	0x00,
+	LE_WORD(0x0110),
+// call management functional descriptor
+	0x05,
+	CS_INTERFACE,
+	0x01,
+	0x01,				// bmCapabilities = device handles call management
+	0x01,				// bDataInterface
+// ACM functional descriptor
+	0x04,
+	CS_INTERFACE,
+	0x02,
+	0x02,				// bmCapabilities
+// union functional descriptor
+	0x05,
+	CS_INTERFACE,
+	0x06,
+	0x00,				// bMasterInterface
+	0x01,				// bSlaveInterface0
+// notification EP
+	0x07,
+	DESC_ENDPOINT,
+	INT_IN_EP,			// bEndpointAddress
+	0x03,				// bmAttributes = intr
+	LE_WORD(8),			// wMaxPacketSize
+	0x0A,				// bInterval
+// data class interface descriptor
+	0x09,
+	DESC_INTERFACE,
+	0x01,				// bInterfaceNumber
+	0x00,				// bAlternateSetting
+	0x02,				// bNumEndPoints
+	0x0A,				// bInterfaceClass = data
+	0x00,				// bInterfaceSubClass
+	0x00,				// bInterfaceProtocol
+	0x00,				// iInterface
+// data EP OUT
+	0x07,
+	DESC_ENDPOINT,
+	BULK_OUT_EP,			// bEndpointAddress
+	0x02,				// bmAttributes = bulk
+	LE_WORD(MAX_PACKET_SIZE),	// wMaxPacketSize
+	0x00,				// bInterval
+// data EP in
+	0x07,
+	DESC_ENDPOINT,
+	BULK_IN_EP,			// bEndpointAddress
+	0x02,				// bmAttributes = bulk
+	LE_WORD(MAX_PACKET_SIZE),	// wMaxPacketSize
+	0x00,				// bInterval
+
+	// string descriptors
+	0x04,
+	DESC_STRING,
+	LE_WORD(0x0409),
+
+	0x0E,
+	DESC_STRING,
+	'L', 0, 'P', 0, 'C', 0, 'U', 0, 'S', 0, 'B', 0,
+
+	0x14,
+	DESC_STRING,
+	'U', 0, 'S', 0, 'B', 0, 'S', 0, 'e', 0, 'r', 0, 'i', 0, 'a', 0, 'l', 0,
+
+	0x12,
+	DESC_STRING,
+	'A', 0, 'B', 0, 'S', 0, 'M', 0, 'o', 0, 't', 0, 'o', 0, 'r', 0,
+
+// terminating zero
+	0
+};
+
+
+/**
+	Local function to handle incoming bulk data
+
+	@param [in] bEP
+	@param [in] bEPStatus
+ */
+static void BulkOut(unsigned char bEP, unsigned char bEPStatus)
+{
+	int i, iLen;
+	long lHigherPriorityTaskWoken = pdFALSE;
+
+	(void) bEPStatus;
+
+	// get data from USB into intermediate buffer
+	iLen = USBHwEPRead(bEP, abBulkBuf, sizeof(abBulkBuf));
+	for (i = 0; i < iLen; i++) {
+		// put into queue
+		xQueueSendFromISR(xRxedChars, &(abBulkBuf[ i ]), &lHigherPriorityTaskWoken);
+	}
+
+	portEND_SWITCHING_ISR(lHigherPriorityTaskWoken);
+}
+
+
+/**
+	Local function to handle outgoing bulk data
+
+	@param [in] bEP
+	@param [in] bEPStatus
+ */
+static void BulkIn(unsigned char bEP, unsigned char bEPStatus)
+{
+	int i, iLen;
+	long lHigherPriorityTaskWoken = pdFALSE;
+
+	(void) bEPStatus;
+
+	if (uxQueueMessagesWaitingFromISR(xCharsForTx) == 0) {
+		// no more data, disable further NAK interrupts until next USB frame
+		USBHwNakIntEnable(0);
+		return;
+	}
+
+	// get bytes from transmit FIFO into intermediate buffer
+	for (i = 0; i < MAX_PACKET_SIZE; i++) {
+		if (xQueueReceiveFromISR(xCharsForTx, (&abBulkBuf[i]), &lHigherPriorityTaskWoken) != pdPASS) {
+			break;
+		}
+	}
+	iLen = i;
+
+	// send over USB
+	if (iLen > 0) {
+		USBHwEPWrite(bEP, abBulkBuf, iLen);
+	}
+
+	portEND_SWITCHING_ISR(lHigherPriorityTaskWoken);
+}
+
+
+/**
+	Local function to handle the USB-CDC class requests
+
+	@param [in] pSetup
+	@param [out] piLen
+	@param [out] ppbData
+ */
+static BOOL HandleClassRequest(TSetupPacket *pSetup, int *piLen, unsigned char **ppbData)
+{
+	switch (pSetup->bRequest) {
+
+		// set line coding
+	case SET_LINE_CODING:
+		DBG("SET_LINE_CODING\n");
+		memcpy((unsigned char *)&LineCoding, *ppbData, 7);
+		*piLen = 7;
+		DBG("dwDTERate=%u, bCharFormat=%u, bParityType=%u, bDataBits=%u\n",
+		    LineCoding.dwDTERate,
+		    LineCoding.bCharFormat,
+		    LineCoding.bParityType,
+		    LineCoding.bDataBits);
+		break;
+
+		// get line coding
+	case GET_LINE_CODING:
+		DBG("GET_LINE_CODING\n");
+		*ppbData = (unsigned char *) & LineCoding;
+		*piLen = 7;
+		break;
+
+		// set control line state
+	case SET_CONTROL_LINE_STATE:
+		// bit0 = DTR, bit = RTS
+		DBG("SET_CONTROL_LINE_STATE %X\n", pSetup->wValue);
+		break;
+
+	default:
+		return FALSE;
+	}
+	return TRUE;
+}
+
+
+/**
+	Writes one character to VCOM port
+
+	@param [in] c character to write
+	@returns character written, or EOF if character could not be written
+ */
+int VCOM_putchar(int c)
+{
+	char cc = (char) c;
+
+	if (xQueueSend(xCharsForTx, &cc, usbMAX_SEND_BLOCK) == pdPASS) {
+		return c;
+	} else {
+		return EOF;
+	}
+}
+
+
+/**
+	Reads one character from VCOM port
+
+	@returns character read, or EOF if character could not be read
+ */
+int VCOM_getchar(void)
+{
+	unsigned char c;
+
+	/* Block the task until a character is available. */
+	xQueueReceive(xRxedChars, &c, portMAX_DELAY);
+	return c;
+}
+
+
+/**
+	Interrupt handler
+
+	Simply calls the USB ISR
+ */
+void USB_IRQHandler(void)
+{
+	USBHwISR();
+}
+
+
+static void USBFrameHandler(unsigned short wFrame)
+{
+	(void) wFrame;
+
+	if (uxQueueMessagesWaitingFromISR(xCharsForTx) > 0) {
+		// data available, enable NAK interrupt on bulk in
+		USBHwNakIntEnable(INACK_BI);
+	}
+}
+
+unsigned long CPUcpsie(void)
+{
+	unsigned long ulRet;
+
+	//
+	// Read PRIMASK and enable interrupts.
+	//
+	__asm("    mrs     %0, PRIMASK\n"
+	      "    cpsie   i\n"
+	      "    bx      lr\n"
+      : "=r"(ulRet));
+
+	//
+	// The return is handled in the inline assembly, but the compiler will
+	// still complain if there is not an explicit return here (despite the fact
+	// that this does not result in any code being produced because of the
+	// naked attribute).
+	//
+	return(ulRet);
+}
+
+void vUSBTask(void *pvParameters)
+{
+	//int c;
+	portTickType xLastFlashTime;
+
+	/* Just to prevent compiler warnings about the unused parameter. */
+	(void) pvParameters;
+	DBG("Initialising USB stack\n");
+
+	xRxedChars = xQueueCreate(usbRXBUFFER_LEN, sizeof(char));
+	xCharsForTx = xQueueCreate(usbTXBUFFER_LEN, sizeof(char));
+
+	if ((xRxedChars == NULL) || (xCharsForTx == NULL)) {
+		/* Not enough heap available to create the buffer queues, can't do
+		anything so just delete ourselves. */
+		vTaskDelete(NULL);
+	}
+
+
+	// initialise stack
+	USBInit();
+
+	// register descriptors
+	USBRegisterDescriptors(abDescriptors);
+
+	// register class request handler
+	USBRegisterRequestHandler(REQTYPE_TYPE_CLASS, HandleClassRequest, abClassReqData);
+
+	// register endpoint handlers
+	USBHwRegisterEPIntHandler(INT_IN_EP, NULL);
+	USBHwRegisterEPIntHandler(BULK_IN_EP, BulkIn);
+	USBHwRegisterEPIntHandler(BULK_OUT_EP, BulkOut);
+
+	// register frame handler
+	USBHwRegisterFrameHandler(USBFrameHandler);
+
+	// enable bulk-in interrupts on NAKs
+	USBHwNakIntEnable(INACK_BI);
+
+	DBG("Starting USB communication\n");
+
+	NVIC_SetPriority(USB_IRQn, configUSB_INTERRUPT_PRIORITY);
+	NVIC_EnableIRQ(USB_IRQn);
+
+	// connect to bus
+
+	DBG("Connecting to USB bus\n");
+	USBHwConnect(TRUE);
+	
+	xLastFlashTime = xTaskGetTickCount();
+	
+	// echo any character received (do USB stuff in interrupt)
+	for (;;) {
+	//	c = VCOM_getchar();
+	//	if (c != EOF) {
+	//		// Echo character back with INCREMENT_ECHO_BY offset, so for example if
+	//		// INCREMENT_ECHO_BY is 1 and 'A' is received, 'B' will be echoed back.
+	//		VCOM_putchar(c + INCREMENT_ECHO_BY);
+	//	}
+		vTaskDelayUntil(&xLastFlashTime, 1000 / portTICK_RATE_MS);
+	}
+}
+
diff --git a/gyro_board/src/usb/LPCUSB/USB_SENSOR_STREAM.c b/gyro_board/src/usb/LPCUSB/USB_SENSOR_STREAM.c
new file mode 100644
index 0000000..af1eede
--- /dev/null
+++ b/gyro_board/src/usb/LPCUSB/USB_SENSOR_STREAM.c
@@ -0,0 +1,355 @@
+/*
+	LPCUSB, an USB device driver for LPC microcontrollers
+	Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
+
+	Redistribution and use in source and binary forms, with or without
+	modification, are permitted provided that the following conditions are met:
+
+	1. Redistributions of source code must retain the above copyright
+	   notice, this list of conditions and the following disclaimer.
+	2. Redistributions in binary form must reproduce the above copyright
+	   notice, this list of conditions and the following disclaimer in the
+	   documentation and/or other materials provided with the distribution.
+	3. The name of the author may not be used to endorse or promote products
+	   derived from this software without specific prior written permission.
+
+	THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+	IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+	OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+	IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+	INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+	NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+	DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+	THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+	(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+	THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "FreeRTOS.h"
+#include "queue.h"
+#include "task.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include "usbapi.h"
+#include "usbdebug.h"
+#include "usbstruct.h"
+
+#include "LPC17xx.h"
+
+#define usbMAX_SEND_BLOCK		( 20 / portTICK_RATE_MS )
+#define usbRXBUFFER_LEN			( 80 )
+#define usbTXBUFFER_LEN			( 600 )
+
+#define INT_IN_EP		0x81 //read manual for picking these...
+#define INT_OUT_EP		0x04
+#define BULK_IN_EP		0x82
+#define BULK_OUT_EP		0x05
+
+#define MAX_PACKET_SIZE	64
+
+#define LE_WORD(x)		((x)&0xFF),((x)>>8)
+
+static xQueueHandle xRxedChars = NULL, xCharsForTx = NULL;
+
+static const unsigned char abDescriptors[] = {
+
+// device descriptor
+	0x12,
+	DESC_DEVICE,
+	LE_WORD(0x0101),		// bcdUSB
+	0xFF,				// bDeviceClass
+	0x00,				// bDeviceSubClass
+	0x00,				// bDeviceProtocol
+	MAX_PACKET_SIZE0,		// bMaxPacketSize
+	LE_WORD(0x1424),		// idVendor
+	LE_WORD(0xd243),		// idProduct
+	LE_WORD(0x0153),		// bcdDevice
+	0x03,				// iManufacturer
+	0x36,				// iProduct
+	0x33,				// iSerialNumber
+	0x01,				// bNumConfigurations
+
+// configuration descriptor
+	0x09,
+	DESC_CONFIGURATION,
+	LE_WORD(67),			// wTotalLength
+	0x01,				// bNumInterfaces
+	0x01,				// bConfigurationValue
+	0x00,				// iConfiguration
+	0xC0,				// bmAttributes
+	0x32,				// bMaxPower
+// data class interface descriptor
+	0x09,
+	DESC_INTERFACE,
+	0x00,				// bInterfaceNumber
+	0x00,				// bAlternateSetting
+	0x04,				// bNumEndPoints
+	0x0A,				// bInterfaceClass = data
+	0x00,				// bInterfaceSubClass
+	0x00,				// bInterfaceProtocol
+	0x00,				// iInterface
+// debug EP OUT
+	0x07,
+	DESC_ENDPOINT,
+	BULK_OUT_EP,			// bEndpointAddress
+	0x02,				// bmAttributes = bulk
+	LE_WORD(MAX_PACKET_SIZE),	// wMaxPacketSize
+	0x00,				// bInterval
+// debug EP in
+	0x07,
+	DESC_ENDPOINT,
+	BULK_IN_EP,			// bEndpointAddress
+	0x02,				// bmAttributes = bulk
+	LE_WORD(MAX_PACKET_SIZE),	// wMaxPacketSize
+	0x00,				// bInterval
+// data EP OUT
+	0x07,
+	DESC_ENDPOINT,
+	INT_OUT_EP,			// bEndpointAddress
+	0x03,				// bmAttributes = intr
+	LE_WORD(MAX_PACKET_SIZE),	// wMaxPacketSize
+	0x01,				// bInterval
+// data EP in
+	0x07,
+	DESC_ENDPOINT,
+	INT_IN_EP,			// bEndpointAddress
+	0x03,				// bmAttributes = intr
+	LE_WORD(MAX_PACKET_SIZE),	// wMaxPacketSize
+	0x01,				// bInterval
+
+	// string descriptors
+	0x04,
+	DESC_STRING,
+	LE_WORD(0x0409),
+
+	0x0E,
+	DESC_STRING,
+	'L', 0, 'P', 0, 'C', 0, 'U', 0, 'S', 0, 'B', 0,
+
+	0x14,
+	DESC_STRING,
+	'U', 0, 'S', 0, 'B', 0, 'S', 0, 'e', 0, 'r', 0, 'i', 0, 'a', 0, 'l', 0,
+
+	0x12,
+	DESC_STRING,
+	'A', 0, 'B', 0, 'S', 0, 'M', 0, 'o', 0, 't', 0, 'o', 0, 'r', 0,
+
+// terminating zero
+	0
+};
+
+
+/**
+ * Local function to handle incoming bulk data
+ *
+ * @param [in] bEP
+ * @param [in] bEPStatus
+ */
+static void DebugOut(unsigned char bEP, unsigned char bEPStatus) {
+  int i, iLen;
+  long lHigherPriorityTaskWoken = pdFALSE;
+  unsigned char abBulkBuf[64];
+
+  (void) bEPStatus;
+
+  // get data from USB into intermediate buffer
+  iLen = USBHwEPRead(bEP, abBulkBuf, sizeof(abBulkBuf));
+  for (i = 0; i < iLen; i++) {
+    // put into queue
+    xQueueSendFromISR(xRxedChars, &(abBulkBuf[ i ]), &lHigherPriorityTaskWoken);
+  }
+
+  portEND_SWITCHING_ISR(lHigherPriorityTaskWoken);
+}
+
+
+/**
+ * Local function to handle outgoing bulk data
+ *
+ * @param [in] bEP
+ * @param [in] bEPStatus
+ */
+static void DebugIn(unsigned char bEP, unsigned char bEPStatus) {
+  int i, iLen;
+  long lHigherPriorityTaskWoken = pdFALSE;
+  unsigned char abBulkBuf[64];
+
+  (void) bEPStatus;
+
+  if (uxQueueMessagesWaitingFromISR(xCharsForTx) == 0) {
+    // no more data, disable further NAK interrupts until next USB frame
+    USBHwNakIntEnable(INACK_II);
+    return;
+  }
+
+  // get bytes from transmit FIFO into intermediate buffer
+  for (i = 0; i < MAX_PACKET_SIZE; i++) {
+    if (xQueueReceiveFromISR(xCharsForTx, (&abBulkBuf[i]),
+                             &lHigherPriorityTaskWoken) != pdPASS) {
+      break;
+    }
+  }
+  iLen = i;
+
+  // send over USB
+  if (iLen > 0) {
+    USBHwEPWrite(bEP, abBulkBuf, iLen);
+  }
+
+  portEND_SWITCHING_ISR(lHigherPriorityTaskWoken);
+}
+
+extern int64_t gyro_angle;
+static unsigned char abDataBuf[64];
+int VCOM_putcharFromISR(int c, long *woken);
+static void DataOut(unsigned char bEP, unsigned char bEPStatus) {
+  int iLen;
+  long lHigherPriorityTaskWoken = pdFALSE;
+  char *a = "hello\n";
+  while(*a){
+    VCOM_putcharFromISR(*a,&lHigherPriorityTaskWoken);
+    a ++;
+  }
+  iLen = USBHwEPRead(bEP, abDataBuf, sizeof(abDataBuf));
+  portEND_SWITCHING_ISR(lHigherPriorityTaskWoken);
+}
+static void DataIn(unsigned char bEP, unsigned char bEPStatus) {
+  long lHigherPriorityTaskWoken = pdFALSE;
+  unsigned char buff[16];
+  memcpy(buff, &gyro_angle, sizeof(gyro_angle));
+  USBHwEPWrite(bEP, buff, sizeof(gyro_angle));
+  portEND_SWITCHING_ISR(lHigherPriorityTaskWoken);
+}
+
+/**
+ * Writes one character to VCOM port
+ *
+ * @param [in] c character to write
+ * @returns character written, or EOF if character could not be written
+ */
+int VCOM_putcharFromISR(int c, long *lHigherPriorityTaskWoken) {
+  char cc = (char) c;
+
+  if (xQueueSendFromISR(xCharsForTx, &cc,
+                        lHigherPriorityTaskWoken) == pdPASS) {
+    return c;
+  } else {
+    return EOF;
+  }
+}
+
+int VCOM_putchar(int c) {
+  char cc = (char) c;
+
+  // Don't block if not connected to USB.
+  if (xQueueSend(xCharsForTx, &cc,
+                 USBIsConnected() ? usbMAX_SEND_BLOCK : 0) == pdPASS) {
+    return c;
+  } else {
+    return EOF;
+  }
+}
+
+
+/**
+ * Reads one character from VCOM port
+ *
+ * @returns character read, or EOF if character could not be read
+ */
+int VCOM_getchar(void) {
+  unsigned char c;
+
+  /* Block the task until a character is available. */
+  if(xQueueReceive(xRxedChars, &c, 0) == pdTRUE){  //portMAX_DELAY);
+    return c;
+  }
+  return -1;
+}
+
+
+/**
+ * Interrupt handler
+ *
+ * Simply calls the USB ISR
+ */
+void USB_IRQHandler(void) {
+	USBHwISR();
+}
+
+
+static void USBFrameHandler(unsigned short wFrame) {
+  (void) wFrame;
+
+	if (uxQueueMessagesWaitingFromISR(xCharsForTx) > 0) {
+		// data available, enable NAK interrupt on bulk in
+		USBHwNakIntEnable(INACK_BI);
+	}
+}
+
+void vUSBTask(void *pvParameters) {
+  portTickType xLastFlashTime;
+
+  /* Just to prevent compiler warnings about the unused parameter. */
+  (void) pvParameters;
+  DBG("Initialising USB stack\n");
+
+  xRxedChars = xQueueCreate(usbRXBUFFER_LEN, sizeof(char));
+  xCharsForTx = xQueueCreate(usbTXBUFFER_LEN, sizeof(char));
+
+  if ((xRxedChars == NULL) || (xCharsForTx == NULL)) {
+    /* Not enough heap available to create the buffer queues, can't do
+       anything so just delete ourselves. */
+    vTaskDelete(NULL);
+  }
+
+  // initialise stack
+  USBInit();
+
+  // register descriptors
+  USBRegisterDescriptors(abDescriptors);
+
+  // register class request handler
+  //USBRegisterRequestHandler(REQTYPE_TYPE_CLASS,
+  //                          HandleClassRequest, abClassReqData);
+
+  // register endpoint handlers
+  USBHwRegisterEPIntHandler(INT_IN_EP, DataIn);
+  USBHwRegisterEPIntHandler(INT_OUT_EP, DataOut);
+  USBHwRegisterEPIntHandler(BULK_IN_EP, DebugIn);
+  USBHwRegisterEPIntHandler(BULK_OUT_EP, DebugOut);
+
+  // register frame handler
+  USBHwRegisterFrameHandler(USBFrameHandler);
+
+  // enable bulk-in interrupts on NAKs
+  USBHwNakIntEnable(INACK_BI);
+
+  DBG("Starting USB communication\n");
+
+  NVIC_SetPriority(USB_IRQn, configUSB_INTERRUPT_PRIORITY);
+  NVIC_EnableIRQ(USB_IRQn);
+
+  // connect to bus
+
+  DBG("Connecting to USB bus\n");
+  USBHwConnect(TRUE);
+
+  xLastFlashTime = xTaskGetTickCount();
+
+  vTaskDelayUntil(&xLastFlashTime, 1000 / portTICK_RATE_MS * 100);
+
+  //USBHwAllowConnect();
+  // echo any character received (do USB stuff in interrupt)
+  for (;;) {
+    //	c = VCOM_getchar();
+    //	if (c != EOF) {
+    //		// Echo character back with INCREMENT_ECHO_BY offset, so for example if
+    //		// INCREMENT_ECHO_BY is 1 and 'A' is received, 'B' will be echoed back.
+    //		VCOM_putchar(c + INCREMENT_ECHO_BY);
+    //	}
+    vTaskDelayUntil(&xLastFlashTime, 1000 / portTICK_RATE_MS);
+  }
+}
+
diff --git a/gyro_board/src/usb/LPCUSB/type.h b/gyro_board/src/usb/LPCUSB/type.h
new file mode 100644
index 0000000..0727519
--- /dev/null
+++ b/gyro_board/src/usb/LPCUSB/type.h
@@ -0,0 +1,38 @@
+/*****************************************************************************
+ *   type.h:  Type definition Header file for NXP LPC17xx Family
+ *   Microprocessors
+ *
+ *   Copyright(C) 2008, NXP Semiconductor
+ *   All rights reserved.
+ *
+ *   History
+ *   2008.08.21  ver 1.00    Prelimnary version, first Release
+ *
+******************************************************************************/
+#ifndef __TYPE_H__
+#define __TYPE_H__
+
+#ifndef NULL
+#define NULL    ((void *)0)
+#endif
+
+#ifndef FALSE
+#define FALSE   (0)
+#endif
+
+#ifndef TRUE
+#define TRUE    (1)
+#endif
+
+typedef unsigned char  BYTE;
+typedef unsigned short WORD;
+typedef unsigned long  DWORD;
+typedef unsigned int   BOOL;
+
+typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus;
+typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;
+
+/* Pointer to Function returning Void (any number of parameters) */
+typedef void (*PFV)();
+
+#endif  /* __TYPE_H__ */
diff --git a/gyro_board/src/usb/LPCUSB/usbapi.h b/gyro_board/src/usb/LPCUSB/usbapi.h
new file mode 100644
index 0000000..e1fade8
--- /dev/null
+++ b/gyro_board/src/usb/LPCUSB/usbapi.h
@@ -0,0 +1,125 @@
+/*
+	LPCUSB, an USB device driver for LPC microcontrollers
+	Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
+
+	Redistribution and use in source and binary forms, with or without
+	modification, are permitted provided that the following conditions are met:
+
+	1. Redistributions of source code must retain the above copyright
+	   notice, this list of conditions and the following disclaimer.
+	2. Redistributions in binary form must reproduce the above copyright
+	   notice, this list of conditions and the following disclaimer in the
+	   documentation and/or other materials provided with the distribution.
+	3. The name of the author may not be used to endorse or promote products
+	   derived from this software without specific prior written permission.
+
+	THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+	IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+	OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+	IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+	INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+	NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+	DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+	THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+	(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+	THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/**
+	@file
+*/
+
+#include "usbstruct.h"		// for TSetupPacket
+
+/*************************************************************************
+	USB configuration
+**************************************************************************/
+
+#define MAX_PACKET_SIZE0	64		/**< maximum packet size for EP 0 */
+
+/*************************************************************************
+	USB hardware interface
+**************************************************************************/
+
+// endpoint status sent through callback
+#define EP_STATUS_DATA		(1<<0)		/**< EP has data */
+#define EP_STATUS_STALLED	(1<<1)		/**< EP is stalled */
+#define EP_STATUS_SETUP		(1<<2)		/**< EP received setup packet */
+#define EP_STATUS_ERROR		(1<<3)		/**< EP data was overwritten by setup packet */
+#define EP_STATUS_NACKED	(1<<4)		/**< EP sent NAK */
+
+// device status sent through callback
+#define DEV_STATUS_CONNECT		(1<<0)	/**< device just got connected */
+#define DEV_STATUS_SUSPEND		(1<<2)	/**< device entered suspend state */
+#define DEV_STATUS_RESET		(1<<4)	/**< device just got reset */
+
+// interrupt bits for NACK events in USBHwNakIntEnable
+// (these bits conveniently coincide with the LPC176x USB controller bit)
+#define INACK_CI		(1<<1)			/**< interrupt on NACK for control in */
+#define INACK_CO		(1<<2)			/**< interrupt on NACK for control out */
+#define INACK_II		(1<<3)			/**< interrupt on NACK for interrupt in */
+#define INACK_IO		(1<<4)			/**< interrupt on NACK for interrupt out */
+#define INACK_BI		(1<<5)			/**< interrupt on NACK for bulk in */
+#define INACK_BO		(1<<6)			/**< interrupt on NACK for bulk out */
+
+BOOL USBHwInit(void);
+void USBHwISR(void);
+
+void USBHwNakIntEnable(unsigned char bIntBits);
+
+void USBHwConnect(BOOL fConnect);
+int USBIsConnected(void);
+
+void USBHwSetAddress(unsigned char bAddr);
+void USBHwConfigDevice(BOOL fConfigured);
+
+// endpoint operations
+void USBHwEPConfig(unsigned char bEP, unsigned short wMaxPacketSize);
+int  USBHwEPRead(unsigned char bEP, unsigned char *pbBuf, int iMaxLen);
+int	 USBHwEPWrite(unsigned char bEP, unsigned char *pbBuf, int iLen);
+void USBHwEPStall(unsigned char bEP, BOOL fStall);
+unsigned char   USBHwEPGetStatus(unsigned char bEP);
+
+/** Endpoint interrupt handler callback */
+typedef void (TFnEPIntHandler)(unsigned char bEP, unsigned char bEPStatus);
+void USBHwRegisterEPIntHandler(unsigned char bEP, TFnEPIntHandler *pfnHandler);
+
+/** Device status handler callback */
+typedef void (TFnDevIntHandler)(unsigned char bDevStatus);
+void USBHwRegisterDevIntHandler(TFnDevIntHandler *pfnHandler);
+
+/** Frame event handler callback */
+typedef void (TFnFrameHandler)(unsigned short wFrame);
+void USBHwRegisterFrameHandler(TFnFrameHandler *pfnHandler);
+
+/** Configuration event handler callback */
+typedef void (SetConfigHandler)(void);
+void USBHwRegisterSetConfigHandler(SetConfigHandler *handler);
+
+
+/*************************************************************************
+	USB application interface
+**************************************************************************/
+
+// initialise the complete stack, including HW
+BOOL USBInit(void);
+
+/** Request handler callback (standard, vendor, class) */
+typedef BOOL (TFnHandleRequest)(TSetupPacket *pSetup, int *piLen, unsigned char **ppbData);
+void USBRegisterRequestHandler(int iType, TFnHandleRequest *pfnHandler, unsigned char *pbDataStore);
+void USBRegisterCustomReqHandler(TFnHandleRequest *pfnHandler);
+
+/** Descriptor handler callback */
+typedef BOOL (TFnGetDescriptor)(unsigned short wTypeIndex, unsigned short wLangID, int *piLen, unsigned char **ppbData);
+
+/** Default standard request handler */
+BOOL USBHandleStandardRequest(TSetupPacket *pSetup, int *piLen, unsigned char **ppbData);
+
+/** Default EP0 handler */
+void USBHandleControlTransfer(unsigned char bEP, unsigned char bEPStat);
+
+/** Descriptor handling */
+void USBRegisterDescriptors(const unsigned char *pabDescriptors);
+BOOL USBGetDescriptor(unsigned short wTypeIndex, unsigned short wLangID, int *piLen, unsigned char **ppbData);
+
+void USBHwAllowConnect(void);
diff --git a/gyro_board/src/usb/LPCUSB/usbcontrol.c b/gyro_board/src/usb/LPCUSB/usbcontrol.c
new file mode 100644
index 0000000..e02f492
--- /dev/null
+++ b/gyro_board/src/usb/LPCUSB/usbcontrol.c
@@ -0,0 +1,236 @@
+/*
+	LPCUSB, an USB device driver for LPC microcontrollers
+	Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
+
+	Redistribution and use in source and binary forms, with or without
+	modification, are permitted provided that the following conditions are met:
+
+	1. Redistributions of source code must retain the above copyright
+	   notice, this list of conditions and the following disclaimer.
+	2. Redistributions in binary form must reproduce the above copyright
+	   notice, this list of conditions and the following disclaimer in the
+	   documentation and/or other materials provided with the distribution.
+	3. The name of the author may not be used to endorse or promote products
+	   derived from this software without specific prior written permission.
+
+	THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+	IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+	OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+	IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+	INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+	NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+	DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+	THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+	(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+	THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+/** @file
+	Control transfer handler.
+
+	This module handles control transfers and is normally installed on the
+	endpoint 0 callback.
+
+	Control transfers can be of the following type:
+	0 Standard;
+	1 Class;
+	2 Vendor;
+	3 Reserved.
+
+	A callback can be installed for each of these control transfers using
+	USBRegisterRequestHandler.
+	When an OUT request arrives, data is collected in the data store provided
+	with the USBRegisterRequestHandler call. When the transfer is done, the
+	callback is called.
+	When an IN request arrives, the callback is called immediately to either
+	put the control transfer data in the data store, or to get a pointer to
+	control transfer data. The data is then packetised and sent to the host.
+*/
+
+#include "usbdebug.h"
+
+#include "usbstruct.h"
+#include "usbapi.h"
+
+
+
+#define	MAX_CONTROL_SIZE	128	/**< maximum total size of control transfer data */
+#define	MAX_REQ_HANDLERS	4	/**< standard, class, vendor, reserved */
+
+static TSetupPacket		Setup;	/**< setup packet */
+
+static unsigned char				*pbData;	/**< pointer to data buffer */
+static int				iResidue;	/**< remaining bytes in buffer */
+static int				iLen;		/**< total length of control transfer */
+
+/** Array of installed request handler callbacks */
+static TFnHandleRequest *apfnReqHandlers[4] = {NULL, NULL, NULL, NULL};
+/** Array of installed request data pointers */
+static unsigned char				*apbDataStore[4] = {NULL, NULL, NULL, NULL};
+
+/**
+	Local function to handle a request by calling one of the installed
+	request handlers.
+
+	In case of data going from host to device, the data is at *ppbData.
+	In case of data going from device to host, the handler can either
+	choose to write its data at *ppbData or update the data pointer.
+
+	@param [in]		pSetup		The setup packet
+	@param [in,out]	*piLen		Pointer to data length
+	@param [in,out]	ppbData		Data buffer.
+
+	@return TRUE if the request was handles successfully
+ */
+static BOOL _HandleRequest(TSetupPacket *pSetup, int *piLen, unsigned char **ppbData)
+{
+	TFnHandleRequest *pfnHandler;
+	int iType;
+
+	iType = REQTYPE_GET_TYPE(pSetup->bmRequestType);
+	pfnHandler = apfnReqHandlers[iType];
+	if (pfnHandler == NULL) {
+		DBG("No handler for reqtype %d\n", iType);
+		return FALSE;
+	}
+
+	return pfnHandler(pSetup, piLen, ppbData);
+}
+
+
+/**
+	Local function to stall the control endpoint
+
+	@param [in]	bEPStat	Endpoint status
+ */
+static void StallControlPipe(unsigned char bEPStat)
+{
+	unsigned char	*pb;
+	int	i;
+
+	USBHwEPStall(0x80, TRUE);
+
+// dump setup packet
+	DBG("STALL on [");
+	pb = (unsigned char *) & Setup;
+	for (i = 0; i < 8; i++) {
+		DBG(" %02x", *pb++);
+	}
+	DBG("] stat=%x\n", bEPStat);
+}
+
+
+/**
+	Sends next chunk of data (possibly 0 bytes) to host
+ */
+static void DataIn(void)
+{
+	int iChunk;
+
+	if (MAX_PACKET_SIZE0 < iResidue) {
+		iChunk = MAX_PACKET_SIZE0;
+	} else {
+		iChunk = iResidue;
+	}
+
+	USBHwEPWrite(0x80, pbData, iChunk);
+	pbData += iChunk;
+	iResidue -= iChunk;
+}
+
+
+/**
+ *	Handles IN/OUT transfers on EP0
+ *
+ *	@param [in]	bEP		Endpoint address
+ *	@param [in]	bEPStat	Endpoint status
+ */
+void USBHandleControlTransfer(unsigned char bEP, unsigned char bEPStat)
+{
+	int iChunk, iType;
+
+	if (bEP == 0x00) {
+		// OUT transfer
+		if (bEPStat & EP_STATUS_SETUP) {
+			// setup packet, reset request message state machine
+			USBHwEPRead(0x00, (unsigned char *)&Setup, sizeof(Setup));
+			DBG("S%x", Setup.bRequest);
+
+			// defaults for data pointer and residue
+			iType = REQTYPE_GET_TYPE(Setup.bmRequestType);
+			pbData = apbDataStore[iType];
+			iResidue = Setup.wLength;
+			iLen = Setup.wLength;
+
+			if ((Setup.wLength == 0) ||
+			                (REQTYPE_GET_DIR(Setup.bmRequestType) == REQTYPE_DIR_TO_HOST)) {
+				// ask installed handler to process request
+				if (!_HandleRequest(&Setup, &iLen, &pbData)) {
+					DBG("_HandleRequest1 failed\n");
+					StallControlPipe(bEPStat);
+					return;
+				}
+				// send smallest of requested and offered length
+				if (iLen < Setup.wLength) {
+					iResidue = iLen;
+				} else {
+					iResidue = Setup.wLength;
+				}
+
+				// send first part (possibly a zero-length status message)
+				DataIn();
+			}
+		} else {
+			if (iResidue > 0) {
+				// store data
+				iChunk = USBHwEPRead(0x00, pbData, iResidue);
+				if (iChunk < 0) {
+					StallControlPipe(bEPStat);
+					return;
+				}
+				pbData += iChunk;
+				iResidue -= iChunk;
+				if (iResidue == 0) {
+					// received all, send data to handler
+					iType = REQTYPE_GET_TYPE(Setup.bmRequestType);
+					pbData = apbDataStore[iType];
+					if (!_HandleRequest(&Setup, &iLen, &pbData)) {
+						DBG("_HandleRequest2 failed\n");
+						StallControlPipe(bEPStat);
+						return;
+					}
+					// send status to host
+					DataIn();
+				}
+			} else {
+				// absorb zero-length status message
+				iChunk = USBHwEPRead(0x00, NULL, 0);
+				DBG(iChunk > 0 ? "?" : "");
+			}
+		}
+	} else if (bEP == 0x80) {
+		// IN transfer
+		// send more data if available (possibly a 0-length packet)
+		DataIn();
+	} else {
+		ASSERT(FALSE);
+	}
+}
+
+
+/**
+	Registers a callback for handling requests
+
+	@param [in]	iType			Type of request, e.g. REQTYPE_TYPE_STANDARD
+	@param [in]	*pfnHandler		Callback function pointer
+	@param [in]	*pbDataStore	Data storage area for this type of request
+ */
+void USBRegisterRequestHandler(int iType, TFnHandleRequest *pfnHandler, unsigned char *pbDataStore)
+{
+	ASSERT(iType >= 0);
+	ASSERT(iType < 4);
+	apfnReqHandlers[iType] = pfnHandler;
+	apbDataStore[iType] = pbDataStore;
+}
+
diff --git a/gyro_board/src/usb/LPCUSB/usbdebug.h b/gyro_board/src/usb/LPCUSB/usbdebug.h
new file mode 100644
index 0000000..4b3d16b
--- /dev/null
+++ b/gyro_board/src/usb/LPCUSB/usbdebug.h
@@ -0,0 +1,41 @@
+/*
+	LPCUSB, an USB device driver for LPC microcontrollers
+	Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
+
+	Redistribution and use in source and binary forms, with or without
+	modification, are permitted provided that the following conditions are met:
+
+	1. Redistributions of source code must retain the above copyright
+	   notice, this list of conditions and the following disclaimer.
+	2. Redistributions in binary form must reproduce the above copyright
+	   notice, this list of conditions and the following disclaimer in the
+	   documentation and/or other materials provided with the distribution.
+	3. The name of the author may not be used to endorse or promote products
+	   derived from this software without specific prior written permission.
+
+	THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+	IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+	OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+	IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+	INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+	NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+	DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+	THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+	(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+	THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+// CodeRed - comment out this printf, as will use real one from stdio.h
+// to implement output via semihosting
+
+//int printf(const char *format, ...);
+# include <stdio.h>
+
+#ifdef _DEBUG
+#define DBG	printf
+#define ASSERT(x)	if(!(x)){DBG("\nAssertion '%s' failed in %s:%s#%d!\n",#x,__FILE__,__FUNCTION__,__LINE__);while(1);}
+#else
+#define DBG(x ...)
+#define ASSERT(x)
+#endif
+
diff --git a/gyro_board/src/usb/LPCUSB/usbhw_lpc.c b/gyro_board/src/usb/LPCUSB/usbhw_lpc.c
new file mode 100644
index 0000000..8229371
--- /dev/null
+++ b/gyro_board/src/usb/LPCUSB/usbhw_lpc.c
@@ -0,0 +1,538 @@
+/*
+	LPCUSB, an USB device driver for LPC microcontrollers
+	Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
+
+	Redistribution and use in source and binary forms, with or without
+	modification, are permitted provided that the following conditions are met:
+
+	1. Redistributions of source code must retain the above copyright
+	   notice, this list of conditions and the following disclaimer.
+	2. Redistributions in binary form must reproduce the above copyright
+	   notice, this list of conditions and the following disclaimer in the
+	   documentation and/or other materials provided with the distribution.
+	3. The name of the author may not be used to endorse or promote products
+	   derived from this software without specific prior written permission.
+
+	THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+	IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+	OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+	IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+	INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+	NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+	DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+	THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+	(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+	THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+/** @file
+	USB hardware layer
+ */
+
+
+#include "usbdebug.h"
+#include "usbhw_lpc.h"
+#include "usbapi.h"
+
+#ifdef DEBUG
+// comment out the following line if you don't want to use debug LEDs
+//#define DEBUG_LED
+#endif
+
+/** Installed device interrupt handler */
+static TFnDevIntHandler *_pfnDevIntHandler = NULL;
+/** Installed endpoint interrupt handlers */
+static TFnEPIntHandler	*_apfnEPIntHandlers[16];
+/** Installed frame interrupt handlers */
+static TFnFrameHandler	*_pfnFrameHandler = NULL;
+
+/** convert from endpoint address to endpoint index */
+#define EP2IDX(bEP)	((((bEP)&0xF)<<1)|(((bEP)&0x80)>>7))
+/** convert from endpoint index to endpoint address */
+#define IDX2EP(idx)	((((idx)<<7)&0x80)|(((idx)>>1)&0xF))
+
+
+
+/**
+	Local function to wait for a device interrupt (and clear it)
+
+	@param [in]	dwIntr		Bitmask of interrupts to wait for
+ */
+static void Wait4DevInt(unsigned long dwIntr)
+{
+	// wait for specific interrupt
+	while ((USB->USBDevIntSt & dwIntr) != dwIntr);
+	// clear the interrupt bits
+	USB->USBDevIntClr = dwIntr;
+}
+
+
+/**
+	Local function to send a command to the USB protocol engine
+
+	@param [in]	bCmd		Command to send
+ */
+static void USBHwCmd(unsigned char bCmd)
+{
+	// clear CDFULL/CCEMTY
+	USB->USBDevIntClr = CDFULL | CCEMTY;
+	// write command code
+	USB->USBCmdCode = 0x00000500 | (bCmd << 16);
+	Wait4DevInt(CCEMTY);
+}
+
+
+/**
+	Local function to send a command + data to the USB protocol engine
+
+	@param [in]	bCmd		Command to send
+	@param [in]	bData		Data to send
+ */
+static void USBHwCmdWrite(unsigned char bCmd, unsigned short bData)
+{
+	// write command code
+	USBHwCmd(bCmd);
+
+	// write command data
+	USB->USBCmdCode = 0x00000100 | (bData << 16);
+	Wait4DevInt(CCEMTY);
+}
+
+
+/**
+	Local function to send a command to the USB protocol engine and read data
+
+	@param [in]	bCmd		Command to send
+
+	@return the data
+ */
+static unsigned char USBHwCmdRead(unsigned char bCmd)
+{
+	// write command code
+	USBHwCmd(bCmd);
+
+	// get data
+	USB->USBCmdCode = 0x00000200 | (bCmd << 16);
+	Wait4DevInt(CDFULL);
+	return USB->USBCmdData;
+}
+
+
+/**
+	'Realizes' an endpoint, meaning that buffer space is reserved for
+	it. An endpoint needs to be realised before it can be used.
+
+	From experiments, it appears that a USB reset causes USBReEP to
+	re-initialise to 3 (= just the control endpoints).
+	However, a USB bus reset does not disturb the USBMaxPSize settings.
+
+	@param [in]	idx			Endpoint index
+	@param [in] wMaxPSize	Maximum packet size for this endpoint
+ */
+static void USBHwEPRealize(int idx, unsigned short wMaxPSize)
+{
+	USB->USBReEP |= (1 << idx);
+	USB->USBEpInd = idx;
+	USB->USBMaxPSize = wMaxPSize;
+	Wait4DevInt(EP_RLZED);
+}
+
+
+/**
+	Enables or disables an endpoint
+
+	@param [in]	idx		Endpoint index
+	@param [in]	fEnable	TRUE to enable, FALSE to disable
+ */
+static void USBHwEPEnable(int idx, BOOL fEnable)
+{
+	USBHwCmdWrite(CMD_EP_SET_STATUS | idx, fEnable ? 0 : EP_DA);
+}
+
+
+/**
+	Configures an endpoint and enables it
+
+	@param [in]	bEP				Endpoint number
+	@param [in]	wMaxPacketSize	Maximum packet size for this EP
+ */
+void USBHwEPConfig(unsigned char bEP, unsigned short wMaxPacketSize)
+{
+	int idx;
+
+	idx = EP2IDX(bEP);
+
+	// realise EP
+	USBHwEPRealize(idx, wMaxPacketSize);
+
+	// enable EP
+	USBHwEPEnable(idx, TRUE);
+}
+
+
+/**
+	Registers an endpoint event callback
+
+	@param [in]	bEP				Endpoint number
+	@param [in]	pfnHandler		Callback function
+ */
+void USBHwRegisterEPIntHandler(unsigned char bEP, TFnEPIntHandler *pfnHandler)
+{
+	int idx;
+
+	idx = EP2IDX(bEP);
+
+	ASSERT(idx < 32);
+
+	/* add handler to list of EP handlers */
+	_apfnEPIntHandlers[idx / 2] = pfnHandler;
+
+	/* enable EP interrupt */
+	USB->USBEpIntEn |= (1 << idx);
+	USB->USBDevIntEn |= EP_SLOW;
+
+	DBG("Registered handler for EP 0x%x\n", bEP);
+}
+
+
+/**
+	Registers an device status callback
+
+	@param [in]	pfnHandler	Callback function
+ */
+void USBHwRegisterDevIntHandler(TFnDevIntHandler *pfnHandler)
+{
+	_pfnDevIntHandler = pfnHandler;
+
+	// enable device interrupt
+	USB->USBDevIntEn |= DEV_STAT;
+
+	DBG("Registered handler for device status\n");
+}
+
+
+/**
+	Registers the frame callback
+
+	@param [in]	pfnHandler	Callback function
+ */
+void USBHwRegisterFrameHandler(TFnFrameHandler *pfnHandler)
+{
+	_pfnFrameHandler = pfnHandler;
+
+	// enable device interrupt
+	USB->USBDevIntEn |= FRAME;
+
+	DBG("Registered handler for frame\n");
+}
+
+
+/**
+	Sets the USB address.
+
+	@param [in]	bAddr		Device address to set
+ */
+void USBHwSetAddress(unsigned char bAddr)
+{
+	USBHwCmdWrite(CMD_DEV_SET_ADDRESS, DEV_EN | bAddr);
+}
+
+
+/**
+	Connects or disconnects from the USB bus
+
+	@param [in]	fConnect	If TRUE, connect, otherwise disconnect
+ */
+void USBHwConnect(BOOL fConnect)
+{
+	USBHwCmdWrite(CMD_DEV_STATUS, fConnect ? CON : 0);
+}
+
+int USBIsConnected(void) {
+  return (GPIO1->FIOPIN >> 18) & 0x1;
+}
+
+
+/**
+	Enables interrupt on NAK condition
+
+	For IN endpoints a NAK is generated when the host wants to read data
+	from the device, but none is available in the endpoint buffer.
+	For OUT endpoints a NAK is generated when the host wants to write data
+	to the device, but the endpoint buffer is still full.
+
+	The endpoint interrupt handlers can distinguish regular (ACK) interrupts
+	from NAK interrupt by checking the bits in their bEPStatus argument.
+
+	@param [in]	bIntBits	Bitmap indicating which NAK interrupts to enable
+ */
+void USBHwNakIntEnable(unsigned char bIntBits)
+{
+	USBHwCmdWrite(CMD_DEV_SET_MODE, bIntBits);
+}
+
+
+/**
+	Gets the status from a specific endpoint.
+
+	@param [in]	bEP		Endpoint number
+	@return Endpoint status byte (containing EP_STATUS_xxx bits)
+ */
+unsigned char	USBHwEPGetStatus(unsigned char bEP)
+{
+	int idx = EP2IDX(bEP);
+
+	return USBHwCmdRead(CMD_EP_SELECT | idx);
+}
+
+
+/**
+	Sets the stalled property of an endpoint
+
+	@param [in]	bEP		Endpoint number
+	@param [in]	fStall	TRUE to stall, FALSE to unstall
+ */
+void USBHwEPStall(unsigned char bEP, BOOL fStall)
+{
+	int idx = EP2IDX(bEP);
+
+	USBHwCmdWrite(CMD_EP_SET_STATUS | idx, fStall ? EP_ST : 0);
+}
+
+
+/**
+	Writes data to an endpoint buffer
+
+	@param [in]	bEP		Endpoint number
+	@param [in]	pbBuf	Endpoint data
+	@param [in]	iLen	Number of bytes to write
+
+	@return TRUE if the data was successfully written or <0 in case of error.
+*/
+int USBHwEPWrite(unsigned char bEP, unsigned char *pbBuf, int iLen)
+{
+	int idx;
+
+	idx = EP2IDX(bEP);
+
+	// set write enable for specific endpoint
+	USB->USBCtrl = WR_EN | ((bEP & 0xF) << 2);
+
+	// set packet length
+	USB->USBTxPLen = iLen;
+
+	// write data
+	while (USB->USBCtrl & WR_EN) {
+		USB->USBTxData = (pbBuf[3] << 24) | (pbBuf[2] << 16) | (pbBuf[1] << 8) | pbBuf[0];
+		pbBuf += 4;
+	}
+
+	// select endpoint and validate buffer
+	USBHwCmd(CMD_EP_SELECT | idx);
+	USBHwCmd(CMD_EP_VALIDATE_BUFFER);
+
+	return iLen;
+}
+
+
+/**
+	Reads data from an endpoint buffer
+
+	@param [in]	bEP		Endpoint number
+	@param [in]	pbBuf	Endpoint data
+	@param [in]	iMaxLen	Maximum number of bytes to read
+
+	@return the number of bytes available in the EP (possibly more than iMaxLen),
+	or <0 in case of error.
+ */
+int USBHwEPRead(unsigned char bEP, unsigned char *pbBuf, int iMaxLen)
+{
+	int i, idx;
+	unsigned long	dwData, dwLen;
+
+	idx = EP2IDX(bEP);
+
+	// set read enable bit for specific endpoint
+	USB->USBCtrl = RD_EN | ((bEP & 0xF) << 2);
+
+	// wait for PKT_RDY
+	do {
+		dwLen = USB->USBRxPLen;
+	} while ((dwLen & PKT_RDY) == 0);
+
+	// packet valid?
+	if ((dwLen & DV) == 0) {
+		return -1;
+	}
+
+	// get length
+	dwLen &= PKT_LNGTH_MASK;
+
+	// get data
+	dwData = 0;
+	for (i = 0; i < dwLen; i++) {
+		if ((i % 4) == 0) {
+			dwData = USB->USBRxData;
+		}
+		if ((pbBuf != NULL) && (i < iMaxLen)) {
+			pbBuf[i] = dwData & 0xFF;
+		}
+		dwData >>= 8;
+	}
+
+	// make sure RD_EN is clear
+	USB->USBCtrl = 0;
+
+	// select endpoint and clear buffer
+	USBHwCmd(CMD_EP_SELECT | idx);
+	USBHwCmd(CMD_EP_CLEAR_BUFFER);
+
+	return dwLen;
+}
+
+
+/**
+	Sets the 'configured' state.
+
+	All registered endpoints are 'realised' and enabled, and the
+	'configured' bit is set in the device status register.
+
+	@param [in]	fConfigured	If TRUE, configure device, else unconfigure
+ */
+void USBHwConfigDevice(BOOL fConfigured)
+{
+	// set configured bit
+	USBHwCmdWrite(CMD_DEV_CONFIG, fConfigured ? CONF_DEVICE : 0);
+}
+
+
+/**
+ * USB interrupt handler
+ *
+ * @todo Get all 11 bits of frame number instead of just 8
+ *
+ * Endpoint interrupts are mapped to the slow interrupt
+ */
+void USBHwISR(void) {
+	unsigned long dwStatus;
+	unsigned long dwIntBit;
+	unsigned char bEPStat, bDevStat, bStat;
+	int i;
+	unsigned short wFrame;
+
+	// handle device interrupts
+	dwStatus = USB->USBDevIntSt;
+
+	// frame interrupt
+	if (dwStatus & FRAME) {
+		// clear int
+		USB->USBDevIntClr = FRAME;
+		// call handler
+		if (_pfnFrameHandler != NULL) {
+			wFrame = USBHwCmdRead(CMD_DEV_READ_CUR_FRAME_NR);
+			_pfnFrameHandler(wFrame);
+		}
+	}
+
+	// device status interrupt
+	if (dwStatus & DEV_STAT) {
+		/*	Clear DEV_STAT interrupt before reading DEV_STAT register.
+			This prevents corrupted device status reads, see
+			LPC2148 User manual revision 2, 25 july 2006.
+		*/
+		USB->USBDevIntClr = DEV_STAT;
+		bDevStat = USBHwCmdRead(CMD_DEV_STATUS);
+		if (bDevStat & (CON_CH | SUS_CH | RST)) {
+			// convert device status into something HW independent
+			bStat = ((bDevStat & CON) ? DEV_STATUS_CONNECT : 0) |
+			        ((bDevStat & SUS) ? DEV_STATUS_SUSPEND : 0) |
+			        ((bDevStat & RST) ? DEV_STATUS_RESET : 0);
+			// call handler
+			if (_pfnDevIntHandler != NULL) {
+				_pfnDevIntHandler(bStat);
+			}
+		}
+	}
+
+	// endpoint interrupt
+	if (dwStatus & EP_SLOW) {
+		// clear EP_SLOW
+		USB->USBDevIntClr = EP_SLOW;
+		// check all endpoints
+		for (i = 0; i < 32; i++) {
+			dwIntBit = (1 << i);
+			if (USB->USBEpIntSt & dwIntBit) {
+				// clear int (and retrieve status)
+				USB->USBEpIntClr = dwIntBit;
+				Wait4DevInt(CDFULL);
+				bEPStat = USB->USBCmdData;
+				// convert EP pipe stat into something HW independent
+				bStat = ((bEPStat & EPSTAT_FE) ? EP_STATUS_DATA : 0) |
+				        ((bEPStat & EPSTAT_ST) ? EP_STATUS_STALLED : 0) |
+				        ((bEPStat & EPSTAT_STP) ? EP_STATUS_SETUP : 0) |
+				        ((bEPStat & EPSTAT_EPN) ? EP_STATUS_NACKED : 0) |
+				        ((bEPStat & EPSTAT_PO) ? EP_STATUS_ERROR : 0);
+				// call handler
+				if (_apfnEPIntHandlers[i / 2] != NULL) {
+					_apfnEPIntHandlers[i / 2](IDX2EP(i), bStat);
+				}
+			}
+		}
+	}
+}
+
+
+
+/**
+	Initialises the USB hardware
+
+
+	@return TRUE if the hardware was successfully initialised
+ */
+BOOL USBHwInit(void)
+{
+  // P2.9 -> USB_CONNECT
+  //PINCON->PINSEL4 &= ~0x000C0000;
+  //PINCON->PINSEL4 |= 0x00040000;
+  // Leave it disconnected.
+  // Before the device can be used, it needs to be connected.
+  GPIO2->FIODIR |= (1UL << 9UL);
+  GPIO2->FIOCLR = (1UL << 9UL);
+
+  // P1.18 -> USB_UP_LED
+  // P1.30 -> VBUS
+  PINCON->PINSEL3 &= ~0x30000030;
+  PINCON->PINSEL3 |= 0x00000010;
+
+  // P0.29 -> USB_D+
+  // P0.30 -> USB_D-
+  PINCON->PINSEL1 &= ~0x3C000000;
+  PINCON->PINSEL1 |= 0x14000000;
+
+  // enable PUSB
+  SC->PCONP |= (1 << 31);
+
+  USB->OTGClkCtrl = 0x12;	                  /* Dev clock, AHB clock enable  */
+  while ((USB->OTGClkSt & 0x12) != 0x12);
+
+  // disable/clear all interrupts for now
+  USB->USBDevIntEn = 0;
+  USB->USBDevIntClr = 0xFFFFFFFF;
+  USB->USBDevIntPri = 0;
+
+  USB->USBEpIntEn = 0;
+  USB->USBEpIntClr = 0xFFFFFFFF;
+  USB->USBEpIntPri = 0;
+
+  // by default, only ACKs generate interrupts
+  USBHwNakIntEnable(0);
+
+  return TRUE;
+}
+
+void USBHwAllowConnect(void)
+{
+	// Enable USB.
+        GPIO2->FIOSET = (1UL << 9UL);
+}
diff --git a/gyro_board/src/usb/LPCUSB/usbhw_lpc.h b/gyro_board/src/usb/LPCUSB/usbhw_lpc.h
new file mode 100644
index 0000000..d6b60af
--- /dev/null
+++ b/gyro_board/src/usb/LPCUSB/usbhw_lpc.h
@@ -0,0 +1,149 @@
+/*
+	LPCUSB, an USB device driver for LPC microcontrollers
+	Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
+
+	Redistribution and use in source and binary forms, with or without
+	modification, are permitted provided that the following conditions are met:
+
+	1. Redistributions of source code must retain the above copyright
+	   notice, this list of conditions and the following disclaimer.
+	2. Redistributions in binary form must reproduce the above copyright
+	   notice, this list of conditions and the following disclaimer in the
+	   documentation and/or other materials provided with the distribution.
+	3. The name of the author may not be used to endorse or promote products
+	   derived from this software without specific prior written permission.
+
+	THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+	IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+	OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+	IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+	INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+	NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+	DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+	THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+	(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+	THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+/**
+	Hardware definitions for the LPC176x USB controller
+
+	These are private to the usbhw module
+*/
+
+// CodeRed - pull in defines from NXP header file
+//#include "NXP\LPC17xx\LPC17xx.h"
+#include "LPC17xx.h"
+
+
+// CodeRed - these registers have been renamed on LPC176x
+#define USBReEP USBReEp
+#define OTG_CLK_CTRL USBClkCtrl
+#define OTG_CLK_STAT USBClkSt
+
+/* USBIntSt bits */
+#define USB_INT_REQ_LP				(1<<0)
+#define USB_INT_REQ_HP				(1<<1)
+#define USB_INT_REQ_DMA				(1<<2)
+#define USB_need_clock				(1<<8)
+#define EN_USB_BITS					(1<<31)
+
+/* USBDevInt... bits */
+#define FRAME						(1<<0)
+#define EP_FAST						(1<<1)
+#define EP_SLOW						(1<<2)
+#define DEV_STAT					(1<<3)
+#define CCEMTY						(1<<4)
+#define CDFULL						(1<<5)
+#define RxENDPKT					(1<<6)
+#define TxENDPKT					(1<<7)
+#define EP_RLZED					(1<<8)
+#define ERR_INT						(1<<9)
+
+/* USBRxPLen bits */
+#define PKT_LNGTH					(1<<0)
+#define PKT_LNGTH_MASK				0x3FF
+#define DV							(1<<10)
+#define PKT_RDY						(1<<11)
+
+/* USBCtrl bits */
+#define RD_EN						(1<<0)
+#define WR_EN						(1<<1)
+#define LOG_ENDPOINT				(1<<2)
+
+/* protocol engine command codes */
+/* device commands */
+#define CMD_DEV_SET_ADDRESS			0xD0
+#define CMD_DEV_CONFIG				0xD8
+#define CMD_DEV_SET_MODE			0xF3
+#define CMD_DEV_READ_CUR_FRAME_NR	0xF5
+#define CMD_DEV_READ_TEST_REG		0xFD
+#define CMD_DEV_STATUS				0xFE		/* read/write */
+#define CMD_DEV_GET_ERROR_CODE		0xFF
+#define CMD_DEV_READ_ERROR_STATUS	0xFB
+/* endpoint commands */
+#define CMD_EP_SELECT				0x00
+#define CMD_EP_SELECT_CLEAR			0x40
+#define CMD_EP_SET_STATUS			0x40
+#define CMD_EP_CLEAR_BUFFER			0xF2
+#define CMD_EP_VALIDATE_BUFFER		0xFA
+
+/* set address command */
+#define DEV_ADDR					(1<<0)
+#define DEV_EN						(1<<7)
+
+/* configure device command */
+#define CONF_DEVICE					(1<<0)
+
+/* set mode command */
+#define AP_CLK						(1<<0)
+#define INAK_CI						(1<<1)
+#define INAK_CO						(1<<2)
+#define INAK_II						(1<<3)
+#define INAK_IO						(1<<4)
+#define INAK_BI						(1<<5)
+#define INAK_BO						(1<<6)
+
+/* set get device status command */
+#define CON							(1<<0)
+#define CON_CH						(1<<1)
+#define SUS							(1<<2)
+#define SUS_CH						(1<<3)
+#define RST							(1<<4)
+
+/* get error code command */
+// ...
+
+/* Select Endpoint command read bits */
+#define EPSTAT_FE					(1<<0)
+#define EPSTAT_ST					(1<<1)
+#define EPSTAT_STP					(1<<2)
+#define EPSTAT_PO					(1<<3)
+#define EPSTAT_EPN					(1<<4)
+#define EPSTAT_B1FULL				(1<<5)
+#define EPSTAT_B2FULL				(1<<6)
+
+/* CMD_EP_SET_STATUS command */
+#define EP_ST						(1<<0)
+#define EP_DA						(1<<5)
+#define EP_RF_MO					(1<<6)
+#define EP_CND_ST					(1<<7)
+
+/* read error status command */
+#define PID_ERR						(1<<0)
+#define UEPKT						(1<<1)
+#define DCRC						(1<<2)
+#define TIMEOUT						(1<<3)
+#define EOP							(1<<4)
+#define B_OVRN						(1<<5)
+#define BTSTF						(1<<6)
+#define TGL_ERR						(1<<7)
+
+
+
+
+
+
+
+
diff --git a/gyro_board/src/usb/LPCUSB/usbinit.c b/gyro_board/src/usb/LPCUSB/usbinit.c
new file mode 100644
index 0000000..49b31a0
--- /dev/null
+++ b/gyro_board/src/usb/LPCUSB/usbinit.c
@@ -0,0 +1,82 @@
+/*
+	LPCUSB, an USB device driver for LPC microcontrollers
+	Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
+
+	Redistribution and use in source and binary forms, with or without
+	modification, are permitted provided that the following conditions are met:
+
+	1. Redistributions of source code must retain the above copyright
+	   notice, this list of conditions and the following disclaimer.
+	2. Redistributions in binary form must reproduce the above copyright
+	   notice, this list of conditions and the following disclaimer in the
+	   documentation and/or other materials provided with the distribution.
+	3. The name of the author may not be used to endorse or promote products
+	   derived from this software without specific prior written permission.
+
+	THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+	IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+	OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+	IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+	INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+	NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+	DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+	THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+	(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+	THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+/** @file
+	USB stack initialisation
+ */
+
+
+#include "usbdebug.h"
+#include "usbapi.h"
+
+
+/** data storage area for standard requests */
+static unsigned char	abStdReqData[8];
+
+
+/**
+	USB reset handler
+
+	@param [in] bDevStatus	Device status
+ */
+static void HandleUsbReset(unsigned char bDevStatus)
+{
+	if (bDevStatus & DEV_STATUS_RESET) {
+		DBG("\n!");
+	}
+}
+
+
+/**
+	Initialises the USB hardware and sets up the USB stack by
+	installing default callbacks.
+
+	@return TRUE if initialisation was successful
+ */
+BOOL USBInit(void)
+{
+	// init hardware
+	USBHwInit();
+
+	// register bus reset handler
+	USBHwRegisterDevIntHandler(HandleUsbReset);
+
+	// register control transfer handler on EP0
+	USBHwRegisterEPIntHandler(0x00, USBHandleControlTransfer);
+	USBHwRegisterEPIntHandler(0x80, USBHandleControlTransfer);
+
+	// setup control endpoints
+	USBHwEPConfig(0x00, MAX_PACKET_SIZE0);
+	USBHwEPConfig(0x80, MAX_PACKET_SIZE0);
+
+	// register standard request handler
+	USBRegisterRequestHandler(REQTYPE_TYPE_STANDARD, USBHandleStandardRequest, abStdReqData);
+
+	return TRUE;
+}
+
diff --git a/gyro_board/src/usb/LPCUSB/usbstdreq.c b/gyro_board/src/usb/LPCUSB/usbstdreq.c
new file mode 100644
index 0000000..6a3fde5
--- /dev/null
+++ b/gyro_board/src/usb/LPCUSB/usbstdreq.c
@@ -0,0 +1,438 @@
+/*
+	LPCUSB, an USB device driver for LPC microcontrollers
+	Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
+
+	Redistribution and use in source and binary forms, with or without
+	modification, are permitted provided that the following conditions are met:
+
+	1. Redistributions of source code must retain the above copyright
+	   notice, this list of conditions and the following disclaimer.
+	2. Redistributions in binary form must reproduce the above copyright
+	   notice, this list of conditions and the following disclaimer in the
+	   documentation and/or other materials provided with the distribution.
+	3. The name of the author may not be used to endorse or promote products
+	   derived from this software without specific prior written permission.
+
+	THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+	IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+	OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+	IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+	INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+	NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+	DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+	THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+	(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+	THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+/** @file
+	Standard request handler.
+
+	This modules handles the 'chapter 9' processing, specifically the
+	standard device requests in table 9-3 from the universal serial bus
+	specification revision 2.0
+
+	Specific types of devices may specify additional requests (for example
+	HID devices add a GET_DESCRIPTOR request for interfaces), but they
+	will not be part of this module.
+
+	@todo some requests have to return a request error if device not configured:
+	@todo GET_INTERFACE, GET_STATUS, SET_INTERFACE, SYNCH_FRAME
+	@todo this applies to the following if endpoint != 0:
+	@todo SET_FEATURE, GET_FEATURE
+*/
+
+#include "usbdebug.h"
+#include "usbstruct.h"
+#include "usbapi.h"
+
+#define MAX_DESC_HANDLERS	4		/**< device, interface, endpoint, other */
+
+
+/* general descriptor field offsets */
+#define DESC_bLength					0	/**< length offset */
+#define DESC_bDescriptorType			1	/**< descriptor type offset */
+
+/* config descriptor field offsets */
+#define CONF_DESC_wTotalLength			2	/**< total length offset */
+#define CONF_DESC_bConfigurationValue	5	/**< configuration value offset */
+#define CONF_DESC_bmAttributes			7	/**< configuration characteristics */
+
+/* interface descriptor field offsets */
+#define INTF_DESC_bAlternateSetting		3	/**< alternate setting offset */
+
+/* endpoint descriptor field offsets */
+#define ENDP_DESC_bEndpointAddress		2	/**< endpoint address offset */
+#define ENDP_DESC_wMaxPacketSize		4	/**< maximum packet size offset */
+
+
+/** Currently selected configuration */
+static unsigned char				bConfiguration = 0;
+/** Installed custom request handler */
+static TFnHandleRequest	*pfnHandleCustomReq = NULL;
+/** Pointer to registered descriptors */
+static const unsigned char			*pabDescrip = NULL;
+
+
+/**
+	Registers a pointer to a descriptor block containing all descriptors
+	for the device.
+
+	@param [in]	pabDescriptors	The descriptor byte array
+ */
+void USBRegisterDescriptors(const unsigned char *pabDescriptors)
+{
+	pabDescrip = pabDescriptors;
+}
+
+
+/**
+	Parses the list of installed USB descriptors and attempts to find
+	the specified USB descriptor.
+
+	@param [in]		wTypeIndex	Type and index of the descriptor
+	@param [in]		wLangID		Language ID of the descriptor (currently unused)
+	@param [out]	*piLen		Descriptor length
+	@param [out]	*ppbData	Descriptor data
+
+	@return TRUE if the descriptor was found, FALSE otherwise
+ */
+BOOL USBGetDescriptor(unsigned short wTypeIndex, unsigned short wLangID, int *piLen, unsigned char **ppbData)
+{
+	unsigned char	bType, bIndex;
+	unsigned char	*pab;
+	int iCurIndex;
+
+	ASSERT(pabDescrip != NULL);
+
+	bType = GET_DESC_TYPE(wTypeIndex);
+	bIndex = GET_DESC_INDEX(wTypeIndex);
+
+	pab = (unsigned char *)pabDescrip;
+	iCurIndex = 0;
+
+	while (pab[DESC_bLength] != 0) {
+		if (pab[DESC_bDescriptorType] == bType) {
+			if (iCurIndex == bIndex) {
+				// set data pointer
+				*ppbData = pab;
+				// get length from structure
+				if (bType == DESC_CONFIGURATION) {
+					// configuration descriptor is an exception, length is at offset 2 and 3
+					*piLen =	(pab[CONF_DESC_wTotalLength]) |
+					         (pab[CONF_DESC_wTotalLength + 1] << 8);
+				} else {
+					// normally length is at offset 0
+					*piLen = pab[DESC_bLength];
+				}
+				return TRUE;
+			}
+			iCurIndex++;
+		}
+		// skip to next descriptor
+		pab += pab[DESC_bLength];
+	}
+	// nothing found
+	DBG("Desc %x not found!\n", wTypeIndex);
+	return FALSE;
+}
+
+
+/**
+	Configures the device according to the specified configuration index and
+	alternate setting by parsing the installed USB descriptor list.
+	A configuration index of 0 unconfigures the device.
+
+	@param [in]		bConfigIndex	Configuration index
+	@param [in]		bAltSetting		Alternate setting number
+
+	@todo function always returns TRUE, add stricter checking?
+
+	@return TRUE if successfully configured, FALSE otherwise
+ */
+static BOOL USBSetConfiguration(unsigned char bConfigIndex, unsigned char bAltSetting)
+{
+	unsigned char	*pab;
+	unsigned char	bCurConfig, bCurAltSetting;
+	unsigned char	bEP;
+	unsigned short	wMaxPktSize;
+
+	ASSERT(pabDescrip != NULL);
+
+	if (bConfigIndex == 0) {
+		// unconfigure device
+		USBHwConfigDevice(FALSE);
+	} else {
+		// configure endpoints for this configuration/altsetting
+		pab = (unsigned char *)pabDescrip;
+		bCurConfig = 0xFF;
+		bCurAltSetting = 0xFF;
+
+		while (pab[DESC_bLength] != 0) {
+
+			switch (pab[DESC_bDescriptorType]) {
+
+			case DESC_CONFIGURATION:
+				// remember current configuration index
+				bCurConfig = pab[CONF_DESC_bConfigurationValue];
+				break;
+
+			case DESC_INTERFACE:
+				// remember current alternate setting
+				bCurAltSetting = pab[INTF_DESC_bAlternateSetting];
+				break;
+
+			case DESC_ENDPOINT:
+				if ((bCurConfig == bConfigIndex) &&
+				                (bCurAltSetting == bAltSetting)) {
+					// endpoint found for desired config and alternate setting
+					bEP = pab[ENDP_DESC_bEndpointAddress];
+					wMaxPktSize =	(pab[ENDP_DESC_wMaxPacketSize]) |
+					              (pab[ENDP_DESC_wMaxPacketSize + 1] << 8);
+					// configure endpoint
+					USBHwEPConfig(bEP, wMaxPktSize);
+				}
+				break;
+
+			default:
+				break;
+			}
+			// skip to next descriptor
+			pab += pab[DESC_bLength];
+		}
+
+		// configure device
+		USBHwConfigDevice(TRUE);
+	}
+
+	return TRUE;
+}
+SetConfigHandler *SetConfig_CallBack = NULL;
+void USBHwRegisterSetConfigHandler(SetConfigHandler *handler){
+	SetConfig_CallBack = handler;
+}
+
+
+/**
+	Local function to handle a standard device request
+
+	@param [in]		pSetup		The setup packet
+	@param [in,out]	*piLen		Pointer to data length
+	@param [in,out]	ppbData		Data buffer.
+
+	@return TRUE if the request was handled successfully
+ */
+static BOOL HandleStdDeviceReq(TSetupPacket *pSetup, int *piLen, unsigned char **ppbData)
+{
+	unsigned char	*pbData = *ppbData;
+
+	switch (pSetup->bRequest) {
+
+	case REQ_GET_STATUS:
+		// bit 0: self-powered
+		// bit 1: remote wakeup = not supported
+		pbData[0] = 0;
+		pbData[1] = 0;
+		*piLen = 2;
+		break;
+
+	case REQ_SET_ADDRESS:
+		USBHwSetAddress(pSetup->wValue);
+		break;
+
+	case REQ_GET_DESCRIPTOR:
+		DBG("D%x", pSetup->wValue);
+		return USBGetDescriptor(pSetup->wValue, pSetup->wIndex, piLen, ppbData);
+
+	case REQ_GET_CONFIGURATION:
+		// indicate if we are configured
+		pbData[0] = bConfiguration;
+		*piLen = 1;
+		break;
+
+	case REQ_SET_CONFIGURATION:
+		if (!USBSetConfiguration(pSetup->wValue & 0xFF, 0)) {
+			DBG("USBSetConfiguration failed!\n");
+			return FALSE;
+		}
+		// configuration successful, update current configuration
+		bConfiguration = pSetup->wValue & 0xFF;
+		if(SetConfig_CallBack != NULL)
+			SetConfig_CallBack();
+		break;
+
+	case REQ_CLEAR_FEATURE:
+	case REQ_SET_FEATURE:
+		if (pSetup->wValue == FEA_REMOTE_WAKEUP) {
+			// put DEVICE_REMOTE_WAKEUP code here
+		}
+		if (pSetup->wValue == FEA_TEST_MODE) {
+			// put TEST_MODE code here
+		}
+		return FALSE;
+
+	case REQ_SET_DESCRIPTOR:
+		DBG("Device req %d not implemented\n", pSetup->bRequest);
+		return FALSE;
+
+	default:
+		DBG("Illegal device req %d\n", pSetup->bRequest);
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+
+/**
+	Local function to handle a standard interface request
+
+	@param [in]		pSetup		The setup packet
+	@param [in,out]	*piLen		Pointer to data length
+	@param [in]		ppbData		Data buffer.
+
+	@return TRUE if the request was handled successfully
+ */
+static BOOL HandleStdInterfaceReq(TSetupPacket	*pSetup, int *piLen, unsigned char **ppbData)
+{
+	unsigned char	*pbData = *ppbData;
+
+	switch (pSetup->bRequest) {
+
+	case REQ_GET_STATUS:
+		// no bits specified
+		pbData[0] = 0;
+		pbData[1] = 0;
+		*piLen = 2;
+		break;
+
+	case REQ_CLEAR_FEATURE:
+	case REQ_SET_FEATURE:
+		// not defined for interface
+		return FALSE;
+
+	case REQ_GET_INTERFACE:	// TODO use bNumInterfaces
+		// there is only one interface, return n-1 (= 0)
+		pbData[0] = 0;
+		*piLen = 1;
+		break;
+
+	case REQ_SET_INTERFACE:	// TODO use bNumInterfaces
+		// there is only one interface (= 0)
+		if (pSetup->wValue != 0) {
+			return FALSE;
+		}
+		*piLen = 0;
+		break;
+
+	default:
+		DBG("Illegal interface req %d\n", pSetup->bRequest);
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+
+/**
+	Local function to handle a standard endpoint request
+
+	@param [in]		pSetup		The setup packet
+	@param [in,out]	*piLen		Pointer to data length
+	@param [in]		ppbData		Data buffer.
+
+	@return TRUE if the request was handled successfully
+ */
+static BOOL HandleStdEndPointReq(TSetupPacket	*pSetup, int *piLen, unsigned char **ppbData)
+{
+	unsigned char	*pbData = *ppbData;
+
+	switch (pSetup->bRequest) {
+	case REQ_GET_STATUS:
+		// bit 0 = endpointed halted or not
+		pbData[0] = (USBHwEPGetStatus(pSetup->wIndex) & EP_STATUS_STALLED) ? 1 : 0;
+		pbData[1] = 0;
+		*piLen = 2;
+		break;
+
+	case REQ_CLEAR_FEATURE:
+		if (pSetup->wValue == FEA_ENDPOINT_HALT) {
+			// clear HALT by unstalling
+			USBHwEPStall(pSetup->wIndex, FALSE);
+			break;
+		}
+		// only ENDPOINT_HALT defined for endpoints
+		return FALSE;
+
+	case REQ_SET_FEATURE:
+		if (pSetup->wValue == FEA_ENDPOINT_HALT) {
+			// set HALT by stalling
+			USBHwEPStall(pSetup->wIndex, TRUE);
+			break;
+		}
+		// only ENDPOINT_HALT defined for endpoints
+		return FALSE;
+
+	case REQ_SYNCH_FRAME:
+		DBG("EP req %d not implemented\n", pSetup->bRequest);
+		return FALSE;
+
+	default:
+		DBG("Illegal EP req %d\n", pSetup->bRequest);
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+
+/**
+	Default handler for standard ('chapter 9') requests
+
+	If a custom request handler was installed, this handler is called first.
+
+	@param [in]		pSetup		The setup packet
+	@param [in,out]	*piLen		Pointer to data length
+	@param [in]		ppbData		Data buffer.
+
+	@return TRUE if the request was handled successfully
+ */
+BOOL USBHandleStandardRequest(TSetupPacket	*pSetup, int *piLen, unsigned char **ppbData)
+{
+	// try the custom request handler first
+	if ((pfnHandleCustomReq != NULL) && pfnHandleCustomReq(pSetup, piLen, ppbData)) {
+		return TRUE;
+	}
+
+	switch (REQTYPE_GET_RECIP(pSetup->bmRequestType)) {
+	case REQTYPE_RECIP_DEVICE:
+		return HandleStdDeviceReq(pSetup, piLen, ppbData);
+	case REQTYPE_RECIP_INTERFACE:
+		return HandleStdInterfaceReq(pSetup, piLen, ppbData);
+	case REQTYPE_RECIP_ENDPOINT:
+		return HandleStdEndPointReq(pSetup, piLen, ppbData);
+	default:
+		return FALSE;
+	}
+}
+
+
+/**
+	Registers a callback for custom device requests
+
+	In USBHandleStandardRequest, the custom request handler gets a first
+	chance at handling the request before it is handed over to the 'chapter 9'
+	request handler.
+
+	This can be used for example in HID devices, where a REQ_GET_DESCRIPTOR
+	request is sent to an interface, which is not covered by the 'chapter 9'
+	specification.
+
+	@param [in]	pfnHandler	Callback function pointer
+ */
+void USBRegisterCustomReqHandler(TFnHandleRequest *pfnHandler)
+{
+	pfnHandleCustomReq = pfnHandler;
+}
+
diff --git a/gyro_board/src/usb/LPCUSB/usbstruct.h b/gyro_board/src/usb/LPCUSB/usbstruct.h
new file mode 100644
index 0000000..d6bd725
--- /dev/null
+++ b/gyro_board/src/usb/LPCUSB/usbstruct.h
@@ -0,0 +1,119 @@
+/*
+	LPCUSB, an USB device driver for LPC microcontrollers
+	Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
+
+	Redistribution and use in source and binary forms, with or without
+	modification, are permitted provided that the following conditions are met:
+
+	1. Redistributions of source code must retain the above copyright
+	   notice, this list of conditions and the following disclaimer.
+	2. Redistributions in binary form must reproduce the above copyright
+	   notice, this list of conditions and the following disclaimer in the
+	   documentation and/or other materials provided with the distribution.
+	3. The name of the author may not be used to endorse or promote products
+	   derived from this software without specific prior written permission.
+
+	THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+	IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+	OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+	IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+	INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+	NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+	DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+	THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+	(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+	THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+/**
+	Definitions of structures of standard USB packets
+*/
+
+#ifndef _USBSTRUCT_H_
+#define _USBSTRUCT_H_
+
+// CodeRed - include the LPCUSB type.h file rather than NXP one directly
+#include "type.h"
+
+/** setup packet definitions */
+typedef struct {
+	unsigned char	bmRequestType;			/**< characteristics of the specific request */
+	unsigned char	bRequest;				/**< specific request */
+	unsigned short	wValue;					/**< request specific parameter */
+	unsigned short	wIndex;					/**< request specific parameter */
+	unsigned short	wLength;				/**< length of data transfered in data phase */
+} TSetupPacket;
+
+
+#define REQTYPE_GET_DIR(x)		(((x)>>7)&0x01)
+#define REQTYPE_GET_TYPE(x)		(((x)>>5)&0x03)
+#define REQTYPE_GET_RECIP(x)	((x)&0x1F)
+
+#define REQTYPE_DIR_TO_DEVICE	0
+#define REQTYPE_DIR_TO_HOST		1
+
+#define REQTYPE_TYPE_STANDARD	0
+#define REQTYPE_TYPE_CLASS		1
+#define REQTYPE_TYPE_VENDOR		2
+#define REQTYPE_TYPE_RESERVED	3
+
+#define REQTYPE_RECIP_DEVICE	0
+#define REQTYPE_RECIP_INTERFACE	1
+#define REQTYPE_RECIP_ENDPOINT	2
+#define REQTYPE_RECIP_OTHER		3
+
+/* standard requests */
+#define	REQ_GET_STATUS			0x00
+#define REQ_CLEAR_FEATURE		0x01
+#define REQ_SET_FEATURE			0x03
+#define REQ_SET_ADDRESS			0x05
+#define REQ_GET_DESCRIPTOR		0x06
+#define REQ_SET_DESCRIPTOR		0x07
+#define REQ_GET_CONFIGURATION	0x08
+#define REQ_SET_CONFIGURATION	0x09
+#define REQ_GET_INTERFACE		0x0A
+#define REQ_SET_INTERFACE		0x0B
+#define REQ_SYNCH_FRAME			0x0C
+
+/* class requests HID */
+#define HID_GET_REPORT			0x01
+#define HID_GET_IDLE			0x02
+#define HID_GET_PROTOCOL	 	0x03
+#define HID_SET_REPORT			0x09
+#define HID_SET_IDLE			0x0A
+#define HID_SET_PROTOCOL		0x0B
+
+/* feature selectors */
+#define FEA_ENDPOINT_HALT		0x00
+#define FEA_REMOTE_WAKEUP		0x01
+#define FEA_TEST_MODE			0x02
+
+/*
+	USB descriptors
+*/
+
+/** USB descriptor header */
+typedef struct {
+	unsigned char	bLength;			/**< descriptor length */
+	unsigned char	bDescriptorType;	/**< descriptor type */
+} TUSBDescHeader;
+
+#define DESC_DEVICE				1
+#define DESC_CONFIGURATION		2
+#define DESC_STRING				3
+#define DESC_INTERFACE			4
+#define DESC_ENDPOINT			5
+#define DESC_DEVICE_QUALIFIER	6
+#define DESC_OTHER_SPEED		7
+#define DESC_INTERFACE_POWER	8
+
+#define DESC_HID_HID			0x21
+#define DESC_HID_REPORT			0x22
+#define DESC_HID_PHYSICAL		0x23
+
+#define GET_DESC_TYPE(x)		(((x)>>8)&0xFF)
+#define GET_DESC_INDEX(x)		((x)&0xFF)
+
+#endif /* _USBSTRUCT_H_ */
+