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_ */
+