Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Revision 0:505207de8566, committed 2011-11-29
- Comitter:
 - znuh
 - Date:
 - Tue Nov 29 21:26:20 2011 +0000
 - Commit message:
 
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/.svn/all-wcprops Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,5 @@ +K 25 +svn:wc:ra_dav:version-url +V 66 +/svn/sdd/mbed/!svn/ver/830/product/libraries/branches/emilmont/usb +END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/.svn/entries Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,59 @@ +10 + +dir +834 +http://cam-svn2.cambridge.arm.com/svn/sdd/mbed/product/libraries/branches/emilmont/usb +http://cam-svn2.cambridge.arm.com/svn/sdd/mbed + + + +2011-11-01T16:02:29.187445Z +830 +sammok01 + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + +incomplete +55d82849-f8ce-43ef-8e1a-fbdbc5b469c3 + +audio +dir + + + +delete + +cdc +dir + +hid +dir + + + +delete + +msd +dir + + + +delete + +stack +dir + + + +delete +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBDevice/.svn/all-wcprops Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,5 @@ +K 25 +svn:wc:ra_dav:version-url +V 72 +/svn/sdd/mbed/!svn/ver/830/product/libraries/branches/emilmont/usb/stack +END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBDevice/.svn/entries Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,292 @@ +10 + +dir +830 +http://cam-svn2.cambridge.arm.com/svn/sdd/mbed/product/libraries/branches/emilmont/usb/stack +http://cam-svn2.cambridge.arm.com/svn/sdd/mbed +delete + + +2011-11-01T16:02:29.187445Z +830 +sammok01 + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +55d82849-f8ce-43ef-8e1a-fbdbc5b469c3 + +USBBusInterface.h +file +836 + + + + + + + + + + + + + + + + + + + +deleted + +USBBusInterface_LPC11U.cpp +file +836 + + + + + + + + + + + + + + + + + + + +deleted + +USBBusInterface_LPC17_LPC23.cpp +file +836 + + + + + + + + + + + + + + + + + + + +deleted + +USBDescriptor.h +file +836 + + + + + + + + + + + + + + + + + + + +deleted + +USBDevice.cpp +file +836 + + + + + + + + + + + + + + + + + + + +deleted + +USBDevice.h +file +836 + + + + + + + + + + + + + + + + + + + +deleted + +USBDevice_Types.h +file +836 + + + + + + + + + + + + + + + + + + + +deleted + +USBEndpoints.h +file +836 + + + + + + + + + + + + + + + + + + + +deleted + +USBEndpoints_LPC11U.h +file +836 + + + + + + + + + + + + + + + + + + + +deleted + +USBEndpoints_LPC17_LPC23.h +file +836 + + + + + + + + + + + + + + + + + + + +deleted + +USBEvents.h +file +833 + + + + + + + + + + + + + + + + + + + +deleted +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBDevice/.svn/prop-base/USBBusInterface.h.svn-base Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 10 +text/plain +END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBDevice/.svn/prop-base/USBBusInterface_LPC11U.cpp.svn-base Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 10 +text/plain +END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBDevice/.svn/prop-base/USBBusInterface_LPC17_LPC23.cpp.svn-base Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 10 +text/plain +END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBDevice/.svn/prop-base/USBDescriptor.h.svn-base Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 10 +text/plain +END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBDevice/.svn/prop-base/USBDevice.cpp.svn-base Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 10 +text/plain +END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBDevice/.svn/prop-base/USBDevice.h.svn-base Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 10 +text/plain +END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBDevice/.svn/prop-base/USBDevice_Types.h.svn-base Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 10 +text/plain +END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBDevice/.svn/prop-base/USBEndpoints.h.svn-base Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 10 +text/plain +END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBDevice/.svn/prop-base/USBEndpoints_LPC11U.h.svn-base Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 10 +text/plain +END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBDevice/.svn/prop-base/USBEndpoints_LPC17_LPC23.h.svn-base Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 10 +text/plain +END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBDevice/.svn/prop-base/USBEvents.h.svn-base Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 10 +text/plain +END
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBDevice/.svn/text-base/USBBusInterface.h.svn-base	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,59 @@
+/* USBBusInterface.h */
+/* USB Bus Interface */
+/* Copyright (c) 2011 ARM Limited. All rights reserved. */
+
+#ifndef _USB_BUS_INTERFACE_
+#define _USB_BUS_INTERFACE_
+
+#include "mbed.h"
+#include "USBEndpoints.h"
+
+class USBHAL {
+public:
+    /* Configuration */
+    bool USBBusInterface_init(void);
+    void USBBusInterface_uninit(void);
+    void USBBusInterface_connect(void);
+    void USBBusInterface_disconnect(void);
+    void USBBusInterface_configureDevice(void);
+    void USBBusInterface_unconfigureDevice(void);
+    void USBBusInterface_setAddress(uint8_t address);
+    void USBBusInterface_remoteWakeup(void);
+
+    /* Endpoint 0 */
+    void USBBusInterface_EP0setup(uint8_t *buffer);
+    void USBBusInterface_EP0read(void);
+    uint32_t USBBusInterface_EP0getReadResult(uint8_t *buffer);
+    void USBBusInterface_EP0write(uint8_t *buffer, uint32_t size);
+    void USBBusInterface_EP0getWriteResult(void);
+    void USBBusInterface_EP0stall(void);
+
+    /* Other endpoints */
+    EP_STATUS USBBusInterface_endpointRead(uint8_t endpoint, uint32_t maximumSize);
+    EP_STATUS USBBusInterface_endpointReadResult(uint8_t endpoint, uint8_t *data, uint32_t *bytesRead);
+    EP_STATUS USBBusInterface_endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size);
+    EP_STATUS USBBusInterface_endpointWriteResult(uint8_t endpoint);
+    void USBBusInterface_stallEndpoint(uint8_t endpoint);
+    void USBBusInterface_unstallEndpoint(uint8_t endpoint);
+    bool USBBusInterface_realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t options);
+    bool USBBusInterface_getEndpointStallState(unsigned char endpoint);
+    
+protected:
+    virtual void USBDevice_busReset(void){};
+    virtual void USBDevice_EP0setup(void){};
+    virtual void USBDevice_EP0out(void){};
+    virtual void USBDevice_EP0in(void){};
+    virtual void USBDevice_connectStateChanged(unsigned int connected){};
+    virtual void USBDevice_suspendStateChanged(unsigned int suspended){};
+    void USBDevice_SOF(int frameNumber){};
+    virtual bool EPBULK_OUT_callback(){return false;};
+    virtual bool EPBULK_IN_callback(){return false;};
+    
+private:
+    void usbisr(void);
+    static void _usbisr(void);
+    static USBHAL * instance;
+};
+#endif
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBDevice/.svn/text-base/USBBusInterface_LPC11U.cpp.svn-base	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,674 @@
+/* USBBusInterface_LPC11U.c */
+/* USB Bus Interface for NXP LPC11Uxx */
+/* Copyright (c) 2011 ARM Limited. All rights reserved. */
+
+/* Reference: */
+/* NXP UM10462 LPC11U1x User manual Rev. 1 � 14 April 2011 */
+
+#ifdef TARGET_LPC11U24
+
+#include "USBBusInterface.h"
+#include "USBEvents.h"
+
+USBHAL * USBHAL::instance;
+
+
+/* Valid physical endpoint numbers are 0 to (NUMBER_OF_PHYSICAL_ENDPOINTS-1) */
+#define LAST_PHYSICAL_ENDPOINT (NUMBER_OF_PHYSICAL_ENDPOINTS-1)
+/* Convert physical endpoint number to register bit */
+#define EP(endpoint) (1UL<<endpoint)
+/* Convert physical to logical */
+#define PHY_TO_LOG(endpoint)    ((endpoint)>>1)
+/* Get endpoint direction */
+#define IN_EP(endpoint)     ((endpoint) & 1U ? true : false)
+#define OUT_EP(endpoint)    ((endpoint) & 1U ? false : true)
+
+/* USB RAM */
+#define USB_RAM_START (0x20004000)
+#define USB_RAM_SIZE  (0x00000800)
+
+/* SYSAHBCLKCTRL */
+#define CLK_USB     (1UL<<14)
+#define CLK_USBRAM  (1UL<<27)
+
+/* USB Information register */
+#define FRAME_NR(a)     ((a) & 0x7ff)   /* Frame number */
+
+/* USB Device Command/Status register */
+#define DEV_ADDR_MASK   (0x7f)          /* Device address */
+#define DEV_ADDR(a)     ((a) & DEV_ADDR_MASK)
+#define DEV_EN          (1UL<<7)        /* Device enable */
+#define SETUP           (1UL<<8)        /* SETUP token received */
+#define PLL_ON          (1UL<<9)        /* PLL enabled in suspend */
+#define DCON            (1UL<<16)       /* Device status - connect */
+#define DSUS            (1UL<<17)       /* Device status - suspend */
+#define DCON_C          (1UL<<24)       /* Connect change */
+#define DSUS_C          (1UL<<25)       /* Suspend change */
+#define DRES_C          (1UL<<26)       /* Reset change */
+#define VBUSDEBOUNCED   (1UL<<28)       /* Vbus detected */
+
+/* Endpoint Command/Status list */
+#define CMDSTS_A                 (1UL<<31)          /* Active */
+#define CMDSTS_D                 (1UL<<30)          /* Disable */
+#define CMDSTS_S                 (1UL<<29)          /* Stall */
+#define CMDSTS_TR                (1UL<<28)          /* Toggle Reset */
+#define CMDSTS_RF                (1UL<<27)          /* Rate Feedback mode */
+#define CMDSTS_TV                (1UL<<27)          /* Toggle Value */
+#define CMDSTS_T                 (1UL<<26)          /* Endpoint Type */
+#define CMDSTS_NBYTES(n)         (((n)&0x3ff)<<16)  /* Number of bytes */
+#define CMDSTS_ADDRESS_OFFSET(a) (((a)>>6)&0xffff)  /* Buffer start address */
+
+#define BYTES_REMAINING(s)       (((s)>>16)&0x3ff)  /* Bytes remaining after transfer */
+
+/* USB Non-endpoint interrupt sources */
+#define FRAME_INT   (1UL<<30)
+#define DEV_INT     (1UL<<31)
+
+static int epComplete = 0;
+
+/* One entry for a double-buffered logical endpoint in the endpoint */
+/* command/status list. Endpoint 0 is single buffered, out[1] is used */
+/* for the SETUP packet and in[1] is not used */
+typedef __packed struct {
+    uint32_t out[2];
+    uint32_t in[2];
+} EP_COMMAND_STATUS;
+
+typedef __packed struct {
+    uint8_t out[MAX_PACKET_SIZE_EP0];
+    uint8_t in[MAX_PACKET_SIZE_EP0];
+    uint8_t setup[SETUP_PACKET_SIZE];
+} CONTROL_TRANSFER;
+
+typedef __packed struct {
+    uint32_t    maxPacket;
+    uint32_t    buffer[2];
+    uint32_t    options;
+} EP_STATE;
+
+static volatile EP_STATE endpointState[NUMBER_OF_PHYSICAL_ENDPOINTS];
+
+/* Pointer to the endpoint command/status list */
+static EP_COMMAND_STATUS *ep = NULL;
+
+/* Pointer to endpoint 0 data (IN/OUT and SETUP) */
+static CONTROL_TRANSFER *ct = NULL;
+
+/* Shadow DEVCMDSTAT register to avoid accidentally clearing flags or */
+/* initiating a remote wakeup event. */
+static volatile uint32_t devCmdStat;
+
+/* Pointers used to allocate USB RAM */
+static uint32_t usbRamPtr = USB_RAM_START;
+static uint32_t epRamPtr = 0; /* Buffers for endpoints > 0 start here */
+
+#define ROUND_UP_TO_MULTIPLE(x, m) ((((x)+((m)-1))/(m))*(m))
+
+void USBMemCopy(uint8_t *dst, uint8_t *src, uint32_t size);
+void USBMemCopy(uint8_t *dst, uint8_t *src, uint32_t size) {
+    if (size > 0) {
+        do {
+            *dst++ = *src++;
+        } while (--size > 0);
+    }
+}
+
+/*
+ *  USBBusInterface API
+ */
+
+
+bool USBHAL::USBBusInterface_init(void) {
+    NVIC_DisableIRQ(USB_IRQn);
+
+    /* USB_VBUS input, Pull down, Hysteresis enabled */
+    //LPC_IOCON->PIO0_3 = 0x00000029;
+    /* nUSB_CONNECT output */
+    LPC_IOCON->PIO0_6 = 0x00000001;
+
+    /* Enable clocks (USB registers, USB RAM) */
+    LPC_SYSCON->SYSAHBCLKCTRL |= CLK_USB | CLK_USBRAM;
+
+    /* Ensure device disconnected (DCON not set) */
+    LPC_USB->DEVCMDSTAT = 0;
+    /* Device must be disconnected for at least 2.5uS */
+    /* to ensure that the USB host sees the device as */
+    /* disconnected if the target CPU is reset. */
+    wait(0.3);
+
+
+    /* Reserve space in USB RAM for endpoint command/status list */
+    /* Must be 256 byte aligned */
+    usbRamPtr = ROUND_UP_TO_MULTIPLE(usbRamPtr, 256);
+    ep = (EP_COMMAND_STATUS *)usbRamPtr;
+    usbRamPtr += (sizeof(EP_COMMAND_STATUS) * NUMBER_OF_LOGICAL_ENDPOINTS);
+    LPC_USB->EPLISTSTART = (uint32_t)(ep) & 0xffffff00;
+
+    /* Reserve space in USB RAM for Endpoint 0 */
+    /* Must be 64 byte aligned */
+    usbRamPtr = ROUND_UP_TO_MULTIPLE(usbRamPtr, 64);
+    ct = (CONTROL_TRANSFER *)usbRamPtr;
+    usbRamPtr += sizeof(CONTROL_TRANSFER);
+    LPC_USB->DATABUFSTART =(uint32_t)(ct) & 0xffc00000;
+
+    /* Setup command/status list for EP0 */
+    ep[0].out[0] = 0;
+    ep[0].in[0] =  0;
+    ep[0].out[1] = CMDSTS_ADDRESS_OFFSET((uint32_t)ct->setup);
+
+    /* Route all interrupts to IRQ, some can be routed to  */
+    /* USB_FIQ if you wish. */
+    LPC_USB->INTROUTING = 0;
+
+    /* Set device address 0, enable USB device, no remote wakeup */
+    devCmdStat = DEV_ADDR(0) | DEV_EN | DSUS;
+    LPC_USB->DEVCMDSTAT = devCmdStat;
+
+    /* Enable interrupts for device events and EP0 */
+    LPC_USB->INTEN = DEV_INT | EP(EP0IN) | EP(EP0OUT);
+    instance = this;
+    NVIC_SetVector(USB_IRQn, (uint32_t)&_usbisr);
+    NVIC_EnableIRQ(USB_IRQn);
+
+
+    /* Successful */
+    return true;
+}
+
+void USBHAL::USBBusInterface_uninit(void) {
+    /* Ensure device disconnected (DCON not set) */
+    LPC_USB->DEVCMDSTAT = 0;
+
+    /* Disable USB interrupts */
+    NVIC_DisableIRQ(USB_IRQn);
+}
+
+void USBHAL::USBBusInterface_connect(void) {
+    devCmdStat |= DCON;
+    LPC_USB->DEVCMDSTAT = devCmdStat;
+}
+
+void USBHAL::USBBusInterface_disconnect(void) {
+    devCmdStat &= ~DCON;
+    LPC_USB->DEVCMDSTAT = devCmdStat;
+}
+
+void USBHAL::USBBusInterface_configureDevice(void) {
+}
+
+void USBHAL::USBBusInterface_unconfigureDevice(void) {
+}
+
+void USBHAL::USBBusInterface_EP0setup(uint8_t *buffer) {
+    /* Copy setup packet data */
+    USBMemCopy(buffer, ct->setup, SETUP_PACKET_SIZE);
+}
+
+void USBHAL::USBBusInterface_EP0read(void) {
+    /* Start an endpoint 0 read */
+
+    /* The USB ISR will call USBDevice_EP0out() when a packet has been read, */
+    /* the USBDevice layer then calls USBBusInterface_EP0getReadResult() to */
+    /* read the data. */
+
+    ep[0].out[0] = CMDSTS_A |CMDSTS_NBYTES(MAX_PACKET_SIZE_EP0) \
+                   | CMDSTS_ADDRESS_OFFSET((uint32_t)ct->out);
+}
+
+uint32_t USBHAL::USBBusInterface_EP0getReadResult(uint8_t *buffer) {
+    /* Complete an endpoint 0 read */
+    uint32_t bytesRead;
+
+    /* Find how many bytes were read */
+    bytesRead = MAX_PACKET_SIZE_EP0 - BYTES_REMAINING(ep[0].out[0]);
+
+    /* Copy data */
+    USBMemCopy(buffer, ct->out, bytesRead);
+    return bytesRead;
+}
+
+void USBHAL::USBBusInterface_EP0write(uint8_t *buffer, uint32_t size) {
+    /* Start and endpoint 0 write */
+
+    /* The USB ISR will call USBDevice_EP0in() when the data has */
+    /* been written, the USBDevice layer then calls */
+    /* USBBusInterface_EP0getWriteResult() to complete the transaction. */
+
+    /* Copy data */
+    USBMemCopy(ct->in, buffer, size);
+
+    /* Start transfer */
+    ep[0].in[0] = CMDSTS_A | CMDSTS_NBYTES(size) \
+                  | CMDSTS_ADDRESS_OFFSET((uint32_t)ct->in);
+}
+
+
+EP_STATUS USBHAL::USBBusInterface_endpointRead(uint8_t endpoint, uint32_t maximumSize) {
+    ep[PHY_TO_LOG(endpoint)].out[0] = CMDSTS_A | CMDSTS_NBYTES(maximumSize) \
+                                      | CMDSTS_ADDRESS_OFFSET((uint32_t)ct->out);
+    return EP_PENDING;
+}
+
+EP_STATUS USBHAL::USBBusInterface_endpointReadResult(uint8_t endpoint, uint8_t *data, uint32_t *bytesRead) {
+    if (!(epComplete & EP(endpoint)))
+        return EP_PENDING;
+    else {
+        epComplete &= ~EP(endpoint);
+        /* Find how many bytes were read */
+        *bytesRead = (uint32_t) (endpointState[endpoint].maxPacket - BYTES_REMAINING(ep[PHY_TO_LOG(endpoint)].out[0]));
+        /* Copy data */
+        USBMemCopy(data, ct->out, *bytesRead);
+        return EP_COMPLETED;
+    }
+}
+
+void USBHAL::USBBusInterface_EP0getWriteResult(void) {
+    /* Complete an endpoint 0 write */
+
+    /* Nothing required for this target */
+    return;
+}
+
+void USBHAL::USBBusInterface_EP0stall(void) {
+    ep[0].in[0] = CMDSTS_S;
+    ep[0].out[0] = CMDSTS_S;
+}
+
+void USBHAL::USBBusInterface_setAddress(uint8_t address) {
+    devCmdStat &= ~DEV_ADDR_MASK;
+    devCmdStat |= DEV_ADDR(address);
+    LPC_USB->DEVCMDSTAT = devCmdStat;
+}
+
+EP_STATUS USBHAL::USBBusInterface_endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size) {
+    uint32_t flags = 0;
+    uint32_t bf;
+
+    /* Validate parameters */
+    if (data == NULL) {
+        return EP_INVALID;
+    }
+
+    if (endpoint > LAST_PHYSICAL_ENDPOINT) {
+        return EP_INVALID;
+    }
+
+    if ((endpoint==EP0IN) || (endpoint==EP0OUT)) {
+        return EP_INVALID;
+    }
+
+    if (size > endpointState[endpoint].maxPacket) {
+        return EP_INVALID;
+    }
+
+    if (LPC_USB->EPBUFCFG & EP(endpoint)) {
+        /* Double buffered */ /* TODO: FIX THIS */
+        if (LPC_USB->EPINUSE & EP(endpoint)) {
+            bf = 1;
+        } else {
+            bf = 0;
+        }
+    } else {
+        /* Single buffered */
+        bf = 0;
+    }
+
+    /* Check if already active */
+    if (ep[PHY_TO_LOG(endpoint)].in[bf] & CMDSTS_A) {
+        return EP_INVALID;
+    }
+
+    /* Check if stalled */
+    if (ep[PHY_TO_LOG(endpoint)].in[bf] & CMDSTS_S) {
+        return EP_STALLED;
+    }
+
+    /* Copy data to USB RAM */
+    USBMemCopy((uint8_t *)endpointState[endpoint].buffer[bf], data, size);
+
+    /* Add options */
+    if (endpointState[endpoint].options & RATE_FEEDBACK_MODE) {
+        flags |= CMDSTS_RF;
+    }
+
+    if (endpointState[endpoint].options & ISOCHRONOUS) {
+        flags |= CMDSTS_T;
+    }
+
+    /* Add transfer */
+    ep[PHY_TO_LOG(endpoint)].in[bf] = CMDSTS_ADDRESS_OFFSET( \
+                                      endpointState[endpoint].buffer[bf]) \
+                                      | CMDSTS_NBYTES(size) | CMDSTS_A | flags;
+
+    return EP_PENDING;
+}
+
+EP_STATUS USBHAL::USBBusInterface_endpointWriteResult(uint8_t endpoint) {
+    uint32_t bf;
+    /* Validate parameters */
+
+    if (endpoint > LAST_PHYSICAL_ENDPOINT) {
+        return EP_INVALID;
+    }
+
+    if (OUT_EP(endpoint)) {
+        return EP_INVALID;
+    }
+
+    if (LPC_USB->EPBUFCFG & EP(endpoint)) {
+        /* Double buffered */    /* TODO: FIX THIS */
+        if (LPC_USB->EPINUSE & EP(endpoint)) {
+            bf = 1;
+        } else {
+            bf = 0;
+        }
+    } else {
+        /* Single buffered */
+        bf = 0;
+    }
+
+    /* Check if endpoint still active */
+    if (ep[PHY_TO_LOG(endpoint)].in[bf] & CMDSTS_A) {
+        return EP_PENDING;
+    }
+
+    /* Check if stalled */
+    if (ep[PHY_TO_LOG(endpoint)].in[bf] & CMDSTS_S) {
+        return EP_STALLED;
+    }
+
+    return EP_COMPLETED;
+}
+
+void USBHAL::USBBusInterface_stallEndpoint(uint8_t endpoint) {
+
+    // TODO: should this clear active bit?
+
+    if (IN_EP(endpoint)) {
+        ep[PHY_TO_LOG(endpoint)].in[0] |= CMDSTS_S;
+        ep[PHY_TO_LOG(endpoint)].in[1] |= CMDSTS_S;
+    } else {
+        ep[PHY_TO_LOG(endpoint)].out[0] |= CMDSTS_S;
+        ep[PHY_TO_LOG(endpoint)].out[1] |= CMDSTS_S;
+    }
+}
+
+void USBHAL::USBBusInterface_unstallEndpoint(uint8_t endpoint) {
+    if (LPC_USB->EPBUFCFG & EP(endpoint)) {
+        /* Double buffered */
+        if (IN_EP(endpoint)) {
+            ep[PHY_TO_LOG(endpoint)].in[0] = 0; /* S = 0 */
+            ep[PHY_TO_LOG(endpoint)].in[1] = 0; /* S = 0 */
+
+            if (LPC_USB->EPINUSE & EP(endpoint)) {
+                ep[PHY_TO_LOG(endpoint)].in[1] = CMDSTS_TR; /* S =0, TR=1, TV = 0 */
+            } else {
+                ep[PHY_TO_LOG(endpoint)].in[0] = CMDSTS_TR; /* S =0, TR=1, TV = 0 */
+            }
+        } else {
+            ep[PHY_TO_LOG(endpoint)].out[0] = 0; /* S = 0 */
+            ep[PHY_TO_LOG(endpoint)].out[1] = 0; /* S = 0 */
+
+            if (LPC_USB->EPINUSE & EP(endpoint)) {
+                ep[PHY_TO_LOG(endpoint)].out[1] = CMDSTS_TR; /* S =0, TR=1, TV = 0 */
+            } else {
+                ep[PHY_TO_LOG(endpoint)].out[0] = CMDSTS_TR; /* S =0, TR=1, TV = 0 */
+            }
+        }
+    } else {
+        /* Single buffered */
+        if (IN_EP(endpoint)) {
+            ep[PHY_TO_LOG(endpoint)].in[0] = CMDSTS_TR; /* S=0, TR=1, TV = 0 */
+        } else {
+            ep[PHY_TO_LOG(endpoint)].out[0] = CMDSTS_TR; /* S=0, TR=1, TV = 0 */
+        }
+    }
+}
+
+bool USBHAL::USBBusInterface_getEndpointStallState(unsigned char endpoint) {
+    if (IN_EP(endpoint)) {
+        if (LPC_USB->EPINUSE & EP(endpoint)) {
+            if (ep[PHY_TO_LOG(endpoint)].in[1] & CMDSTS_S) {
+                return true;
+            }
+        } else {
+            if (ep[PHY_TO_LOG(endpoint)].in[0] & CMDSTS_S) {
+                return true;
+            }
+        }
+    } else {
+        if (LPC_USB->EPINUSE & EP(endpoint)) {
+            if (ep[PHY_TO_LOG(endpoint)].out[1] & CMDSTS_S) {
+                return true;
+            }
+        } else {
+            if (ep[PHY_TO_LOG(endpoint)].out[0] & CMDSTS_S) {
+                return true;
+            }
+        }
+    }
+
+    return false;
+}
+
+bool USBHAL::USBBusInterface_realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t options) {
+    uint32_t tmpEpRamPtr;
+
+    /*
+        *
+        *   Support for double buffered endpoints needs to be fixed/finished in this
+        *   software - force single buffered for now.
+        *
+    */
+    options |= SINGLE_BUFFERED; /* TODO - FIX THIS */
+
+    if (endpoint > LAST_PHYSICAL_ENDPOINT) {
+        return false;
+    }
+
+    /* Not applicable to the control endpoints */
+    if ((endpoint==EP0IN) || (endpoint==EP0OUT)) {
+        return false;
+    }
+
+    /* Allocate buffers in USB RAM */
+    tmpEpRamPtr = epRamPtr;
+
+    /* Must be 64 byte aligned */
+    tmpEpRamPtr = ROUND_UP_TO_MULTIPLE(tmpEpRamPtr, 64);
+
+    if ((tmpEpRamPtr + maxPacket) > (USB_RAM_START + USB_RAM_SIZE)) {
+        /* Out of memory */
+        return false;
+    }
+
+    /* Allocate first buffer */
+    endpointState[endpoint].buffer[0] = tmpEpRamPtr;
+    tmpEpRamPtr += maxPacket;
+
+    if (!(options & SINGLE_BUFFERED)) {
+        /* Must be 64 byte aligned */
+        tmpEpRamPtr = ROUND_UP_TO_MULTIPLE(tmpEpRamPtr, 64);
+
+        if ((tmpEpRamPtr + maxPacket) > (USB_RAM_START + USB_RAM_SIZE)) {
+            /* Out of memory */
+            return false;
+        }
+
+        /* Allocate second buffer */
+        endpointState[endpoint].buffer[1] = tmpEpRamPtr;
+        tmpEpRamPtr += maxPacket;
+    }
+
+    /* Commit to this USB RAM allocation */
+    epRamPtr = tmpEpRamPtr;
+
+    /* Remaining endpoint state values */
+    endpointState[endpoint].maxPacket = maxPacket;
+    endpointState[endpoint].options = options;
+
+    /* Enable double buffering if required */
+    if (options & SINGLE_BUFFERED) {
+        LPC_USB->EPBUFCFG &= ~EP(endpoint);
+    } else {
+        /* Double buffered */
+        LPC_USB->EPBUFCFG |= EP(endpoint);
+    }
+
+    /* Enable interrupt for OUT endpoint */
+    LPC_USB->INTEN |= EP(endpoint);
+
+    /* Enable endpoint */
+    USBBusInterface_unstallEndpoint(endpoint);
+    return true;
+}
+
+void USBHAL::USBBusInterface_remoteWakeup(void) {
+    /* Clearing DSUS bit initiates a remote wakeup if the */
+    /* device is currently enabled and suspended - otherwise */
+    /* it has no effect. */
+    LPC_USB->DEVCMDSTAT = devCmdStat & ~DSUS;
+}
+
+/*
+ *  Configuration helper functions
+ */
+
+static void disableEndpoints(void) {
+    uint32_t logEp;
+
+    /* Ref. Table 158 "When a bus reset is received, software */
+    /* must set the disable bit of all endpoints to 1".*/
+
+    for (logEp = 1; logEp < NUMBER_OF_LOGICAL_ENDPOINTS; logEp++) {
+        ep[logEp].out[0] = CMDSTS_D;
+        ep[logEp].out[1] = CMDSTS_D;
+        ep[logEp].in[0] =  CMDSTS_D;
+        ep[logEp].in[1] =  CMDSTS_D;
+    }
+
+    /* Start of USB RAM for endpoints > 0 */
+    epRamPtr = usbRamPtr;
+}
+
+
+
+
+/*
+ *  USB interrupt handler
+ */
+
+void USBHAL::_usbisr(void)
+{
+    instance->usbisr();
+}
+DigitalOut l1(LED1);
+void USBHAL::usbisr(void) {
+    /* Start of frame */
+    if (LPC_USB->INTSTAT & FRAME_INT) {
+        /* Clear SOF interrupt */
+        LPC_USB->INTSTAT = FRAME_INT;
+
+        /* SOF event, read frame number */
+        USBDevice_SOF(FRAME_NR(LPC_USB->INFO));
+    }
+
+    /* Device state */
+    if (LPC_USB->INTSTAT & DEV_INT) {
+        LPC_USB->INTSTAT = DEV_INT;
+
+        if (LPC_USB->DEVCMDSTAT & DCON_C) {
+            /* Connect status changed */
+            LPC_USB->DEVCMDSTAT = devCmdStat | DCON_C;
+
+            USBDevice_connectStateChanged((LPC_USB->DEVCMDSTAT & DCON) != 0);
+        }
+
+        if (LPC_USB->DEVCMDSTAT & DSUS_C) {
+            /* Suspend status changed */
+            LPC_USB->DEVCMDSTAT = devCmdStat | DSUS_C;
+
+            USBDevice_suspendStateChanged((LPC_USB->DEVCMDSTAT & DSUS) != 0);
+        }
+
+        if (LPC_USB->DEVCMDSTAT & DRES_C) {
+            /* Bus reset */
+            LPC_USB->DEVCMDSTAT = devCmdStat | DRES_C;
+
+            /* Disable endpoints > 0 */
+            disableEndpoints();
+
+            /* Bus reset event */
+            USBDevice_busReset();
+        }
+    }
+
+    /* Endpoint 0 */
+    if (LPC_USB->INTSTAT & EP(EP0OUT)) {
+        /* Clear EP0OUT/SETUP interrupt */
+        LPC_USB->INTSTAT = EP(EP0OUT);
+
+        /* Check if SETUP */
+        if (LPC_USB->DEVCMDSTAT & SETUP) {
+            /* Clear Active and Stall bits for EP0 */
+            /* Documentation does not make it clear if we must use the */
+            /* EPSKIP register to achieve this, Fig. 16 and NXP reference */
+            /* code suggests we can just clear the Active bits - check with */
+            /* NXP to be sure. */
+            ep[0].in[0] = 0;
+            ep[0].out[0] = 0;
+
+            /* Clear EP0IN interrupt */
+            LPC_USB->INTSTAT = EP(EP0IN);
+
+            /* Clear SETUP (and INTONNAK_CI/O) in device status register */
+            LPC_USB->DEVCMDSTAT = devCmdStat | SETUP;
+
+            /* EP0 SETUP event (SETUP data received) */
+            USBDevice_EP0setup();
+        } else {
+            /* EP0OUT ACK event (OUT data received) */
+            USBDevice_EP0out();
+        }
+    }
+
+    if (LPC_USB->INTSTAT & EP(EP0IN)) {
+        /* Clear EP0IN interrupt */
+        LPC_USB->INTSTAT = EP(EP0IN);
+
+        /* EP0IN ACK event (IN data sent) */
+        USBDevice_EP0in();
+    }
+
+    if (LPC_USB->INTSTAT & EP(EP1IN)) {
+        /* Clear EP1IN interrupt */
+        LPC_USB->INTSTAT = EP(EP1IN);
+        epComplete |= EP(EP1IN);
+    }
+
+    if (LPC_USB->INTSTAT & EP(EP1OUT)) {
+        /* Clear EP1OUT interrupt */
+        LPC_USB->INTSTAT = EP(EP1OUT);
+        epComplete |= EP(EP1OUT);
+    }
+
+    if (LPC_USB->INTSTAT & EP(EPBULK_IN)) {
+        /* Clear EPBULK_OUT interrupt */
+        LPC_USB->INTSTAT = EP(EPBULK_IN);
+        epComplete |= EP(EPBULK_IN);
+        if(EPBULK_IN_callback())
+        	epComplete &= ~EP(EPBULK_IN);
+    }
+
+    if (LPC_USB->INTSTAT & EP(EPBULK_OUT)) {
+        /* Clear EPBULK_OUT interrupt */
+        LPC_USB->INTSTAT = EP(EPBULK_OUT);
+        epComplete |= EP(EPBULK_OUT);
+        //Call callback function. If true, clear epComplete
+        if(EPBULK_OUT_callback())
+        	epComplete &= ~EP(EPBULK_OUT);
+    }
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBDevice/.svn/text-base/USBBusInterface_LPC17_LPC23.cpp.svn-base	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,691 @@
+/* USBBusInterface_LPC17_LPC23.c */
+/* USB Bus Interface for NXP LPC1768 and LPC2368 */
+/* Copyright (c) 2011 ARM Limited. All rights reserved. */
+
+#ifdef TARGET_LPC1768
+
+#include "USBBusInterface.h"
+#include "USBEvents.h"
+
+
+/* Get endpoint direction */
+#define IN_EP(endpoint)     ((endpoint) & 1U ? true : false)
+#define OUT_EP(endpoint)    ((endpoint) & 1U ? false : true)
+
+/* Convert physical endpoint number to register bit */
+#define EP(endpoint) (1UL<<endpoint)
+
+/* Power Control for Peripherals register */
+#define PCUSB      (1UL<<31)
+
+/* USB Clock Control register */
+#define DEV_CLK_EN (1UL<<1)
+#define AHB_CLK_EN (1UL<<4)
+
+/* USB Clock Status register */
+#define DEV_CLK_ON (1UL<<1)
+#define AHB_CLK_ON (1UL<<4)
+
+/* USB Device Interupt registers */
+#define FRAME      (1UL<<0)
+#define EP_FAST    (1UL<<1)
+#define EP_SLOW    (1UL<<2)
+#define DEV_STAT   (1UL<<3)
+#define CCEMPTY    (1UL<<4)
+#define CDFULL     (1UL<<5)
+#define RxENDPKT   (1UL<<6)
+#define TxENDPKT   (1UL<<7)
+#define EP_RLZED   (1UL<<8)
+#define ERR_INT    (1UL<<9)
+
+/* USB Control register */
+#define RD_EN (1<<0)
+#define WR_EN (1<<1)
+#define LOG_ENDPOINT(endpoint) ((endpoint>>1)<<2)
+
+/* USB Receive Packet Length register */
+#define DV      (1UL<<10)
+#define PKT_RDY (1UL<<11)
+#define PKT_LNGTH_MASK (0x3ff)
+
+/* Serial Interface Engine (SIE) */
+#define SIE_WRITE   (0x01)
+#define SIE_READ    (0x02)
+#define SIE_COMMAND (0x05)
+#define SIE_CMD_CODE(phase, data) ((phase<<8)|(data<<16))
+
+/* SIE Command codes */
+#define SIE_CMD_SET_ADDRESS        (0xD0)
+#define SIE_CMD_CONFIGURE_DEVICE   (0xD8)
+#define SIE_CMD_SET_MODE           (0xF3)
+#define SIE_CMD_READ_FRAME_NUMBER  (0xF5)
+#define SIE_CMD_READ_TEST_REGISTER (0xFD)
+#define SIE_CMD_SET_DEVICE_STATUS  (0xFE)
+#define SIE_CMD_GET_DEVICE_STATUS  (0xFE)
+#define SIE_CMD_GET_ERROR_CODE     (0xFF)
+#define SIE_CMD_READ_ERROR_STATUS  (0xFB)
+
+#define SIE_CMD_SELECT_ENDPOINT(endpoint)                 (0x00+endpoint)
+#define SIE_CMD_SELECT_ENDPOINT_CLEAR_INTERRUPT(endpoint) (0x40+endpoint)
+#define SIE_CMD_SET_ENDPOINT_STATUS(endpoint)             (0x40+endpoint)
+
+#define SIE_CMD_CLEAR_BUFFER    (0xF2)
+#define SIE_CMD_VALIDATE_BUFFER (0xFA)
+
+/* SIE Device Status register */
+#define SIE_DS_CON    (1<<0)
+#define SIE_DS_CON_CH (1<<1)
+#define SIE_DS_SUS    (1<<2)
+#define SIE_DS_SUS_CH (1<<3)
+#define SIE_DS_RST    (1<<4)
+
+/* SIE Device Set Address register */
+#define SIE_DSA_DEV_EN  (1<<7)
+
+/* SIE Configue Device register */
+#define SIE_CONF_DEVICE (1<<0)
+
+/* Select Endpoint register */
+#define SIE_SE_FE       (1<<0)
+#define SIE_SE_ST       (1<<1)
+#define SIE_SE_STP      (1<<2)
+#define SIE_SE_PO       (1<<3)
+#define SIE_SE_EPN      (1<<4)
+#define SIE_SE_B_1_FULL (1<<5)
+#define SIE_SE_B_2_FULL (1<<6)
+
+/* Set Endpoint Status command */
+#define SIE_SES_ST      (1<<0)
+#define SIE_SES_DA      (1<<5)
+#define SIE_SES_RF_MO   (1<<6)
+#define SIE_SES_CND_ST  (1<<7)
+
+
+USBHAL * USBHAL::instance;
+
+static uint32_t endpointStallState;
+
+static int epComplete = 0;
+/*
+ *  Serial Interface Engine commands
+ */
+
+static void SIECommand(uint32_t command)
+{
+    /* The command phase of a SIE transaction */
+    LPC_USB->USBDevIntClr = CCEMPTY;
+    LPC_USB->USBCmdCode = SIE_CMD_CODE(SIE_COMMAND, command);
+    while (!(LPC_USB->USBDevIntSt & CCEMPTY)); 
+}
+
+static void SIEWriteData(uint8_t data)
+{
+    /* The data write phase of a SIE transaction */
+    LPC_USB->USBDevIntClr = CCEMPTY;
+    LPC_USB->USBCmdCode = SIE_CMD_CODE(SIE_WRITE, data);
+    while (!(LPC_USB->USBDevIntSt & CCEMPTY)); 
+}
+
+static uint8_t SIEReadData(uint32_t command)
+{
+    /* The data read phase of a SIE transaction */
+    LPC_USB->USBDevIntClr = CDFULL;
+    LPC_USB->USBCmdCode = SIE_CMD_CODE(SIE_READ, command);
+    while (!(LPC_USB->USBDevIntSt & CDFULL));
+    return (uint8_t)LPC_USB->USBCmdData;
+}
+
+static void SIEsetDeviceStatus(uint8_t status)
+{
+    /* Write SIE device status register */
+    SIECommand(SIE_CMD_SET_DEVICE_STATUS);
+    SIEWriteData(status);
+}
+
+static uint8_t SIEgetDeviceStatus(void)
+{
+    /* Read SIE device status register */
+    SIECommand(SIE_CMD_GET_DEVICE_STATUS);
+    return SIEReadData(SIE_CMD_GET_DEVICE_STATUS);
+}
+
+void SIEsetAddress(uint8_t address)
+{
+    /* Write SIE device address register */
+    SIECommand(SIE_CMD_SET_ADDRESS);
+    SIEWriteData((address & 0x7f) | SIE_DSA_DEV_EN);
+}
+
+static uint8_t SIEselectEndpoint(uint8_t endpoint)
+{
+    /* SIE select endpoint command */
+    SIECommand(SIE_CMD_SELECT_ENDPOINT(endpoint));
+    return SIEReadData(SIE_CMD_SELECT_ENDPOINT(endpoint));
+}
+
+static uint8_t SIEclearBuffer(void)
+{
+    /* SIE clear buffer command */
+    SIECommand(SIE_CMD_CLEAR_BUFFER);
+    return SIEReadData(SIE_CMD_CLEAR_BUFFER);
+}
+
+static void SIEvalidateBuffer(void)
+{
+    /* SIE validate buffer command */
+    SIECommand(SIE_CMD_VALIDATE_BUFFER);
+}
+
+static void SIEsetEndpointStatus(uint8_t endpoint, uint8_t status)
+{
+    /* SIE set endpoint status command */
+    SIECommand(SIE_CMD_SET_ENDPOINT_STATUS(endpoint));
+    SIEWriteData(status);
+}
+
+static uint16_t SIEgetFrameNumber(void) __attribute__ ((unused));
+static uint16_t SIEgetFrameNumber(void)
+{
+    /* Read current frame number */
+    uint16_t lowByte;
+    uint16_t highByte;
+
+    SIECommand(SIE_CMD_READ_FRAME_NUMBER);
+    lowByte = SIEReadData(SIE_CMD_READ_FRAME_NUMBER);
+    highByte = SIEReadData(SIE_CMD_READ_FRAME_NUMBER);
+
+    return (highByte << 8) | lowByte;
+}
+
+static void SIEconfigureDevice(void)
+{
+    /* SIE Configure device command */
+    SIECommand(SIE_CMD_CONFIGURE_DEVICE);
+    SIEWriteData(SIE_CONF_DEVICE);
+}
+
+static void SIEunconfigureDevice(void)
+{
+    /* SIE Configure device command */
+    SIECommand(SIE_CMD_CONFIGURE_DEVICE);
+    SIEWriteData(0);
+}
+
+static void SIEconnect(void)
+{
+    /* Connect USB device */
+    uint8_t status;
+
+    status = SIEgetDeviceStatus();
+    SIEsetDeviceStatus(status | SIE_DS_CON);
+}
+
+
+static void SIEdisconnect(void)
+{
+    /* Disconnect USB device */
+    uint8_t status;
+
+    status = SIEgetDeviceStatus();
+    SIEsetDeviceStatus(status & ~SIE_DS_CON);
+}
+
+/*
+ *  Endpoint commands
+ */
+
+static uint8_t selectEndpointClearInterrupt(uint8_t endpoint)
+{
+    /* Implemented using using EP_INT_CLR. */
+    LPC_USB->USBEpIntClr = EP(endpoint);
+    while (!(LPC_USB->USBDevIntSt & CDFULL));
+    return (uint8_t)LPC_USB->USBCmdData;
+}
+
+static void stallEndpoint(uint8_t endpoint)
+{
+    /* Stall an endpoint */
+    if ( (endpoint==EP0IN) || (endpoint==EP0OUT) )
+    {
+        /* Conditionally stall both control endpoints */
+        SIEsetEndpointStatus(EP0OUT, SIE_SES_CND_ST);
+    }
+    else
+    {
+        SIEsetEndpointStatus(endpoint, SIE_SES_ST);
+
+        /* Update stall state */
+        endpointStallState |= EP(endpoint);
+    }
+}
+
+static void unstallEndpoint(uint8_t endpoint)
+{
+    /* Unstall an endpoint. The endpoint will also be reinitialised */
+    SIEsetEndpointStatus(endpoint, 0);
+
+    /* Update stall state */
+    endpointStallState &= ~EP(endpoint);
+}
+
+static bool getEndpointStallState(uint8_t endpoint)
+{ 
+    /* Returns true if endpoint stalled */
+    return endpointStallState & EP(endpoint);
+}
+
+static void realiseEndpoint(uint8_t endpoint, uint32_t maxPacket)
+{
+    /* Realise an endpoint */
+    LPC_USB->USBDevIntClr = EP_RLZED;
+    LPC_USB->USBReEp |= EP(endpoint);
+    LPC_USB->USBEpInd = endpoint;
+    LPC_USB->USBMaxPSize = maxPacket;
+
+    while (!(LPC_USB->USBDevIntSt & EP_RLZED));
+    LPC_USB->USBDevIntClr = EP_RLZED;
+
+    /* Clear stall state */
+    endpointStallState &= ~EP(endpoint);
+}
+
+static void enableEndpointEvent(uint8_t endpoint)
+{
+    /* Enable an endpoint interrupt */
+    LPC_USB->USBEpIntEn |= EP(endpoint);
+}
+
+static void disableEndpointEvent(uint8_t endpoint) __attribute__ ((unused));
+static void disableEndpointEvent(uint8_t endpoint)
+{
+    /* Disable an endpoint interrupt */
+    LPC_USB->USBEpIntEn &= ~EP(endpoint);
+}
+
+static volatile uint32_t __attribute__((used)) dummyRead;
+
+static uint32_t endpointRead(uint8_t endpoint, uint8_t *buffer)
+{
+    /* Read from an OUT endpoint */
+    uint32_t size;
+    uint32_t i;
+    uint32_t data;
+    uint8_t offset;
+
+    LPC_USB->USBCtrl = LOG_ENDPOINT(endpoint) | RD_EN;
+    while (!(LPC_USB->USBRxPLen & PKT_RDY));
+
+    size = LPC_USB->USBRxPLen & PKT_LNGTH_MASK;
+
+    offset = 0;
+
+    if (size > 0)
+    {
+        for (i=0; i<size; i++)
+        {
+            if (offset==0)
+            {
+                /* Fetch up to four bytes of data as a word */
+                data = LPC_USB->USBRxData;
+            }
+
+            /* extract a byte */
+            *buffer = (data>>offset) & 0xff;
+            buffer++;
+
+            /* move on to the next byte */
+            offset = (offset + 8) % 32;
+        }
+    }
+    else
+    {
+        dummyRead = LPC_USB->USBRxData;
+    }
+
+    SIEselectEndpoint(endpoint);
+    SIEclearBuffer();
+    return size;
+}
+
+static void endpointWrite(uint8_t endpoint, uint8_t *buffer, uint32_t size)
+{
+    /* Write to an IN endpoint */
+    uint32_t temp, data;
+    uint8_t offset;
+
+    LPC_USB->USBCtrl = LOG_ENDPOINT(endpoint) | WR_EN;
+
+    LPC_USB->USBTxPLen = size;
+    offset = 0;
+    data = 0;
+
+    if (size>0)
+    {
+        do {
+            /* Fetch next data byte into a word-sized temporary variable */
+            temp = *buffer++;
+
+            /* Add to current data word */
+            temp = temp << offset;
+            data = data | temp;
+
+            /* move on to the next byte */
+            offset = (offset + 8) % 32;
+            size--;
+
+            if ((offset==0) || (size==0))
+            {
+                /* Write the word to the endpoint */
+                LPC_USB->USBTxData = data;
+                data = 0;
+            }
+        } while (size>0);
+    }
+    else
+    {
+        LPC_USB->USBTxData = 0;
+    }
+
+    /* Clear WR_EN to cover zero length packet case */
+    LPC_USB->USBCtrl=0;
+
+    SIEselectEndpoint(endpoint);
+    SIEvalidateBuffer();
+}
+
+/*
+ *  USBBusInterface API
+ */
+
+bool USBHAL::USBBusInterface_init(void)
+{
+    /* Disable IRQ */
+    NVIC_DisableIRQ(USB_IRQn);
+
+    /* Enable power to USB device controller */
+    LPC_SC->PCONP |= PCUSB;
+
+    /* Enable USB clocks */
+    LPC_USB->USBClkCtrl |= DEV_CLK_EN | AHB_CLK_EN;
+    while (LPC_USB->USBClkSt != (DEV_CLK_ON | AHB_CLK_ON));
+
+    /* Configure pins P0.29 and P0.30 to be USB D+ and USB D- */
+    LPC_PINCON->PINSEL1 &= 0xc3ffffff;
+    LPC_PINCON->PINSEL1 |= 0x14000000;
+
+    /* Disconnect USB device */
+    SIEdisconnect();
+
+    /* Configure pin P2.9 to be Connect */
+    LPC_PINCON->PINSEL4 &= 0xfffcffff;
+    LPC_PINCON->PINSEL4 |= 0x00040000;
+    
+    /* Connect must be low for at least 2.5uS */
+    wait(0.3);
+
+    /* Set the maximum packet size for the control endpoints */
+    realiseEndpoint(EP0IN, MAX_PACKET_SIZE_EP0);
+    realiseEndpoint(EP0OUT, MAX_PACKET_SIZE_EP0);
+
+    /* Attach IRQ */
+    instance = this;
+    NVIC_SetVector(USB_IRQn, (uint32_t)&_usbisr);
+    NVIC_EnableIRQ(USB_IRQn); 
+
+    /* Enable interrupts for device events and EP0 */
+    LPC_USB->USBDevIntEn = EP_SLOW | DEV_STAT;
+    enableEndpointEvent(EP0IN);
+    enableEndpointEvent(EP0OUT);
+    return true;
+}
+
+void USBHAL::USBBusInterface_uninit(void)
+{
+    /* Ensure device disconnected */
+    SIEdisconnect();
+
+    /* Disable USB interrupts */
+    NVIC_DisableIRQ(USB_IRQn);
+}
+
+void USBHAL::USBBusInterface_connect(void)
+{
+    /* Connect USB device */
+    SIEconnect();
+}
+
+void USBHAL::USBBusInterface_disconnect(void)
+{
+    /* Disconnect USB device */
+    SIEdisconnect();
+}
+
+void USBHAL::USBBusInterface_configureDevice(void)
+{
+    SIEconfigureDevice();
+}
+
+void USBHAL::USBBusInterface_unconfigureDevice(void)
+{
+    SIEunconfigureDevice();
+}
+
+void USBHAL::USBBusInterface_setAddress(uint8_t address)
+{
+    SIEsetAddress(address);
+}
+
+void USBHAL::USBBusInterface_EP0setup(uint8_t *buffer)
+{
+    endpointRead(EP0OUT, buffer);
+}
+
+void USBHAL::USBBusInterface_EP0read(void)
+{
+    /* Not required */
+}
+
+uint32_t USBHAL::USBBusInterface_EP0getReadResult(uint8_t *buffer)
+{
+    return endpointRead(EP0OUT, buffer);
+}
+
+void USBHAL::USBBusInterface_EP0write(uint8_t *buffer, uint32_t size)
+{
+    endpointWrite(EP0IN, buffer, size);
+}
+
+void USBHAL::USBBusInterface_EP0getWriteResult(void)
+{
+    /* Not required */
+}
+
+void USBHAL::USBBusInterface_EP0stall(void)
+{
+    /* This will stall both control endpoints */
+    stallEndpoint(EP0OUT);
+}
+
+EP_STATUS USBHAL::USBBusInterface_endpointRead(uint8_t endpoint, uint32_t maximumSize)
+{
+    if (getEndpointStallState(endpoint))
+    {
+        return EP_STALLED;
+    }
+
+    return EP_PENDING;
+}
+
+EP_STATUS USBHAL::USBBusInterface_endpointReadResult(uint8_t endpoint, uint8_t * buffer, uint32_t *bytesRead)
+{
+    if(!(epComplete & EP(endpoint)))
+        return EP_PENDING;
+    *bytesRead = endpointRead(endpoint, buffer);
+    epComplete &= ~EP(endpoint);
+    return EP_COMPLETED;
+}
+
+EP_STATUS USBHAL::USBBusInterface_endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size)
+{
+    if (getEndpointStallState(endpoint))
+    {
+        return EP_STALLED;
+    }
+
+    epComplete &= EP(endpoint);
+
+    endpointWrite(endpoint, data, size);
+    return EP_PENDING;
+}
+
+EP_STATUS USBHAL::USBBusInterface_endpointWriteResult(uint8_t endpoint)
+{
+    if (epComplete & EP(endpoint))
+    {
+        epComplete &= ~EP(endpoint);
+        return EP_COMPLETED;
+    }
+
+    return EP_PENDING;
+}
+
+bool USBHAL::USBBusInterface_realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t flags)
+{
+    realiseEndpoint(endpoint, maxPacket);
+    enableEndpointEvent(endpoint);
+    return true;
+}
+
+void USBHAL::USBBusInterface_stallEndpoint(uint8_t endpoint)
+{
+    stallEndpoint(endpoint);
+}
+
+void USBHAL::USBBusInterface_unstallEndpoint(uint8_t endpoint)
+{
+    unstallEndpoint(endpoint);
+}
+
+bool USBHAL::USBBusInterface_getEndpointStallState(uint8_t endpoint)
+{
+    return getEndpointStallState(endpoint);
+}
+
+void USBHAL::USBBusInterface_remoteWakeup(void)
+{
+    /* Remote wakeup */
+    uint8_t status;
+
+    /* Enable USB clocks */
+    LPC_USB->USBClkCtrl |= DEV_CLK_EN | AHB_CLK_EN;
+    while (LPC_USB->USBClkSt != (DEV_CLK_ON | AHB_CLK_ON));
+
+    status = SIEgetDeviceStatus();
+    SIEsetDeviceStatus(status & ~SIE_DS_SUS);
+}
+
+/*
+ *  USB interrupt handler
+ */
+
+void USBHAL::_usbisr(void)
+{
+    instance->usbisr();
+} 
+ 
+void USBHAL::usbisr(void)
+{ 
+    uint8_t devStat;
+    
+    if (LPC_USB->USBDevIntSt & FRAME)
+    {
+        /* Start of frame event */
+        USBDevice_SOF(SIEgetFrameNumber());
+        /* Clear interrupt status flag */
+        LPC_USB->USBDevIntClr = FRAME;
+    }
+
+    if (LPC_USB->USBDevIntSt & DEV_STAT)
+    {
+        /* Device Status interrupt */
+        /* Must clear the interrupt status flag before reading the device status from the SIE */
+        LPC_USB->USBDevIntClr = DEV_STAT;
+            
+        /* Read device status from SIE */
+        devStat = SIEgetDeviceStatus();
+        
+        if (devStat & SIE_DS_RST)
+        {
+            /* Bus reset */
+            USBDevice_busReset();
+        }
+    }
+
+    if (LPC_USB->USBDevIntSt & EP_SLOW)
+    {
+        /* (Slow) Endpoint Interrupt */
+        
+        /* Process each endpoint interrupt */
+        if (LPC_USB->USBEpIntSt & EP(EP0OUT))
+        {
+            if (selectEndpointClearInterrupt(EP0OUT) & SIE_SE_STP)
+            {
+                /* this is a setup packet */
+                USBDevice_EP0setup();
+            }
+            else
+            {
+                USBDevice_EP0out();
+            }
+        }
+
+        if (LPC_USB->USBEpIntSt & EP(EP0IN))
+        {
+            selectEndpointClearInterrupt(EP0IN);
+            USBDevice_EP0in();
+        }
+
+/* TODO: This should cover all endpoints, not just EP1,2,3:*/
+        if (LPC_USB->USBEpIntSt & EP(EP1IN))
+        {
+            selectEndpointClearInterrupt(EP1IN);
+            epComplete |= EP(EP1IN);
+        }
+
+        if (LPC_USB->USBEpIntSt & EP(EP1OUT))
+        {
+            selectEndpointClearInterrupt(EP1OUT);
+            epComplete |= EP(EP1OUT);
+        }
+
+        if (LPC_USB->USBEpIntSt & EP(EP2IN))
+        {
+            selectEndpointClearInterrupt(EP2IN);
+            epComplete |= EP(EP2IN);
+        }
+
+        if (LPC_USB->USBEpIntSt & EP(EP2OUT))
+        {
+            selectEndpointClearInterrupt(EP2OUT);
+            epComplete |= EP(EP2OUT);
+        }
+
+        if (LPC_USB->USBEpIntSt & EP(EP3IN))
+        {
+            selectEndpointClearInterrupt(EP3IN);
+            epComplete |= EP(EP3IN);
+        }
+
+        if (LPC_USB->USBEpIntSt & EP(EP3OUT))
+        {
+            selectEndpointClearInterrupt(EP3OUT);
+            epComplete |= EP(EP3OUT);
+        }
+
+        /* Clear interrupt status flag */
+        /* EP_SLOW and EP_FAST interrupt bits should be cleared after the corresponding endpoint interrupts are cleared. */
+        LPC_USB->USBDevIntClr = EP_SLOW;
+    }
+}
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBDevice/.svn/text-base/USBDescriptor.h.svn-base Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,59 @@ +/* USBDescriptor.h */ +/* Definitions and macros for constructing USB descriptors */ +/* Copyright (c) 2011 ARM Limited. All rights reserved. */ + +/* Standard descriptor types */ +#define DEVICE_DESCRIPTOR (1) +#define CONFIGURATION_DESCRIPTOR (2) +#define STRING_DESCRIPTOR (3) +#define INTERFACE_DESCRIPTOR (4) +#define ENDPOINT_DESCRIPTOR (5) + +/* Standard descriptor lengths */ +#define DEVICE_DESCRIPTOR_LENGTH (0x12) +#define CONFIGURATION_DESCRIPTOR_LENGTH (0x09) +#define INTERFACE_DESCRIPTOR_LENGTH (0x09) +#define ENDPOINT_DESCRIPTOR_LENGTH (0x07) + + +/*string offset*/ +#define STRING_OFFSET_LANGID (0) +#define STRING_OFFSET_IMANUFACTURER (1) +#define STRING_OFFSET_IPRODUCT (2) +#define STRING_OFFSET_ISERIAL (3) +#define STRING_OFFSET_ICONFIGURATION (4) +#define STRING_OFFSET_IINTERFACE (5) + +/* USB Specification Release Number */ +#define USB_VERSION_2_0 (0x0200) + +/* Least/Most significant byte of short integer */ +#define LSB(n) ((n)&0xff) +#define MSB(n) (((n)&0xff00)>>8) + +/* Convert physical endpoint number to descriptor endpoint number */ +#define PHY_TO_DESC(endpoint) (((endpoint)>>1) | (((endpoint) & 1) ? 0x80:0)) + +/* bmAttributes in configuration descriptor */ +/* C_RESERVED must always be set */ +#define C_RESERVED (1U<<7) +#define C_SELF_POWERED (1U<<6) +#define C_REMOTE_WAKEUP (1U<<5) + +/* bMaxPower in configuration descriptor */ +#define C_POWER(mA) ((mA)/2) + +/* bmAttributes in endpoint descriptor */ +#define E_CONTROL (0x00) +#define E_ISOCHRONOUS (0x01) +#define E_BULK (0x02) +#define E_INTERRUPT (0x03) + +/* For isochronous endpoints only: */ +#define E_NO_SYNCHRONIZATION (0x00) +#define E_ASYNCHRONOUS (0x04) +#define E_ADAPTIVE (0x08) +#define E_SYNCHRONOUS (0x0C) +#define E_DATA (0x00) +#define E_FEEDBACK (0x10) +#define E_IMPLICIT_FEEDBACK (0x20)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBDevice/.svn/text-base/USBDevice.cpp.svn-base	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,899 @@
+/* USBDevice.c */
+/* Generic USB device */
+/* Copyright (c) 2011 ARM Limited. All rights reserved. */
+
+/* Reference: */
+/* Universal Serial Bus Specification Revision 2.0, Chapter 9 "USB Device Framework" */
+
+#include "stdint.h"
+
+#include "USBEndpoints.h"
+#include "USBDevice.h"
+#include "USBDescriptor.h"
+#include "USBHID_Types.h"
+
+
+/* Device status */
+#define DEVICE_STATUS_SELF_POWERED  (1U<<0)
+#define DEVICE_STATUS_REMOTE_WAKEUP (1U<<1)
+
+/* Endpoint status */
+#define ENDPOINT_STATUS_HALT        (1U<<0)
+
+/* Standard feature selectors */
+#define DEVICE_REMOTE_WAKEUP        (1)
+#define ENDPOINT_HALT               (0)
+
+/* Macro to convert wIndex endpoint number to physical endpoint number */
+#define WINDEX_TO_PHYSICAL(endpoint) (((endpoint & 0x0f) << 1) + \
+    ((endpoint & 0x80) ? 1 : 0))
+    
+
+CONTROL_TRANSFER transfer;
+USB_DEVICE device;
+
+bool USBDevice::requestGetDescriptor(void)
+{
+    bool success = false;
+
+    switch (DESCRIPTOR_TYPE(transfer.setup.wValue))
+    {
+        case DEVICE_DESCRIPTOR:
+            if (DeviceDesc() != NULL)
+            {
+                if ((DeviceDesc()[0] == DEVICE_DESCRIPTOR_LENGTH) \
+                    && (DeviceDesc()[1] == DEVICE_DESCRIPTOR))
+                {
+                    transfer.remaining = DEVICE_DESCRIPTOR_LENGTH;
+                    transfer.ptr = DeviceDesc();
+                    transfer.direction = DEVICE_TO_HOST;
+                    success = true;
+                }
+            }
+            break;
+        case CONFIGURATION_DESCRIPTOR:
+            if (ConfigurationDesc() != NULL)
+            {
+                if ((ConfigurationDesc()[0] == CONFIGURATION_DESCRIPTOR_LENGTH) \
+                    && (ConfigurationDesc()[1] == CONFIGURATION_DESCRIPTOR))
+                {
+                    /* Get wTotalLength */
+                    transfer.remaining = ConfigurationDesc()[2] \
+                        | (ConfigurationDesc()[3] << 8);
+
+                    transfer.ptr = ConfigurationDesc();
+                    transfer.direction = DEVICE_TO_HOST;
+                    success = true;
+                }
+            }
+            break;
+        case STRING_DESCRIPTOR:
+            switch (DESCRIPTOR_INDEX(transfer.setup.wValue))
+            {
+                            case STRING_OFFSET_LANGID:
+                                transfer.remaining = StringLangidDesc()[0];
+                                transfer.ptr = StringLangidDesc();
+                                transfer.direction = DEVICE_TO_HOST;
+                                success = true;
+                                break;
+                            case STRING_OFFSET_IMANUFACTURER:
+                                transfer.remaining =  StringImanufacturerDesc()[0];
+                                transfer.ptr = StringImanufacturerDesc();
+                                transfer.direction = DEVICE_TO_HOST;
+                                success = true;
+                                break;       
+                            case STRING_OFFSET_IPRODUCT:
+                                transfer.remaining = StringIproductDesc()[0];
+                                transfer.ptr = StringIproductDesc();
+                                transfer.direction = DEVICE_TO_HOST;
+                                success = true;
+                                break;            
+                            case STRING_OFFSET_ISERIAL:
+                                transfer.remaining = StringIserialDesc()[0];
+                                transfer.ptr = StringIserialDesc();
+                                transfer.direction = DEVICE_TO_HOST;
+                                success = true;
+                                break;        
+                            case STRING_OFFSET_ICONFIGURATION:
+                                transfer.remaining = StringIConfigurationDesc()[0];
+                                transfer.ptr = StringIConfigurationDesc();
+                                transfer.direction = DEVICE_TO_HOST;
+                                success = true;
+                                break; 
+                            case STRING_OFFSET_IINTERFACE:
+                                transfer.remaining = StringIinterfaceDesc()[0];
+                                transfer.ptr = StringIinterfaceDesc();
+                                transfer.direction = DEVICE_TO_HOST;
+                                success = true;
+                                break; 
+            }
+            break;
+        case INTERFACE_DESCRIPTOR:
+        case ENDPOINT_DESCRIPTOR:
+            /* TODO: Support is optional, not implemented here */
+            break;
+        default:
+            break;
+    }
+
+    return success;
+}
+
+static void decodeSetupPacket(uint8_t *data, SETUP_PACKET *packet)
+{
+    /* Fill in the elements of a SETUP_PACKET structure from raw data */
+    packet->bmRequestType.dataTransferDirection = (data[0] & 0x80) >> 7;
+    packet->bmRequestType.Type = (data[0] & 0x60) >> 5;
+    packet->bmRequestType.Recipient = data[0] & 0x1f;
+    packet->bRequest = data[1];
+    packet->wValue = (data[2] | (uint16_t)data[3] << 8);
+    packet->wIndex = (data[4] | (uint16_t)data[5] << 8);
+    packet->wLength = (data[6] | (uint16_t)data[7] << 8);
+}
+
+
+bool USBDevice::controlOut(void)
+{
+    /* Control transfer data OUT stage */
+    uint8_t buffer[MAX_PACKET_SIZE_EP0];
+    uint32_t packetSize;
+
+    /* Check we should be transferring data OUT */
+    if (transfer.direction != HOST_TO_DEVICE)
+    {
+        return false;
+    }
+
+    /* Read from endpoint */
+    packetSize = USBBusInterface_EP0getReadResult(buffer);
+
+    /* Check if transfer size is valid */
+    if (packetSize > transfer.remaining)
+    {
+        /* Too big */
+        return false;
+    }
+
+    /* Update transfer */
+    transfer.ptr += packetSize;
+    transfer.remaining -= packetSize;
+
+    /* Check if transfer has completed */
+    if (transfer.remaining == 0)
+    {
+        /* Transfer completed */
+        if (transfer.notify)
+        {
+            /* Notify class layer. */
+            USBCallback_requestCompleted();
+            transfer.notify = false;
+        }
+        /* Status stage */
+        USBBusInterface_EP0write(NULL, 0);
+    }
+    else
+    {
+        USBBusInterface_EP0read();
+    }
+
+    return true;
+}
+
+bool USBDevice::controlIn(void)
+{
+    /* Control transfer data IN stage */
+    uint32_t packetSize;
+
+    /* Check if transfer has completed (status stage transactions */
+    /* also have transfer.remaining == 0) */
+    if (transfer.remaining == 0)
+    {
+        if (transfer.zlp)
+        {
+            /* Send zero length packet */
+            USBBusInterface_EP0write(NULL, 0);
+            transfer.zlp = false;
+        }
+
+        /* Transfer completed */
+        if (transfer.notify)
+        {
+            /* Notify class layer. */
+            USBCallback_requestCompleted();
+            transfer.notify = false;
+        }
+
+        USBBusInterface_EP0read();
+
+        /* Completed */
+        return true;
+    }
+
+    /* Check we should be transferring data IN */
+    if (transfer.direction != DEVICE_TO_HOST)
+    {
+        return false;
+    }
+
+    packetSize = transfer.remaining;
+
+    if (packetSize > MAX_PACKET_SIZE_EP0)
+    {
+        packetSize = MAX_PACKET_SIZE_EP0;
+    }
+
+    /* Write to endpoint */
+    USBBusInterface_EP0write(transfer.ptr, packetSize);
+
+    /* Update transfer */
+    transfer.ptr += packetSize;
+    transfer.remaining -= packetSize;
+
+    return true;
+}
+
+bool USBDevice::requestSetAddress(void)
+{
+    /* Set the device address */
+    USBBusInterface_setAddress(transfer.setup.wValue);
+
+    if (transfer.setup.wValue == 0)
+    {
+        device.state = DEFAULT;
+    }
+    else
+    {
+        device.state = ADDRESS;
+    }
+
+    return true;
+}
+
+bool USBDevice::requestSetConfiguration(void)
+{
+
+    device.configuration = transfer.setup.wValue;
+    /* Set the device configuration */
+    if (device.configuration == 0)
+    {
+        /* Not configured */
+        USBBusInterface_unconfigureDevice();
+        device.state = ADDRESS;
+    }
+    else
+    {
+        if (USBCallback_setConfiguration(device.configuration))
+        {
+            /* Valid configuration */
+            USBBusInterface_configureDevice();
+            device.state = CONFIGURED;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+static bool requestGetConfiguration(void)
+{
+    /* Send the device configuration */
+    transfer.ptr = &device.configuration;
+    transfer.remaining = sizeof(device.configuration);
+    transfer.direction = DEVICE_TO_HOST;
+    return true;
+}
+
+static bool requestGetInterface(void)
+{
+    static uint8_t alternateSetting;
+
+    /* Return the selected alternate setting for an interface */
+
+    if (device.state != CONFIGURED)
+    {
+        return false;
+    }
+
+    /* TODO: We currently do not support alternate settings */
+    /* so always return zero */
+    /* TODO: Should check that the interface number is valid */
+    alternateSetting = 0;
+
+    /* Send the alternate setting */
+    transfer.ptr = &alternateSetting;
+    transfer.remaining = sizeof(alternateSetting);
+    transfer.direction = DEVICE_TO_HOST;
+    return true;
+}
+
+static bool requestSetInterface(void)
+{
+    /* TODO: We currently do not support alternate settings, return false */
+    return false;
+}
+
+bool USBDevice::requestSetFeature()
+{
+    bool success = false;
+
+    if (device.state != CONFIGURED)
+    {
+        /* Endpoint or interface must be zero */
+        if (transfer.setup.wIndex != 0)
+        {
+            return false;
+        }
+    }
+
+    switch (transfer.setup.bmRequestType.Recipient)
+    {
+        case DEVICE_RECIPIENT:
+            /* TODO: Remote wakeup feature not supported */
+            break;
+        case ENDPOINT_RECIPIENT:
+            if (transfer.setup.wValue == ENDPOINT_HALT)
+            {
+                /* TODO: We should check that the endpoint number is valid */
+                USBBusInterface_stallEndpoint(
+                    WINDEX_TO_PHYSICAL(transfer.setup.wIndex));
+                success = true;
+            }
+            break;
+        default:
+            break;
+    }
+
+    return success;
+}
+
+bool USBDevice::requestClearFeature()
+{
+    bool success = false;
+
+    if (device.state != CONFIGURED)
+    {
+        /* Endpoint or interface must be zero */
+        if (transfer.setup.wIndex != 0)
+        {
+            return false;
+        }
+    }
+
+    switch (transfer.setup.bmRequestType.Recipient)
+    {
+        case DEVICE_RECIPIENT:
+            /* TODO: Remote wakeup feature not supported */
+            break;
+        case ENDPOINT_RECIPIENT:
+            /* TODO: We should check that the endpoint number is valid */
+            if (transfer.setup.wValue == ENDPOINT_HALT)
+            {
+                USBBusInterface_unstallEndpoint(
+                    WINDEX_TO_PHYSICAL(transfer.setup.wIndex));
+                success = true;
+            }
+            break;
+        default:
+            break;
+    }
+
+    return success;
+}
+
+bool USBDevice::requestGetStatus(void)
+{
+    static uint16_t status;
+    bool success = false;
+
+    if (device.state != CONFIGURED)
+    {
+        /* Endpoint or interface must be zero */
+        if (transfer.setup.wIndex != 0)
+        {
+            return false;
+        }
+    }
+
+    switch (transfer.setup.bmRequestType.Recipient)
+    {
+        case DEVICE_RECIPIENT:
+            /* TODO: Currently only supports self powered devices */
+            status = DEVICE_STATUS_SELF_POWERED;
+            success = true;
+            break;
+        case INTERFACE_RECIPIENT:
+            status = 0;
+            success = true;
+            break;
+        case ENDPOINT_RECIPIENT:
+            /* TODO: We should check that the endpoint number is valid */
+            if (USBBusInterface_getEndpointStallState(
+                WINDEX_TO_PHYSICAL(transfer.setup.wIndex)))
+            {
+                status = ENDPOINT_STATUS_HALT;
+            }
+            else
+            {
+                status = 0;
+            }
+            success = true;
+            break;
+        default:
+            break;
+    }
+
+    if (success)
+    {
+        /* Send the status */ 
+        transfer.ptr = (uint8_t *)&status; /* Assumes little endian */
+        transfer.remaining = sizeof(status);
+        transfer.direction = DEVICE_TO_HOST;
+    }
+    
+    return success;
+}
+
+bool USBDevice::requestSetup(void)
+{
+    bool success = false;
+
+    /* Process standard requests */
+    if ((transfer.setup.bmRequestType.Type == STANDARD_TYPE))
+    {
+        switch (transfer.setup.bRequest)
+        {
+             case GET_STATUS:
+                 success = requestGetStatus();
+                 break;
+             case CLEAR_FEATURE:
+                 success = requestClearFeature();
+                 break;
+             case SET_FEATURE:
+                 success = requestSetFeature();
+                 break;
+             case SET_ADDRESS:
+                success = requestSetAddress();
+                 break;
+             case GET_DESCRIPTOR:
+                 success = requestGetDescriptor();
+                 break;
+             case SET_DESCRIPTOR:
+                 /* TODO: Support is optional, not implemented here */
+                 success = false;
+                 break;
+             case GET_CONFIGURATION:
+                 success = requestGetConfiguration();
+                 break;
+             case SET_CONFIGURATION:
+                 success = requestSetConfiguration();
+                 break;
+             case GET_INTERFACE:
+                 success = requestGetInterface();
+                 break;
+             case SET_INTERFACE:
+                 success = requestSetInterface();
+                 break;
+             default:
+                 break;
+        }
+    }
+
+    return success;
+}
+
+bool USBDevice::controlSetup(void)
+{
+    bool success = false;
+
+    /* Control transfer setup stage */
+    uint8_t buffer[MAX_PACKET_SIZE_EP0];
+
+    USBBusInterface_EP0setup(buffer);
+
+    /* Initialise control transfer state */
+    decodeSetupPacket(buffer, &transfer.setup);
+    transfer.ptr = NULL;
+    transfer.remaining = 0;
+    transfer.direction = 0;
+    transfer.zlp = false;
+    transfer.notify = false;
+
+    /* Process request */
+
+    /* Class / vendor specific */
+    success = USBCallback_request();
+
+    if (!success)
+    {
+        /* Standard requests */
+        if (!requestSetup())
+        {
+            return false;
+        }
+    }
+
+    /* Check transfer size and direction */
+    if (transfer.setup.wLength>0)
+    {
+        if (transfer.setup.bmRequestType.dataTransferDirection \
+            == DEVICE_TO_HOST)
+        {
+            /* IN data stage is required */
+            if (transfer.direction != DEVICE_TO_HOST)
+            {
+                return false;
+            }
+
+            /* Transfer must be less than or equal to the size */
+            /* requested by the host */
+            if (transfer.remaining > transfer.setup.wLength)
+            {
+                transfer.remaining = transfer.setup.wLength;
+            }
+        }
+        else
+        {
+            
+            /* OUT data stage is required */
+            if (transfer.direction != HOST_TO_DEVICE)
+            {
+                return false;
+            }
+
+            /* Transfer must be equal to the size requested by the host */
+            if (transfer.remaining != transfer.setup.wLength)
+            {
+                return false;
+            }
+        }
+    }
+    else
+    {
+        /* No data stage; transfer size must be zero */
+        if (transfer.remaining != 0)
+        {
+            return false;
+        }
+    }
+
+    /* Data or status stage if applicable */
+    if (transfer.setup.wLength>0)
+    {
+        if (transfer.setup.bmRequestType.dataTransferDirection \
+            == DEVICE_TO_HOST)
+        {
+            /* Check if we'll need to send a zero length packet at */
+            /* the end of this transfer */
+            if (transfer.setup.wLength > transfer.remaining)
+            {
+                /* Device wishes to transfer less than host requested */
+                if ((transfer.remaining % MAX_PACKET_SIZE_EP0) == 0)
+                {
+                    /* Transfer is a multiple of EP0 max packet size */
+                    transfer.zlp = true;
+                }
+            }
+
+            /* IN stage */
+            controlIn();
+        }
+        else
+        {
+            /* OUT stage */
+            USBBusInterface_EP0read();
+        }
+    }
+    else
+    {
+        /* Status stage */
+        USBBusInterface_EP0write(NULL, 0);
+    }
+
+    return true;
+}
+
+void USBDevice::USBDevice_busReset(void)
+{
+    device.state = DEFAULT;
+    device.configuration = 0;
+    device.suspended = false;
+
+    /* Call class / vendor specific busReset function */
+    USBCallback_busReset();
+}
+
+void USBDevice::USBDevice_EP0setup(void)
+{
+    /* Endpoint 0 setup event */
+    if (!controlSetup())
+    {
+        /* Protocol stall */
+        USBBusInterface_EP0stall();
+    }
+
+    /* Return true if an OUT data stage is expected */
+}
+
+void USBDevice::USBDevice_EP0out(void)
+{
+    /* Endpoint 0 OUT data event */
+    if (!controlOut())
+    {
+        /* Protocol stall; this will stall both endpoints */
+        USBBusInterface_EP0stall();
+    }
+}
+
+void USBDevice::USBDevice_EP0in(void)
+{
+    /* Endpoint 0 IN data event */
+    if (!controlIn())
+    {
+        /* Protocol stall; this will stall both endpoints */
+        USBBusInterface_EP0stall();
+    }
+}
+
+bool USBDevice::USBDevice_isConfigured(void)
+{
+    /* Returns true if device is in the CONFIGURED state */
+    return (device.state == CONFIGURED);
+}
+
+bool USBDevice::USBDevice_init(void)
+{
+    /* Set initial device state */
+    device.state = POWERED;
+    device.configuration = 0;
+    device.suspended = false;
+
+    /* Initialise bus interface */
+    return USBBusInterface_init();
+}
+
+void USBDevice::USBDevice_uninit(void)
+{
+    /* Uninitialise bus interface */
+    USBBusInterface_uninit();
+}
+
+void USBDevice::USBDevice_connect(void)
+{
+    /* Connect device */
+    USBBusInterface_connect();
+}
+
+void USBDevice::USBDevice_disconnect(void)
+{
+    /* Disconnect device */
+    USBBusInterface_disconnect();
+}
+
+CONTROL_TRANSFER *USBDevice_getTransferPtr(void)
+{
+    return &transfer;
+}
+
+bool USBDevice::USBDevice_addEndpoint(uint8_t endpoint, uint32_t maxPacket)
+{
+    return USBBusInterface_realiseEndpoint(endpoint, maxPacket, 0);
+}
+
+bool USBDevice::USBDevice_addRateFeedbackEndpoint(uint8_t endpoint, uint32_t maxPacket)
+{
+    /* For interrupt endpoints only */
+    return USBBusInterface_realiseEndpoint(endpoint, maxPacket, RATE_FEEDBACK_MODE);
+}
+
+uint8_t * USBDevice::USBDevice_findDescriptor(uint8_t descriptorType)
+{
+    /* Find a descriptor within the list of descriptors */
+    /* following a configuration descriptor. */
+    uint16_t wTotalLength;
+    uint8_t *ptr;
+
+    if (ConfigurationDesc() == NULL)
+    {
+        return NULL;
+    }
+
+    /* Check this is a configuration descriptor */
+    if ((ConfigurationDesc()[0] != CONFIGURATION_DESCRIPTOR_LENGTH) \
+            || (ConfigurationDesc()[1] != CONFIGURATION_DESCRIPTOR))
+    {
+        return NULL;
+    }
+
+    wTotalLength = ConfigurationDesc()[2] | (ConfigurationDesc()[3] << 8);
+
+    /* Check there are some more descriptors to follow */
+    if (wTotalLength <= (CONFIGURATION_DESCRIPTOR_LENGTH+2))
+    /* +2 is for bLength and bDescriptorType of next descriptor */
+    {
+        return false;
+    }
+
+    /* Start at first descriptor after the configuration descriptor */
+    ptr = &(ConfigurationDesc()[CONFIGURATION_DESCRIPTOR_LENGTH]);
+
+    do {
+        if (ptr[1] /* bDescriptorType */ == descriptorType)
+        {
+            /* Found */
+            return ptr;
+        }
+
+        /* Skip to next descriptor */
+        ptr += ptr[0]; /* bLength */
+    } while (ptr < (ConfigurationDesc() + wTotalLength));
+
+    /* Reached end of the descriptors - not found */
+    return NULL;
+}
+
+void USBDevice::USBDevice_SOF(int frameNumber)
+{
+}
+
+void USBDevice::USBDevice_connectStateChanged(unsigned int connected)
+{
+}
+
+void USBDevice::USBDevice_suspendStateChanged(unsigned int suspended)
+{
+}
+
+
+USBDevice::USBDevice(uint16_t vendor_id, uint16_t product_id, uint16_t product_release){
+    VENDOR_ID = vendor_id; 
+    PRODUCT_ID = product_id; 
+    PRODUCT_RELEASE = product_release;
+};
+
+
+bool USBDevice::USBDevice_readStart(uint8_t endpoint, uint16_t maxSize)
+{
+
+    return USBBusInterface_endpointRead(endpoint, maxSize) == EP_PENDING;
+}
+
+bool USBDevice::USBDevice_write(uint8_t endpoint, uint8_t * buffer, uint16_t size, uint16_t maxSize)
+{
+    EP_STATUS result;
+
+    if (size > maxSize)
+    {
+        return false;
+    }
+
+    /* Block if not configured */
+    while (!USBDevice_isConfigured());
+    
+    /* Send report */
+    result = USBBusInterface_endpointWrite(endpoint, buffer, size);
+
+    if (result != EP_PENDING)
+    {
+        return false;
+    }
+
+    /* Wait for completion */
+    do {
+        result = USBBusInterface_endpointWriteResult(endpoint);
+    } while ((result == EP_PENDING) && USBDevice_isConfigured());
+
+    return (result == EP_COMPLETED);
+}
+
+
+
+bool USBDevice::USBDevice_read(uint8_t endpoint, uint8_t * buffer, uint16_t * size, uint16_t maxSize)
+{
+    EP_STATUS result;
+
+    /* Block if not configured */
+    while (!USBDevice_isConfigured());
+
+    /* Wait for completion */
+    do {
+        result = USBBusInterface_endpointReadResult(endpoint, buffer, (uint32_t *)size);
+    } while ((result == EP_PENDING) && USBDevice_isConfigured());
+
+    return (result == EP_COMPLETED);
+}
+
+
+bool USBDevice::USBDevice_readNB(uint8_t endpoint, uint8_t * buffer, uint16_t * size, uint16_t maxSize)
+{
+    EP_STATUS result;
+
+    /* Block if not configured */
+    while (!USBDevice_isConfigured());
+
+    result = USBBusInterface_endpointReadResult(endpoint, buffer, (uint32_t *)size);
+    
+    return (result == EP_COMPLETED);
+}
+
+
+
+uint8_t * USBDevice::DeviceDesc() {
+    static uint8_t deviceDescriptor[] = {
+        DEVICE_DESCRIPTOR_LENGTH,       /* bLength */
+        DEVICE_DESCRIPTOR,              /* bDescriptorType */
+        LSB(USB_VERSION_2_0),           /* bcdUSB (LSB) */
+        MSB(USB_VERSION_2_0),           /* bcdUSB (MSB) */
+        0x00,                           /* bDeviceClass */
+        0x00,                           /* bDeviceSubClass */
+        0x00,                           /* bDeviceprotocol */
+        MAX_PACKET_SIZE_EP0,            /* bMaxPacketSize0 */
+        LSB(VENDOR_ID),                 /* idVendor (LSB) */
+        MSB(VENDOR_ID),                 /* idVendor (MSB) */
+        LSB(PRODUCT_ID),                /* idProduct (LSB) */
+        MSB(PRODUCT_ID),                /* idProduct (MSB) */
+        LSB(PRODUCT_RELEASE),           /* bcdDevice (LSB) */
+        MSB(PRODUCT_RELEASE),           /* bcdDevice (MSB) */
+        STRING_OFFSET_IMANUFACTURER,    /* iManufacturer */
+        STRING_OFFSET_IPRODUCT,         /* iProduct */
+        STRING_OFFSET_ISERIAL,          /* iSerialNumber */
+        0x01                            /* bNumConfigurations */
+    };
+    return deviceDescriptor;
+}
+
+uint8_t * USBDevice::StringLangidDesc() {
+    static uint8_t stringLangidDescriptor[] = {
+        0x04,                                                   /*bLength*/
+        STRING_DESCRIPTOR,                                      /*bDescriptorType 0x03*/
+        0x09,0x00,                                              /*bString Lang ID - 0x009 - English*/
+    };
+    return stringLangidDescriptor;
+}
+
+uint8_t * USBDevice::StringImanufacturerDesc() {
+    static uint8_t stringImanufacturerDescriptor[] = {
+        0x12,                                                   /*bLength*/
+        STRING_DESCRIPTOR,                                      /*bDescriptorType 0x03*/
+        'm',0,'b',0,'e',0,'d',0,'.',0,'o',0,'r',0,'g',0,        /*bString iManufacturer - mbed.org*/
+    };
+    return stringImanufacturerDescriptor;
+}
+
+uint8_t * USBDevice::StringIserialDesc() {
+    static uint8_t stringIserialDescriptor[] = {
+        0x16,                                                           /*bLength*/
+        STRING_DESCRIPTOR,                                              /*bDescriptorType 0x03*/
+        '0',0,'1',0,'2',0,'3',0,'4',0,'5',0,'6',0,'7',0,'8',0,'9',0,    /*bString iSerial - 0123456789*/
+    };
+    return stringIserialDescriptor;
+}
+
+uint8_t * USBDevice::StringIConfigurationDesc() {
+    static uint8_t stringIconfigurationDescriptor[] = {
+        0x06,                                                           /*bLength*/
+        STRING_DESCRIPTOR,                                              /*bDescriptorType 0x03*/
+        '0',0,'1',0,                                                    /*bString iConfiguration - 01*/
+    };
+    return stringIconfigurationDescriptor;
+}
+
+uint8_t * USBDevice::StringIinterfaceDesc() {
+    static uint8_t stringIinterfaceDescriptor[] = {
+        0x08,                                                           /*bLength*/
+        STRING_DESCRIPTOR,                                              /*bDescriptorType 0x03*/
+        'U',0,'S',0,'B',0,                                              /*bString iInterface - HID*/
+    };
+    return stringIinterfaceDescriptor;
+}
+
+uint8_t * USBDevice::StringIproductDesc() {
+    static uint8_t stringIproductDescriptor[] = {
+        0x16,                                                   /*bLength*/
+        STRING_DESCRIPTOR,                                      /*bDescriptorType 0x03*/
+        'U',0,'S',0,'B',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0  /*bString iProduct - Rel Mouse*/
+    };
+    return stringIproductDescriptor;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBDevice/.svn/text-base/USBDevice.h.svn-base	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,248 @@
+/* USBDevice.h */
+/* Generic USB device */
+/* Copyright (c) 2011 ARM Limited. All rights reserved. */
+
+#ifndef _USB_DEVICE_
+#define _USB_DEVICE_
+
+#include "mbed.h"
+#include "USBDevice_Types.h"
+#include "USBBusInterface.h"
+
+CONTROL_TRANSFER *USBDevice_getTransferPtr(void);
+
+/* Endpoint events that must be implemented by device layer: */
+void USBDevice_EP0setup(void);
+void USBDevice_EP0out(void);
+void USBDevice_EP0in(void);
+
+/* Endpoint events that are optionally implemented by device layer: */
+void USBDevice_busReset(void);
+void USBDevice_SOF(uint16_t frameNumber);
+void USBDevice_connectStateChanged(unsigned int state);
+void USBDevice_suspendStateChanged(unsigned int state);
+
+uint8_t * USBDevice_findDescriptor(uint8_t descriptorType);
+
+class USBDevice: public USBHAL
+{
+public:
+    USBDevice(uint16_t vendor_id, uint16_t product_id, uint16_t product_release);
+
+    /**
+    * Device initialization
+    */
+    bool USBDevice_init(void);
+    
+    /**
+    * Device uninitialization
+    */
+    void USBDevice_uninit(void);
+    
+    /**
+    * Check if the device is configured
+    *
+    * @return true if configured, false otherwise
+    */
+    bool USBDevice_isConfigured(void);
+    
+    /**
+    * Connect a device
+    */
+    void USBDevice_connect(void);
+    
+    /**
+    * Disconnect a device
+    */
+    void USBDevice_disconnect(void);
+    
+    /**
+    * Add an endpoint
+    *
+    * @param endpoint endpoint which will be added
+    * @param maxPacket Maximum size of a packet which can be sent for this endpoint
+    * @return true if successful, false otherwise
+    */
+    bool USBDevice_addEndpoint(uint8_t endpoint, uint32_t maxPacket);
+
+    /**
+    * Start a reading on a certain endpoint.
+    * You can access the result of the reading by USBDevice_read
+    *
+    * @param endpoint endpoint which will be read
+    * @param maxSize the maximum length that can be read
+    * @return true if successful
+    */
+    bool USBDevice_readStart(uint8_t endpoint, uint16_t maxSize);
+    
+    /**
+    * Read a certain endpoint. Before calling this function, USBUSBDevice_readStart
+    * must be called.
+    *
+    * Warning: blocking
+    *
+    * @param endpoint endpoint which will be read
+    * @param buffer buffer will be filled with the data received
+    * @param size the number of bytes read will be stored in *size
+    * @param maxSize the maximum length that can be read
+    * @return true if successful
+    */
+    bool USBDevice_read(uint8_t endpoint, uint8_t * buffer, uint16_t * size, uint16_t maxSize);
+    
+    /**
+    * Read a certain endpoint.
+    *
+    * Warning: non blocking
+    *
+    * @param endpoint endpoint which will be read
+    * @param buffer buffer will be filled with the data received (if data are available) 
+    * @param size the number of bytes read will be stored in *size
+    * @param maxSize the maximum length that can be read
+    * @return true if successful
+    */
+    bool USBDevice_readNB(uint8_t endpoint, uint8_t * buffer, uint16_t * size, uint16_t maxSize);
+    
+    /**
+    * Write a certain endpoint.
+    *
+    * Warning: blocking
+    *
+    * @param endpoint endpoint to write
+    * @param buffer data contained in buffer will be write
+    * @param size the number of bytes to write
+    * @param maxSize the maximum length that can be written on this endpoint
+    */
+    bool USBDevice_write(uint8_t endpoint, uint8_t * buffer, uint16_t size, uint16_t maxSize);
+    
+    
+    /**
+    * Called by USBDevice layer on bus reset. Warning: Called in ISR context
+    *
+    * May be used to reset state
+    */
+    virtual void USBCallback_busReset(void) {};
+    
+    /**
+    * Called by USBDevice on Endpoint0 request. Warning: Called in ISR context
+    * This is used to handle extensions to standard requests
+    * and class specific requests
+    *
+    * @return true if class handles this request
+    */
+    virtual bool USBCallback_request() { return false; };   
+    
+    /**
+    * Called by USBDevice on Endpoint0 request completion
+    * if the 'notify' flag has been set to true. Warning: Called in ISR context
+    *
+    * In this case it is used to indicate that a HID report has
+    * been received from the host on endpoint 0
+    */
+    virtual void USBCallback_requestCompleted() {};
+    
+    /*
+    * Called by USBDevice layer. Set configuration of the device.
+    * For instance, you can add all endpoints that you need on this function.
+    *
+    * @param configuration Number of the configuration
+    */
+    virtual bool USBCallback_setConfiguration(uint8_t configuration) { return false; };
+
+    /*
+    * Get device descriptor. Warning: this method has to store the length of the report descriptor in reportLength.
+    *
+    * @return pointer to the device descriptor
+    */
+    virtual uint8_t * DeviceDesc();
+    
+    /*
+    * Get configuration descriptor
+    *
+    * @return pointer to the configuration descriptor
+    */
+    virtual uint8_t * ConfigurationDesc(){return NULL;};
+    
+    /*
+    * Get string lang id descriptor
+    *
+    * @return pointer to the string lang id descriptor
+    */
+    virtual uint8_t * StringLangidDesc();
+    
+    /*
+    * Get string manufacturer descriptor
+    *
+    * @return pointer to the string manufacturer descriptor
+    */
+    virtual uint8_t * StringImanufacturerDesc();
+    
+    /*
+    * Get string product descriptor
+    *
+    * @return pointer to the string product descriptor
+    */
+    virtual uint8_t * StringIproductDesc();
+    
+    /*
+    * Get string serial descriptor
+    *
+    * @return pointer to the string serial descriptor
+    */
+    virtual uint8_t * StringIserialDesc();
+    
+    /*
+    * Get string configuration descriptor
+    *
+    * @return pointer to the string configuration descriptor
+    */
+    virtual uint8_t * StringIConfigurationDesc();
+    
+    /*
+    * Get string interface descriptor
+    *
+    * @return pointer to the string interface descriptor
+    */
+    virtual uint8_t * StringIinterfaceDesc();
+    
+    /*
+    * Get the length of the report descriptor
+    *
+    * @return length of the report descriptor
+    */
+    virtual uint16_t ReportDescLength() { return 0; };
+    
+
+
+protected:
+    virtual void USBDevice_busReset(void);
+    virtual void USBDevice_EP0setup(void);
+    virtual void USBDevice_EP0out(void);
+    virtual void USBDevice_EP0in(void);
+    virtual void USBDevice_SOF(int frameNumber);
+    virtual void USBDevice_connectStateChanged(unsigned int connected);
+    virtual void USBDevice_suspendStateChanged(unsigned int suspended);
+    uint8_t * USBDevice_findDescriptor(uint8_t descriptorType);
+    
+    uint16_t VENDOR_ID;
+    uint16_t PRODUCT_ID;
+    uint16_t PRODUCT_RELEASE;
+
+private:
+    bool USBDevice_addRateFeedbackEndpoint(uint8_t endpoint, uint32_t maxPacket);
+    bool requestGetDescriptor(void);
+    bool controlOut(void);
+    bool controlIn(void);
+    bool requestSetAddress(void);
+    bool requestSetConfiguration(void);
+    bool requestSetFeature(void);
+    bool requestClearFeature(void);
+    bool requestGetStatus(void);
+    bool requestSetup(void);
+    bool controlSetup(void);
+};
+
+
+void setInstanceDevice(USBDevice * _inst);
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBDevice/.svn/text-base/USBDevice_Types.h.svn-base	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,69 @@
+/* USBDevice_Types.h */
+/* USB Device type definitions, conversions and constants */
+/* Copyright (c) 2011 ARM Limited. All rights reserved. */
+
+#ifndef USB_DEVICE_TYPES
+#define USB_DEVICE_TYPES 
+
+/* Standard requests */
+#define GET_STATUS        (0)
+#define CLEAR_FEATURE     (1)
+#define SET_FEATURE       (3)
+#define SET_ADDRESS       (5)
+#define GET_DESCRIPTOR    (6)
+#define SET_DESCRIPTOR    (7)
+#define GET_CONFIGURATION (8)
+#define SET_CONFIGURATION (9)
+#define GET_INTERFACE     (10)
+#define SET_INTERFACE     (11)
+
+/* bmRequestType.dataTransferDirection */
+#define HOST_TO_DEVICE (0)
+#define DEVICE_TO_HOST (1)
+
+/* bmRequestType.Type*/
+#define STANDARD_TYPE  (0)
+#define CLASS_TYPE     (1)
+#define VENDOR_TYPE    (2)
+#define RESERVED_TYPE  (3)
+
+/* bmRequestType.Recipient */
+#define DEVICE_RECIPIENT    (0)
+#define INTERFACE_RECIPIENT (1)
+#define ENDPOINT_RECIPIENT  (2)
+#define OTHER_RECIPIENT     (3)
+
+/* Descriptors */
+#define DESCRIPTOR_TYPE(wValue)  (wValue >> 8)
+#define DESCRIPTOR_INDEX(wValue) (wValue & 0xf)
+
+typedef struct {
+    struct {
+        uint8_t dataTransferDirection;
+        uint8_t Type;
+        uint8_t Recipient;
+    } bmRequestType;
+    uint8_t  bRequest;
+    uint16_t wValue;
+    uint16_t wIndex;
+    uint16_t wLength;
+} SETUP_PACKET;
+
+typedef struct {
+    SETUP_PACKET setup;
+    uint8_t *ptr;
+    uint32_t remaining;
+    uint8_t direction;
+    bool zlp;
+    bool notify;
+} CONTROL_TRANSFER;
+
+typedef enum {ATTACHED, POWERED, DEFAULT, ADDRESS, CONFIGURED} DEVICE_STATE;
+
+typedef struct {
+    volatile DEVICE_STATE state;
+    uint8_t configuration;
+    bool suspended;
+} USB_DEVICE;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBDevice/.svn/text-base/USBEndpoints.h.svn-base	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,34 @@
+/* USBEndpoints.h */
+/* USB endpoint configuration */
+/* Copyright (c) 2011 ARM Limited. All rights reserved. */
+
+#ifndef USB_ENDPOINTS
+#define USB_ENDPOINTS
+
+/* SETUP packet size */
+#define SETUP_PACKET_SIZE (8)
+
+/* Options flags for configuring endpoints */
+#define DEFAULT_OPTIONS     (0)
+#define SINGLE_BUFFERED     (1U << 0)
+#define ISOCHRONOUS         (1U << 1)
+#define RATE_FEEDBACK_MODE  (1U << 2) /* Interrupt endpoints only */
+
+/* Endpoint transfer status, for endpoints > 0 */
+typedef enum {
+    EP_COMPLETED,   /* Transfer completed */
+    EP_PENDING,     /* Transfer in progress */
+    EP_INVALID,     /* Invalid parameter */
+    EP_STALLED,     /* Endpoint stalled */
+} EP_STATUS;
+
+/* Include configuration for specific target */
+#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
+#include "USBEndpoints_LPC17_LPC23.h"
+#elif defined(TARGET_LPC11U24)
+#include "USBEndpoints_LPC11U.h"
+#else
+#error "Unknown target type"
+#endif
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBDevice/.svn/text-base/USBEndpoints_LPC11U.h.svn-base Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,51 @@ +/* USBEndpoints_LPC11U.h */ +/* Endpoint configuration for LPC11U */ +/* Copyright (c) 2011 ARM Limited. All rights reserved. */ + +#define NUMBER_OF_LOGICAL_ENDPOINTS (5) +#define NUMBER_OF_PHYSICAL_ENDPOINTS (NUMBER_OF_LOGICAL_ENDPOINTS * 2) + +/* Define physical endpoint numbers */ + +/* Endpoint No. Type(s) MaxPacket DoubleBuffer */ +/* ---------------- ------------ ---------- --- */ +#define EP0OUT (0) /* Control 64 No */ +#define EP0IN (1) /* Control 64 No */ +#define EP1OUT (2) /* Int/Bulk/Iso 64/64/1023 Yes */ +#define EP1IN (3) /* Int/Bulk/Iso 64/64/1023 Yes */ +#define EP2OUT (4) /* Int/Bulk/Iso 64/64/1023 Yes */ +#define EP2IN (5) /* Int/Bulk/Iso 64/64/1023 Yes */ +#define EP3OUT (6) /* Int/Bulk/Iso 64/64/1023 Yes */ +#define EP3IN (7) /* Int/Bulk/Iso 64/64/1023 Yes */ +#define EP4OUT (8) /* Int/Bulk/Iso 64/64/1023 Yes */ +#define EP4IN (9) /* Int/Bulk/Iso 64/64/1023 Yes */ + +/* Maximum Packet sizes */ + +#define MAX_PACKET_SIZE_EP0 (64) +#define MAX_PACKET_SIZE_EP1 (64) /* Int/Bulk */ +#define MAX_PACKET_SIZE_EP2 (64) /* Int/Bulk */ +#define MAX_PACKET_SIZE_EP3 (64) /* Int/Bulk */ +#define MAX_PACKET_SIZE_EP4 (64) /* Int/Bulk */ + +#define MAX_PACKET_SIZE_EP1_ISO (1023) /* Isochronous */ +#define MAX_PACKET_SIZE_EP2_ISO (1023) /* Isochronous */ +#define MAX_PACKET_SIZE_EP3_ISO (1023) /* Isochronous */ +#define MAX_PACKET_SIZE_EP4_ISO (1023) /* Isochronous */ + +/* Generic endpoints - intended to be portable accross devices */ +/* and be suitable for simple USB devices. */ + +/* Bulk endpoint */ +#define EPBULK_OUT (EP2OUT) +#define EPBULK_IN (EP2IN) +/* Interrupt endpoint */ +#define EPINT_OUT (EP1OUT) +#define EPINT_IN (EP1IN) +/* Isochronous endpoint */ +#define EPISO_OUT (EP3OUT) +#define EPISO_IN (EP3IN) + +#define MAX_PACKET_SIZE_EPBULK (MAX_PACKET_SIZE_EP2) +#define MAX_PACKET_SIZE_EPINT (MAX_PACKET_SIZE_EP1) +#define MAX_PACKET_SIZE_EPISO (MAX_PACKET_SIZE_EP3_ISO)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBDevice/.svn/text-base/USBEndpoints_LPC17_LPC23.h.svn-base Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,79 @@ +/* USBEndpoints_LPC17_LPC23.h */ +/* Endpoint configuration for LPC1768 and LPC2368 */ +/* Copyright (c) 2011 ARM Limited. All rights reserved. */ + +#define NUMBER_OF_LOGICAL_ENDPOINTS (16) +#define NUMBER_OF_PHYSICAL_ENDPOINTS (NUMBER_OF_LOGICAL_ENDPOINTS * 2) + +/* Define physical endpoint numbers */ + +/* Endpoint No. Type(s) MaxPacket DoubleBuffer */ +/* ---------------- ------------ ---------- --- */ +#define EP0OUT (0) /* Control 64 No */ +#define EP0IN (1) /* Control 64 No */ +#define EP1OUT (2) /* Interrupt 64 No */ +#define EP1IN (3) /* Interrupt 64 No */ +#define EP2OUT (4) /* Bulk 64 Yes */ +#define EP2IN (5) /* Bulk 64 Yes */ +#define EP3OUT (6) /* Isochronous 1023 Yes */ +#define EP3IN (7) /* Isochronous 1023 Yes */ +#define EP4OUT (8) /* Interrupt 64 No */ +#define EP4IN (9) /* Interrupt 64 No */ +#define EP5OUT (10) /* Bulk 64 Yes */ +#define EP5IN (11) /* Bulk 64 Yes */ +#define EP6OUT (12) /* Isochronous 1023 Yes */ +#define EP6IN (13) /* Isochronous 1023 Yes */ +#define EP7OUT (14) /* Interrupt 64 No */ +#define EP7IN (15) /* Interrupt 64 No */ +#define EP8OUT (16) /* Bulk 64 Yes */ +#define EP8IN (17) /* Bulk 64 Yes */ +#define EP9OUT (18) /* Isochronous 1023 Yes */ +#define EP9IN (19) /* Isochronous 1023 Yes */ +#define EP10OUT (20) /* Interrupt 64 No */ +#define EP10IN (21) /* Interrupt 64 No */ +#define EP11OUT (22) /* Bulk 64 Yes */ +#define EP11IN (23) /* Bulk 64 Yes */ +#define EP12OUT (24) /* Isochronous 1023 Yes */ +#define EP12IN (25) /* Isochronous 1023 Yes */ +#define EP13OUT (26) /* Interrupt 64 No */ +#define EP13IN (27) /* Interrupt 64 No */ +#define EP14OUT (28) /* Bulk 64 Yes */ +#define EP14IN (29) /* Bulk 64 Yes */ +#define EP15OUT (30) /* Bulk 64 Yes */ +#define EP15IN (31) /* Bulk 64 Yes */ + +/* Maximum Packet sizes */ + +#define MAX_PACKET_SIZE_EP0 (64) +#define MAX_PACKET_SIZE_EP1 (64) +#define MAX_PACKET_SIZE_EP2 (64) +#define MAX_PACKET_SIZE_EP3 (1023) +#define MAX_PACKET_SIZE_EP4 (64) +#define MAX_PACKET_SIZE_EP5 (64) +#define MAX_PACKET_SIZE_EP6 (1023) +#define MAX_PACKET_SIZE_EP7 (64) +#define MAX_PACKET_SIZE_EP8 (64) +#define MAX_PACKET_SIZE_EP9 (1023) +#define MAX_PACKET_SIZE_EP10 (64) +#define MAX_PACKET_SIZE_EP11 (64) +#define MAX_PACKET_SIZE_EP12 (1023) +#define MAX_PACKET_SIZE_EP13 (64) +#define MAX_PACKET_SIZE_EP14 (64) +#define MAX_PACKET_SIZE_EP15 (64) + +/* Generic endpoints - intended to be portable accross devices */ +/* and be suitable for simple USB devices. */ + +/* Bulk endpoints */ +#define EPBULK_OUT (EP2OUT) +#define EPBULK_IN (EP2IN) +/* Interrupt endpoints */ +#define EPINT_OUT (EP1OUT) +#define EPINT_IN (EP1IN) +/* Isochronous endpoints */ +#define EPISO_OUT (EP3OUT) +#define EPISO_IN (EP3IN) + +#define MAX_PACKET_SIZE_EPBULK (MAX_PACKET_SIZE_EP2) +#define MAX_PACKET_SIZE_EPINT (MAX_PACKET_SIZE_EP1) +#define MAX_PACKET_SIZE_EPISO (MAX_PACKET_SIZE_EP3)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBDevice/.svn/text-base/USBEvents.h.svn-base Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,19 @@ +/* USBEvents.h */ +/* USB device and endpoint event handlers */ +/* Copyright (c) 2011 ARM Limited. All rights reserved. */ + +#ifndef _USB_EBVENTS_ +#define _USB_EBVENTS_ + +/* Endpoint events that must be implemented by device layer: */ +void USBDevice_EP0setup(void); +void USBDevice_EP0out(void); +void USBDevice_EP0in(void); + +/* Endpoint events that are optionally implemented by device layer: */ +void USBDevice_busReset(void); +void USBDevice_SOF(int frameNumber); +void USBDevice_connectStateChanged(unsigned int state); +void USBDevice_suspendStateChanged(unsigned int state); + +#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBDevice/USBBusInterface.h	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,89 @@
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef USBBUSINTERFACE_H
+#define USBBUSINTERFACE_H
+
+#include "mbed.h"
+#include "USBEndpoints.h"
+
+class USBHAL {
+public:
+    /* Configuration */
+    USBHAL();
+    ~USBHAL();
+    void connect(void);
+    void disconnect(void);
+    void configureDevice(void);
+    void unconfigureDevice(void);
+    void setAddress(uint8_t address);
+    void remoteWakeup(void);
+
+    /* Endpoint 0 */
+    void EP0setup(uint8_t *buffer);
+    void EP0read(void);
+    uint32_t EP0getReadResult(uint8_t *buffer);
+    void EP0write(uint8_t *buffer, uint32_t size);
+    void EP0getWriteResult(void);
+    void EP0stall(void);
+
+    /* Other endpoints */
+    EP_STATUS endpointRead(uint8_t endpoint, uint32_t maximumSize);
+    EP_STATUS endpointReadResult(uint8_t endpoint, uint8_t *data, uint32_t *bytesRead);
+    EP_STATUS endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size);
+    EP_STATUS endpointWriteResult(uint8_t endpoint);
+    void stallEndpoint(uint8_t endpoint);
+    void unstallEndpoint(uint8_t endpoint);
+    bool realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t options);
+    bool getEndpointStallState(unsigned char endpoint);
+
+protected:
+    virtual void busReset(void) {};
+    virtual void EP0setupCallback(void) {};
+    virtual void EP0out(void) {};
+    virtual void EP0in(void) {};
+    virtual void connectStateChanged(unsigned int connected) {};
+    virtual void suspendStateChanged(unsigned int suspended) {};
+    virtual void SOF(int frameNumber) {};
+    virtual bool EP1_OUT_callback() {
+        return false;
+    };
+    virtual bool EP1_IN_callback() {
+        return false;
+    };
+    virtual bool EP2_OUT_callback() {
+        return false;
+    };
+    virtual bool EP2_IN_callback() {
+        return false;
+    };
+    virtual bool EP3_OUT_callback() {
+        return false;
+    };
+    virtual bool EP3_IN_callback() {
+        return false;
+    };
+
+private:
+    void usbisr(void);
+    static void _usbisr(void);
+    static USBHAL * instance;
+};
+#endif
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBDevice/USBBusInterface_LPC11U.cpp	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,710 @@
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifdef TARGET_LPC11U24
+
+#include "USBBusInterface.h"
+
+USBHAL * USBHAL::instance;
+
+
+// Valid physical endpoint numbers are 0 to (NUMBER_OF_PHYSICAL_ENDPOINTS-1)
+#define LAST_PHYSICAL_ENDPOINT (NUMBER_OF_PHYSICAL_ENDPOINTS-1)
+
+// Convert physical endpoint number to register bit
+#define EP(endpoint) (1UL<<endpoint)
+
+// Convert physical to logical
+#define PHY_TO_LOG(endpoint)    ((endpoint)>>1)
+
+// Get endpoint direction
+#define IN_EP(endpoint)     ((endpoint) & 1U ? true : false)
+#define OUT_EP(endpoint)    ((endpoint) & 1U ? false : true)
+
+// USB RAM
+#define USB_RAM_START (0x20004000)
+#define USB_RAM_SIZE  (0x00000800)
+
+// SYSAHBCLKCTRL
+#define CLK_USB     (1UL<<14)
+#define CLK_USBRAM  (1UL<<27)
+
+// USB Information register
+#define FRAME_NR(a)     ((a) & 0x7ff)   // Frame number
+
+// USB Device Command/Status register
+#define DEV_ADDR_MASK   (0x7f)          // Device address
+#define DEV_ADDR(a)     ((a) & DEV_ADDR_MASK)
+#define DEV_EN          (1UL<<7)        // Device enable
+#define SETUP           (1UL<<8)        // SETUP token received
+#define PLL_ON          (1UL<<9)        // PLL enabled in suspend
+#define DCON            (1UL<<16)       // Device status - connect
+#define DSUS            (1UL<<17)       // Device status - suspend
+#define DCON_C          (1UL<<24)       // Connect change
+#define DSUS_C          (1UL<<25)       // Suspend change
+#define DRES_C          (1UL<<26)       // Reset change
+#define VBUSDEBOUNCED   (1UL<<28)       // Vbus detected
+
+// Endpoint Command/Status list
+#define CMDSTS_A                 (1UL<<31)          // Active
+#define CMDSTS_D                 (1UL<<30)          // Disable
+#define CMDSTS_S                 (1UL<<29)          // Stall
+#define CMDSTS_TR                (1UL<<28)          // Toggle Reset
+#define CMDSTS_RF                (1UL<<27)          // Rate Feedback mode
+#define CMDSTS_TV                (1UL<<27)          // Toggle Value
+#define CMDSTS_T                 (1UL<<26)          // Endpoint Type
+#define CMDSTS_NBYTES(n)         (((n)&0x3ff)<<16)  // Number of bytes
+#define CMDSTS_ADDRESS_OFFSET(a) (((a)>>6)&0xffff)  // Buffer start address
+
+#define BYTES_REMAINING(s)       (((s)>>16)&0x3ff)  // Bytes remaining after transfer
+
+// USB Non-endpoint interrupt sources
+#define FRAME_INT   (1UL<<30)
+#define DEV_INT     (1UL<<31)
+
+static int epComplete = 0;
+
+// One entry for a double-buffered logical endpoint in the endpoint
+// command/status list. Endpoint 0 is single buffered, out[1] is used
+// for the SETUP packet and in[1] is not used
+typedef __packed struct {
+    uint32_t out[2];
+    uint32_t in[2];
+} EP_COMMAND_STATUS;
+
+typedef __packed struct {
+    uint8_t out[MAX_PACKET_SIZE_EP0];
+    uint8_t in[MAX_PACKET_SIZE_EP0];
+    uint8_t setup[SETUP_PACKET_SIZE];
+} CONTROL_TRANSFER;
+
+typedef __packed struct {
+    uint32_t    maxPacket;
+    uint32_t    buffer[2];
+    uint32_t    options;
+} EP_STATE;
+
+static volatile EP_STATE endpointState[NUMBER_OF_PHYSICAL_ENDPOINTS];
+
+// Pointer to the endpoint command/status list
+static EP_COMMAND_STATUS *ep = NULL;
+
+// Pointer to endpoint 0 data (IN/OUT and SETUP)
+static CONTROL_TRANSFER *ct = NULL;
+
+// Shadow DEVCMDSTAT register to avoid accidentally clearing flags or
+// initiating a remote wakeup event.
+static volatile uint32_t devCmdStat;
+
+// Pointers used to allocate USB RAM
+static uint32_t usbRamPtr = USB_RAM_START;
+static uint32_t epRamPtr = 0; // Buffers for endpoints > 0 start here
+
+#define ROUND_UP_TO_MULTIPLE(x, m) ((((x)+((m)-1))/(m))*(m))
+
+void USBMemCopy(uint8_t *dst, uint8_t *src, uint32_t size);
+void USBMemCopy(uint8_t *dst, uint8_t *src, uint32_t size) {
+    if (size > 0) {
+        do {
+            *dst++ = *src++;
+        } while (--size > 0);
+    }
+}
+
+
+USBHAL::USBHAL(void) {
+    NVIC_DisableIRQ(USB_IRQn);
+
+    // nUSB_CONNECT output
+    LPC_IOCON->PIO0_6 = 0x00000001;
+
+    // Enable clocks (USB registers, USB RAM)
+    LPC_SYSCON->SYSAHBCLKCTRL |= CLK_USB | CLK_USBRAM;
+
+    // Ensure device disconnected (DCON not set)
+    LPC_USB->DEVCMDSTAT = 0;
+
+    // to ensure that the USB host sees the device as
+    // disconnected if the target CPU is reset.
+    wait(0.3);
+
+    // Reserve space in USB RAM for endpoint command/status list
+    // Must be 256 byte aligned
+    usbRamPtr = ROUND_UP_TO_MULTIPLE(usbRamPtr, 256);
+    ep = (EP_COMMAND_STATUS *)usbRamPtr;
+    usbRamPtr += (sizeof(EP_COMMAND_STATUS) * NUMBER_OF_LOGICAL_ENDPOINTS);
+    LPC_USB->EPLISTSTART = (uint32_t)(ep) & 0xffffff00;
+
+    // Reserve space in USB RAM for Endpoint 0
+    // Must be 64 byte aligned
+    usbRamPtr = ROUND_UP_TO_MULTIPLE(usbRamPtr, 64);
+    ct = (CONTROL_TRANSFER *)usbRamPtr;
+    usbRamPtr += sizeof(CONTROL_TRANSFER);
+    LPC_USB->DATABUFSTART =(uint32_t)(ct) & 0xffc00000;
+
+    // Setup command/status list for EP0
+    ep[0].out[0] = 0;
+    ep[0].in[0] =  0;
+    ep[0].out[1] = CMDSTS_ADDRESS_OFFSET((uint32_t)ct->setup);
+
+    // Route all interrupts to IRQ, some can be routed to
+    // USB_FIQ if you wish.
+    LPC_USB->INTROUTING = 0;
+
+    // Set device address 0, enable USB device, no remote wakeup
+    devCmdStat = DEV_ADDR(0) | DEV_EN | DSUS;
+    LPC_USB->DEVCMDSTAT = devCmdStat;
+
+    // Enable interrupts for device events and EP0
+    LPC_USB->INTEN = DEV_INT | EP(EP0IN) | EP(EP0OUT);
+    instance = this;
+    
+    //attach IRQ handler and enable interrupts
+    NVIC_SetVector(USB_IRQn, (uint32_t)&_usbisr);
+    NVIC_EnableIRQ(USB_IRQn);
+}
+
+USBHAL::~USBHAL(void) {
+    // Ensure device disconnected (DCON not set)
+    LPC_USB->DEVCMDSTAT = 0;
+
+    // Disable USB interrupts
+    NVIC_DisableIRQ(USB_IRQn);
+}
+
+void USBHAL::connect(void) {
+    devCmdStat |= DCON;
+    LPC_USB->DEVCMDSTAT = devCmdStat;
+}
+
+void USBHAL::disconnect(void) {
+    devCmdStat &= ~DCON;
+    LPC_USB->DEVCMDSTAT = devCmdStat;
+}
+
+void USBHAL::configureDevice(void) {
+}
+
+void USBHAL::unconfigureDevice(void) {
+}
+
+void USBHAL::EP0setup(uint8_t *buffer) {
+    // Copy setup packet data
+    USBMemCopy(buffer, ct->setup, SETUP_PACKET_SIZE);
+}
+
+void USBHAL::EP0read(void) {
+    // Start an endpoint 0 read
+
+    // The USB ISR will call USBDevice_EP0out() when a packet has been read,
+    // the USBDevice layer then calls USBBusInterface_EP0getReadResult() to
+    // read the data.
+
+    ep[0].out[0] = CMDSTS_A |CMDSTS_NBYTES(MAX_PACKET_SIZE_EP0) \
+                   | CMDSTS_ADDRESS_OFFSET((uint32_t)ct->out);
+}
+
+uint32_t USBHAL::EP0getReadResult(uint8_t *buffer) {
+    // Complete an endpoint 0 read
+    uint32_t bytesRead;
+
+    // Find how many bytes were read
+    bytesRead = MAX_PACKET_SIZE_EP0 - BYTES_REMAINING(ep[0].out[0]);
+
+    // Copy data
+    USBMemCopy(buffer, ct->out, bytesRead);
+    return bytesRead;
+}
+
+void USBHAL::EP0write(uint8_t *buffer, uint32_t size) {
+    // Start and endpoint 0 write
+
+    // The USB ISR will call USBDevice_EP0in() when the data has
+    // been written, the USBDevice layer then calls
+    // USBBusInterface_EP0getWriteResult() to complete the transaction.
+
+    // Copy data
+    USBMemCopy(ct->in, buffer, size);
+
+    // Start transfer
+    ep[0].in[0] = CMDSTS_A | CMDSTS_NBYTES(size) \
+                  | CMDSTS_ADDRESS_OFFSET((uint32_t)ct->in);
+}
+
+
+EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize) {
+    uint8_t bf = 0;
+    
+    //check which buffer must be filled
+    if (LPC_USB->EPBUFCFG & EP(endpoint)) {
+        // Double buffered
+        if (LPC_USB->EPINUSE & EP(endpoint)) {
+            bf = 1;
+        } else {
+            bf = 0;
+        }
+    }
+    
+    //Active the endpoint for reading
+    ep[PHY_TO_LOG(endpoint)].out[bf] = CMDSTS_A | CMDSTS_NBYTES(maximumSize) \
+                                      | CMDSTS_ADDRESS_OFFSET((uint32_t)ct->out);
+    return EP_PENDING;
+}
+
+EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t *data, uint32_t *bytesRead) {
+
+    uint8_t bf = 0;
+    
+    if (!(epComplete & EP(endpoint)))
+        return EP_PENDING;
+    else {
+        epComplete &= ~EP(endpoint);
+
+        //check which buffer has been filled
+        if (LPC_USB->EPBUFCFG & EP(endpoint)) {
+            // Double buffered (here we read the previous buffer which was used)
+            if (LPC_USB->EPINUSE & EP(endpoint)) {
+                bf = 0;
+            } else {
+                bf = 1;
+            }
+        }
+
+        // Find how many bytes were read
+        *bytesRead = (uint32_t) (endpointState[endpoint].maxPacket - BYTES_REMAINING(ep[PHY_TO_LOG(endpoint)].out[bf]));
+
+        // Copy data
+        USBMemCopy(data, ct->out, *bytesRead);
+        return EP_COMPLETED;
+    }
+}
+
+void USBHAL::EP0getWriteResult(void) {
+    // Complete an endpoint 0 write
+
+    // Nothing required for this target
+    return;
+}
+
+void USBHAL::EP0stall(void) {
+    ep[0].in[0] = CMDSTS_S;
+    ep[0].out[0] = CMDSTS_S;
+}
+
+void USBHAL::setAddress(uint8_t address) {
+    devCmdStat &= ~DEV_ADDR_MASK;
+    devCmdStat |= DEV_ADDR(address);
+    LPC_USB->DEVCMDSTAT = devCmdStat;
+}
+
+EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size) {
+    uint32_t flags = 0;
+    uint32_t bf;
+
+    // Validate parameters
+    if (data == NULL) {
+        return EP_INVALID;
+    }
+
+    if (endpoint > LAST_PHYSICAL_ENDPOINT) {
+        return EP_INVALID;
+    }
+
+    if ((endpoint==EP0IN) || (endpoint==EP0OUT)) {
+        return EP_INVALID;
+    }
+
+    if (size > endpointState[endpoint].maxPacket) {
+        return EP_INVALID;
+    }
+
+    if (LPC_USB->EPBUFCFG & EP(endpoint)) {
+        // Double buffered
+        if (LPC_USB->EPINUSE & EP(endpoint)) {
+            bf = 1;
+        } else {
+            bf = 0;
+        }
+    } else {
+        // Single buffered
+        bf = 0;
+    }
+
+    // Check if already active
+    if (ep[PHY_TO_LOG(endpoint)].in[bf] & CMDSTS_A) {
+        return EP_INVALID;
+    }
+
+    // Check if stalled
+    if (ep[PHY_TO_LOG(endpoint)].in[bf] & CMDSTS_S) {
+        return EP_STALLED;
+    }
+
+    // Copy data to USB RAM
+    USBMemCopy((uint8_t *)endpointState[endpoint].buffer[bf], data, size);
+
+    // Add options
+    if (endpointState[endpoint].options & RATE_FEEDBACK_MODE) {
+        flags |= CMDSTS_RF;
+    }
+
+    if (endpointState[endpoint].options & ISOCHRONOUS) {
+        flags |= CMDSTS_T;
+    }
+
+    // Add transfer
+    ep[PHY_TO_LOG(endpoint)].in[bf] = CMDSTS_ADDRESS_OFFSET( \
+                                      endpointState[endpoint].buffer[bf]) \
+                                      | CMDSTS_NBYTES(size) | CMDSTS_A | flags;
+
+    return EP_PENDING;
+}
+
+EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint) {
+    uint32_t bf;
+    // Validate parameters
+
+    if (endpoint > LAST_PHYSICAL_ENDPOINT) {
+        return EP_INVALID;
+    }
+
+    if (OUT_EP(endpoint)) {
+        return EP_INVALID;
+    }
+
+    if (LPC_USB->EPBUFCFG & EP(endpoint)) {
+        // Double buffered     // TODO: FIX THIS
+        if (LPC_USB->EPINUSE & EP(endpoint)) {
+            bf = 1;
+        } else {
+            bf = 0;
+        }
+    } else {
+        // Single buffered
+        bf = 0;
+    }
+
+    // Check if endpoint still active
+    if (ep[PHY_TO_LOG(endpoint)].in[bf] & CMDSTS_A) {
+        return EP_PENDING;
+    }
+
+    // Check if stalled
+    if (ep[PHY_TO_LOG(endpoint)].in[bf] & CMDSTS_S) {
+        return EP_STALLED;
+    }
+
+    return EP_COMPLETED;
+}
+
+void USBHAL::stallEndpoint(uint8_t endpoint) {
+
+    // TODO: should this clear active bit?
+
+    if (IN_EP(endpoint)) {
+        ep[PHY_TO_LOG(endpoint)].in[0] |= CMDSTS_S;
+        ep[PHY_TO_LOG(endpoint)].in[1] |= CMDSTS_S;
+    } else {
+        ep[PHY_TO_LOG(endpoint)].out[0] |= CMDSTS_S;
+        ep[PHY_TO_LOG(endpoint)].out[1] |= CMDSTS_S;
+    }
+}
+
+void USBHAL::unstallEndpoint(uint8_t endpoint) {
+    if (LPC_USB->EPBUFCFG & EP(endpoint)) {
+        // Double buffered
+        if (IN_EP(endpoint)) {
+            ep[PHY_TO_LOG(endpoint)].in[0] = 0; // S = 0
+            ep[PHY_TO_LOG(endpoint)].in[1] = 0; // S = 0
+
+            if (LPC_USB->EPINUSE & EP(endpoint)) {
+                ep[PHY_TO_LOG(endpoint)].in[1] = CMDSTS_TR; // S =0, TR=1, TV = 0
+            } else {
+                ep[PHY_TO_LOG(endpoint)].in[0] = CMDSTS_TR; // S =0, TR=1, TV = 0
+            }
+        } else {
+            ep[PHY_TO_LOG(endpoint)].out[0] = 0; // S = 0
+            ep[PHY_TO_LOG(endpoint)].out[1] = 0; // S = 0
+
+            if (LPC_USB->EPINUSE & EP(endpoint)) {
+                ep[PHY_TO_LOG(endpoint)].out[1] = CMDSTS_TR; // S =0, TR=1, TV = 0
+            } else {
+                ep[PHY_TO_LOG(endpoint)].out[0] = CMDSTS_TR; // S =0, TR=1, TV = 0
+            }
+        }
+    } else {
+        // Single buffered
+        if (IN_EP(endpoint)) {
+            ep[PHY_TO_LOG(endpoint)].in[0] = CMDSTS_TR; // S=0, TR=1, TV = 0
+        } else {
+            ep[PHY_TO_LOG(endpoint)].out[0] = CMDSTS_TR; // S=0, TR=1, TV = 0
+        }
+    }
+}
+
+bool USBHAL::getEndpointStallState(unsigned char endpoint) {
+    if (IN_EP(endpoint)) {
+        if (LPC_USB->EPINUSE & EP(endpoint)) {
+            if (ep[PHY_TO_LOG(endpoint)].in[1] & CMDSTS_S) {
+                return true;
+            }
+        } else {
+            if (ep[PHY_TO_LOG(endpoint)].in[0] & CMDSTS_S) {
+                return true;
+            }
+        }
+    } else {
+        if (LPC_USB->EPINUSE & EP(endpoint)) {
+            if (ep[PHY_TO_LOG(endpoint)].out[1] & CMDSTS_S) {
+                return true;
+            }
+        } else {
+            if (ep[PHY_TO_LOG(endpoint)].out[0] & CMDSTS_S) {
+                return true;
+            }
+        }
+    }
+
+    return false;
+}
+
+bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t options) {
+    uint32_t tmpEpRamPtr;
+
+    if (endpoint > LAST_PHYSICAL_ENDPOINT) {
+        return false;
+    }
+
+    // Not applicable to the control endpoints
+    if ((endpoint==EP0IN) || (endpoint==EP0OUT)) {
+        return false;
+    }
+
+    // Allocate buffers in USB RAM
+    tmpEpRamPtr = epRamPtr;
+
+    // Must be 64 byte aligned
+    tmpEpRamPtr = ROUND_UP_TO_MULTIPLE(tmpEpRamPtr, 64);
+
+    if ((tmpEpRamPtr + maxPacket) > (USB_RAM_START + USB_RAM_SIZE)) {
+        // Out of memory
+        return false;
+    }
+
+    // Allocate first buffer
+    endpointState[endpoint].buffer[0] = tmpEpRamPtr;
+    tmpEpRamPtr += maxPacket;
+
+    if (!(options & SINGLE_BUFFERED)) {
+        // Must be 64 byte aligned
+        tmpEpRamPtr = ROUND_UP_TO_MULTIPLE(tmpEpRamPtr, 64);
+
+        if ((tmpEpRamPtr + maxPacket) > (USB_RAM_START + USB_RAM_SIZE)) {
+            // Out of memory
+            return false;
+        }
+
+        // Allocate second buffer
+        endpointState[endpoint].buffer[1] = tmpEpRamPtr;
+        tmpEpRamPtr += maxPacket;
+    }
+
+    // Commit to this USB RAM allocation
+    epRamPtr = tmpEpRamPtr;
+
+    // Remaining endpoint state values
+    endpointState[endpoint].maxPacket = maxPacket;
+    endpointState[endpoint].options = options;
+
+    // Enable double buffering if required
+    if (options & SINGLE_BUFFERED) {
+        LPC_USB->EPBUFCFG &= ~EP(endpoint);
+    } else {
+        // Double buffered
+        LPC_USB->EPBUFCFG |= EP(endpoint);
+    }
+
+    // Enable interrupt
+    LPC_USB->INTEN |= EP(endpoint);
+
+    // Enable endpoint
+    unstallEndpoint(endpoint);
+    return true;
+}
+
+void USBHAL::remoteWakeup(void) {
+    // Clearing DSUS bit initiates a remote wakeup if the
+    // device is currently enabled and suspended - otherwise
+    // it has no effect.
+    LPC_USB->DEVCMDSTAT = devCmdStat & ~DSUS;
+}
+
+
+static void disableEndpoints(void) {
+    uint32_t logEp;
+
+    // Ref. Table 158 "When a bus reset is received, software
+    // must set the disable bit of all endpoints to 1".
+
+    for (logEp = 1; logEp < NUMBER_OF_LOGICAL_ENDPOINTS; logEp++) {
+        ep[logEp].out[0] = CMDSTS_D;
+        ep[logEp].out[1] = CMDSTS_D;
+        ep[logEp].in[0] =  CMDSTS_D;
+        ep[logEp].in[1] =  CMDSTS_D;
+    }
+
+    // Start of USB RAM for endpoints > 0
+    epRamPtr = usbRamPtr;
+}
+
+
+
+void USBHAL::_usbisr(void) {
+    instance->usbisr();
+}
+
+
+void USBHAL::usbisr(void) {
+    // Start of frame
+    if (LPC_USB->INTSTAT & FRAME_INT) {
+        // Clear SOF interrupt
+        LPC_USB->INTSTAT = FRAME_INT;
+
+        // SOF event, read frame number
+        SOF(FRAME_NR(LPC_USB->INFO));
+    }
+
+    // Device state
+    if (LPC_USB->INTSTAT & DEV_INT) {
+        LPC_USB->INTSTAT = DEV_INT;
+
+        if (LPC_USB->DEVCMDSTAT & DCON_C) {
+            // Connect status changed
+            LPC_USB->DEVCMDSTAT = devCmdStat | DCON_C;
+
+            connectStateChanged((LPC_USB->DEVCMDSTAT & DCON) != 0);
+        }
+
+        if (LPC_USB->DEVCMDSTAT & DSUS_C) {
+            // Suspend status changed
+            LPC_USB->DEVCMDSTAT = devCmdStat | DSUS_C;
+
+            suspendStateChanged((LPC_USB->DEVCMDSTAT & DSUS) != 0);
+        }
+
+        if (LPC_USB->DEVCMDSTAT & DRES_C) {
+            // Bus reset
+            LPC_USB->DEVCMDSTAT = devCmdStat | DRES_C;
+
+            // Disable endpoints > 0
+            disableEndpoints();
+
+            // Bus reset event
+            busReset();
+        }
+    }
+
+    // Endpoint 0
+    if (LPC_USB->INTSTAT & EP(EP0OUT)) {
+        // Clear EP0OUT/SETUP interrupt
+        LPC_USB->INTSTAT = EP(EP0OUT);
+
+        // Check if SETUP
+        if (LPC_USB->DEVCMDSTAT & SETUP) {
+            // Clear Active and Stall bits for EP0
+            // Documentation does not make it clear if we must use the
+            // EPSKIP register to achieve this, Fig. 16 and NXP reference
+            // code suggests we can just clear the Active bits - check with
+            // NXP to be sure.
+            ep[0].in[0] = 0;
+            ep[0].out[0] = 0;
+
+            // Clear EP0IN interrupt
+            LPC_USB->INTSTAT = EP(EP0IN);
+
+            // Clear SETUP (and INTONNAK_CI/O) in device status register
+            LPC_USB->DEVCMDSTAT = devCmdStat | SETUP;
+
+            // EP0 SETUP event (SETUP data received)
+            EP0setupCallback();
+        } else {
+            // EP0OUT ACK event (OUT data received)
+            EP0out();
+        }
+    }
+
+    if (LPC_USB->INTSTAT & EP(EP0IN)) {
+        // Clear EP0IN interrupt
+        LPC_USB->INTSTAT = EP(EP0IN);
+
+        // EP0IN ACK event (IN data sent)
+        EP0in();
+    }
+
+    if (LPC_USB->INTSTAT & EP(EP1IN)) {
+        // Clear EP1IN interrupt
+        LPC_USB->INTSTAT = EP(EP1IN);
+        epComplete |= EP(EP1IN);
+        if(EP1_IN_callback())
+            epComplete &= ~EP(EP1IN);
+    }
+
+    if (LPC_USB->INTSTAT & EP(EP1OUT)) {
+        // Clear EP1OUT interrupt
+        LPC_USB->INTSTAT = EP(EP1OUT);
+        epComplete |= EP(EP1OUT);
+        if(EP1_OUT_callback())
+            epComplete &= ~EP(EP1OUT);
+    }
+
+    if (LPC_USB->INTSTAT & EP(EP2IN)) {
+        // Clear EPBULK_IN interrupt
+        LPC_USB->INTSTAT = EP(EP2IN);
+        epComplete |= EP(EP2IN);
+        if(EP2_IN_callback())
+            epComplete &= ~EP(EP2IN);
+    }
+
+    if (LPC_USB->INTSTAT & EP(EP2OUT)) {
+        // Clear EPBULK_OUT interrupt
+        LPC_USB->INTSTAT = EP(EP2OUT);
+        epComplete |= EP(EP2OUT);
+        //Call callback function. If true, clear epComplete
+        if(EP2_OUT_callback())
+            epComplete &= ~EP(EP2OUT);
+    }
+    
+    if (LPC_USB->INTSTAT & EP(EP3IN)) {
+        // Clear EP3_IN interrupt
+        LPC_USB->INTSTAT = EP(EP3IN);
+        epComplete |= EP(EP3IN);
+        if(EP3_IN_callback())
+            epComplete &= ~EP(EP3IN);
+    }
+
+    if (LPC_USB->INTSTAT & EP(EP3OUT)) {
+        // Clear EP3_OUT interrupt
+        LPC_USB->INTSTAT = EP(EP3OUT);
+        epComplete |= EP(EP3OUT);
+        //Call callback function. If true, clear epComplete
+        if(EP3_OUT_callback())
+            epComplete &= ~EP(EP3OUT);
+    }
+}
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBDevice/USBBusInterface_LPC17_LPC23.cpp	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,696 @@
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifdef TARGET_LPC1768
+
+#include "USBBusInterface.h"
+
+
+// Get endpoint direction
+#define IN_EP(endpoint)     ((endpoint) & 1U ? true : false)
+#define OUT_EP(endpoint)    ((endpoint) & 1U ? false : true)
+
+// Convert physical endpoint number to register bit
+#define EP(endpoint) (1UL<<endpoint)
+
+// Power Control for Peripherals register
+#define PCUSB      (1UL<<31)
+
+// USB Clock Control register
+#define DEV_CLK_EN (1UL<<1)
+#define AHB_CLK_EN (1UL<<4)
+
+// USB Clock Status register
+#define DEV_CLK_ON (1UL<<1)
+#define AHB_CLK_ON (1UL<<4)
+
+// USB Device Interupt registers
+#define FRAME      (1UL<<0)
+#define EP_FAST    (1UL<<1)
+#define EP_SLOW    (1UL<<2)
+#define DEV_STAT   (1UL<<3)
+#define CCEMPTY    (1UL<<4)
+#define CDFULL     (1UL<<5)
+#define RxENDPKT   (1UL<<6)
+#define TxENDPKT   (1UL<<7)
+#define EP_RLZED   (1UL<<8)
+#define ERR_INT    (1UL<<9)
+
+// USB Control register
+#define RD_EN (1<<0)
+#define WR_EN (1<<1)
+#define LOG_ENDPOINT(endpoint) ((endpoint>>1)<<2)
+
+// USB Receive Packet Length register
+#define DV      (1UL<<10)
+#define PKT_RDY (1UL<<11)
+#define PKT_LNGTH_MASK (0x3ff)
+
+// Serial Interface Engine (SIE)
+#define SIE_WRITE   (0x01)
+#define SIE_READ    (0x02)
+#define SIE_COMMAND (0x05)
+#define SIE_CMD_CODE(phase, data) ((phase<<8)|(data<<16))
+
+// SIE Command codes
+#define SIE_CMD_SET_ADDRESS        (0xD0)
+#define SIE_CMD_CONFIGURE_DEVICE   (0xD8)
+#define SIE_CMD_SET_MODE           (0xF3)
+#define SIE_CMD_READ_FRAME_NUMBER  (0xF5)
+#define SIE_CMD_READ_TEST_REGISTER (0xFD)
+#define SIE_CMD_SET_DEVICE_STATUS  (0xFE)
+#define SIE_CMD_GET_DEVICE_STATUS  (0xFE)
+#define SIE_CMD_GET_ERROR_CODE     (0xFF)
+#define SIE_CMD_READ_ERROR_STATUS  (0xFB)
+
+#define SIE_CMD_SELECT_ENDPOINT(endpoint)                 (0x00+endpoint)
+#define SIE_CMD_SELECT_ENDPOINT_CLEAR_INTERRUPT(endpoint) (0x40+endpoint)
+#define SIE_CMD_SET_ENDPOINT_STATUS(endpoint)             (0x40+endpoint)
+
+#define SIE_CMD_CLEAR_BUFFER    (0xF2)
+#define SIE_CMD_VALIDATE_BUFFER (0xFA)
+
+// SIE Device Status register
+#define SIE_DS_CON    (1<<0)
+#define SIE_DS_CON_CH (1<<1)
+#define SIE_DS_SUS    (1<<2)
+#define SIE_DS_SUS_CH (1<<3)
+#define SIE_DS_RST    (1<<4)
+
+// SIE Device Set Address register
+#define SIE_DSA_DEV_EN  (1<<7)
+
+// SIE Configue Device register
+#define SIE_CONF_DEVICE (1<<0)
+
+// Select Endpoint register
+#define SIE_SE_FE       (1<<0)
+#define SIE_SE_ST       (1<<1)
+#define SIE_SE_STP      (1<<2)
+#define SIE_SE_PO       (1<<3)
+#define SIE_SE_EPN      (1<<4)
+#define SIE_SE_B_1_FULL (1<<5)
+#define SIE_SE_B_2_FULL (1<<6)
+
+// Set Endpoint Status command
+#define SIE_SES_ST      (1<<0)
+#define SIE_SES_DA      (1<<5)
+#define SIE_SES_RF_MO   (1<<6)
+#define SIE_SES_CND_ST  (1<<7)
+
+
+USBHAL * USBHAL::instance;
+
+volatile int epComplete;
+uint32_t endpointStallState;
+
+static void SIECommand(uint32_t command)
+{
+    // The command phase of a SIE transaction
+    LPC_USB->USBDevIntClr = CCEMPTY;
+    LPC_USB->USBCmdCode = SIE_CMD_CODE(SIE_COMMAND, command);
+    while (!(LPC_USB->USBDevIntSt & CCEMPTY));
+}
+
+static void SIEWriteData(uint8_t data)
+{
+    // The data write phase of a SIE transaction
+    LPC_USB->USBDevIntClr = CCEMPTY;
+    LPC_USB->USBCmdCode = SIE_CMD_CODE(SIE_WRITE, data);
+    while (!(LPC_USB->USBDevIntSt & CCEMPTY));
+}
+
+static uint8_t SIEReadData(uint32_t command)
+{
+    // The data read phase of a SIE transaction
+    LPC_USB->USBDevIntClr = CDFULL;
+    LPC_USB->USBCmdCode = SIE_CMD_CODE(SIE_READ, command);
+    while (!(LPC_USB->USBDevIntSt & CDFULL));
+    return (uint8_t)LPC_USB->USBCmdData;
+}
+
+static void SIEsetDeviceStatus(uint8_t status)
+{
+    // Write SIE device status register
+    SIECommand(SIE_CMD_SET_DEVICE_STATUS);
+    SIEWriteData(status);
+}
+
+static uint8_t SIEgetDeviceStatus(void)
+{
+    // Read SIE device status register
+    SIECommand(SIE_CMD_GET_DEVICE_STATUS);
+    return SIEReadData(SIE_CMD_GET_DEVICE_STATUS);
+}
+
+void SIEsetAddress(uint8_t address)
+{
+    // Write SIE device address register
+    SIECommand(SIE_CMD_SET_ADDRESS);
+    SIEWriteData((address & 0x7f) | SIE_DSA_DEV_EN);
+}
+
+static uint8_t SIEselectEndpoint(uint8_t endpoint)
+{
+    // SIE select endpoint command
+    SIECommand(SIE_CMD_SELECT_ENDPOINT(endpoint));
+    return SIEReadData(SIE_CMD_SELECT_ENDPOINT(endpoint));
+}
+
+static uint8_t SIEclearBuffer(void)
+{
+    // SIE clear buffer command
+    SIECommand(SIE_CMD_CLEAR_BUFFER);
+    return SIEReadData(SIE_CMD_CLEAR_BUFFER);
+}
+
+static void SIEvalidateBuffer(void)
+{
+    // SIE validate buffer command
+    SIECommand(SIE_CMD_VALIDATE_BUFFER);
+}
+
+static void SIEsetEndpointStatus(uint8_t endpoint, uint8_t status)
+{
+    // SIE set endpoint status command
+    SIECommand(SIE_CMD_SET_ENDPOINT_STATUS(endpoint));
+    SIEWriteData(status);
+}
+
+static uint16_t SIEgetFrameNumber(void) __attribute__ ((unused));
+static uint16_t SIEgetFrameNumber(void)
+{
+    // Read current frame number
+    uint16_t lowByte;
+    uint16_t highByte;
+
+    SIECommand(SIE_CMD_READ_FRAME_NUMBER);
+    lowByte = SIEReadData(SIE_CMD_READ_FRAME_NUMBER);
+    highByte = SIEReadData(SIE_CMD_READ_FRAME_NUMBER);
+
+    return (highByte << 8) | lowByte;
+}
+
+static void SIEconfigureDevice(void)
+{
+    // SIE Configure device command
+    SIECommand(SIE_CMD_CONFIGURE_DEVICE);
+    SIEWriteData(SIE_CONF_DEVICE);
+}
+
+static void SIEunconfigureDevice(void)
+{
+    // SIE Configure device command
+    SIECommand(SIE_CMD_CONFIGURE_DEVICE);
+    SIEWriteData(0);
+}
+
+static void SIEconnect(void)
+{
+    // Connect USB device
+    uint8_t status;
+
+    status = SIEgetDeviceStatus();
+    SIEsetDeviceStatus(status | SIE_DS_CON);
+}
+
+
+static void SIEdisconnect(void)
+{
+    // Disconnect USB device
+    uint8_t status;
+
+    status = SIEgetDeviceStatus();
+    SIEsetDeviceStatus(status & ~SIE_DS_CON);
+}
+
+
+static uint8_t selectEndpointClearInterrupt(uint8_t endpoint)
+{
+    // Implemented using using EP_INT_CLR.
+    LPC_USB->USBEpIntClr = EP(endpoint);
+    while (!(LPC_USB->USBDevIntSt & CDFULL));
+    return (uint8_t)LPC_USB->USBCmdData;
+}
+
+
+
+
+
+static void enableEndpointEvent(uint8_t endpoint)
+{
+    // Enable an endpoint interrupt
+    LPC_USB->USBEpIntEn |= EP(endpoint);
+}
+
+static void disableEndpointEvent(uint8_t endpoint) __attribute__ ((unused));
+static void disableEndpointEvent(uint8_t endpoint)
+{
+    // Disable an endpoint interrupt
+    LPC_USB->USBEpIntEn &= ~EP(endpoint);
+}
+
+static volatile uint32_t __attribute__((used)) dummyRead;
+
+
+static uint32_t endpointReadcore(uint8_t endpoint, uint8_t *buffer)
+{
+    // Read from an OUT endpoint
+    uint32_t size;
+    uint32_t i;
+    uint32_t data = 0;
+    uint8_t offset;
+
+    LPC_USB->USBCtrl = LOG_ENDPOINT(endpoint) | RD_EN;
+    while (!(LPC_USB->USBRxPLen & PKT_RDY));
+
+    size = LPC_USB->USBRxPLen & PKT_LNGTH_MASK;
+
+    offset = 0;
+
+    if (size > 0)
+    {
+        for (i=0; i<size; i++)
+        {
+            if (offset==0)
+            {
+                // Fetch up to four bytes of data as a word
+                data = LPC_USB->USBRxData;
+            }
+
+            // extract a byte
+            *buffer = (data>>offset) & 0xff;
+            buffer++;
+
+            // move on to the next byte
+            offset = (offset + 8) % 32;
+        }
+    }
+    else
+    {
+        dummyRead = LPC_USB->USBRxData;
+    }
+
+    SIEselectEndpoint(endpoint);
+    SIEclearBuffer();
+    return size;
+}
+
+static void endpointWritecore(uint8_t endpoint, uint8_t *buffer, uint32_t size)
+{
+    // Write to an IN endpoint
+    uint32_t temp, data;
+    uint8_t offset;
+
+    LPC_USB->USBCtrl = LOG_ENDPOINT(endpoint) | WR_EN;
+
+    LPC_USB->USBTxPLen = size;
+    offset = 0;
+    data = 0;
+
+    if (size>0)
+    {
+        do {
+            // Fetch next data byte into a word-sized temporary variable
+            temp = *buffer++;
+
+            // Add to current data word
+            temp = temp << offset;
+            data = data | temp;
+
+            // move on to the next byte
+            offset = (offset + 8) % 32;
+            size--;
+
+            if ((offset==0) || (size==0))
+            {
+                // Write the word to the endpoint
+                LPC_USB->USBTxData = data;
+                data = 0;
+            }
+        } while (size>0);
+    }
+    else
+    {
+        LPC_USB->USBTxData = 0;
+    }
+
+    // Clear WR_EN to cover zero length packet case
+    LPC_USB->USBCtrl=0;
+
+    SIEselectEndpoint(endpoint);
+    SIEvalidateBuffer();
+}
+
+
+
+
+
+
+
+USBHAL::USBHAL(void)
+{
+    // Disable IRQ
+    NVIC_DisableIRQ(USB_IRQn);
+
+    // Enable power to USB device controller
+    LPC_SC->PCONP |= PCUSB;
+
+    // Enable USB clocks
+    LPC_USB->USBClkCtrl |= DEV_CLK_EN | AHB_CLK_EN;
+    while (LPC_USB->USBClkSt != (DEV_CLK_ON | AHB_CLK_ON));
+
+    // Configure pins P0.29 and P0.30 to be USB D+ and USB D-
+    LPC_PINCON->PINSEL1 &= 0xc3ffffff;
+    LPC_PINCON->PINSEL1 |= 0x14000000;
+
+    // Disconnect USB device
+    SIEdisconnect();
+
+    // Configure pin P2.9 to be Connect
+    LPC_PINCON->PINSEL4 &= 0xfffcffff;
+    LPC_PINCON->PINSEL4 |= 0x00040000;
+
+    // Connect must be low for at least 2.5uS
+    wait(0.3);
+
+    // Set the maximum packet size for the control endpoints
+    realiseEndpoint(EP0IN, MAX_PACKET_SIZE_EP0, 0);
+    realiseEndpoint(EP0OUT, MAX_PACKET_SIZE_EP0, 0);
+
+    // Attach IRQ
+    instance = this;
+    NVIC_SetVector(USB_IRQn, (uint32_t)&_usbisr);
+    NVIC_EnableIRQ(USB_IRQn);
+
+    // Enable interrupts for device events and EP0
+    LPC_USB->USBDevIntEn = EP_SLOW | DEV_STAT;
+    enableEndpointEvent(EP0IN);
+    enableEndpointEvent(EP0OUT);
+}
+
+USBHAL::~USBHAL(void)
+{
+    // Ensure device disconnected
+    SIEdisconnect();
+
+    // Disable USB interrupts
+    NVIC_DisableIRQ(USB_IRQn);
+}
+
+void USBHAL::connect(void)
+{
+    // Connect USB device
+    SIEconnect();
+}
+
+void USBHAL::disconnect(void)
+{
+    // Disconnect USB device
+    SIEdisconnect();
+}
+
+void USBHAL::configureDevice(void)
+{
+    SIEconfigureDevice();
+}
+
+void USBHAL::unconfigureDevice(void)
+{
+    SIEunconfigureDevice();
+}
+
+void USBHAL::setAddress(uint8_t address)
+{
+    SIEsetAddress(address);
+}
+
+void USBHAL::EP0setup(uint8_t *buffer)
+{
+    endpointReadcore(EP0OUT, buffer);
+}
+
+void USBHAL::EP0read(void)
+{
+    // Not required
+}
+
+uint32_t USBHAL::EP0getReadResult(uint8_t *buffer)
+{
+    return endpointReadcore(EP0OUT, buffer);
+}
+
+void USBHAL::EP0write(uint8_t *buffer, uint32_t size)
+{
+    endpointWritecore(EP0IN, buffer, size);
+}
+
+void USBHAL::EP0getWriteResult(void)
+{
+    // Not required
+}
+
+void USBHAL::EP0stall(void)
+{
+    // This will stall both control endpoints
+    stallEndpoint(EP0OUT);
+}
+
+EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize)
+{
+    return EP_PENDING;
+}
+
+EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t * buffer, uint32_t *bytesRead)
+{
+    if(!(epComplete & EP(endpoint)))
+        return EP_PENDING;
+    *bytesRead = endpointReadcore(endpoint, buffer);
+    epComplete &= ~EP(endpoint);
+    return EP_COMPLETED;
+}
+
+EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size)
+{
+    if (getEndpointStallState(endpoint))
+    {
+        return EP_STALLED;
+    }
+
+    epComplete &= ~EP(endpoint);
+
+    endpointWritecore(endpoint, data, size);
+    return EP_PENDING;
+}
+
+EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint)
+{
+    if (epComplete & EP(endpoint))
+    {
+        epComplete &= ~EP(endpoint);
+        return EP_COMPLETED;
+    }
+
+    return EP_PENDING;
+}
+
+bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t flags)
+{
+    // Realise an endpoint
+    LPC_USB->USBDevIntClr = EP_RLZED;
+    LPC_USB->USBReEp |= EP(endpoint);
+    LPC_USB->USBEpInd = endpoint;
+    LPC_USB->USBMaxPSize = maxPacket;
+
+    while (!(LPC_USB->USBDevIntSt & EP_RLZED));
+    LPC_USB->USBDevIntClr = EP_RLZED;
+
+    // Clear stall state
+    endpointStallState &= ~EP(endpoint);
+
+    enableEndpointEvent(endpoint);
+    return true;
+}
+
+void USBHAL::stallEndpoint(uint8_t endpoint)
+{
+    // Stall an endpoint
+    if ( (endpoint==EP0IN) || (endpoint==EP0OUT) )
+    {
+        // Conditionally stall both control endpoints
+        SIEsetEndpointStatus(EP0OUT, SIE_SES_CND_ST);
+    }
+    else
+    {
+        SIEsetEndpointStatus(endpoint, SIE_SES_ST);
+
+        // Update stall state
+        endpointStallState |= EP(endpoint);
+    }
+}
+
+void USBHAL::unstallEndpoint(uint8_t endpoint)
+{
+    // Unstall an endpoint. The endpoint will also be reinitialised
+    SIEsetEndpointStatus(endpoint, 0);
+
+    // Update stall state
+    endpointStallState &= ~EP(endpoint);
+}
+
+bool USBHAL::getEndpointStallState(uint8_t endpoint)
+{
+    // Returns true if endpoint stalled
+    return endpointStallState & EP(endpoint);
+}
+
+void USBHAL::remoteWakeup(void)
+{
+    // Remote wakeup
+    uint8_t status;
+
+    // Enable USB clocks
+    LPC_USB->USBClkCtrl |= DEV_CLK_EN | AHB_CLK_EN;
+    while (LPC_USB->USBClkSt != (DEV_CLK_ON | AHB_CLK_ON));
+
+    status = SIEgetDeviceStatus();
+    SIEsetDeviceStatus(status & ~SIE_DS_SUS);
+}
+
+
+
+
+
+void USBHAL::_usbisr(void)
+{
+    instance->usbisr();
+} 
+
+
+void USBHAL::usbisr(void)
+{ 
+    uint8_t devStat;
+
+    if (LPC_USB->USBDevIntSt & FRAME)
+    {
+        // Start of frame event
+        SOF(SIEgetFrameNumber());
+        // Clear interrupt status flag
+        LPC_USB->USBDevIntClr = FRAME;
+    }
+
+    if (LPC_USB->USBDevIntSt & DEV_STAT)
+    {
+        // Device Status interrupt
+        // Must clear the interrupt status flag before reading the device status from the SIE
+        LPC_USB->USBDevIntClr = DEV_STAT;
+
+        // Read device status from SIE
+        devStat = SIEgetDeviceStatus();
+
+        if (devStat & SIE_DS_RST)
+        {
+            // Bus reset
+            busReset();
+        }
+    }
+
+    if (LPC_USB->USBDevIntSt & EP_SLOW)
+    {
+        // (Slow) Endpoint Interrupt
+
+        // Process each endpoint interrupt
+        if (LPC_USB->USBEpIntSt & EP(EP0OUT))
+        {
+            if (selectEndpointClearInterrupt(EP0OUT) & SIE_SE_STP)
+            {
+                // this is a setup packet
+                EP0setupCallback();
+            }
+            else
+            {
+                EP0out();
+            }
+            LPC_USB->USBDevIntClr = EP_SLOW;
+        }
+
+        if (LPC_USB->USBEpIntSt & EP(EP0IN))
+        {
+            selectEndpointClearInterrupt(EP0IN);
+            LPC_USB->USBDevIntClr = EP_SLOW;
+            EP0in();
+        }
+
+        // TODO: This should cover all endpoints, not just EP1,2,3:
+        if (LPC_USB->USBEpIntSt & EP(EP1IN))
+        {
+            selectEndpointClearInterrupt(EP1IN);
+            epComplete |= EP(EP1IN);
+            LPC_USB->USBDevIntClr = EP_SLOW;
+            if(EP1_IN_callback())
+                epComplete &= ~EP(EP1IN);
+        }
+
+        if (LPC_USB->USBEpIntSt & EP(EP1OUT))
+        {
+            selectEndpointClearInterrupt(EP1OUT);
+            epComplete |= EP(EP1OUT);
+            LPC_USB->USBDevIntClr = EP_SLOW;
+            if(EP1_OUT_callback())
+                epComplete &= ~EP(EP1OUT);
+        }
+
+        if (LPC_USB->USBEpIntSt & EP(EP2IN))
+        {
+            selectEndpointClearInterrupt(EP2IN);
+            epComplete |= EP(EP2IN);
+            LPC_USB->USBDevIntClr = EP_SLOW;
+            if(EP2_IN_callback())
+                epComplete &= ~EP(EP2IN);
+        }
+
+        if (LPC_USB->USBEpIntSt & EP(EP2OUT))
+        {
+            selectEndpointClearInterrupt(EP2OUT);
+            epComplete |= EP(EP2OUT);
+            LPC_USB->USBDevIntClr = EP_SLOW;
+            if(EP2_OUT_callback())
+                epComplete &= ~EP(EP2OUT);
+        }
+
+        if (LPC_USB->USBEpIntSt & EP(EP3IN))
+        {
+            selectEndpointClearInterrupt(EP3IN);
+            epComplete |= EP(EP3IN);
+            LPC_USB->USBDevIntClr = EP_SLOW;
+            if(EP3_IN_callback())
+                epComplete &= ~EP(EP3IN);
+        }
+
+        if (LPC_USB->USBEpIntSt & EP(EP3OUT))
+        {
+            selectEndpointClearInterrupt(EP3OUT);
+            epComplete |= EP(EP3OUT);
+            LPC_USB->USBDevIntClr = EP_SLOW;
+            if(EP3_OUT_callback())
+                epComplete &= ~EP(EP3OUT);
+        }
+    }
+}
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBDevice/USBDescriptor.h Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,74 @@ +/* Copyright (c) 2010-2011 mbed.org, MIT License +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of this software +* and associated documentation files (the "Software"), to deal in the Software without +* restriction, including without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all copies or +* substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* Standard descriptor types */ +#define DEVICE_DESCRIPTOR (1) +#define CONFIGURATION_DESCRIPTOR (2) +#define STRING_DESCRIPTOR (3) +#define INTERFACE_DESCRIPTOR (4) +#define ENDPOINT_DESCRIPTOR (5) +#define QUALIFIER_DESCRIPTOR (6) + +/* Standard descriptor lengths */ +#define DEVICE_DESCRIPTOR_LENGTH (0x12) +#define CONFIGURATION_DESCRIPTOR_LENGTH (0x09) +#define INTERFACE_DESCRIPTOR_LENGTH (0x09) +#define ENDPOINT_DESCRIPTOR_LENGTH (0x07) + + +/*string offset*/ +#define STRING_OFFSET_LANGID (0) +#define STRING_OFFSET_IMANUFACTURER (1) +#define STRING_OFFSET_IPRODUCT (2) +#define STRING_OFFSET_ISERIAL (3) +#define STRING_OFFSET_ICONFIGURATION (4) +#define STRING_OFFSET_IINTERFACE (5) + +/* USB Specification Release Number */ +#define USB_VERSION_2_0 (0x0200) + +/* Least/Most significant byte of short integer */ +#define LSB(n) ((n)&0xff) +#define MSB(n) (((n)&0xff00)>>8) + +/* Convert physical endpoint number to descriptor endpoint number */ +#define PHY_TO_DESC(endpoint) (((endpoint)>>1) | (((endpoint) & 1) ? 0x80:0)) + +/* bmAttributes in configuration descriptor */ +/* C_RESERVED must always be set */ +#define C_RESERVED (1U<<7) +#define C_SELF_POWERED (1U<<6) +#define C_REMOTE_WAKEUP (1U<<5) + +/* bMaxPower in configuration descriptor */ +#define C_POWER(mA) ((mA)/2) + +/* bmAttributes in endpoint descriptor */ +#define E_CONTROL (0x00) +#define E_ISOCHRONOUS (0x01) +#define E_BULK (0x02) +#define E_INTERRUPT (0x03) + +/* For isochronous endpoints only: */ +#define E_NO_SYNCHRONIZATION (0x00) +#define E_ASYNCHRONOUS (0x04) +#define E_ADAPTIVE (0x08) +#define E_SYNCHRONOUS (0x0C) +#define E_DATA (0x00) +#define E_FEEDBACK (0x10) +#define E_IMPLICIT_FEEDBACK (0x20)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBDevice/USBDevice.cpp	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,921 @@
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include "stdint.h"
+
+#include "USBEndpoints.h"
+#include "USBDevice.h"
+#include "USBDescriptor.h"
+#include "USBHID_Types.h"
+
+
+/* Device status */
+#define DEVICE_STATUS_SELF_POWERED  (1U<<0)
+#define DEVICE_STATUS_REMOTE_WAKEUP (1U<<1)
+
+/* Endpoint status */
+#define ENDPOINT_STATUS_HALT        (1U<<0)
+
+/* Standard feature selectors */
+#define DEVICE_REMOTE_WAKEUP        (1)
+#define ENDPOINT_HALT               (0)
+
+/* Macro to convert wIndex endpoint number to physical endpoint number */
+#define WINDEX_TO_PHYSICAL(endpoint) (((endpoint & 0x0f) << 1) + \
+    ((endpoint & 0x80) ? 1 : 0))
+
+
+bool USBDevice::requestGetDescriptor(void)
+{
+    bool success = false;
+
+    switch (DESCRIPTOR_TYPE(transfer.setup.wValue))
+    {
+        case DEVICE_DESCRIPTOR:
+        case QUALIFIER_DESCRIPTOR:
+            if (deviceDesc() != NULL)
+            {
+                if ((deviceDesc()[0] == DEVICE_DESCRIPTOR_LENGTH) \
+                    && (deviceDesc()[1] == DEVICE_DESCRIPTOR))
+                {
+                    transfer.remaining = DEVICE_DESCRIPTOR_LENGTH;
+                    transfer.ptr = deviceDesc();
+                    transfer.direction = DEVICE_TO_HOST;
+                    success = true;
+                }
+            }
+            break;
+        case CONFIGURATION_DESCRIPTOR:
+            if (configurationDesc() != NULL)
+            {
+                if ((configurationDesc()[0] == CONFIGURATION_DESCRIPTOR_LENGTH) \
+                    && (configurationDesc()[1] == CONFIGURATION_DESCRIPTOR))
+                {
+                    /* Get wTotalLength */
+                    transfer.remaining = configurationDesc()[2] \
+                        | (configurationDesc()[3] << 8);
+
+                    transfer.ptr = configurationDesc();
+                    transfer.direction = DEVICE_TO_HOST;
+                    success = true;
+                }
+            }
+            break;
+        case STRING_DESCRIPTOR:
+            switch (DESCRIPTOR_INDEX(transfer.setup.wValue))
+            {
+                            case STRING_OFFSET_LANGID:
+                                transfer.remaining = stringLangidDesc()[0];
+                                transfer.ptr = stringLangidDesc();
+                                transfer.direction = DEVICE_TO_HOST;
+                                success = true;
+                                break;
+                            case STRING_OFFSET_IMANUFACTURER:
+                                transfer.remaining =  stringImanufacturerDesc()[0];
+                                transfer.ptr = stringImanufacturerDesc();
+                                transfer.direction = DEVICE_TO_HOST;
+                                success = true;
+                                break;       
+                            case STRING_OFFSET_IPRODUCT:
+                                transfer.remaining = stringIproductDesc()[0];
+                                transfer.ptr = stringIproductDesc();
+                                transfer.direction = DEVICE_TO_HOST;
+                                success = true;
+                                break;            
+                            case STRING_OFFSET_ISERIAL:
+                                transfer.remaining = stringIserialDesc()[0];
+                                transfer.ptr = stringIserialDesc();
+                                transfer.direction = DEVICE_TO_HOST;
+                                success = true;
+                                break;        
+                            case STRING_OFFSET_ICONFIGURATION:
+                                transfer.remaining = stringIConfigurationDesc()[0];
+                                transfer.ptr = stringIConfigurationDesc();
+                                transfer.direction = DEVICE_TO_HOST;
+                                success = true;
+                                break; 
+                            case STRING_OFFSET_IINTERFACE:
+                                transfer.remaining = stringIinterfaceDesc()[0];
+                                transfer.ptr = stringIinterfaceDesc();
+                                transfer.direction = DEVICE_TO_HOST;
+                                success = true;
+                                break; 
+            }
+            break;
+        case INTERFACE_DESCRIPTOR:
+        case ENDPOINT_DESCRIPTOR:
+            /* TODO: Support is optional, not implemented here */
+            break;
+        default:
+            break;
+    }
+
+    return success;
+}
+
+void USBDevice::decodeSetupPacket(uint8_t *data, SETUP_PACKET *packet)
+{
+    /* Fill in the elements of a SETUP_PACKET structure from raw data */
+    packet->bmRequestType.dataTransferDirection = (data[0] & 0x80) >> 7;
+    packet->bmRequestType.Type = (data[0] & 0x60) >> 5;
+    packet->bmRequestType.Recipient = data[0] & 0x1f;
+    packet->bRequest = data[1];
+    packet->wValue = (data[2] | (uint16_t)data[3] << 8);
+    packet->wIndex = (data[4] | (uint16_t)data[5] << 8);
+    packet->wLength = (data[6] | (uint16_t)data[7] << 8);
+}
+
+
+bool USBDevice::controlOut(void)
+{
+    /* Control transfer data OUT stage */
+    uint8_t buffer[MAX_PACKET_SIZE_EP0];
+    uint32_t packetSize;
+
+    /* Check we should be transferring data OUT */
+    if (transfer.direction != HOST_TO_DEVICE)
+    {
+        return false;
+    }
+
+    /* Read from endpoint */
+    packetSize = EP0getReadResult(buffer);
+
+    /* Check if transfer size is valid */
+    if (packetSize > transfer.remaining)
+    {
+        /* Too big */
+        return false;
+    }
+
+    /* Update transfer */
+    transfer.ptr += packetSize;
+    transfer.remaining -= packetSize;
+
+    /* Check if transfer has completed */
+    if (transfer.remaining == 0)
+    {
+        /* Transfer completed */
+        if (transfer.notify)
+        {
+            /* Notify class layer. */
+            USBCallback_requestCompleted();
+            transfer.notify = false;
+        }
+        /* Status stage */
+        EP0write(NULL, 0);
+    }
+    else
+    {
+        EP0read();
+    }
+
+    return true;
+}
+
+bool USBDevice::controlIn(void)
+{
+    /* Control transfer data IN stage */
+    uint32_t packetSize;
+
+    /* Check if transfer has completed (status stage transactions */
+    /* also have transfer.remaining == 0) */
+    if (transfer.remaining == 0)
+    {
+        if (transfer.zlp)
+        {
+            /* Send zero length packet */
+            EP0write(NULL, 0);
+            transfer.zlp = false;
+        }
+
+        /* Transfer completed */
+        if (transfer.notify)
+        {
+            /* Notify class layer. */
+            USBCallback_requestCompleted();
+            transfer.notify = false;
+        }
+
+        EP0read();
+
+        /* Completed */
+        return true;
+    }
+
+    /* Check we should be transferring data IN */
+    if (transfer.direction != DEVICE_TO_HOST)
+    {
+        return false;
+    }
+
+    packetSize = transfer.remaining;
+
+    if (packetSize > MAX_PACKET_SIZE_EP0)
+    {
+        packetSize = MAX_PACKET_SIZE_EP0;
+    }
+
+    /* Write to endpoint */
+    EP0write(transfer.ptr, packetSize);
+
+    /* Update transfer */
+    transfer.ptr += packetSize;
+    transfer.remaining -= packetSize;
+
+    return true;
+}
+
+bool USBDevice::requestSetAddress(void)
+{
+    /* Set the device address */
+    setAddress(transfer.setup.wValue);
+
+    if (transfer.setup.wValue == 0)
+    {
+        device.state = DEFAULT;
+    }
+    else
+    {
+        device.state = ADDRESS;
+    }
+
+    return true;
+}
+
+bool USBDevice::requestSetConfiguration(void)
+{
+
+    device.configuration = transfer.setup.wValue;
+    /* Set the device configuration */
+    if (device.configuration == 0)
+    {
+        /* Not configured */
+        unconfigureDevice();
+        device.state = ADDRESS;
+    }
+    else
+    {
+        if (USBCallback_setConfiguration(device.configuration))
+        {
+            /* Valid configuration */
+            configureDevice();
+            device.state = CONFIGURED;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool USBDevice::requestGetConfiguration(void)
+{
+    /* Send the device configuration */
+    transfer.ptr = &device.configuration;
+    transfer.remaining = sizeof(device.configuration);
+    transfer.direction = DEVICE_TO_HOST;
+    return true;
+}
+
+bool USBDevice::requestGetInterface(void)
+{
+    static uint8_t alternateSetting;
+
+    /* Return the selected alternate setting for an interface */
+
+    if (device.state != CONFIGURED)
+    {
+        return false;
+    }
+
+    /* TODO: We currently do not support alternate settings */
+    /* so always return zero */
+    /* TODO: Should check that the interface number is valid */
+    alternateSetting = 0;
+
+    /* Send the alternate setting */
+    transfer.ptr = &alternateSetting;
+    transfer.remaining = sizeof(alternateSetting);
+    transfer.direction = DEVICE_TO_HOST;
+    return true;
+}
+
+bool USBDevice::requestSetInterface(void)
+{
+    /* TODO: We currently do not support alternate settings, return false */
+    return false;
+}
+
+bool USBDevice::requestSetFeature()
+{
+    bool success = false;
+
+    if (device.state != CONFIGURED)
+    {
+        /* Endpoint or interface must be zero */
+        if (transfer.setup.wIndex != 0)
+        {
+            return false;
+        }
+    }
+
+    switch (transfer.setup.bmRequestType.Recipient)
+    {
+        case DEVICE_RECIPIENT:
+            /* TODO: Remote wakeup feature not supported */
+            break;
+        case ENDPOINT_RECIPIENT:
+            if (transfer.setup.wValue == ENDPOINT_HALT)
+            {
+                /* TODO: We should check that the endpoint number is valid */
+                stallEndpoint(
+                    WINDEX_TO_PHYSICAL(transfer.setup.wIndex));
+                success = true;
+            }
+            break;
+        default:
+            break;
+    }
+
+    return success;
+}
+
+bool USBDevice::requestClearFeature()
+{
+    bool success = false;
+
+    if (device.state != CONFIGURED)
+    {
+        /* Endpoint or interface must be zero */
+        if (transfer.setup.wIndex != 0)
+        {
+            return false;
+        }
+    }
+
+    switch (transfer.setup.bmRequestType.Recipient)
+    {
+        case DEVICE_RECIPIENT:
+            /* TODO: Remote wakeup feature not supported */
+            break;
+        case ENDPOINT_RECIPIENT:
+            /* TODO: We should check that the endpoint number is valid */
+            if (transfer.setup.wValue == ENDPOINT_HALT)
+            {
+                unstallEndpoint( WINDEX_TO_PHYSICAL(transfer.setup.wIndex));
+                success = true;
+            }
+            break;
+        default:
+            break;
+    }
+
+    return success;
+}
+
+bool USBDevice::requestGetStatus(void)
+{
+    static uint16_t status;
+    bool success = false;
+
+    if (device.state != CONFIGURED)
+    {
+        /* Endpoint or interface must be zero */
+        if (transfer.setup.wIndex != 0)
+        {
+            return false;
+        }
+    }
+
+    switch (transfer.setup.bmRequestType.Recipient)
+    {
+        case DEVICE_RECIPIENT:
+            /* TODO: Currently only supports self powered devices */
+            status = DEVICE_STATUS_SELF_POWERED;
+            success = true;
+            break;
+        case INTERFACE_RECIPIENT:
+            status = 0;
+            success = true;
+            break;
+        case ENDPOINT_RECIPIENT:
+            /* TODO: We should check that the endpoint number is valid */
+            if (getEndpointStallState(
+                WINDEX_TO_PHYSICAL(transfer.setup.wIndex)))
+            {
+                status = ENDPOINT_STATUS_HALT;
+            }
+            else
+            {
+                status = 0;
+            }
+            success = true;
+            break;
+        default:
+            break;
+    }
+
+    if (success)
+    {
+        /* Send the status */ 
+        transfer.ptr = (uint8_t *)&status; /* Assumes little endian */
+        transfer.remaining = sizeof(status);
+        transfer.direction = DEVICE_TO_HOST;
+    }
+    
+    return success;
+}
+
+bool USBDevice::requestSetup(void)
+{
+    bool success = false;
+
+    /* Process standard requests */
+    if ((transfer.setup.bmRequestType.Type == STANDARD_TYPE))
+    {
+        switch (transfer.setup.bRequest)
+        {
+             case GET_STATUS:
+                 success = requestGetStatus();
+                 break;
+             case CLEAR_FEATURE:
+                 success = requestClearFeature();
+                 break;
+             case SET_FEATURE:
+                 success = requestSetFeature();
+                 break;
+             case SET_ADDRESS:
+                success = requestSetAddress();
+                 break;
+             case GET_DESCRIPTOR:
+                 success = requestGetDescriptor();
+                 break;
+             case SET_DESCRIPTOR:
+                 /* TODO: Support is optional, not implemented here */
+                 success = false;
+                 break;
+             case GET_CONFIGURATION:
+                 success = requestGetConfiguration();
+                 break;
+             case SET_CONFIGURATION:
+                 success = requestSetConfiguration();
+                 break;
+             case GET_INTERFACE:
+                 success = requestGetInterface();
+                 break;
+             case SET_INTERFACE:
+                 success = requestSetInterface();
+                 break;
+             default:
+                 break;
+        }
+    }
+
+    return success;
+}
+
+bool USBDevice::controlSetup(void)
+{
+    bool success = false;
+
+    /* Control transfer setup stage */
+    uint8_t buffer[MAX_PACKET_SIZE_EP0];
+
+    EP0setup(buffer);
+
+    /* Initialise control transfer state */
+    decodeSetupPacket(buffer, &transfer.setup);
+    transfer.ptr = NULL;
+    transfer.remaining = 0;
+    transfer.direction = 0;
+    transfer.zlp = false;
+    transfer.notify = false;
+
+    /* Process request */
+
+    /* Class / vendor specific */
+    success = USBCallback_request();
+
+    if (!success)
+    {
+        /* Standard requests */
+        if (!requestSetup())
+        {
+            return false;
+        }
+    }
+
+    /* Check transfer size and direction */
+    if (transfer.setup.wLength>0)
+    {
+        if (transfer.setup.bmRequestType.dataTransferDirection \
+            == DEVICE_TO_HOST)
+        {
+            /* IN data stage is required */
+            if (transfer.direction != DEVICE_TO_HOST)
+            {
+                return false;
+            }
+
+            /* Transfer must be less than or equal to the size */
+            /* requested by the host */
+            if (transfer.remaining > transfer.setup.wLength)
+            {
+                transfer.remaining = transfer.setup.wLength;
+            }
+        }
+        else
+        {
+            
+            /* OUT data stage is required */
+            if (transfer.direction != HOST_TO_DEVICE)
+            {
+                return false;
+            }
+
+            /* Transfer must be equal to the size requested by the host */
+            if (transfer.remaining != transfer.setup.wLength)
+            {
+                return false;
+            }
+        }
+    }
+    else
+    {
+        /* No data stage; transfer size must be zero */
+        if (transfer.remaining != 0)
+        {
+            return false;
+        }
+    }
+
+    /* Data or status stage if applicable */
+    if (transfer.setup.wLength>0)
+    {
+        if (transfer.setup.bmRequestType.dataTransferDirection \
+            == DEVICE_TO_HOST)
+        {
+            /* Check if we'll need to send a zero length packet at */
+            /* the end of this transfer */
+            if (transfer.setup.wLength > transfer.remaining)
+            {
+                /* Device wishes to transfer less than host requested */
+                if ((transfer.remaining % MAX_PACKET_SIZE_EP0) == 0)
+                {
+                    /* Transfer is a multiple of EP0 max packet size */
+                    transfer.zlp = true;
+                }
+            }
+
+            /* IN stage */
+            controlIn();
+        }
+        else
+        {
+            /* OUT stage */
+            EP0read();
+        }
+    }
+    else
+    {
+        /* Status stage */
+        EP0write(NULL, 0);
+    }
+
+    return true;
+}
+
+void USBDevice::busReset(void)
+{
+    device.state = DEFAULT;
+    device.configuration = 0;
+    device.suspended = false;
+
+    /* Call class / vendor specific busReset function */
+    USBCallback_busReset();
+}
+
+void USBDevice::EP0setupCallback(void)
+{
+    /* Endpoint 0 setup event */
+    if (!controlSetup())
+    {
+        /* Protocol stall */
+        EP0stall();
+    }
+
+    /* Return true if an OUT data stage is expected */
+}
+
+void USBDevice::EP0out(void)
+{
+    /* Endpoint 0 OUT data event */
+    if (!controlOut())
+    {
+        /* Protocol stall; this will stall both endpoints */
+        EP0stall();
+    }
+}
+
+void USBDevice::EP0in(void)
+{
+    /* Endpoint 0 IN data event */
+    if (!controlIn())
+    {
+        /* Protocol stall; this will stall both endpoints */
+        EP0stall();
+    }
+}
+
+bool USBDevice::configured(void)
+{
+    /* Returns true if device is in the CONFIGURED state */
+    return (device.state == CONFIGURED);
+}
+
+void USBDevice::connect(void)
+{
+    /* Connect device */
+    USBHAL::connect();
+}
+
+void USBDevice::disconnect(void)
+{
+    /* Disconnect device */
+    USBHAL::disconnect();
+}
+
+CONTROL_TRANSFER * USBDevice::getTransferPtr(void)
+{
+    return &transfer;
+}
+
+bool USBDevice::addEndpoint(uint8_t endpoint, uint32_t maxPacket)
+{
+    return realiseEndpoint(endpoint, maxPacket, 0);
+}
+
+bool USBDevice::addRateFeedbackEndpoint(uint8_t endpoint, uint32_t maxPacket)
+{
+    /* For interrupt endpoints only */
+    return realiseEndpoint(endpoint, maxPacket, RATE_FEEDBACK_MODE);
+}
+
+uint8_t * USBDevice::findDescriptor(uint8_t descriptorType)
+{
+    /* Find a descriptor within the list of descriptors */
+    /* following a configuration descriptor. */
+    uint16_t wTotalLength;
+    uint8_t *ptr;
+
+    if (configurationDesc() == NULL)
+    {
+        return NULL;
+    }
+
+    /* Check this is a configuration descriptor */
+    if ((configurationDesc()[0] != CONFIGURATION_DESCRIPTOR_LENGTH) \
+            || (configurationDesc()[1] != CONFIGURATION_DESCRIPTOR))
+    {
+        return NULL;
+    }
+
+    wTotalLength = configurationDesc()[2] | (configurationDesc()[3] << 8);
+
+    /* Check there are some more descriptors to follow */
+    if (wTotalLength <= (CONFIGURATION_DESCRIPTOR_LENGTH+2))
+    /* +2 is for bLength and bDescriptorType of next descriptor */
+    {
+        return false;
+    }
+
+    /* Start at first descriptor after the configuration descriptor */
+    ptr = &(configurationDesc()[CONFIGURATION_DESCRIPTOR_LENGTH]);
+
+    do {
+        if (ptr[1] /* bDescriptorType */ == descriptorType)
+        {
+            /* Found */
+            return ptr;
+        }
+
+        /* Skip to next descriptor */
+        ptr += ptr[0]; /* bLength */
+    } while (ptr < (configurationDesc() + wTotalLength));
+
+    /* Reached end of the descriptors - not found */
+    return NULL;
+}
+
+void USBDevice::SOF(int frameNumber)
+{
+}
+
+void USBDevice::connectStateChanged(unsigned int connected)
+{
+}
+
+void USBDevice::suspendStateChanged(unsigned int suspended)
+{
+}
+
+
+USBDevice::USBDevice(uint16_t vendor_id, uint16_t product_id, uint16_t product_release){
+    VENDOR_ID = vendor_id; 
+    PRODUCT_ID = product_id; 
+    PRODUCT_RELEASE = product_release;
+
+    /* Set initial device state */
+    device.state = POWERED;
+    device.configuration = 0;
+    device.suspended = false;
+};
+
+
+bool USBDevice::readStart(uint8_t endpoint, uint16_t maxSize)
+{
+    return endpointRead(endpoint, maxSize) == EP_PENDING;
+}
+
+
+bool USBDevice::write(uint8_t endpoint, uint8_t * buffer, uint16_t size, uint16_t maxSize)
+{
+    EP_STATUS result;
+
+    if (size > maxSize)
+    {
+        return false;
+    }
+
+    /* Block if not configured */
+    while (!configured());
+    
+    /* Send report */
+    result = endpointWrite(endpoint, buffer, size);
+
+    if (result != EP_PENDING)
+    {
+        return false;
+    }
+
+    /* Wait for completion */
+    do {
+        result = endpointWriteResult(endpoint);
+    } while ((result == EP_PENDING) && configured());
+
+    return (result == EP_COMPLETED);
+}
+
+
+bool USBDevice::writeNB(uint8_t endpoint, uint8_t * buffer, uint16_t size, uint16_t maxSize)
+{
+    EP_STATUS result;
+
+    if (size > maxSize)
+    {
+        return false;
+    }
+
+    /* Block if not configured */
+    while (!configured());
+
+    /* Send report */
+    result = endpointWrite(endpoint, buffer, size);
+
+    if (result != EP_PENDING)
+    {
+        return false;
+    }
+
+    result = endpointWriteResult(endpoint);
+
+    return (result == EP_COMPLETED);
+}
+
+
+
+bool USBDevice::read(uint8_t endpoint, uint8_t * buffer, uint16_t * size, uint16_t maxSize)
+{
+    EP_STATUS result;
+
+    /* Block if not configured */
+    while (!configured());
+
+    /* Wait for completion */
+    do {
+        result = endpointReadResult(endpoint, buffer, (uint32_t *)size);
+    } while ((result == EP_PENDING) && configured());
+
+    return (result == EP_COMPLETED);
+}
+
+
+bool USBDevice::readNB(uint8_t endpoint, uint8_t * buffer, uint16_t * size, uint16_t maxSize)
+{
+    EP_STATUS result;
+
+    /* Block if not configured */
+    while (!configured());
+
+    result = endpointReadResult(endpoint, buffer, (uint32_t *)size);
+    
+    return (result == EP_COMPLETED);
+}
+
+
+
+uint8_t * USBDevice::deviceDesc() {
+    static uint8_t deviceDescriptor[] = {
+        DEVICE_DESCRIPTOR_LENGTH,       /* bLength */
+        DEVICE_DESCRIPTOR,              /* bDescriptorType */
+        LSB(USB_VERSION_2_0),           /* bcdUSB (LSB) */
+        MSB(USB_VERSION_2_0),           /* bcdUSB (MSB) */
+        0x00,                           /* bDeviceClass */
+        0x00,                           /* bDeviceSubClass */
+        0x00,                           /* bDeviceprotocol */
+        MAX_PACKET_SIZE_EP0,            /* bMaxPacketSize0 */
+        LSB(VENDOR_ID),                 /* idVendor (LSB) */
+        MSB(VENDOR_ID),                 /* idVendor (MSB) */
+        LSB(PRODUCT_ID),                /* idProduct (LSB) */
+        MSB(PRODUCT_ID),                /* idProduct (MSB) */
+        LSB(PRODUCT_RELEASE),           /* bcdDevice (LSB) */
+        MSB(PRODUCT_RELEASE),           /* bcdDevice (MSB) */
+        STRING_OFFSET_IMANUFACTURER,    /* iManufacturer */
+        STRING_OFFSET_IPRODUCT,         /* iProduct */
+        STRING_OFFSET_ISERIAL,          /* iSerialNumber */
+        0x01                            /* bNumConfigurations */
+    };
+    return deviceDescriptor;
+}
+
+uint8_t * USBDevice::stringLangidDesc() {
+    static uint8_t stringLangidDescriptor[] = {
+        0x04,               /*bLength*/
+        STRING_DESCRIPTOR,  /*bDescriptorType 0x03*/
+        0x09,0x00,          /*bString Lang ID - 0x009 - English*/
+    };
+    return stringLangidDescriptor;
+}
+
+uint8_t * USBDevice::stringImanufacturerDesc() {
+    static uint8_t stringImanufacturerDescriptor[] = {
+        0x12,                                            /*bLength*/
+        STRING_DESCRIPTOR,                               /*bDescriptorType 0x03*/
+        'm',0,'b',0,'e',0,'d',0,'.',0,'o',0,'r',0,'g',0, /*bString iManufacturer - mbed.org*/
+    };
+    return stringImanufacturerDescriptor;
+}
+
+uint8_t * USBDevice::stringIserialDesc() {
+    static uint8_t stringIserialDescriptor[] = {
+        0x16,                                                           /*bLength*/
+        STRING_DESCRIPTOR,                                              /*bDescriptorType 0x03*/
+        '0',0,'1',0,'2',0,'3',0,'4',0,'5',0,'6',0,'7',0,'8',0,'9',0,    /*bString iSerial - 0123456789*/
+    };
+    return stringIserialDescriptor;
+}
+
+uint8_t * USBDevice::stringIConfigurationDesc() {
+    static uint8_t stringIconfigurationDescriptor[] = {
+        0x06,               /*bLength*/
+        STRING_DESCRIPTOR,  /*bDescriptorType 0x03*/
+        '0',0,'1',0,        /*bString iConfiguration - 01*/
+    };
+    return stringIconfigurationDescriptor;
+}
+
+uint8_t * USBDevice::stringIinterfaceDesc() {
+    static uint8_t stringIinterfaceDescriptor[] = {
+        0x08,               /*bLength*/
+        STRING_DESCRIPTOR,  /*bDescriptorType 0x03*/
+        'U',0,'S',0,'B',0,  /*bString iInterface - USB*/
+    };
+    return stringIinterfaceDescriptor;
+}
+
+uint8_t * USBDevice::stringIproductDesc() {
+    static uint8_t stringIproductDescriptor[] = {
+        0x16,                                                       /*bLength*/
+        STRING_DESCRIPTOR,                                          /*bDescriptorType 0x03*/
+        'U',0,'S',0,'B',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0 /*bString iProduct - USB DEVICE*/
+    };
+    return stringIproductDescriptor;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBDevice/USBDevice.h	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,245 @@
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef USBDEVICE_H
+#define USBDEVICE_H
+
+#include "mbed.h"
+#include "USBDevice_Types.h"
+#include "USBBusInterface.h"
+
+
+
+class USBDevice: public USBHAL
+{
+public:
+    USBDevice(uint16_t vendor_id, uint16_t product_id, uint16_t product_release);
+    
+    /*
+    * Check if the device is configured
+    *
+    * @returns true if configured, false otherwise
+    */
+    bool configured(void);
+    
+    /*
+    * Connect a device
+    */
+    void connect(void);
+    
+    /*
+    * Disconnect a device
+    */
+    void disconnect(void);
+    
+    /*
+    * Add an endpoint
+    *
+    * @param endpoint endpoint which will be added
+    * @param maxPacket Maximum size of a packet which can be sent for this endpoint
+    * @returns true if successful, false otherwise
+    */
+    bool addEndpoint(uint8_t endpoint, uint32_t maxPacket);
+
+    /*
+    * Start a reading on a certain endpoint.
+    * You can access the result of the reading by USBDevice_read
+    *
+    * @param endpoint endpoint which will be read
+    * @param maxSize the maximum length that can be read
+    * @return true if successful
+    */
+    bool readStart(uint8_t endpoint, uint16_t maxSize);
+    
+    /*
+    * Read a certain endpoint. Before calling this function, USBUSBDevice_readStart
+    * must be called.
+    *
+    * Warning: blocking
+    *
+    * @param endpoint endpoint which will be read
+    * @param buffer buffer will be filled with the data received
+    * @param size the number of bytes read will be stored in *size
+    * @param maxSize the maximum length that can be read
+    * @returns true if successful
+    */
+    bool read(uint8_t endpoint, uint8_t * buffer, uint16_t * size, uint16_t maxSize);
+    
+    /*
+    * Read a certain endpoint.
+    *
+    * Warning: non blocking
+    *
+    * @param endpoint endpoint which will be read
+    * @param buffer buffer will be filled with the data received (if data are available) 
+    * @param size the number of bytes read will be stored in *size
+    * @param maxSize the maximum length that can be read
+    * @returns true if successful
+    */
+    bool readNB(uint8_t endpoint, uint8_t * buffer, uint16_t * size, uint16_t maxSize);
+    
+    /*
+    * Write a certain endpoint.
+    *
+    * Warning: blocking
+    *
+    * @param endpoint endpoint to write
+    * @param buffer data contained in buffer will be write
+    * @param size the number of bytes to write
+    * @param maxSize the maximum length that can be written on this endpoint
+    */
+    bool write(uint8_t endpoint, uint8_t * buffer, uint16_t size, uint16_t maxSize);
+    bool writeNB(uint8_t endpoint, uint8_t * buffer, uint16_t size, uint16_t maxSize);
+
+    
+    /*
+    * Called by USBDevice layer on bus reset. Warning: Called in ISR context
+    *
+    * May be used to reset state
+    */
+    virtual void USBCallback_busReset(void) {};
+    
+    /*
+    * Called by USBDevice on Endpoint0 request. Warning: Called in ISR context
+    * This is used to handle extensions to standard requests
+    * and class specific requests
+    *
+    * @returns true if class handles this request
+    */
+    virtual bool USBCallback_request() { return false; };   
+    
+    /*
+    * Called by USBDevice on Endpoint0 request completion
+    * if the 'notify' flag has been set to true. Warning: Called in ISR context
+    *
+    * In this case it is used to indicate that a HID report has
+    * been received from the host on endpoint 0
+    */
+    virtual void USBCallback_requestCompleted() {};
+    
+    /*
+    * Called by USBDevice layer. Set configuration of the device.
+    * For instance, you can add all endpoints that you need on this function.
+    *
+    * @param configuration Number of the configuration
+    */
+    virtual bool USBCallback_setConfiguration(uint8_t configuration) { return false; };
+
+    /*
+    * Get device descriptor. Warning: this method has to store the length of the report descriptor in reportLength.
+    *
+    * @returns pointer to the device descriptor
+    */
+    virtual uint8_t * deviceDesc();
+    
+    /*
+    * Get configuration descriptor
+    *
+    * @returns pointer to the configuration descriptor
+    */
+    virtual uint8_t * configurationDesc(){return NULL;};
+    
+    /*
+    * Get string lang id descriptor
+    *
+    * @return pointer to the string lang id descriptor
+    */
+    virtual uint8_t * stringLangidDesc();
+    
+    /*
+    * Get string manufacturer descriptor
+    *
+    * @returns pointer to the string manufacturer descriptor
+    */
+    virtual uint8_t * stringImanufacturerDesc();
+    
+    /*
+    * Get string product descriptor
+    *
+    * @returns pointer to the string product descriptor
+    */
+    virtual uint8_t * stringIproductDesc();
+    
+    /*
+    * Get string serial descriptor
+    *
+    * @returns pointer to the string serial descriptor
+    */
+    virtual uint8_t * stringIserialDesc();
+    
+    /*
+    * Get string configuration descriptor
+    *
+    * @returns pointer to the string configuration descriptor
+    */
+    virtual uint8_t * stringIConfigurationDesc();
+    
+    /*
+    * Get string interface descriptor
+    *
+    * @returns pointer to the string interface descriptor
+    */
+    virtual uint8_t * stringIinterfaceDesc();
+    
+    /*
+    * Get the length of the report descriptor
+    *
+    * @returns length of the report descriptor
+    */
+    virtual uint16_t reportDescLength() { return 0; };
+    
+
+
+protected:
+    virtual void busReset(void);
+    virtual void EP0setupCallback(void);
+    virtual void EP0out(void);
+    virtual void EP0in(void);
+    virtual void SOF(int frameNumber);
+    virtual void connectStateChanged(unsigned int connected);
+    virtual void suspendStateChanged(unsigned int suspended);
+    uint8_t * findDescriptor(uint8_t descriptorType);
+    CONTROL_TRANSFER * getTransferPtr(void);
+    
+    uint16_t VENDOR_ID;
+    uint16_t PRODUCT_ID;
+    uint16_t PRODUCT_RELEASE;
+
+private:
+    bool addRateFeedbackEndpoint(uint8_t endpoint, uint32_t maxPacket);
+    bool requestGetDescriptor(void);
+    bool controlOut(void);
+    bool controlIn(void);
+    bool requestSetAddress(void);
+    bool requestSetConfiguration(void);
+    bool requestSetFeature(void);
+    bool requestClearFeature(void);
+    bool requestGetStatus(void);
+    bool requestSetup(void);
+    bool controlSetup(void);
+    void decodeSetupPacket(uint8_t *data, SETUP_PACKET *packet);
+    bool requestGetConfiguration(void);
+    bool requestGetInterface(void);
+    bool requestSetInterface(void);
+
+    CONTROL_TRANSFER transfer;
+    USB_DEVICE device;
+};
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBDevice/USBDevice_Types.h	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,83 @@
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef USBDEVICE_TYPES_H
+#define USBDEVICE_TYPES_H
+
+/* Standard requests */
+#define GET_STATUS        (0)
+#define CLEAR_FEATURE     (1)
+#define SET_FEATURE       (3)
+#define SET_ADDRESS       (5)
+#define GET_DESCRIPTOR    (6)
+#define SET_DESCRIPTOR    (7)
+#define GET_CONFIGURATION (8)
+#define SET_CONFIGURATION (9)
+#define GET_INTERFACE     (10)
+#define SET_INTERFACE     (11)
+
+/* bmRequestType.dataTransferDirection */
+#define HOST_TO_DEVICE (0)
+#define DEVICE_TO_HOST (1)
+
+/* bmRequestType.Type*/
+#define STANDARD_TYPE  (0)
+#define CLASS_TYPE     (1)
+#define VENDOR_TYPE    (2)
+#define RESERVED_TYPE  (3)
+
+/* bmRequestType.Recipient */
+#define DEVICE_RECIPIENT    (0)
+#define INTERFACE_RECIPIENT (1)
+#define ENDPOINT_RECIPIENT  (2)
+#define OTHER_RECIPIENT     (3)
+
+/* Descriptors */
+#define DESCRIPTOR_TYPE(wValue)  (wValue >> 8)
+#define DESCRIPTOR_INDEX(wValue) (wValue & 0xf)
+
+typedef struct {
+    struct {
+        uint8_t dataTransferDirection;
+        uint8_t Type;
+        uint8_t Recipient;
+    } bmRequestType;
+    uint8_t  bRequest;
+    uint16_t wValue;
+    uint16_t wIndex;
+    uint16_t wLength;
+} SETUP_PACKET;
+
+typedef struct {
+    SETUP_PACKET setup;
+    uint8_t *ptr;
+    uint32_t remaining;
+    uint8_t direction;
+    bool zlp;
+    bool notify;
+} CONTROL_TRANSFER;
+
+typedef enum {ATTACHED, POWERED, DEFAULT, ADDRESS, CONFIGURED} DEVICE_STATE;
+
+typedef struct {
+    volatile DEVICE_STATE state;
+    uint8_t configuration;
+    bool suspended;
+} USB_DEVICE;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBDevice/USBEndpoints.h	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,48 @@
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef USBENDPOINTS_H
+#define USBENDPOINTS_H
+
+/* SETUP packet size */
+#define SETUP_PACKET_SIZE (8)
+
+/* Options flags for configuring endpoints */
+#define DEFAULT_OPTIONS     (0)
+#define SINGLE_BUFFERED     (1U << 0)
+#define ISOCHRONOUS         (1U << 1)
+#define RATE_FEEDBACK_MODE  (1U << 2) /* Interrupt endpoints only */
+
+/* Endpoint transfer status, for endpoints > 0 */
+typedef enum {
+    EP_COMPLETED,   /* Transfer completed */
+    EP_PENDING,     /* Transfer in progress */
+    EP_INVALID,     /* Invalid parameter */
+    EP_STALLED,     /* Endpoint stalled */
+} EP_STATUS;
+
+/* Include configuration for specific target */
+#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
+#include "USBEndpoints_LPC17_LPC23.h"
+#elif defined(TARGET_LPC11U24)
+#include "USBEndpoints_LPC11U.h"
+#else
+#error "Unknown target type"
+#endif
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBDevice/USBEndpoints_LPC11U.h Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,65 @@ +/* Copyright (c) 2010-2011 mbed.org, MIT License +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of this software +* and associated documentation files (the "Software"), to deal in the Software without +* restriction, including without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all copies or +* substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#define NUMBER_OF_LOGICAL_ENDPOINTS (5) +#define NUMBER_OF_PHYSICAL_ENDPOINTS (NUMBER_OF_LOGICAL_ENDPOINTS * 2) + +/* Define physical endpoint numbers */ + +/* Endpoint No. Type(s) MaxPacket DoubleBuffer */ +/* ---------------- ------------ ---------- --- */ +#define EP0OUT (0) /* Control 64 No */ +#define EP0IN (1) /* Control 64 No */ +#define EP1OUT (2) /* Int/Bulk/Iso 64/64/1023 Yes */ +#define EP1IN (3) /* Int/Bulk/Iso 64/64/1023 Yes */ +#define EP2OUT (4) /* Int/Bulk/Iso 64/64/1023 Yes */ +#define EP2IN (5) /* Int/Bulk/Iso 64/64/1023 Yes */ +#define EP3OUT (6) /* Int/Bulk/Iso 64/64/1023 Yes */ +#define EP3IN (7) /* Int/Bulk/Iso 64/64/1023 Yes */ +#define EP4OUT (8) /* Int/Bulk/Iso 64/64/1023 Yes */ +#define EP4IN (9) /* Int/Bulk/Iso 64/64/1023 Yes */ + +/* Maximum Packet sizes */ + +#define MAX_PACKET_SIZE_EP0 (64) +#define MAX_PACKET_SIZE_EP1 (64) /* Int/Bulk */ +#define MAX_PACKET_SIZE_EP2 (64) /* Int/Bulk */ +#define MAX_PACKET_SIZE_EP3 (64) /* Int/Bulk */ +#define MAX_PACKET_SIZE_EP4 (64) /* Int/Bulk */ + +#define MAX_PACKET_SIZE_EP1_ISO (1023) /* Isochronous */ +#define MAX_PACKET_SIZE_EP2_ISO (1023) /* Isochronous */ +#define MAX_PACKET_SIZE_EP3_ISO (1023) /* Isochronous */ +#define MAX_PACKET_SIZE_EP4_ISO (1023) /* Isochronous */ + +/* Generic endpoints - intended to be portable accross devices */ +/* and be suitable for simple USB devices. */ + +/* Bulk endpoint */ +#define EPBULK_OUT (EP2OUT) +#define EPBULK_IN (EP2IN) +/* Interrupt endpoint */ +#define EPINT_OUT (EP1OUT) +#define EPINT_IN (EP1IN) +/* Isochronous endpoint */ +#define EPISO_OUT (EP3OUT) +#define EPISO_IN (EP3IN) + +#define MAX_PACKET_SIZE_EPBULK (MAX_PACKET_SIZE_EP2) +#define MAX_PACKET_SIZE_EPINT (MAX_PACKET_SIZE_EP1) +#define MAX_PACKET_SIZE_EPISO (MAX_PACKET_SIZE_EP3_ISO)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBDevice/USBEndpoints_LPC17_LPC23.h Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,93 @@ +/* Copyright (c) 2010-2011 mbed.org, MIT License +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of this software +* and associated documentation files (the "Software"), to deal in the Software without +* restriction, including without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all copies or +* substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#define NUMBER_OF_LOGICAL_ENDPOINTS (16) +#define NUMBER_OF_PHYSICAL_ENDPOINTS (NUMBER_OF_LOGICAL_ENDPOINTS * 2) + +/* Define physical endpoint numbers */ + +/* Endpoint No. Type(s) MaxPacket DoubleBuffer */ +/* ---------------- ------------ ---------- --- */ +#define EP0OUT (0) /* Control 64 No */ +#define EP0IN (1) /* Control 64 No */ +#define EP1OUT (2) /* Interrupt 64 No */ +#define EP1IN (3) /* Interrupt 64 No */ +#define EP2OUT (4) /* Bulk 64 Yes */ +#define EP2IN (5) /* Bulk 64 Yes */ +#define EP3OUT (6) /* Isochronous 1023 Yes */ +#define EP3IN (7) /* Isochronous 1023 Yes */ +#define EP4OUT (8) /* Interrupt 64 No */ +#define EP4IN (9) /* Interrupt 64 No */ +#define EP5OUT (10) /* Bulk 64 Yes */ +#define EP5IN (11) /* Bulk 64 Yes */ +#define EP6OUT (12) /* Isochronous 1023 Yes */ +#define EP6IN (13) /* Isochronous 1023 Yes */ +#define EP7OUT (14) /* Interrupt 64 No */ +#define EP7IN (15) /* Interrupt 64 No */ +#define EP8OUT (16) /* Bulk 64 Yes */ +#define EP8IN (17) /* Bulk 64 Yes */ +#define EP9OUT (18) /* Isochronous 1023 Yes */ +#define EP9IN (19) /* Isochronous 1023 Yes */ +#define EP10OUT (20) /* Interrupt 64 No */ +#define EP10IN (21) /* Interrupt 64 No */ +#define EP11OUT (22) /* Bulk 64 Yes */ +#define EP11IN (23) /* Bulk 64 Yes */ +#define EP12OUT (24) /* Isochronous 1023 Yes */ +#define EP12IN (25) /* Isochronous 1023 Yes */ +#define EP13OUT (26) /* Interrupt 64 No */ +#define EP13IN (27) /* Interrupt 64 No */ +#define EP14OUT (28) /* Bulk 64 Yes */ +#define EP14IN (29) /* Bulk 64 Yes */ +#define EP15OUT (30) /* Bulk 64 Yes */ +#define EP15IN (31) /* Bulk 64 Yes */ + +/* Maximum Packet sizes */ + +#define MAX_PACKET_SIZE_EP0 (64) +#define MAX_PACKET_SIZE_EP1 (64) +#define MAX_PACKET_SIZE_EP2 (64) +#define MAX_PACKET_SIZE_EP3 (1023) +#define MAX_PACKET_SIZE_EP4 (64) +#define MAX_PACKET_SIZE_EP5 (64) +#define MAX_PACKET_SIZE_EP6 (1023) +#define MAX_PACKET_SIZE_EP7 (64) +#define MAX_PACKET_SIZE_EP8 (64) +#define MAX_PACKET_SIZE_EP9 (1023) +#define MAX_PACKET_SIZE_EP10 (64) +#define MAX_PACKET_SIZE_EP11 (64) +#define MAX_PACKET_SIZE_EP12 (1023) +#define MAX_PACKET_SIZE_EP13 (64) +#define MAX_PACKET_SIZE_EP14 (64) +#define MAX_PACKET_SIZE_EP15 (64) + +/* Generic endpoints - intended to be portable accross devices */ +/* and be suitable for simple USB devices. */ + +/* Bulk endpoints */ +#define EPBULK_OUT (EP2OUT) +#define EPBULK_IN (EP2IN) +/* Interrupt endpoints */ +#define EPINT_OUT (EP1OUT) +#define EPINT_IN (EP1IN) +/* Isochronous endpoints */ +#define EPISO_OUT (EP3OUT) +#define EPISO_IN (EP3IN) + +#define MAX_PACKET_SIZE_EPBULK (MAX_PACKET_SIZE_EP2) +#define MAX_PACKET_SIZE_EPINT (MAX_PACKET_SIZE_EP1) +#define MAX_PACKET_SIZE_EPISO (MAX_PACKET_SIZE_EP3)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBHID/.svn/all-wcprops Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,5 @@ +K 25 +svn:wc:ra_dav:version-url +V 70 +/svn/sdd/mbed/!svn/ver/830/product/libraries/branches/emilmont/usb/hid +END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBHID/.svn/entries Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,292 @@ +10 + +dir +830 +http://cam-svn2.cambridge.arm.com/svn/sdd/mbed/product/libraries/branches/emilmont/usb/hid +http://cam-svn2.cambridge.arm.com/svn/sdd/mbed +delete + + +2011-11-01T16:02:29.187445Z +830 +sammok01 + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +55d82849-f8ce-43ef-8e1a-fbdbc5b469c3 + +RawHID.cpp +file +836 + + + + + + + + + + + + + + + + + + + +deleted + +RawHID.h +file +836 + + + + + + + + + + + + + + + + + + + +deleted + +USBHID.cpp +file +836 + + + + + + + + + + + + + + + + + + + +deleted + +USBHID.h +file +836 + + + + + + + + + + + + + + + + + + + +deleted + +USBHID_Types.h +file +836 + + + + + + + + + + + + + + + + + + + +deleted + +USBKeyboard.cpp +file +836 + + + + + + + + + + + + + + + + + + + +deleted + +USBKeyboard.h +file +836 + + + + + + + + + + + + + + + + + + + +deleted + +USBMouse.cpp +file +836 + + + + + + + + + + + + + + + + + + + +deleted + +USBMouse.h +file +836 + + + + + + + + + + + + + + + + + + + +deleted + +USBMouseKeyboard.cpp +file +836 + + + + + + + + + + + + + + + + + + + +deleted + +USBMouseKeyboard.h +file +836 + + + + + + + + + + + + + + + + + + + +deleted +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBHID/.svn/prop-base/RawHID.cpp.svn-base Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 10 +text/plain +END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBHID/.svn/prop-base/RawHID.h.svn-base Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 10 +text/plain +END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBHID/.svn/prop-base/USBHID.cpp.svn-base Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 10 +text/plain +END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBHID/.svn/prop-base/USBHID.h.svn-base Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 10 +text/plain +END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBHID/.svn/prop-base/USBHID_Types.h.svn-base Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 10 +text/plain +END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBHID/.svn/prop-base/USBKeyboard.cpp.svn-base Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 10 +text/plain +END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBHID/.svn/prop-base/USBKeyboard.h.svn-base Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 10 +text/plain +END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBHID/.svn/prop-base/USBMouse.cpp.svn-base Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 10 +text/plain +END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBHID/.svn/prop-base/USBMouse.h.svn-base Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 10 +text/plain +END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBHID/.svn/prop-base/USBMouseKeyboard.cpp.svn-base Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 10 +text/plain +END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBHID/.svn/prop-base/USBMouseKeyboard.h.svn-base Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 10 +text/plain +END
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBHID/.svn/text-base/RawHID.cpp.svn-base	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,130 @@
+/* USBKeyboard.c */
+/* USB device example: Standard keyboard */
+/* Copyright (c) 2011 ARM Limited. All rights reserved. */
+
+#include "stdint.h"
+
+#include "RawHID.h"
+
+/*
+ *  Descriptors
+ */
+
+#define RAWHID_USAGE_PAGE    0xFFAB    // recommended: 0xFF00 to 0xFFFF
+#define RAWHID_USAGE        0x0200    // recommended: 0x0100 to 0xFFFF
+
+uint8_t * RawHID::ReportDesc() {
+    static uint8_t reportDescriptor[] = {
+        0x06, LSB(RAWHID_USAGE_PAGE), MSB(RAWHID_USAGE_PAGE),
+        0x0A, LSB(RAWHID_USAGE), MSB(RAWHID_USAGE),
+        0xA1, 0x01,                // Collection 0x01
+        0x75, 0x08,                // report size = 8 bits
+        0x15, 0x00,                // logical minimum = 0
+        0x26, 0xFF, 0x00,            // logical maximum = 255
+        0x95, 64,            // report count
+        0x09, 0x01,                // usage
+        0x81, 0x02,                // Input (array)
+        0x95, 64,            // report count
+        0x09, 0x02,                // usage
+        0x91, 0x02,                // Output (array)
+        0xC0                    // end collection
+
+    };
+    reportLength = sizeof(reportDescriptor);
+    return reportDescriptor;
+}
+
+
+#define DEFAULT_CONFIGURATION (1)
+#define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
+                               + (1 * INTERFACE_DESCRIPTOR_LENGTH) \
+                               + (1 * HID_DESCRIPTOR_LENGTH) \
+                               + (2 * ENDPOINT_DESCRIPTOR_LENGTH))
+
+uint8_t * RawHID::ConfigurationDesc() {
+    static uint8_t configurationDescriptor[] = {
+        CONFIGURATION_DESCRIPTOR_LENGTH,/* bLength */
+        CONFIGURATION_DESCRIPTOR,       /* bDescriptorType */
+        LSB(TOTAL_DESCRIPTOR_LENGTH),   /* wTotalLength (LSB) */
+        MSB(TOTAL_DESCRIPTOR_LENGTH),   /* wTotalLength (MSB) */
+        0x01,                           /* bNumInterfaces */
+        DEFAULT_CONFIGURATION,          /* bConfigurationValue */
+        0x00,                           /* iConfiguration */
+        C_RESERVED | C_SELF_POWERED,    /* bmAttributes */
+        C_POWER(0),                     /* bMaxPower */
+
+        INTERFACE_DESCRIPTOR_LENGTH,    /* bLength */
+        INTERFACE_DESCRIPTOR,           /* bDescriptorType */
+        0x00,                           /* bInterfaceNumber */
+        0x00,                           /* bAlternateSetting */
+        0x02,                           /* bNumEndpoints */
+        HID_CLASS,                      /* bInterfaceClass */
+        HID_SUBCLASS_NONE,              /* bInterfaceSubClass */
+        HID_PROTOCOL_NONE,              /* bInterfaceProtocol */
+        0x00,                           /* iInterface */
+
+        HID_DESCRIPTOR_LENGTH,          /* bLength */
+        HID_DESCRIPTOR,                 /* bDescriptorType */
+        LSB(HID_VERSION_1_11),          /* bcdHID (LSB) */
+        MSB(HID_VERSION_1_11),          /* bcdHID (MSB) */
+        0x00,                           /* bCountryCode */
+        0x01,                           /* bNumDescriptors */
+        REPORT_DESCRIPTOR,              /* bDescriptorType */
+        LSB(this->ReportDescLength()),    /* wDescriptorLength (LSB) */
+        MSB(this->ReportDescLength()),    /* wDescriptorLength (MSB) */
+
+        ENDPOINT_DESCRIPTOR_LENGTH,     /* bLength */
+        ENDPOINT_DESCRIPTOR,            /* bDescriptorType */
+        PHY_TO_DESC(EPINT_IN),          /* bEndpointAddress */
+        E_INTERRUPT,                    /* bmAttributes */
+        LSB(MAX_PACKET_SIZE_EPINT),     /* wMaxPacketSize (LSB) */
+        MSB(MAX_PACKET_SIZE_EPINT),     /* wMaxPacketSize (MSB) */
+        10,                             /* bInterval (milliseconds) */
+        
+        ENDPOINT_DESCRIPTOR_LENGTH,     /* bLength */
+        ENDPOINT_DESCRIPTOR,            /* bDescriptorType */
+        PHY_TO_DESC(EPINT_OUT),          /* bEndpointAddress */
+        E_INTERRUPT,                    /* bmAttributes */
+        LSB(MAX_PACKET_SIZE_EPINT),     /* wMaxPacketSize (LSB) */
+        MSB(MAX_PACKET_SIZE_EPINT),     /* wMaxPacketSize (MSB) */
+        10,                             /* bInterval (milliseconds) */
+    };
+    return configurationDescriptor;
+}
+
+bool RawHID::send(uint8_t * buf, uint8_t length)
+{
+    HID_REPORT report;
+    for(int i = 0; i < length; i++)
+        report.data[i] = buf[i];
+    for(int i = length; i < MAX_PACKET_SIZE_EPINT; i++) 
+        report.data[i] = 0;
+    report.length = MAX_PACKET_SIZE_EPINT;
+    return USBHID_send(EPINT_IN, &report);
+    
+}
+
+bool RawHID::USBCallback_setConfiguration(uint8_t configuration) {
+    /* Called in ISR context */
+
+    /* Set configuration. Return false if the */
+    /* configuration is not supported. */
+    if (configuration != DEFAULT_CONFIGURATION) {
+        return false;
+    }
+
+    /* Configure endpoints > 0 */
+    USBDevice_addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);
+    USBDevice_addEndpoint(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
+    return true;
+}
+
+bool RawHID::recv(HID_REPORT& report)
+{
+    return USBHID_read(EPINT_OUT, &report);
+}
+
+bool RawHID::recvNB(HID_REPORT& report)
+{
+    return USBHID_readNB(EPINT_OUT, &report);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBHID/.svn/text-base/RawHID.h.svn-base	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,70 @@
+/* RawHID.h */
+/* USB device example: send and receive raw HID data */
+/* Copyright (c) 2011 ARM Limited. All rights reserved. */
+
+#ifndef _USB_RAWHID_
+#define _USB_RAWHID_
+
+#include "USBHID.h"
+
+class RawHID: public USBHID {
+public:
+
+    /**
+    *   Constructor
+    *
+    * @param vendor_id Your vendor_id (default: 0x1234)
+    * @param product_id Your product_id (default: 0x0001)
+    * @param product_release Your preoduct_release (default: 0x0001)
+    *
+    */
+    RawHID(uint16_t vendor_id = 0x1234, uint16_t product_id = 0x0006, uint16_t product_release = 0x0001): USBHID(vendor_id, product_id, product_release) {};
+
+    /**
+    *   Send a packet of 64 bytes maximum
+    *
+    * @param buf packet to be sent
+    * @return true if successful
+    */
+    bool send(uint8_t * buf, uint8_t length);
+
+    /**
+    *   Receive a packet of 64 bytes maximum. Warning: blocking
+    *
+    * @param report report containing data (report.data) and the length (report.length)
+    * @return true if successful
+    */
+    bool recv(HID_REPORT& report);
+    
+    /**
+    *   Receive a packet of 64 bytes maximum. Warning: non blocking
+    *
+    * @param report report containing data (report.data) and the length (report.length)
+    * @return true if successful
+    */
+    bool recvNB(HID_REPORT& report);
+
+    /**
+    * To define the report descriptor. Warning: this method has to store the length of the report descriptor in reportLength.
+    *
+    * @return pointer to the report descriptor
+    */
+    virtual uint8_t * ReportDesc();
+
+    /**
+    * To define the Configuration descriptor. (Here we have 2 endpoints in the interface descriptor)
+    *
+    * @return pointer to the configuration descriptor
+    */
+    virtual uint8_t * ConfigurationDesc();
+
+    /*
+    * Called by USBDevice layer. Set configuration of the device.
+    * For instance, you can add all endpoints that you need on this function. Here, we enable EPINT_IN and EPINT_OUT
+    *
+    * @param configuration Number of the configuration
+    */
+    virtual bool USBCallback_setConfiguration(uint8_t configuration);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBHID/.svn/text-base/USBHID.cpp.svn-base	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,251 @@
+/* USBHID.c */
+/* Human Interface Device (HID) class */
+/* Copyright (c) 2011 ARM Limited. All rights reserved. */
+
+#include "stdint.h"
+#include "USBBusInterface.h"
+#include "USBHID.h"
+
+/* Output report from SET_REPORT request */
+static HID_REPORT outputReport;
+
+bool USBHID::USBClass_HID_request(void)
+{
+    /* Called in ISR context */
+
+    bool success = false;
+    CONTROL_TRANSFER *transfer = USBDevice_getTransferPtr();
+    uint8_t *hidDescriptor;
+
+    /* Process additional standard requests */
+
+    if ((transfer->setup.bmRequestType.Type == STANDARD_TYPE))
+    {
+        switch (transfer->setup.bRequest)
+        {
+            case GET_DESCRIPTOR:
+                switch (DESCRIPTOR_TYPE(transfer->setup.wValue))
+                {
+                    case REPORT_DESCRIPTOR:
+                        if ((ReportDesc() != NULL) \
+                            && (ReportDescLength() != 0))
+                        {
+                            transfer->remaining = ReportDescLength();
+                            transfer->ptr = ReportDesc();
+                            transfer->direction = DEVICE_TO_HOST;
+                            success = true;
+                        }
+                        break;
+                    case HID_DESCRIPTOR:
+                            /* Find the HID descriptor, after the configuration descriptor */
+                            hidDescriptor = USBDevice_findDescriptor(HID_DESCRIPTOR);
+                            if (hidDescriptor != NULL) /* NULL = Not found */
+                            {
+                                transfer->remaining = HID_DESCRIPTOR_LENGTH;
+                                transfer->ptr = hidDescriptor;
+                                transfer->direction = DEVICE_TO_HOST;
+                                success = true;
+                            }
+                            break;
+                     
+                    default:
+                        break;
+                }
+                break;
+            default:
+                break;
+        }
+    }
+
+    /* Process class-specific requests */
+
+    if (transfer->setup.bmRequestType.Type == CLASS_TYPE)
+    {
+        switch (transfer->setup.bRequest)
+        {
+             case SET_REPORT:
+                /* First byte will be used for report ID */
+                outputReport.data[0] = transfer->setup.wValue & 0xff;
+                outputReport.length = transfer->setup.wLength + 1;
+
+                transfer->remaining = sizeof(outputReport.data) - 1;
+                transfer->ptr = &outputReport.data[1];
+                transfer->direction = HOST_TO_DEVICE;
+                transfer->notify = true; /* Callback on completion */
+                success = true;
+            default:
+                break;
+        }
+    }
+
+    return success;
+}
+
+void USBHID::USBClass_HID_requestCompleted(void)
+{
+    /* SET_REPORT request - data is now valid */
+
+    HID_callbackSetReport(&outputReport);
+}
+
+bool USBHID::USBHID_send(uint8_t endpoint, HID_REPORT *report)
+{
+    return USBDevice_write(endpoint, report->data, report->length, MAX_HID_REPORT_SIZE);
+}
+
+bool USBHID::USBHID_read(uint8_t endpoint, HID_REPORT *report)
+{
+    uint16_t bytesRead = 0;
+    bool result;
+    if(!USBDevice_readStart(endpoint, MAX_HID_REPORT_SIZE))
+    	return false;
+    result = USBDevice_read(endpoint, report->data, &bytesRead, MAX_HID_REPORT_SIZE);
+    report->length = bytesRead;
+    return result;
+}
+
+bool USBHID::USBHID_readNB(uint8_t endpoint, HID_REPORT *report)
+{
+    uint16_t bytesRead = 0;
+    bool result;
+    if(!USBDevice_readStart(endpoint, MAX_HID_REPORT_SIZE))
+    	return false;
+    result = USBDevice_readNB(endpoint, report->data, &bytesRead, MAX_HID_REPORT_SIZE);
+    report->length = bytesRead;
+    return result;
+}
+
+
+#define DEFAULT_CONFIGURATION (1)
+
+USBHID::USBHID(uint16_t vendor_id, uint16_t product_id, uint16_t product_release): USBDevice(vendor_id, product_id, product_release)
+{
+    USBDevice_init(); 
+    USBDevice_connect();
+}
+
+uint16_t USBHID::ReportDescLength() {
+    ReportDesc(); 
+    return reportLength;
+}
+
+/*
+ *  Route callbacks from lower layers to class(es)
+ */
+
+void USBHID::USBCallback_busReset(void) {
+    /* Called in ISR context */
+    /* Called by USBDevice layer on bus reset */
+
+    /* May be used to reset state */
+}
+
+bool USBHID::USBCallback_request() {
+    /* Called in ISR context */
+    /* Called by USBDevice on Endpoint0 request */
+
+    /* This is used to handle extensions to standard requests */
+    /* and class specific requests. */
+
+    /* Return true if class handles this request */
+    return USBClass_HID_request();
+}
+
+void USBHID::USBCallback_requestCompleted() {
+    /* Called in ISR context */
+    /* Called by USBDevice on Endpoint0 request completion */
+    /* if the 'notify' flag has been set to true */
+
+    /* In this case it is used to indicate that a HID report has */
+    /* been received from the host on endpoint 0 */
+
+    USBClass_HID_requestCompleted();
+}
+
+void USBHID::HID_callbackSetReport(HID_REPORT *report) {
+    /* Called in ISR context */
+
+    /* HID Report received by SET_REPORT request */
+    /* First byte of data will be the report ID */
+}
+
+bool USBHID::USBCallback_setConfiguration(uint8_t configuration) {
+    /* Called in ISR context */
+
+    /* Set configuration. Return false if the */
+    /* configuration is not supported. */
+    if (configuration != DEFAULT_CONFIGURATION) {
+        return false;
+    }
+
+    /* Configure endpoints > 0 */
+    USBDevice_addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);
+    return true;
+}
+
+uint8_t * USBHID::StringIinterfaceDesc() {
+    static uint8_t stringIinterfaceDescriptor[] = {
+        0x08,                                                           /*bLength*/
+        STRING_DESCRIPTOR,                                              /*bDescriptorType 0x03*/
+        'H',0,'I',0,'D',0,                                              /*bString iInterface - HID*/
+    };
+    return stringIinterfaceDescriptor;
+}
+
+uint8_t * USBHID::StringIproductDesc() {
+    static uint8_t stringIproductDescriptor[] = {
+        0x16,                                                   /*bLength*/
+        STRING_DESCRIPTOR,                                      /*bDescriptorType 0x03*/
+        'H',0,'I',0,'D',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0  /*bString iProduct - HID device*/
+    };
+    return stringIproductDescriptor;
+}
+
+#define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
+                               + (1 * INTERFACE_DESCRIPTOR_LENGTH) \
+                               + (1 * HID_DESCRIPTOR_LENGTH) \
+                               + (1 * ENDPOINT_DESCRIPTOR_LENGTH))
+
+uint8_t * USBHID::ConfigurationDesc() {
+    static uint8_t configurationDescriptor[] = {
+        CONFIGURATION_DESCRIPTOR_LENGTH,/* bLength */
+        CONFIGURATION_DESCRIPTOR,       /* bDescriptorType */
+        LSB(TOTAL_DESCRIPTOR_LENGTH),   /* wTotalLength (LSB) */
+        MSB(TOTAL_DESCRIPTOR_LENGTH),   /* wTotalLength (MSB) */
+        0x01,                           /* bNumInterfaces */
+        DEFAULT_CONFIGURATION,          /* bConfigurationValue */
+        0x00,                           /* iConfiguration */
+        C_RESERVED | C_SELF_POWERED,    /* bmAttributes */
+        C_POWER(0),                     /* bMaxPower */
+
+        INTERFACE_DESCRIPTOR_LENGTH,    /* bLength */
+        INTERFACE_DESCRIPTOR,           /* bDescriptorType */
+        0x00,                           /* bInterfaceNumber */
+        0x00,                           /* bAlternateSetting */
+        0x01,                           /* bNumEndpoints */
+        HID_CLASS,                      /* bInterfaceClass */
+        HID_SUBCLASS_NONE,              /* bInterfaceSubClass */
+        HID_PROTOCOL_NONE,              /* bInterfaceProtocol */
+        0x00,                           /* iInterface */
+
+        HID_DESCRIPTOR_LENGTH,          /* bLength */
+        HID_DESCRIPTOR,                 /* bDescriptorType */
+        LSB(HID_VERSION_1_11),          /* bcdHID (LSB) */
+        MSB(HID_VERSION_1_11),          /* bcdHID (MSB) */
+        0x00,                           /* bCountryCode */
+        0x01,                           /* bNumDescriptors */
+        REPORT_DESCRIPTOR,              /* bDescriptorType */
+        LSB(this->ReportDescLength()),    /* wDescriptorLength (LSB) */
+        MSB(this->ReportDescLength()),    /* wDescriptorLength (MSB) */
+
+        ENDPOINT_DESCRIPTOR_LENGTH,     /* bLength */
+        ENDPOINT_DESCRIPTOR,            /* bDescriptorType */
+        PHY_TO_DESC(EPINT_IN),          /* bEndpointAddress */
+        E_INTERRUPT,                    /* bmAttributes */
+        LSB(MAX_PACKET_SIZE_EPINT),     /* wMaxPacketSize (LSB) */
+        MSB(MAX_PACKET_SIZE_EPINT),     /* wMaxPacketSize (MSB) */
+        10,                             /* bInterval (milliseconds) */
+    };
+    return configurationDescriptor;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBHID/.svn/text-base/USBHID.h.svn-base	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,116 @@
+/* USBHID.h */
+/* Human Interface Device (HID) class */
+/* Copyright (c) 2011 ARM Limited. All rights reserved. */
+
+#ifndef _USB_CLASS_HID_
+#define _USB_CLASS_HID_
+
+/* These headers are included for child class. */
+#include "USBEndpoints.h"
+#include "USBDescriptor.h"
+#include "USBDevice_Types.h"
+
+#include "USBHID_Types.h"
+#include "USBDevice.h"
+
+
+
+class USBHID: public USBDevice {
+public:
+
+    /**
+    * Constructor
+    *
+    * @param vendor_id Your vendor_id
+    * @param product_id Your product_id
+    * @param product_release Your preoduct_release
+    */
+    USBHID(uint16_t vendor_id, uint16_t product_id, uint16_t product_release);
+
+    /**
+    * Get the Report descriptor
+    *
+    * @return pointer to the report descriptor
+    */
+    virtual uint8_t * ReportDesc() {
+        return NULL;
+    };
+
+    /**
+    * Get the length of the report descriptor
+    *
+    * @return the length of the report descriptor
+    */
+    virtual uint16_t ReportDescLength();
+
+    /**
+    * Send a Report to a certain endpoint
+    *
+    * @param endpoint endpoint which will be sent the report
+    * @param report Report which will be sent (a report is defined by all data and the length)
+    * @return true if successful
+    */
+    bool USBHID_send(uint8_t endpoint, HID_REPORT *report);
+    
+    /**
+    * Read a report from a certain endpoint. Warning: blocking
+    *
+    * @param endpoint endpoint which will be read
+    * @param report pointer to the report to fill
+    * @return true if successful
+    */
+    bool USBHID_read(uint8_t endpoint, HID_REPORT * report);
+    
+    /**
+    * Read a report from a certain endpoint. Warning: non blocking
+    *
+    * @param endpoint endpoint which will be read
+    * @param report pointer to the report to fill
+    * @return true if successful
+    */
+    bool USBHID_readNB(uint8_t endpoint, HID_REPORT * report);
+
+    /**
+    * HID Report received by SET_REPORT request. Warning: Called in ISR context
+    * First byte of data will be the report ID
+    *
+    * @param report Data and length received
+    */
+    virtual void HID_callbackSetReport(HID_REPORT *report);
+
+    virtual void USBCallback_busReset(void);
+    virtual bool USBCallback_request();
+    virtual void USBCallback_requestCompleted();
+    virtual bool USBCallback_setConfiguration(uint8_t configuration);
+    
+    
+    /*
+    * Get string product descriptor
+    *
+    * @return pointer to the string product descriptor
+    */
+    virtual uint8_t * StringIproductDesc();
+    
+    /*
+    * Get string interface descriptor
+    *
+    * @return pointer to the string interface descriptor
+    */
+    virtual uint8_t * StringIinterfaceDesc();
+    
+    /*
+    * Get configuration descriptor
+    *
+    * @return pointer to the configuration descriptor
+    */
+    virtual uint8_t * ConfigurationDesc();
+
+protected:
+    uint16_t reportLength;
+
+private:
+    bool USBClass_HID_request(void);
+    void USBClass_HID_requestCompleted(void);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBHID/.svn/text-base/USBHID_Types.h.svn-base	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,77 @@
+/* USBClass_HID_Types.h */
+/* USB HID class type definitions, conversions and constants */
+/* Copyright (c) 2011 ARM Limited. All rights reserved. */
+
+#ifndef USBCLASS_HID_TYPES
+#define USBCLASS_HID_TYPES
+
+#include <stdint.h>
+
+/* */
+#define HID_VERSION_1_11    (0x0111)
+
+/* HID Class */
+#define HID_CLASS           (3)
+#define HID_SUBCLASS_NONE   (0)
+#define HID_PROTOCOL_NONE   (0)
+
+/* Descriptors */
+#define HID_DESCRIPTOR          (33)
+#define HID_DESCRIPTOR_LENGTH   (0x09)
+#define REPORT_DESCRIPTOR       (34)
+
+/* Class requests */
+#define GET_REPORT (0x1)
+#define GET_IDLE   (0x2)
+#define SET_REPORT (0x9)
+#define SET_IDLE   (0xa)
+
+/* HID Class Report Descriptor */
+/* Short items: size is 0, 1, 2 or 3 specifying 0, 1, 2 or 4 (four) bytes */
+/* of data as per HID Class standard */
+
+/* Main items */
+#define INPUT(size)             (0x80 | size)
+#define OUTPUT(size)            (0x90 | size)
+#define FEATURE(size)           (0xb0 | size)
+#define COLLECTION(size)        (0xa0 | size)
+#define END_COLLECTION(size)    (0xc0 | size)
+
+/* Global items */
+#define USAGE_PAGE(size)        (0x04 | size)
+#define LOGICAL_MINIMUM(size)   (0x14 | size)
+#define LOGICAL_MAXIMUM(size)   (0x24 | size)
+#define PHYSICAL_MINIMUM(size)  (0x34 | size)
+#define PHYSICAL_MAXIMUM(size)  (0x44 | size)
+#define UNIT_EXPONENT(size)     (0x54 | size)
+#define UNIT(size)              (0x64 | size)
+#define REPORT_SIZE(size)       (0x74 | size)
+#define REPORT_ID(size)         (0x84 | size)
+#define REPORT_COUNT(size)      (0x94 | size)
+#define PUSH(size)              (0xa4 | size)
+#define POP(size)               (0xb4 | size)
+
+/* Local items */
+#define USAGE(size)                 (0x08 | size)
+#define USAGE_MINIMUM(size)         (0x18 | size)
+#define USAGE_MAXIMUM(size)         (0x28 | size)
+#define DESIGNATOR_INDEX(size)      (0x38 | size)
+#define DESIGNATOR_MINIMUM(size)    (0x48 | size)
+#define DESIGNATOR_MAXIMUM(size)    (0x58 | size)
+#define STRING_INDEX(size)          (0x78 | size)
+#define STRING_MINIMUM(size)        (0x88 | size)
+#define STRING_MAXIMUM(size)        (0x98 | size)
+#define DELIMITER(size)             (0xa8 | size)
+
+/* HID Report */
+/* Where report IDs are used the first byte of 'data' will be the */
+/* report ID and 'length' will include this report ID byte. */
+
+#define MAX_HID_REPORT_SIZE (64)
+
+typedef struct {
+    uint32_t length;
+    uint8_t data[MAX_HID_REPORT_SIZE];
+} HID_REPORT;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBHID/.svn/text-base/USBKeyboard.cpp.svn-base	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,131 @@
+/* USBKeyboard.c */
+/* USB device example: Standard keyboard */
+/* Copyright (c) 2011 ARM Limited. All rights reserved. */
+
+#include "stdint.h"
+
+#include "USBKeyboard.h"
+
+/*
+ *  Descriptors
+ */
+
+uint8_t * USBKeyboard::ReportDesc() {
+    static uint8_t reportDescriptor[] = {
+
+        /* Based on Appendix E.6 of "Device Class Definition for Human Interface
+           Devices (HID)" Version 1.11. */
+
+        USAGE_PAGE(1), 0x01,                    /* Generic Desktop */
+        USAGE(1), 0x06,                         /* Keyboard */
+        COLLECTION(1), 0x01,                    /* Application*/
+        REPORT_ID(1),       REPORT_ID_KEYBOARD,
+
+        USAGE_PAGE(1), 0x07,                    /* Key Codes */
+        USAGE_MINIMUM(1), 0xE0,
+        USAGE_MAXIMUM(1), 0xE7,
+        LOGICAL_MINIMUM(1), 0x00,
+        LOGICAL_MAXIMUM(1), 0x01,
+        REPORT_SIZE(1), 0x01,
+        REPORT_COUNT(1), 0x08,
+        INPUT(1), 0x02,                         /* Data, Variable, Absolute */
+        REPORT_COUNT(1), 0x01,
+        REPORT_SIZE(1), 0x08,
+        INPUT(1), 0x01,                         /* Constant */
+        REPORT_COUNT(1), 0x05,
+        REPORT_SIZE(1), 0x01,
+
+
+        USAGE_PAGE(1), 0x08,                    /* LEDs */
+        USAGE_MINIMUM(1), 0x01,
+        USAGE_MAXIMUM(1), 0x05,
+        OUTPUT(1), 0x02,                        /* Data, Variable, Absolute */
+        REPORT_COUNT(1), 0x01,
+        REPORT_SIZE(1), 0x03,
+        OUTPUT(1), 0x01,                        /* Constant */
+        REPORT_COUNT(1), 0x06,
+        REPORT_SIZE(1), 0x08,
+        LOGICAL_MINIMUM(1), 0x00,
+        LOGICAL_MAXIMUM(1), 0x65,
+
+
+        USAGE_PAGE(1), 0x07,                    /* Key Codes */
+        USAGE_MINIMUM(1), 0x00,
+        USAGE_MAXIMUM(1), 0x65,
+        INPUT(1), 0x00,                         /* Data, Array */
+        END_COLLECTION(0),
+
+        /* Media Control */
+        USAGE_PAGE(1), 0x0C,
+        USAGE(1), 0x01,
+        COLLECTION(1), 0x01,
+        REPORT_ID(1), REPORT_ID_VOLUME,
+        USAGE_PAGE(1), 0x0C,
+        LOGICAL_MINIMUM(1), 0x00,
+        LOGICAL_MAXIMUM(1), 0x01,
+        REPORT_SIZE(1), 0x01,
+        REPORT_COUNT(1), 0x07,
+        USAGE(1), 0xB5,             /* Next Track */
+        USAGE(1), 0xB6,             /* Previous Track */
+        USAGE(1), 0xB7,             /* Stop */
+        USAGE(1), 0xCD,             /* Play / Pause */
+        USAGE(1), 0xE2,             /* Mute */
+        USAGE(1), 0xE9,             /* Volume Up */
+        USAGE(1), 0xEA,             /* Volume Down */
+        INPUT(1), 0x02,             /* Input (Data, Variable, Absolute) */
+        REPORT_COUNT(1), 0x01,
+        INPUT(1), 0x01,
+        END_COLLECTION(0),
+
+    };
+    reportLength = sizeof(reportDescriptor);
+    return reportDescriptor;
+}
+
+int USBKeyboard::_putc(int c) {
+    return keyCode(keymap[c].modifier, c);
+}
+
+bool USBKeyboard::keyCode(uint8_t modifier, uint8_t key) {
+    /* Send a simulated keyboard keypress. Returns true if successful. */
+
+    HID_REPORT report;
+
+    report.data[0] = REPORT_ID_KEYBOARD;
+    report.data[1] = modifier;
+    report.data[2] = 0;
+    report.data[3] = keymap[key].usage;
+    report.data[4] = 0;
+    report.data[5] = 0;
+    report.data[6] = 0;
+    report.data[7] = 0;
+    report.data[8] = 0;
+
+    report.length = 9;
+
+    if (!USBHID_send(EPINT_IN, &report)) {
+        return false;
+    }
+    
+    report.data[1] = 0;
+    report.data[3] = 0;
+
+    if (!USBHID_send(EPINT_IN, &report)) {
+        return false;
+    }
+
+    return true;
+
+}
+
+
+bool USBKeyboard::mediaControl(MEDIA_KEY key) {
+    HID_REPORT report;
+
+    report.data[0] = REPORT_ID_VOLUME;
+    report.data[1] = (1 << key) & 0x7f;
+
+    report.length = 2;
+
+    return USBHID_send(EPINT_IN, &report);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBHID/.svn/text-base/USBKeyboard.h.svn-base	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,448 @@
+/* USBKeyboard.h */
+/* USB device example: Standard keyboard */
+/* Copyright (c) 2011 ARM Limited. All rights reserved. */
+
+#ifndef _USB_KEYBOARD_
+#define _USB_KEYBOARD_
+
+#include "USBHID.h"
+#include "Stream.h"
+
+#define REPORT_ID_KEYBOARD 1
+#define REPORT_ID_VOLUME   3
+
+enum MEDIA_KEY
+{
+    KEY_NEXT_TRACK,     /*!< next Track Button */
+    KEY_PREVIOUS_TRACK, /*!< Previous track Button */
+    KEY_STOP,           /*!< Stop Button */
+    KEY_PLAY_PAUSE,     /*!< Play/Pause Button */
+    KEY_MUTE,           /*!< Mute Button */
+    KEY_VOLUME_UP,      /*!< Volume Up Button */
+    KEY_VOLUME_DOWN,    /*!< Volume Down Button */
+};
+
+enum FUNCTION_KEY
+{
+    KEY_F1 = 128,   /* F1 key */
+    KEY_F2,         /* F2 key */
+    KEY_F3,         /* F3 key */
+    KEY_F4,         /* F4 key */
+    KEY_F5,         /* F5 key */
+    KEY_F6,         /* F6 key */
+    KEY_F7,         /* F7 key */
+    KEY_F8,         /* F8 key */
+    KEY_F9,         /* F9 key */
+    KEY_F10,        /* F10 key */
+    KEY_F11,        /* F11 key */
+    KEY_F12,        /* F12 key */
+    PRINT_SCREEN,   /* Print Screen key */
+    INSERT,         /* Insert key */
+    HOME,           /* Home key */
+    PAGE_UP,        /* Page Up key */
+    PAGE_DOWN,      /* Page Down key */
+};
+
+/** USB device: a keyboard
+ *
+ * Warning: you can only instantiate one instance of a USB device: USBMouse, USBKeyboard, USBAbsMouse, USBMouseKeyboard, or USBAbsMouseKeyboard.
+ *
+ * Example:
+ * @code
+ *
+ * #include "mbed.h"
+ * #include "USBKeyboard.h"
+ *
+ * USBKeyboard key;
+ * 
+ * int main(void)
+ * {
+ *   while (1)
+ *   {
+ *       key.puts("Hello World\r\n");
+ *       wait(1);
+ *   }
+ * }
+ *
+ * @endcode
+ */
+class USBKeyboard: public USBHID, public Stream
+{
+    public:
+    
+        /**
+        *   Constructor
+        *
+        * @param vendor_id Your vendor_id (default: 0x1234)
+        * @param product_id Your product_id (default: 0x0001)
+        * @param product_release Your preoduct_release (default: 0x0001)
+        *
+        */
+        USBKeyboard(uint16_t vendor_id = 0x1234, uint16_t product_id = 0x0003, uint16_t product_release = 0x0001): USBHID(vendor_id, product_id, product_release){};
+        
+        /**
+        * To send a character defined by a modifier(CTRL, SHIFT, ALT) and the key 
+        *
+        * @code
+        * //To send CTRL + s (save)
+        *  keyboard.keyCode(CTRL, 's');
+        * @endcode
+        *
+        * @param modifier bit 0: CTRL, bit 1: SHIFT, bit 2: ALT
+        * @param key character to send
+        * @return true if there is no error, false otherwise
+        */
+        bool keyCode(uint8_t modifier, uint8_t key);
+        
+        /**
+        * Send a character
+        *
+        * @param c character to be sent
+        * @return true if there is no error, false otherwise
+        */
+        virtual int _putc(int c);
+        
+        /**
+        * Control media keys
+        *
+        * @param key media key pressed (KEY_NEXT_TRACK, KEY_PREVIOUS_TRACK, KEY_STOP, KEY_PLAY_PAUSE, KEY_MUTE, KEY_VOLUME_UP, KEY_VOLUME_DOWN)
+        * @return true if there is no error, false otherwise
+        */
+        bool mediaControl(MEDIA_KEY key);
+        
+        /*
+        * To define the report descriptor. Warning: this method has to store the length of the report descriptor in reportLength.
+        *
+        * @return pointer to the report descriptor
+        */
+        virtual uint8_t * ReportDesc();
+        
+   private:
+        //dummy otherwise it doesn,t compile (we must define all methods of an abstract class)
+        virtual int _getc() { return -1;}
+        
+        
+};
+
+
+/* Modifiers */
+enum MODIFIER
+{
+    CTRL = 1,
+    SHIFT = 2,
+    ALT = 4,
+};
+
+typedef struct {
+    unsigned char usage;
+    unsigned char modifier;
+} KEYMAP;
+
+#ifdef US_KEYBOARD
+/* US keyboard (as HID standard) */
+#define KEYMAP_SIZE (145)
+const KEYMAP keymap[KEYMAP_SIZE] = {
+{0, 0},             /* NUL */
+{0, 0},             /* SOH */
+{0, 0},             /* STX */
+{0, 0},             /* ETX */
+{0, 0},             /* EOT */
+{0, 0},             /* ENQ */
+{0, 0},             /* ACK */  
+{0, 0},             /* BEL */
+{0x2a, 0},          /* BS  */  /* Keyboard Delete (Backspace) */ 
+{0x2b, 0},          /* TAB */  /* Keyboard Tab */
+{0x28, 0},          /* LF  */  /* Keyboard Return (Enter) */
+{0, 0},             /* VT  */
+{0, 0},             /* FF  */
+{0, 0},             /* CR  */
+{0, 0},             /* SO  */
+{0, 0},             /* SI  */
+{0, 0},             /* DEL */
+{0, 0},             /* DC1 */
+{0, 0},             /* DC2 */
+{0, 0},             /* DC3 */
+{0, 0},             /* DC4 */
+{0, 0},             /* NAK */
+{0, 0},             /* SYN */
+{0, 0},             /* ETB */
+{0, 0},             /* CAN */
+{0, 0},             /* EM  */
+{0, 0},             /* SUB */
+{0, 0},             /* ESC */
+{0, 0},             /* FS  */
+{0, 0},             /* GS  */
+{0, 0},             /* RS  */
+{0, 0},             /* US  */
+{0x2c, 0},          /*   */
+{0x1e, SHIFT},      /* ! */
+{0x34, SHIFT},      /* " */
+{0x20, SHIFT},      /* # */
+{0x21, SHIFT},      /* $ */
+{0x22, SHIFT},      /* % */
+{0x24, SHIFT},      /* & */
+{0x34, 0},          /* ' */
+{0x26, SHIFT},      /* ( */
+{0x27, SHIFT},      /* ) */
+{0x25, SHIFT},      /* * */
+{0x2e, SHIFT},      /* + */
+{0x36, 0},          /* , */
+{0x2d, 0},          /* - */
+{0x37, 0},          /* . */
+{0x38, 0},          /* / */
+{0x27, 0},          /* 0 */
+{0x1e, 0},          /* 1 */
+{0x1f, 0},          /* 2 */
+{0x20, 0},          /* 3 */
+{0x21, 0},          /* 4 */
+{0x22, 0},          /* 5 */
+{0x23, 0},          /* 6 */
+{0x24, 0},          /* 7 */
+{0x25, 0},          /* 8 */
+{0x26, 0},          /* 9 */
+{0x33, SHIFT},      /* : */
+{0x33, 0},          /* ; */
+{0x36, SHIFT},      /* < */
+{0x2e, 0},          /* = */
+{0x37, SHIFT},      /* > */
+{0x38, SHIFT},      /* ? */
+{0x1f, SHIFT},      /* @ */
+{0x04, SHIFT},      /* A */
+{0x05, SHIFT},      /* B */
+{0x06, SHIFT},      /* C */
+{0x07, SHIFT},      /* D */
+{0x08, SHIFT},      /* E */
+{0x09, SHIFT},      /* F */
+{0x0a, SHIFT},      /* G */
+{0x0b, SHIFT},      /* H */
+{0x0c, SHIFT},      /* I */
+{0x0d, SHIFT},      /* J */
+{0x0e, SHIFT},      /* K */
+{0x0f, SHIFT},      /* L */
+{0x10, SHIFT},      /* M */
+{0x11, SHIFT},      /* N */
+{0x12, SHIFT},      /* O */
+{0x13, SHIFT},      /* P */
+{0x14, SHIFT},      /* Q */
+{0x15, SHIFT},      /* R */
+{0x16, SHIFT},      /* S */
+{0x17, SHIFT},      /* T */
+{0x18, SHIFT},      /* U */
+{0x19, SHIFT},      /* V */
+{0x1a, SHIFT},      /* W */
+{0x1b, SHIFT},      /* X */
+{0x1c, SHIFT},      /* Y */
+{0x1d, SHIFT},      /* Z */
+{0x2f, 0},          /* [ */
+{0x31, 0},          /* \ */
+{0x30, 0},          /* ] */
+{0x23, SHIFT},      /* ^ */
+{0x2d, SHIFT},      /* _ */
+{0x35, 0},          /* ` */
+{0x04, 0},          /* a */
+{0x05, 0},          /* b */
+{0x06, 0},          /* c */
+{0x07, 0},          /* d */
+{0x08, 0},          /* e */
+{0x09, 0},          /* f */
+{0x0a, 0},          /* g */
+{0x0b, 0},          /* h */
+{0x0c, 0},          /* i */
+{0x0d, 0},          /* j */
+{0x0e, 0},          /* k */
+{0x0f, 0},          /* l */
+{0x10, 0},          /* m */
+{0x11, 0},          /* n */
+{0x12, 0},          /* o */
+{0x13, 0},          /* p */
+{0x14, 0},          /* q */
+{0x15, 0},          /* r */
+{0x16, 0},          /* s */
+{0x17, 0},          /* t */
+{0x18, 0},          /* u */
+{0x19, 0},          /* v */
+{0x1a, 0},          /* w */
+{0x1b, 0},          /* x */
+{0x1c, 0},          /* y */
+{0x1d, 0},          /* z */
+{0x2f, SHIFT},      /* { */
+{0x31, SHIFT},      /* | */
+{0x30, SHIFT},      /* } */
+{0x35, SHIFT},      /* ~ */
+{0,0},              /* DEL */ 
+
+{0x3a, 0},          /* F1 */
+{0x3b, 0},          /* F2 */
+{0x3c, 0},          /* F3 */
+{0x3d, 0},          /* F4 */
+{0x3e, 0},          /* F5 */
+{0x3f, 0},          /* F6 */
+{0x40, 0},          /* F7 */
+{0x41, 0},          /* F8 */
+{0x42, 0},          /* F9 */
+{0x43, 0},          /* F10 */
+{0x44, 0},          /* F11 */
+{0x45, 0},          /* F12 */
+
+{0x46, 0},          /* PRINT_SCREEN */
+{0x49, 0},          /* INSERT */
+{0x4a, 0},          /* HOME */
+{0x4b, 0},          /* PAGE_UP */
+{0x4e, 0},          /* PAGE_DOWN */
+};
+
+#else
+/* UK keyboard */
+#define KEYMAP_SIZE (145)
+const KEYMAP keymap[KEYMAP_SIZE] = {
+{0, 0},             /* NUL */
+{0, 0},             /* SOH */
+{0, 0},             /* STX */
+{0, 0},             /* ETX */
+{0, 0},             /* EOT */
+{0, 0},             /* ENQ */
+{0, 0},             /* ACK */  
+{0, 0},             /* BEL */
+{0x2a, 0},          /* BS  */  /* Keyboard Delete (Backspace) */ 
+{0x2b, 0},          /* TAB */  /* Keyboard Tab */
+{0x28, 0},          /* LF  */  /* Keyboard Return (Enter) */
+{0, 0},             /* VT  */
+{0, 0},             /* FF  */
+{0, 0},             /* CR  */
+{0, 0},             /* SO  */
+{0, 0},             /* SI  */
+{0, 0},             /* DEL */
+{0, 0},             /* DC1 */
+{0, 0},             /* DC2 */
+{0, 0},             /* DC3 */
+{0, 0},             /* DC4 */
+{0, 0},             /* NAK */
+{0, 0},             /* SYN */
+{0, 0},             /* ETB */
+{0, 0},             /* CAN */
+{0, 0},             /* EM  */
+{0, 0},             /* SUB */
+{0, 0},             /* ESC */
+{0, 0},             /* FS  */
+{0, 0},             /* GS  */
+{0, 0},             /* RS  */
+{0, 0},             /* US  */
+{0x2c, 0},          /*   */
+{0x1e, SHIFT},      /* ! */
+{0x1f, SHIFT},      /* " */ 
+{0x32, 0},          /* # */ 
+{0x21, SHIFT},      /* $ */
+{0x22, SHIFT},      /* % */
+{0x24, SHIFT},      /* & */
+{0x34, 0},          /* ' */
+{0x26, SHIFT},      /* ( */
+{0x27, SHIFT},      /* ) */
+{0x25, SHIFT},      /* * */
+{0x2e, SHIFT},      /* + */
+{0x36, 0},          /* , */
+{0x2d, 0},          /* - */
+{0x37, 0},          /* . */
+{0x38, 0},          /* / */
+{0x27, 0},          /* 0 */
+{0x1e, 0},          /* 1 */
+{0x1f, 0},          /* 2 */
+{0x20, 0},          /* 3 */
+{0x21, 0},          /* 4 */
+{0x22, 0},          /* 5 */
+{0x23, 0},          /* 6 */
+{0x24, 0},          /* 7 */
+{0x25, 0},          /* 8 */
+{0x26, 0},          /* 9 */
+{0x33, SHIFT},      /* : */
+{0x33, 0},          /* ; */
+{0x36, SHIFT},      /* < */
+{0x2e, 0},          /* = */
+{0x37, SHIFT},      /* > */
+{0x38, SHIFT},      /* ? */
+{0x34, SHIFT},      /* @ */
+{0x04, SHIFT},      /* A */
+{0x05, SHIFT},      /* B */
+{0x06, SHIFT},      /* C */
+{0x07, SHIFT},      /* D */
+{0x08, SHIFT},      /* E */
+{0x09, SHIFT},      /* F */
+{0x0a, SHIFT},      /* G */
+{0x0b, SHIFT},      /* H */
+{0x0c, SHIFT},      /* I */
+{0x0d, SHIFT},      /* J */
+{0x0e, SHIFT},      /* K */
+{0x0f, SHIFT},      /* L */
+{0x10, SHIFT},      /* M */
+{0x11, SHIFT},      /* N */
+{0x12, SHIFT},      /* O */
+{0x13, SHIFT},      /* P */
+{0x14, SHIFT},      /* Q */
+{0x15, SHIFT},      /* R */
+{0x16, SHIFT},      /* S */
+{0x17, SHIFT},      /* T */
+{0x18, SHIFT},      /* U */
+{0x19, SHIFT},      /* V */
+{0x1a, SHIFT},      /* W */
+{0x1b, SHIFT},      /* X */
+{0x1c, SHIFT},      /* Y */
+{0x1d, SHIFT},      /* Z */
+{0x2f, 0},          /* [ */
+{0x64, 0},          /* \ */ 
+{0x30, 0},          /* ] */
+{0x23, SHIFT},      /* ^ */
+{0x2d, SHIFT},      /* _ */
+{0x35, 0},          /* ` */
+{0x04, 0},          /* a */
+{0x05, 0},          /* b */
+{0x06, 0},          /* c */
+{0x07, 0},          /* d */
+{0x08, 0},          /* e */
+{0x09, 0},          /* f */
+{0x0a, 0},          /* g */
+{0x0b, 0},          /* h */
+{0x0c, 0},          /* i */
+{0x0d, 0},          /* j */
+{0x0e, 0},          /* k */
+{0x0f, 0},          /* l */
+{0x10, 0},          /* m */
+{0x11, 0},          /* n */
+{0x12, 0},          /* o */
+{0x13, 0},          /* p */
+{0x14, 0},          /* q */
+{0x15, 0},          /* r */
+{0x16, 0},          /* s */
+{0x17, 0},          /* t */
+{0x18, 0},          /* u */
+{0x19, 0},          /* v */
+{0x1a, 0},          /* w */
+{0x1b, 0},          /* x */
+{0x1c, 0},          /* y */
+{0x1d, 0},          /* z */
+{0x2f, SHIFT},      /* { */
+{0x64, SHIFT},      /* | */ 
+{0x30, SHIFT},      /* } */
+{0x32, SHIFT},      /* ~ */ 
+{0,0},             /* DEL */
+
+{0x3a, 0},          /* F1 */
+{0x3b, 0},          /* F2 */
+{0x3c, 0},          /* F3 */
+{0x3d, 0},          /* F4 */
+{0x3e, 0},          /* F5 */
+{0x3f, 0},          /* F6 */
+{0x40, 0},          /* F7 */
+{0x41, 0},          /* F8 */
+{0x42, 0},          /* F9 */
+{0x43, 0},          /* F10 */
+{0x44, 0},          /* F11 */
+{0x45, 0},          /* F12 */
+
+{0x46, 0},          /* PRINT_SCREEN */
+{0x49, 0},          /* INSERT */
+{0x4a, 0},          /* HOME */
+{0x4b, 0},          /* PAGE_UP */
+{0x4e, 0},          /* PAGE_DOWN */
+};
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBHID/.svn/text-base/USBMouse.cpp.svn-base	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,188 @@
+/* USBMouse.c */
+/* USB device example: Relative mouse */
+/* Copyright (c) 2011 ARM Limited. All rights reserved. */
+
+#include "stdint.h"
+
+#include "USBMouse.h"
+
+/*
+ *  Descriptors
+ */
+
+uint8_t * USBMouse::ReportDesc() {
+
+    if (mouse_type == REL_MOUSE) {
+        static uint8_t reportDescriptor[] = {
+
+            /* Based on Appendix E.10 of "Device Class Definition for Human Interface
+               Devices (HID)" Version 1.11. */
+
+            USAGE_PAGE(1),      0x01,       /* Genric Desktop */
+            USAGE(1),           0x02,       /* Mouse */
+            COLLECTION(1),      0x01,       /* Application*/
+            USAGE(1),           0x01,       /* Pointer */
+            COLLECTION(1),      0x00,       /* Physical */
+
+            REPORT_COUNT(1),    0x03,
+            REPORT_SIZE(1),     0x01,
+            USAGE_PAGE(1),      0x09,       /* Buttons */
+            USAGE_MINIMUM(1),       0x1,
+            USAGE_MAXIMUM(1),       0x3,
+            LOGICAL_MINIMUM(1),     0x00,
+            LOGICAL_MAXIMUM(1),     0x01,
+            INPUT(1),           0x02,
+            REPORT_COUNT(1),    0x01,
+            REPORT_SIZE(1),     0x05,
+            INPUT(1),           0x01,
+
+            REPORT_COUNT(1),    0x03,
+            REPORT_SIZE(1),     0x08,
+            USAGE_PAGE(1),      0x01,
+            USAGE(1),           0x30,       /* X */
+            USAGE(1),           0x31,       /* Y */
+            USAGE(1),           0x38,       /* scroll */
+            LOGICAL_MINIMUM(1),     0x81,
+            LOGICAL_MAXIMUM(1),     0x7f,
+            INPUT(1),           0x06,       /* Relative data */
+
+            END_COLLECTION(0),
+            END_COLLECTION(0),
+        };
+        reportLength = sizeof(reportDescriptor);
+        return reportDescriptor;
+    } else if (mouse_type == ABS_MOUSE) {
+        static uint8_t reportDescriptor[] = {
+
+            /* Based on Appendix E.10 of "Device Class Definition for Human Interface
+               Devices (HID)" Version 1.11 and modified to use absolute coordinates and a wheel. */
+
+            USAGE_PAGE(1), 0x01,                    /* Generic Desktop */
+            USAGE(1), 0x02,                         /* Mouse */
+            COLLECTION(1), 0x01,                    /* Application*/
+            USAGE(1), 0x01,                     /* Pointer */
+            COLLECTION(1), 0x00,                /* Physical */
+
+            USAGE_PAGE(1), 0x01,            /* Generic Desktop */
+            USAGE(1), 0x30,                 /* X */
+            USAGE(1), 0x31,                 /* Y */
+            LOGICAL_MINIMUM(1), 0x00,       /* 0 */
+            LOGICAL_MAXIMUM(2), 0xff, 0x7f, /* 32767 */
+            REPORT_SIZE(1), 0x10,
+            REPORT_COUNT(1), 0x02,
+            INPUT(1), 0x02,                 /* Data, Variable, Absolute */
+
+            USAGE_PAGE(1), 0x01,            /* Generic Desktop */
+            USAGE(1), 0x38,                 /* scroll */
+            LOGICAL_MINIMUM(1), 0x81,       /* -127 */
+            LOGICAL_MAXIMUM(1), 0x7f,       /* 127 */
+            REPORT_SIZE(1), 0x08,
+            REPORT_COUNT(1), 0x01,
+            INPUT(1), 0x06,                 /* Data, Variable, Relative */
+
+            USAGE_PAGE(1), 0x09,            /* Buttons */
+            USAGE_MINIMUM(1), 0x01,
+            USAGE_MAXIMUM(1), 0x03,
+            LOGICAL_MINIMUM(1), 0x00,       /* 0 */
+            LOGICAL_MAXIMUM(1), 0x01,       /* 1 */
+            REPORT_COUNT(1), 0x03,
+            REPORT_SIZE(1), 0x01,
+            INPUT(1), 0x02,                 /* Data, Variable, Absolute */
+            REPORT_COUNT(1), 0x01,
+            REPORT_SIZE(1), 0x05,
+            INPUT(1), 0x01,                 /* Constant */
+
+            END_COLLECTION(0),
+            END_COLLECTION(0)
+        };
+        reportLength = sizeof(reportDescriptor);
+        return reportDescriptor;
+    }
+    return NULL;
+}
+
+
+bool USBMouse::update(int16_t x, int16_t y, uint8_t button, int8_t z) {
+    switch (mouse_type) {
+        case REL_MOUSE:
+            while (x > 127) {
+                if (!mouseSend(127, 0, button, z)) return false;
+                x = x - 127;
+            }
+            while (x < -128) {
+                if (!mouseSend(-128, 0, button, z)) return false;
+                x = x + 128;
+            }
+            while (y > 127) {
+                if (!mouseSend(0, 127, button, z)) return false;
+                y = y - 127;
+            }
+            while (y < -128) {
+                if (!mouseSend(0, -128, button, z)) return false;
+                y = y + 128;
+            }
+            return mouseSend(x, y, button, z);
+        case ABS_MOUSE:
+            HID_REPORT report;
+
+            report.data[0] = x & 0xff;
+            report.data[1] = (x >> 8) & 0xff;
+            report.data[2] = y & 0xff;
+            report.data[3] = (y >> 8) & 0xff;
+            report.data[4] = -z;
+            report.data[5] = button & 0x07;
+
+            report.length = 6;
+
+            return USBHID_send(EPINT_IN, &report);
+        default:
+            return false;
+    }
+}
+
+bool USBMouse::mouseSend(int8_t x, int8_t y, uint8_t buttons, int8_t z) {
+    HID_REPORT report;
+    report.data[0] = buttons & 0x07;
+    report.data[1] = x;
+    report.data[2] = y;
+    report.data[3] = -z; /* >0 to scroll down, <0 to scroll up */
+
+    report.length = 4;
+
+    return USBHID_send(EPINT_IN, &report);
+}
+
+bool USBMouse::move(int16_t x, int16_t y) {
+    return update(x, y, button, 0);
+}
+
+bool USBMouse::scroll(int8_t z) {
+    return update(0, 0, button, z);
+}
+
+
+bool USBMouse::doubleClick() {
+    if (!click(MOUSE_LEFT))
+        return false;
+    wait(0.1);
+    return click(MOUSE_LEFT);
+}
+
+bool USBMouse::click(uint8_t button) {
+    if (!update(0, 0, button, 0))
+        return false;
+    wait(0.01);
+    return update(0, 0, 0, 0);
+}
+
+bool USBMouse::press(uint8_t button_) {
+    button = button_ & 0x07;
+    return update(0, 0, button, 0);
+}
+
+bool USBMouse::release(uint8_t button_) {
+    button = (button & (~button_)) & 0x07;
+    return update(0, 0, button, 0);
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBHID/.svn/text-base/USBMouse.h.svn-base	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,192 @@
+/* USBMouse.h */
+/* USB device example: relative mouse */
+/* Copyright (c) 2011 ARM Limited. All rights reserved. */
+
+#ifndef _RELATIVE_MOUSE_
+#define _RELATIVE_MOUSE_
+
+#include "USBHID.h"
+
+#define REPORT_ID_MOUSE   2
+
+/* Common usage */
+
+enum MOUSE_BUTTON
+{
+    MOUSE_LEFT = 1,
+    MOUSE_RIGHT = 2,
+    MOUSE_MIDDLE = 4,
+};
+
+/* X and Y limits */
+/* These values do not directly map to screen pixels */
+/* Zero may be interpreted as meaning 'no movement' */
+#define X_MIN_ABS    (1)        /*!< Minimum value on x-axis */  
+#define Y_MIN_ABS    (1)        /*!< Minimum value on y-axis */
+#define X_MAX_ABS    (0x7fff)   /*!< Maximum value on x-axis */
+#define Y_MAX_ABS    (0x7fff)   /*!< Maximum value on y-axis */
+
+#define X_MIN_REL    (-127)     /*!< The maximum value that we can move to the left on the x-axis */
+#define Y_MIN_REL    (-127)     /*!< The maximum value that we can move up on the y-axis */
+#define X_MAX_REL    (127)      /*!< The maximum value that we can move to the right on the x-axis */
+#define Y_MAX_REL    (127)      /*!< The maximum value that we can move down on the y-axis */
+
+enum MOUSE_TYPE
+{
+    ABS_MOUSE,
+    REL_MOUSE,
+};
+
+/** USB device: USBMouse. You can choose a relative mouse or an absolute mouse
+ *
+ * Warning: you can only instantiate one instance of a USB device: USBMouse, USBKeyboard or USBMouseKeyboard.
+ *
+ * Example: A relative mouse
+ * @code
+ * #include "mbed.h"
+ * #include "USBMouse.h"
+ *
+ * USBMouse mouse;
+ *
+ * int main(void)
+ * {
+ *   int32_t a;
+ *
+ *   while (1)
+ *   {
+ *      mouse.move(20, 0);
+ *      wait(0.5);
+ *   }
+ * }
+ *
+ * @endcode
+ *
+ *
+ * Example: An absolute mouse
+ * @code
+ * #include "mbed.h"
+ * #include "USBMouse.h"
+ *
+ * USBMouse mouse(ABS_MOUSE);
+ *
+ * #include <math.h>
+ *
+ * int main(void)
+ * {
+ *   uint16_t x_center = (X_MAX_ABS - X_MIN_ABS)/2;
+ *   uint16_t y_center = (Y_MAX_ABS - Y_MIN_ABS)/2;
+ *   uint16_t x_screen = 0;
+ *   uint16_t y_screen = 0;
+ *   
+ *   uint32_t x_origin = x_center;
+ *   uint32_t y_origin = y_center;
+ *   uint32_t radius = 5000;
+ *   uint32_t angle = 0;
+ *
+ *   while (1)
+ *   {
+ *       x_screen = x_origin + cos((double)angle*3.14/180.0)*radius;
+ *       y_screen = y_origin + sin((double)angle*3.14/180.0)*radius;
+ *       
+ *       mouse.move(x_screen, y_screen);
+ *       angle += 3;
+ *       wait(0.01);
+ *   }
+ * }
+ *
+ * @endcode
+ */
+class USBMouse: public USBHID
+{
+    public:
+        
+        /**
+        *   Constructor
+        *
+        * @param mouse_type Mouse type: ABS_MOUSE (absolute mouse) or REL_MOUSE (relative mouse) (default: REL_MOUSE)
+        * @param vendor_id Your vendor_id (default: 0x1234)
+        * @param product_id Your product_id (default: 0x0001)
+        * @param product_release Your preoduct_release (default: 0x0001)
+        *
+        */
+        USBMouse(MOUSE_TYPE mouse_type = REL_MOUSE, uint16_t vendor_id = 0x1234, uint16_t product_id = 0x0001, uint16_t product_release = 0x0001): 
+            USBHID(vendor_id, product_id, product_release)
+            { 
+                button = 0;
+                this->mouse_type = mouse_type;
+            };
+        
+        /**
+        * Write a state of the mouse
+        *
+        * @param x x-axis position
+        * @param y y-axis position
+        * @param buttons buttons state (first bit represents MOUSE_LEFT, second bit MOUSE_RIGHT and third bit MOUSE_MIDDLE)
+        * @param z wheel state (>0 to scroll down, <0 to scroll up)
+        * @return true if there is no error, false otherwise
+        */
+        bool update(int16_t x, int16_t y, uint8_t buttons, int8_t z);
+        
+        
+        /**
+        * Move the cursor to (x, y)
+        *
+        * @param x-axis position
+        * @param y-axis position
+        * @return true if there is no error, false otherwise
+        */
+        bool move(int16_t x, int16_t y);
+        
+        /**
+        * Press one or several buttons
+        *
+        * @param button button state (ex: press(MOUSE_LEFT))
+        * @return true if there is no error, false otherwise
+        */
+        bool press(uint8_t button);
+        
+        /**
+        * Release one or several buttons
+        *
+        * @param button button state (ex: release(MOUSE_LEFT))
+        * @return true if there is no error, false otherwise
+        */
+        bool release(uint8_t button);
+        
+        /**
+        * Double click (MOUSE_LEFT)
+        *
+        * @return true if there is no error, false otherwise
+        */
+        bool doubleClick();
+        
+        /**
+        * Click
+        *
+        * @param button state of the buttons ( ex: clic(MOUSE_LEFT))
+        * @return true if there is no error, false otherwise
+        */
+        bool click(uint8_t button); 
+        
+        /**
+        * Scrolling
+        *
+        * @param z value of the wheel (>0 to go down, <0 to go up)
+        * @return true if there is no error, false otherwise
+        */
+        bool scroll(int8_t z);
+        
+        /*
+        * To define the report descriptor. Warning: this method has to store the length of the report descriptor in reportLength.
+        *
+        * @return pointer to the report descriptor
+        */
+        virtual uint8_t * ReportDesc();
+        
+    private:
+        MOUSE_TYPE mouse_type;
+        uint8_t button;
+        bool mouseSend(int8_t x, int8_t y, uint8_t buttons, int8_t z);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBHID/.svn/text-base/USBMouseKeyboard.cpp.svn-base	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,354 @@
+/* Keyboard_RelMouse.c */
+
+/* USB device example: Keyboard and a relative mouse */
+/* Copyright (c) 2011 ARM Limited. All rights reserved. */
+
+#include "stdint.h"
+
+#include "USBMouseKeyboard.h"
+
+uint8_t * USBMouseKeyboard::ReportDesc() {
+    if (mouse_type == REL_MOUSE) {
+        static uint8_t reportDescriptor[] = {
+            /* Keyboard */
+            USAGE_PAGE(1),      0x01,
+            USAGE(1),           0x06,
+            COLLECTION(1),      0x01,
+            REPORT_ID(1),       REPORT_ID_KEYBOARD,
+            USAGE_PAGE(1),      0x07,
+            USAGE_MINIMUM(1),       0xE0,
+            USAGE_MAXIMUM(1),       0xE7,
+            LOGICAL_MINIMUM(1),     0x00,
+            LOGICAL_MAXIMUM(1),     0x01,
+            REPORT_SIZE(1),     0x01,
+            REPORT_COUNT(1),    0x08,
+            INPUT(1),           0x02,
+            REPORT_COUNT(1),    0x01,
+            REPORT_SIZE(1),     0x08,
+            INPUT(1),           0x01,
+            REPORT_COUNT(1),    0x05,
+            REPORT_SIZE(1),     0x01,
+            USAGE_PAGE(1),      0x08,
+            USAGE_MINIMUM(1),       0x01,
+            USAGE_MAXIMUM(1),       0x05,
+            OUTPUT(1),          0x02,
+            REPORT_COUNT(1),    0x01,
+            REPORT_SIZE(1),     0x03,
+            OUTPUT(1),          0x01,
+            REPORT_COUNT(1),    0x06,
+            REPORT_SIZE(1),     0x08,
+            LOGICAL_MINIMUM(1),     0x00,
+            LOGICAL_MAXIMUM(2),     0xff, 0x00,
+            USAGE_PAGE(1),      0x07,
+            USAGE_MINIMUM(1),       0x00,
+            USAGE_MAXIMUM(2),       0xff, 0x00,
+            INPUT(1),           0x00,
+            END_COLLECTION(0),
+
+            /* Mouse */
+            USAGE_PAGE(1),      0x01,           /* Generic Desktop */
+            USAGE(1),           0x02,           /* Mouse */
+            COLLECTION(1),      0x01,           /* Application*/
+            USAGE(1),           0x01,           /* Pointer */
+            COLLECTION(1),      0x00,           /* Physical */
+            REPORT_ID(1),       REPORT_ID_MOUSE,
+            REPORT_COUNT(1),    0x03,
+            REPORT_SIZE(1),     0x01,
+            USAGE_PAGE(1),      0x09,           /* Buttons */
+            USAGE_MINIMUM(1),       0x1,
+            USAGE_MAXIMUM(1),       0x3,
+            LOGICAL_MINIMUM(1),     0x00,
+            LOGICAL_MAXIMUM(1),     0x01,
+            INPUT(1),           0x02,
+            REPORT_COUNT(1),    0x01,
+            REPORT_SIZE(1),     0x05,
+            INPUT(1),           0x01,
+            REPORT_COUNT(1),    0x03,
+            REPORT_SIZE(1),     0x08,
+            USAGE_PAGE(1),      0x01,
+            USAGE(1),           0x30,           /* X */
+            USAGE(1),           0x31,           /* Y */
+            USAGE(1),           0x38,           /* scroll */
+            LOGICAL_MINIMUM(1),     0x81,
+            LOGICAL_MAXIMUM(1),     0x7f,
+            INPUT(1),           0x06,
+            END_COLLECTION(0),
+            END_COLLECTION(0),
+
+
+        /* Media Control */
+        USAGE_PAGE(1), 0x0C,
+        USAGE(1), 0x01,
+        COLLECTION(1), 0x01,
+        REPORT_ID(1), REPORT_ID_VOLUME,
+        USAGE_PAGE(1), 0x0C,
+        LOGICAL_MINIMUM(1), 0x00,
+        LOGICAL_MAXIMUM(1), 0x01,
+        REPORT_SIZE(1), 0x01,
+        REPORT_COUNT(1), 0x07,
+        USAGE(1), 0xB5,             /* Next Track */
+        USAGE(1), 0xB6,             /* Previous Track */
+        USAGE(1), 0xB7,             /* Stop */
+        USAGE(1), 0xCD,             /* Play / Pause */
+        USAGE(1), 0xE2,             /* Mute */
+        USAGE(1), 0xE9,             /* Volume Up */
+        USAGE(1), 0xEA,             /* Volume Down */
+        INPUT(1), 0x02,             /* Input (Data, Variable, Absolute) */
+        REPORT_COUNT(1), 0x01,
+        INPUT(1), 0x01,
+        END_COLLECTION(0),
+        };
+        reportLength = sizeof(reportDescriptor);
+        return reportDescriptor;
+    } else if (mouse_type == ABS_MOUSE) {
+        static uint8_t reportDescriptor[] = {
+            
+        /* Keyboard */
+        USAGE_PAGE(1),      0x01,
+        USAGE(1),           0x06,
+        COLLECTION(1),      0x01,
+        REPORT_ID(1),       REPORT_ID_KEYBOARD,
+        USAGE_PAGE(1),      0x07,
+        USAGE_MINIMUM(1),       0xE0,
+        USAGE_MAXIMUM(1),       0xE7,
+        LOGICAL_MINIMUM(1),     0x00,
+        LOGICAL_MAXIMUM(1),     0x01,
+        REPORT_SIZE(1),     0x01,
+        REPORT_COUNT(1),    0x08,
+        INPUT(1),           0x02,
+        REPORT_COUNT(1),    0x01,
+        REPORT_SIZE(1),     0x08,
+        INPUT(1),           0x01,
+        REPORT_COUNT(1),    0x05,
+        REPORT_SIZE(1),     0x01,
+        USAGE_PAGE(1),      0x08,
+        USAGE_MINIMUM(1),       0x01,
+        USAGE_MAXIMUM(1),       0x05,
+        OUTPUT(1),          0x02,
+        REPORT_COUNT(1),    0x01,
+        REPORT_SIZE(1),     0x03,
+        OUTPUT(1),          0x01,
+        REPORT_COUNT(1),    0x06,
+        REPORT_SIZE(1),     0x08,
+        LOGICAL_MINIMUM(1),     0x00,
+        LOGICAL_MAXIMUM(2),     0xff, 0x00,
+        USAGE_PAGE(1),      0x07,
+        USAGE_MINIMUM(1),       0x00,
+        USAGE_MAXIMUM(2),       0xff, 0x00,
+        INPUT(1),           0x00,
+        END_COLLECTION(0),
+
+        /* Mouse */
+
+
+        USAGE_PAGE(1), 0x01,                    /* Generic Desktop */
+        USAGE(1), 0x02,                         /* Mouse */
+        COLLECTION(1), 0x01,                    /* Application*/
+        USAGE(1), 0x01,                         /* Pointer */
+        COLLECTION(1), 0x00,                    /* Physical */
+        REPORT_ID(1),       REPORT_ID_MOUSE,
+
+        USAGE_PAGE(1), 0x01,                /* Generic Desktop */
+        USAGE(1), 0x30,                     /* X */
+        USAGE(1), 0x31,                     /* Y */
+        LOGICAL_MINIMUM(1), 0x00,           /* 0 */
+        LOGICAL_MAXIMUM(2), 0xff, 0x7f,     /* 32767 */
+        REPORT_SIZE(1), 0x10,
+        REPORT_COUNT(1), 0x02,
+        INPUT(1), 0x02,                     /* Data, Variable, Absolute */
+
+        USAGE_PAGE(1), 0x01,                /* Generic Desktop */
+        USAGE(1), 0x38,                     /* scroll */
+        LOGICAL_MINIMUM(1), 0x81,           /* -127 */
+        LOGICAL_MAXIMUM(1), 0x7f,           /* 127 */
+        REPORT_SIZE(1), 0x08,
+        REPORT_COUNT(1), 0x01,
+        INPUT(1), 0x06,                     /* Data, Variable, Relative */
+
+        USAGE_PAGE(1), 0x09,                /* Buttons */
+        USAGE_MINIMUM(1), 0x01,
+        USAGE_MAXIMUM(1), 0x03,
+        LOGICAL_MINIMUM(1), 0x00,           /* 0 */
+        LOGICAL_MAXIMUM(1), 0x01,           /* 1 */
+        REPORT_COUNT(1), 0x03,
+        REPORT_SIZE(1), 0x01,
+        INPUT(1), 0x02,                     /* Data, Variable, Absolute */
+        REPORT_COUNT(1), 0x01,
+        REPORT_SIZE(1), 0x05,
+        INPUT(1), 0x01,                     /* Constant */
+
+        END_COLLECTION(0),
+        END_COLLECTION(0),
+
+
+
+
+        /* Media Control */
+        USAGE_PAGE(1), 0x0C,
+        USAGE(1), 0x01,
+        COLLECTION(1), 0x01,
+        REPORT_ID(1), REPORT_ID_VOLUME,
+        USAGE_PAGE(1), 0x0C,
+        LOGICAL_MINIMUM(1), 0x00,
+        LOGICAL_MAXIMUM(1), 0x01,
+        REPORT_SIZE(1), 0x01,
+        REPORT_COUNT(1), 0x07,
+        USAGE(1), 0xB5,             /* Next Track */
+        USAGE(1), 0xB6,             /* Previous Track */
+        USAGE(1), 0xB7,             /* Stop */
+        USAGE(1), 0xCD,             /* Play / Pause */
+        USAGE(1), 0xE2,             /* Mute */
+        USAGE(1), 0xE9,             /* Volume Up */
+        USAGE(1), 0xEA,             /* Volume Down */
+        INPUT(1), 0x02,             /* Input (Data, Variable, Absolute) */
+        REPORT_COUNT(1), 0x01,
+        INPUT(1), 0x01,
+        END_COLLECTION(0),
+        };
+        reportLength = sizeof(reportDescriptor);
+        return reportDescriptor;
+    }
+
+    return NULL;
+}
+
+bool USBMouseKeyboard::update(int16_t x, int16_t y, uint8_t button, int8_t z) {
+    switch (mouse_type) {
+        case REL_MOUSE:
+            while (x > 127) {
+                if (!mouseSend(127, 0, button, z)) return false;
+                x = x - 127;
+            }
+            while (x < -128) {
+                if (!mouseSend(-128, 0, button, z)) return false;
+                x = x + 128;
+            }
+            while (y > 127) {
+                if (!mouseSend(0, 127, button, z)) return false;
+                y = y - 127;
+            }
+            while (y < -128) {
+                if (!mouseSend(0, -128, button, z)) return false;
+                y = y + 128;
+            }
+            return mouseSend(x, y, button, z);
+        case ABS_MOUSE:
+            HID_REPORT report;
+
+            report.data[0] = REPORT_ID_MOUSE;
+            report.data[1] = x & 0xff;
+            report.data[2] = (x >> 8) & 0xff;
+            report.data[3] = y & 0xff;
+            report.data[4] = (y >> 8) & 0xff;
+            report.data[5] = -z;
+            report.data[6] = button & 0x07;
+
+            report.length = 7;
+
+            return USBHID_send(EPINT_IN, &report);
+        default:
+            return false;
+    }
+}
+
+bool USBMouseKeyboard::mouseSend(int8_t x, int8_t y, uint8_t buttons, int8_t z) {
+    HID_REPORT report;
+    report.data[0] = REPORT_ID_MOUSE;
+    report.data[1] = buttons & 0x07;
+    report.data[2] = x;
+    report.data[3] = y;
+    report.data[4] = -z; /* >0 to scroll down, <0 to scroll up */
+
+    report.length = 5;
+
+    return USBHID_send(EPINT_IN, &report);
+}
+
+bool USBMouseKeyboard::move(int16_t x, int16_t y) {
+    return update(x, y, button, 0);
+}
+
+bool USBMouseKeyboard::scroll(int8_t z) {
+    return update(0, 0, button, z);
+}
+
+bool USBMouseKeyboard::doubleClick() {
+    if (!click(MOUSE_LEFT))
+        return false;
+    wait(0.1);
+    return click(MOUSE_LEFT);
+}
+
+bool USBMouseKeyboard::click(uint8_t button) {
+    if (!update(0, 0, button, 0))
+        return false;
+    wait(0.01);
+    return update(0, 0, 0, 0);
+}
+
+bool USBMouseKeyboard::press(uint8_t button_) {
+    button = button_ & 0x07;
+    return update(0, 0, button, 0);
+}
+
+bool USBMouseKeyboard::release(uint8_t button_) {
+    button = (button & (~button_)) & 0x07;
+    return update(0, 0, button, 0);
+}
+
+int USBMouseKeyboard::_putc(int c) {
+    return keyCode(keymap[c].modifier, c);
+}
+
+bool USBMouseKeyboard::keyCode(uint8_t modifier, uint8_t key) {
+    /* Send a simulated keyboard keypress. Returns true if successful. */
+
+    HID_REPORT report;
+
+    report.data[0] = REPORT_ID_KEYBOARD;
+    report.data[1] = modifier;
+    report.data[2] = 0;
+    report.data[3] = keymap[key].usage;
+    report.data[4] = 0;
+    report.data[5] = 0;
+    report.data[6] = 0;
+    report.data[7] = 0;
+    report.data[8] = 0;
+
+    report.length = 9;
+
+    if (!USBHID_send(EPINT_IN, &report)) {
+        return false;
+    }
+
+    report.data[1] = 0;
+    report.data[3] = 0;
+
+    if (!USBHID_send(EPINT_IN, &report)) {
+        return false;
+    }
+
+    return true;
+
+}
+
+
+bool USBMouseKeyboard::mediaControl(MEDIA_KEY key) {
+    HID_REPORT report;
+
+    report.data[0] = REPORT_ID_VOLUME;
+    report.data[1] = (1 << key) & 0x7f;
+
+    report.length = 2;
+
+    return USBHID_send(EPINT_IN, &report);
+}
+
+
+
+
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBHID/.svn/text-base/USBMouseKeyboard.h.svn-base	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,189 @@
+/* USBMouseKeyboard.h */
+/* USB device example: Keyboard with a relative mouse */
+/* Copyright (c) 2011 ARM Limited. All rights reserved. */
+
+#ifndef _USB_KEYBOARD_REL_MOUSE_
+#define _USB_KEYBOARD_REL_MOUSE_
+
+#define REPORT_ID_KEYBOARD 1
+#define REPORT_ID_MOUSE 2
+#define REPORT_ID_VOLUME 3
+
+#include "USBMouse.h"
+#include "USBKeyboard.h"
+#include "Stream.h"
+#include "USBHID.h"
+
+/** USB device: a keyboard and a mouse
+ *
+ * Warning: you can only instantiate one instance of a USB device: USBMouse, USBKeyboard or USBMouseKeyboard.
+ *
+ * Example: A keyboard with a relative mouse
+ * @code
+ *
+ * #include "mbed.h"
+ * #include "USBMouseKeyboard.h"
+ *
+ * USBMouseKeyboard key_mouse;
+ *
+ * int main(void)
+ * {
+ *   while(1)
+ *   {
+ *       key_mouse.move(20, 0);
+ *       key_mouse.puts("Hello From MBED\r\n");
+ *       wait(1);
+ *   }
+ * }
+ * @endcode
+ *
+ *
+ * Example: A keyboard with an absolute mouse
+ * @code
+ *
+ * #include "mbed.h"
+ * #include "USBMouseKeyboard.h"
+ *
+ * USBMouseKeyboard key_mouse(ABS_MOUSE);
+ *
+ * int main(void)
+ * {
+ *   while(1)
+ *   {
+ *       key_mouse.move(X_MAX_ABS/2, Y_MAX_ABS/2);
+ *       key_mouse.puts("Hello from MBED\r\n");
+ *       wait(1);
+ *   }
+ * }
+ * @endcode
+ */
+class USBMouseKeyboard: public USBHID, public Stream
+{
+    public:
+    
+        /**
+        *   Constructor
+        *
+        * @param mouse_type Mouse type: ABS_MOUSE (absolute mouse) or REL_MOUSE (relative mouse) (default: REL_MOUSE)
+        * @param vendor_id Your vendor_id (default: 0x1234)
+        * @param product_id Your product_id (default: 0x0001)
+        * @param product_release Your preoduct_release (default: 0x0001)
+        *
+        */
+        USBMouseKeyboard(MOUSE_TYPE mouse_type = REL_MOUSE, uint16_t vendor_id = 0x1234, uint16_t product_id = 0x0010, uint16_t product_release = 0x0001): 
+            USBHID(vendor_id, product_id, product_release)
+            {
+                button = 0;
+                this->mouse_type = mouse_type;
+            };
+        
+        
+        /**
+        * Write a state of the mouse
+        *
+        * @param x x-axis position
+        * @param y y-axis position
+        * @param buttons buttons state (first bit represents MOUSE_LEFT, second bit MOUSE_RIGHT and third bit MOUSE_MIDDLE)
+        * @param z wheel state (>0 to scroll down, <0 to scroll up)
+        * @return true if there is no error, false otherwise
+        */
+        bool update(int16_t x, int16_t y, uint8_t buttons, int8_t z);
+        
+        
+        /**
+        * Move the cursor to (x, y)
+        *
+        * @param x x-axis position
+        * @param y y-axis position
+        * @return true if there is no error, false otherwise
+        */
+        bool move(int16_t x, int16_t y);
+        
+        /**
+        * Press one or several buttons
+        *
+        * @param button button state (ex: press(MOUSE_LEFT))
+        * @return true if there is no error, false otherwise
+        */
+        bool press(uint8_t button);
+        
+        /**
+        * Release one or several buttons
+        *
+        * @param button button state (ex: release(MOUSE_LEFT))
+        * @return true if there is no error, false otherwise
+        */
+        bool release(uint8_t button);
+        
+        /**
+        * Double click (MOUSE_LEFT)
+        *
+        * @return true if there is no error, false otherwise
+        */
+        bool doubleClick();
+        
+        /**
+        * Click
+        *
+        * @param button state of the buttons ( ex: clic(MOUSE_LEFT))
+        * @return true if there is no error, false otherwise
+        */
+        bool click(uint8_t button); 
+        
+        /**
+        * Scrolling
+        *
+        * @param z value of the wheel (>0 to go down, <0 to go up)
+        * @return true if there is no error, false otherwise
+        */
+        bool scroll(int8_t z);
+        
+        /**
+        * To send a character defined by a modifier(CTRL, SHIFT, ALT) and the key
+        *
+        * @code
+        * //To send CTRL + s (save)
+        *  keyboard.keyCode(CTRL, 's');
+        * @endcode
+        *
+        * @param modifier bit 0: CTRL, bit 1: SHIFT, bit 2: ALT
+        * @param key character to send
+        * @return true if there is no error, false otherwise
+        */
+        bool keyCode(uint8_t modifier, uint8_t key);
+        
+        /**
+        * Send a character
+        *
+        * @param c character to be sent
+        * @return true if there is no error, false otherwise
+        */
+        virtual int _putc(int c);
+        
+        /**
+        * Control media keys
+        *
+        * @param key media key pressed (KEY_NEXT_TRACK, KEY_PREVIOUS_TRACK, KEY_STOP, KEY_PLAY_PAUSE, KEY_MUTE, KEY_VOLUME_UP, KEY_VOLUME_DOWN)
+        * @return true if there is no error, false otherwise
+        */
+        bool mediaControl(MEDIA_KEY key);
+        
+        /*
+        * To define the report descriptor. Warning: this method has to store the length of the report descriptor in reportLength.
+        *
+        * @return pointer to the report descriptor
+        */
+        virtual uint8_t * ReportDesc();
+        
+        
+    private:
+        bool mouseWrite(int8_t x, int8_t y, uint8_t buttons, int8_t z);
+        MOUSE_TYPE mouse_type;
+        uint8_t button;
+        bool mouseSend(int8_t x, int8_t y, uint8_t buttons, int8_t z);
+        
+        //dummy otherwise it doesn,t compile (we must define all methods of an abstract class)
+        virtual int _getc() { return -1;}
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBHID/USBHID.cpp	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,274 @@
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include "stdint.h"
+#include "USBBusInterface.h"
+#include "USBHID.h"
+
+
+USBHID::USBHID(uint8_t output_report_length, uint8_t input_report_length, uint16_t vendor_id, uint16_t product_id, uint16_t product_release): USBDevice(vendor_id, product_id, product_release)
+{
+    output_length = output_report_length;
+    input_length = input_report_length;
+    USBDevice::connect();
+}
+
+
+bool USBHID::send(HID_REPORT *report)
+{
+    return write(EPINT_IN, report->data, report->length, MAX_HID_REPORT_SIZE);
+}
+
+
+bool USBHID::read(HID_REPORT *report)
+{
+    uint16_t bytesRead = 0;
+    bool result;
+    result = USBDevice::read(EPINT_OUT, report->data, &bytesRead, MAX_HID_REPORT_SIZE);
+    if(!readStart(EPINT_OUT, MAX_HID_REPORT_SIZE))
+        return false;
+    report->length = bytesRead;
+    return result;
+}
+
+
+bool USBHID::readNB(HID_REPORT *report)
+{
+    uint16_t bytesRead = 0;
+    bool result;
+    result = USBDevice::readNB(EPINT_OUT, report->data, &bytesRead, MAX_HID_REPORT_SIZE);
+    report->length = bytesRead;
+    if(!readStart(EPINT_OUT, MAX_HID_REPORT_SIZE))
+        return false;
+    return result;
+}
+
+
+uint16_t USBHID::reportDescLength() {
+    reportDesc();
+    return reportLength;
+}
+
+
+
+//
+//  Route callbacks from lower layers to class(es)
+//
+
+
+// Called in ISR context
+// Called by USBDevice on Endpoint0 request
+// This is used to handle extensions to standard requests
+// and class specific requests
+// Return true if class handles this request
+bool USBHID::USBCallback_request() {
+    bool success = false;
+    CONTROL_TRANSFER * transfer = getTransferPtr();
+    uint8_t *hidDescriptor;
+
+    // Process additional standard requests
+
+    if ((transfer->setup.bmRequestType.Type == STANDARD_TYPE))
+    {
+        switch (transfer->setup.bRequest)
+        {
+            case GET_DESCRIPTOR:
+                switch (DESCRIPTOR_TYPE(transfer->setup.wValue))
+                {
+                    case REPORT_DESCRIPTOR:
+                        if ((reportDesc() != NULL) \
+                            && (reportDescLength() != 0))
+                        {
+                            transfer->remaining = reportDescLength();
+                            transfer->ptr = reportDesc();
+                            transfer->direction = DEVICE_TO_HOST;
+                            success = true;
+                        }
+                        break;
+                    case HID_DESCRIPTOR:
+                            // Find the HID descriptor, after the configuration descriptor
+                            hidDescriptor = findDescriptor(HID_DESCRIPTOR);
+                            if (hidDescriptor != NULL)
+                            {
+                                transfer->remaining = HID_DESCRIPTOR_LENGTH;
+                                transfer->ptr = hidDescriptor;
+                                transfer->direction = DEVICE_TO_HOST;
+                                success = true;
+                            }
+                            break;
+                     
+                    default:
+                        break;
+                }
+                break;
+            default:
+                break;
+        }
+    }
+
+    // Process class-specific requests
+
+    if (transfer->setup.bmRequestType.Type == CLASS_TYPE)
+    {
+        switch (transfer->setup.bRequest)
+        {
+             case SET_REPORT:
+                // First byte will be used for report ID
+                outputReport.data[0] = transfer->setup.wValue & 0xff;
+                outputReport.length = transfer->setup.wLength + 1;
+
+                transfer->remaining = sizeof(outputReport.data) - 1;
+                transfer->ptr = &outputReport.data[1];
+                transfer->direction = HOST_TO_DEVICE;
+                transfer->notify = true;
+                success = true;
+            default:
+                break;
+        }
+    }
+
+    return success;
+}
+
+
+// Called in ISR context
+// Called by USBDevice on Endpoint0 request completion
+// if the 'notify' flag has been set to true
+// In this case it is used to indicate that a HID report has
+// been received from the host on endpoint 0
+void USBHID::USBCallback_requestCompleted() {
+    HID_callbackSetReport(&outputReport);
+}
+
+#define DEFAULT_CONFIGURATION (1)
+
+
+// Called in ISR context
+// Set configuration. Return false if the
+// configuration is not supported
+bool USBHID::USBCallback_setConfiguration(uint8_t configuration) {
+    if (configuration != DEFAULT_CONFIGURATION) {
+        return false;
+    }
+
+    // Configure endpoints > 0
+    addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);
+    addEndpoint(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
+
+    // We activate the endpoint to be able to recceive data
+    readStart(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
+    return true;
+}
+
+uint8_t * USBHID::stringIinterfaceDesc() {
+    static uint8_t stringIinterfaceDescriptor[] = {
+        0x08,               //bLength
+        STRING_DESCRIPTOR,  //bDescriptorType 0x03
+        'H',0,'I',0,'D',0,  //bString iInterface - HID
+    };
+    return stringIinterfaceDescriptor;
+}
+
+uint8_t * USBHID::stringIproductDesc() {
+    static uint8_t stringIproductDescriptor[] = {
+        0x16,                                                       //bLength
+        STRING_DESCRIPTOR,                                          //bDescriptorType 0x03
+        'H',0,'I',0,'D',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0 //bString iProduct - HID device
+    };
+    return stringIproductDescriptor;
+}
+
+
+
+uint8_t * USBHID::reportDesc() {
+    static uint8_t reportDescriptor[] = {
+        0x06, LSB(0xFFAB), MSB(0xFFAB),
+        0x0A, LSB(0x0200), MSB(0x0200),
+        0xA1, 0x01,         // Collection 0x01
+        0x75, 0x08,         // report size = 8 bits
+        0x15, 0x00,         // logical minimum = 0
+        0x26, 0xFF, 0x00,   // logical maximum = 255
+        0x95, input_length,           // report count
+        0x09, 0x01,         // usage
+        0x81, 0x02,         // Input (array)
+        0x95, output_length,           // report count
+        0x09, 0x02,         // usage
+        0x91, 0x02,         // Output (array)
+        0xC0                // end collection
+
+    };
+    reportLength = sizeof(reportDescriptor);
+    return reportDescriptor;
+}
+
+#define DEFAULT_CONFIGURATION (1)
+#define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
+                               + (1 * INTERFACE_DESCRIPTOR_LENGTH) \
+                               + (1 * HID_DESCRIPTOR_LENGTH) \
+                               + (2 * ENDPOINT_DESCRIPTOR_LENGTH))
+
+uint8_t * USBHID::configurationDesc() {
+    static uint8_t configurationDescriptor[] = {
+        CONFIGURATION_DESCRIPTOR_LENGTH,// bLength
+        CONFIGURATION_DESCRIPTOR,       // bDescriptorType
+        LSB(TOTAL_DESCRIPTOR_LENGTH),   // wTotalLength (LSB)
+        MSB(TOTAL_DESCRIPTOR_LENGTH),   // wTotalLength (MSB)
+        0x01,                           // bNumInterfaces
+        DEFAULT_CONFIGURATION,          // bConfigurationValue
+        0x00,                           // iConfiguration
+        C_RESERVED | C_SELF_POWERED,    // bmAttributes
+        C_POWER(0),                     // bMaxPower
+
+        INTERFACE_DESCRIPTOR_LENGTH,    // bLength
+        INTERFACE_DESCRIPTOR,           // bDescriptorType
+        0x00,                           // bInterfaceNumber
+        0x00,                           // bAlternateSetting
+        0x02,                           // bNumEndpoints
+        HID_CLASS,                      // bInterfaceClass
+        HID_SUBCLASS_NONE,              // bInterfaceSubClass
+        HID_PROTOCOL_NONE,              // bInterfaceProtocol
+        0x00,                           // iInterface
+
+        HID_DESCRIPTOR_LENGTH,          // bLength
+        HID_DESCRIPTOR,                 // bDescriptorType
+        LSB(HID_VERSION_1_11),          // bcdHID (LSB)
+        MSB(HID_VERSION_1_11),          // bcdHID (MSB)
+        0x00,                           // bCountryCode
+        0x01,                           // bNumDescriptors
+        REPORT_DESCRIPTOR,              // bDescriptorType
+        LSB(this->reportDescLength()),  // wDescriptorLength (LSB)
+        MSB(this->reportDescLength()),  // wDescriptorLength (MSB)
+
+        ENDPOINT_DESCRIPTOR_LENGTH,     // bLength
+        ENDPOINT_DESCRIPTOR,            // bDescriptorType
+        PHY_TO_DESC(EPINT_IN),          // bEndpointAddress
+        E_INTERRUPT,                    // bmAttributes
+        LSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (LSB)
+        MSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (MSB)
+        10,                             // bInterval (milliseconds)
+
+        ENDPOINT_DESCRIPTOR_LENGTH,     // bLength
+        ENDPOINT_DESCRIPTOR,            // bDescriptorType
+        PHY_TO_DESC(EPINT_OUT),          // bEndpointAddress
+        E_INTERRUPT,                    // bmAttributes
+        LSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (LSB)
+        MSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (MSB)
+        10,                             // bInterval (milliseconds)
+    };
+    return configurationDescriptor;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBHID/USBHID.h	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,170 @@
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef USB_HID_H
+#define USB_HID_H
+
+/* These headers are included for child class. */
+#include "USBEndpoints.h"
+#include "USBDescriptor.h"
+#include "USBDevice_Types.h"
+
+#include "USBHID_Types.h"
+#include "USBDevice.h"
+
+
+/**
+ * USBHID example
+ * @code
+ * #include "mbed.h"
+ * #include "USBHID.h"
+ *
+ * USBHID hid;
+ * HID_REPORT recv;
+ * BusOut leds(LED1,LED2,LED3,LED4);
+ *
+ * int main(void) {
+ *    while (1) {
+ *        hid.read(&recv);
+ *        leds = recv.data[0];
+ *    }
+ * }
+ * @endcode
+ */
+
+class USBHID: public USBDevice {
+public:
+
+    /**
+    * Constructor
+    *
+    * @param output_report_length Maximum length of a sent report (up to 64 bytes) (default: 64 bytes)
+    * @param input_report_length Maximum length of a received report (up to 64 bytes) (default: 64 bytes)
+    * @param vendor_id Your vendor_id
+    * @param product_id Your product_id
+    * @param product_release Your preoduct_release
+    */
+    USBHID(uint8_t output_report_length = 64, uint8_t input_report_length = 64, uint16_t vendor_id = 0x1234, uint16_t product_id = 0x0006, uint16_t product_release = 0x0001);
+
+
+    /**
+    * Send a Report
+    *
+    * @param report Report which will be sent (a report is defined by all data and the length)
+    * @returns true if successful
+    */
+    bool send(HID_REPORT *report);
+    
+    /**
+    * Read a report: blocking
+    *
+    * @param report pointer to the report to fill
+    * @returns true if successful
+    */
+    bool read(HID_REPORT * report);
+    
+    /**
+    * Read a report: non blocking
+    *
+    * @param report pointer to the report to fill
+    * @returns true if successful
+    */
+    bool readNB(HID_REPORT * report);
+
+protected:
+    uint16_t reportLength;
+    
+    /*
+    * Get the Report descriptor
+    *
+    * @returns pointer to the report descriptor
+    */
+    virtual uint8_t * reportDesc();
+
+    /*
+    * Get the length of the report descriptor
+    *
+    * @returns the length of the report descriptor
+    */
+    virtual uint16_t reportDescLength();
+
+    /*
+    * Get string product descriptor
+    *
+    * @returns pointer to the string product descriptor
+    */
+    virtual uint8_t * stringIproductDesc();
+    
+    /*
+    * Get string interface descriptor
+    *
+    * @returns pointer to the string interface descriptor
+    */
+    virtual uint8_t * stringIinterfaceDesc();
+    
+    /*
+    * Get configuration descriptor
+    *
+    * @returns pointer to the configuration descriptor
+    */
+    virtual uint8_t * configurationDesc();
+
+
+    /*
+    * HID Report received by SET_REPORT request. Warning: Called in ISR context
+    * First byte of data will be the report ID
+    *
+    * @param report Data and length received
+    */
+    virtual void HID_callbackSetReport(HID_REPORT *report){};
+
+
+    /*
+    * Called by USBDevice on Endpoint0 request. Warning: Called in ISR context
+    * This is used to handle extensions to standard requests
+    * and class specific requests
+    *
+    * @returns true if class handles this request
+    */
+    virtual bool USBCallback_request();
+
+    /*
+    * Called by USBDevice on Endpoint0 request completion
+    * if the 'notify' flag has been set to true. Warning: Called in ISR context
+    *
+    * In this case it is used to indicate that a HID report has
+    * been received from the host on endpoint 0
+    */
+    virtual void USBCallback_requestCompleted();
+
+    /*
+    * Called by USBDevice layer. Set configuration of the device.
+    * For instance, you can add all endpoints that you need on this function.
+    *
+    * @param configuration Number of the configuration
+    * @returns true if class handles this request
+    */
+    virtual bool USBCallback_setConfiguration(uint8_t configuration);
+
+private:
+    HID_REPORT outputReport;
+    uint8_t output_length;
+    uint8_t input_length;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBHID/USBHID_Types.h	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,91 @@
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef USBCLASS_HID_TYPES
+#define USBCLASS_HID_TYPES
+
+#include <stdint.h>
+
+/* */
+#define HID_VERSION_1_11    (0x0111)
+
+/* HID Class */
+#define HID_CLASS           (3)
+#define HID_SUBCLASS_NONE   (0)
+#define HID_PROTOCOL_NONE   (0)
+
+/* Descriptors */
+#define HID_DESCRIPTOR          (33)
+#define HID_DESCRIPTOR_LENGTH   (0x09)
+#define REPORT_DESCRIPTOR       (34)
+
+/* Class requests */
+#define GET_REPORT (0x1)
+#define GET_IDLE   (0x2)
+#define SET_REPORT (0x9)
+#define SET_IDLE   (0xa)
+
+/* HID Class Report Descriptor */
+/* Short items: size is 0, 1, 2 or 3 specifying 0, 1, 2 or 4 (four) bytes */
+/* of data as per HID Class standard */
+
+/* Main items */
+#define INPUT(size)             (0x80 | size)
+#define OUTPUT(size)            (0x90 | size)
+#define FEATURE(size)           (0xb0 | size)
+#define COLLECTION(size)        (0xa0 | size)
+#define END_COLLECTION(size)    (0xc0 | size)
+
+/* Global items */
+#define USAGE_PAGE(size)        (0x04 | size)
+#define LOGICAL_MINIMUM(size)   (0x14 | size)
+#define LOGICAL_MAXIMUM(size)   (0x24 | size)
+#define PHYSICAL_MINIMUM(size)  (0x34 | size)
+#define PHYSICAL_MAXIMUM(size)  (0x44 | size)
+#define UNIT_EXPONENT(size)     (0x54 | size)
+#define UNIT(size)              (0x64 | size)
+#define REPORT_SIZE(size)       (0x74 | size)
+#define REPORT_ID(size)         (0x84 | size)
+#define REPORT_COUNT(size)      (0x94 | size)
+#define PUSH(size)              (0xa4 | size)
+#define POP(size)               (0xb4 | size)
+
+/* Local items */
+#define USAGE(size)                 (0x08 | size)
+#define USAGE_MINIMUM(size)         (0x18 | size)
+#define USAGE_MAXIMUM(size)         (0x28 | size)
+#define DESIGNATOR_INDEX(size)      (0x38 | size)
+#define DESIGNATOR_MINIMUM(size)    (0x48 | size)
+#define DESIGNATOR_MAXIMUM(size)    (0x58 | size)
+#define STRING_INDEX(size)          (0x78 | size)
+#define STRING_MINIMUM(size)        (0x88 | size)
+#define STRING_MAXIMUM(size)        (0x98 | size)
+#define DELIMITER(size)             (0xa8 | size)
+
+/* HID Report */
+/* Where report IDs are used the first byte of 'data' will be the */
+/* report ID and 'length' will include this report ID byte. */
+
+#define MAX_HID_REPORT_SIZE (64)
+
+typedef struct {
+    uint32_t length;
+    uint8_t data[MAX_HID_REPORT_SIZE];
+} HID_REPORT;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBHID/USBKeyboard.cpp	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,486 @@
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include "stdint.h"
+
+#include "USBKeyboard.h"
+
+#define REPORT_ID_KEYBOARD 1
+#define REPORT_ID_VOLUME   3
+
+
+typedef struct {
+    unsigned char usage;
+    unsigned char modifier;
+} KEYMAP;
+
+#ifdef US_KEYBOARD
+/* US keyboard (as HID standard) */
+#define KEYMAP_SIZE (148)
+const KEYMAP keymap[KEYMAP_SIZE] = {
+    {0, 0},             /* NUL */
+    {0, 0},             /* SOH */
+    {0, 0},             /* STX */
+    {0, 0},             /* ETX */
+    {0, 0},             /* EOT */
+    {0, 0},             /* ENQ */
+    {0, 0},             /* ACK */
+    {0, 0},             /* BEL */
+    {0x2a, 0},          /* BS  */  /* Keyboard Delete (Backspace) */
+    {0x2b, 0},          /* TAB */  /* Keyboard Tab */
+    {0x28, 0},          /* LF  */  /* Keyboard Return (Enter) */
+    {0, 0},             /* VT  */
+    {0, 0},             /* FF  */
+    {0, 0},             /* CR  */
+    {0, 0},             /* SO  */
+    {0, 0},             /* SI  */
+    {0, 0},             /* DEL */
+    {0, 0},             /* DC1 */
+    {0, 0},             /* DC2 */
+    {0, 0},             /* DC3 */
+    {0, 0},             /* DC4 */
+    {0, 0},             /* NAK */
+    {0, 0},             /* SYN */
+    {0, 0},             /* ETB */
+    {0, 0},             /* CAN */
+    {0, 0},             /* EM  */
+    {0, 0},             /* SUB */
+    {0, 0},             /* ESC */
+    {0, 0},             /* FS  */
+    {0, 0},             /* GS  */
+    {0, 0},             /* RS  */
+    {0, 0},             /* US  */
+    {0x2c, 0},          /*   */
+    {0x1e, KEY_SHIFT},      /* ! */
+    {0x34, KEY_SHIFT},      /* " */
+    {0x20, KEY_SHIFT},      /* # */
+    {0x21, KEY_SHIFT},      /* $ */
+    {0x22, KEY_SHIFT},      /* % */
+    {0x24, KEY_SHIFT},      /* & */
+    {0x34, 0},          /* ' */
+    {0x26, KEY_SHIFT},      /* ( */
+    {0x27, KEY_SHIFT},      /* ) */
+    {0x25, KEY_SHIFT},      /* * */
+    {0x2e, KEY_SHIFT},      /* + */
+    {0x36, 0},          /* , */
+    {0x2d, 0},          /* - */
+    {0x37, 0},          /* . */
+    {0x38, 0},          /* / */
+    {0x27, 0},          /* 0 */
+    {0x1e, 0},          /* 1 */
+    {0x1f, 0},          /* 2 */
+    {0x20, 0},          /* 3 */
+    {0x21, 0},          /* 4 */
+    {0x22, 0},          /* 5 */
+    {0x23, 0},          /* 6 */
+    {0x24, 0},          /* 7 */
+    {0x25, 0},          /* 8 */
+    {0x26, 0},          /* 9 */
+    {0x33, KEY_SHIFT},      /* : */
+    {0x33, 0},          /* ; */
+    {0x36, KEY_SHIFT},      /* < */
+    {0x2e, 0},          /* = */
+    {0x37, KEY_SHIFT},      /* > */
+    {0x38, KEY_SHIFT},      /* ? */
+    {0x1f, KEY_SHIFT},      /* @ */
+    {0x04, KEY_SHIFT},      /* A */
+    {0x05, KEY_SHIFT},      /* B */
+    {0x06, KEY_SHIFT},      /* C */
+    {0x07, KEY_SHIFT},      /* D */
+    {0x08, KEY_SHIFT},      /* E */
+    {0x09, KEY_SHIFT},      /* F */
+    {0x0a, KEY_SHIFT},      /* G */
+    {0x0b, KEY_SHIFT},      /* H */
+    {0x0c, KEY_SHIFT},      /* I */
+    {0x0d, KEY_SHIFT},      /* J */
+    {0x0e, KEY_SHIFT},      /* K */
+    {0x0f, KEY_SHIFT},      /* L */
+    {0x10, KEY_SHIFT},      /* M */
+    {0x11, KEY_SHIFT},      /* N */
+    {0x12, KEY_SHIFT},      /* O */
+    {0x13, KEY_SHIFT},      /* P */
+    {0x14, KEY_SHIFT},      /* Q */
+    {0x15, KEY_SHIFT},      /* R */
+    {0x16, KEY_SHIFT},      /* S */
+    {0x17, KEY_SHIFT},      /* T */
+    {0x18, KEY_SHIFT},      /* U */
+    {0x19, KEY_SHIFT},      /* V */
+    {0x1a, KEY_SHIFT},      /* W */
+    {0x1b, KEY_SHIFT},      /* X */
+    {0x1c, KEY_SHIFT},      /* Y */
+    {0x1d, KEY_SHIFT},      /* Z */
+    {0x2f, 0},          /* [ */
+    {0x31, 0},          /* \ */
+    {0x30, 0},          /* ] */
+    {0x23, KEY_SHIFT},      /* ^ */
+    {0x2d, KEY_SHIFT},      /* _ */
+    {0x35, 0},          /* ` */
+    {0x04, 0},          /* a */
+    {0x05, 0},          /* b */
+    {0x06, 0},          /* c */
+    {0x07, 0},          /* d */
+    {0x08, 0},          /* e */
+    {0x09, 0},          /* f */
+    {0x0a, 0},          /* g */
+    {0x0b, 0},          /* h */
+    {0x0c, 0},          /* i */
+    {0x0d, 0},          /* j */
+    {0x0e, 0},          /* k */
+    {0x0f, 0},          /* l */
+    {0x10, 0},          /* m */
+    {0x11, 0},          /* n */
+    {0x12, 0},          /* o */
+    {0x13, 0},          /* p */
+    {0x14, 0},          /* q */
+    {0x15, 0},          /* r */
+    {0x16, 0},          /* s */
+    {0x17, 0},          /* t */
+    {0x18, 0},          /* u */
+    {0x19, 0},          /* v */
+    {0x1a, 0},          /* w */
+    {0x1b, 0},          /* x */
+    {0x1c, 0},          /* y */
+    {0x1d, 0},          /* z */
+    {0x2f, KEY_SHIFT},      /* { */
+    {0x31, KEY_SHIFT},      /* | */
+    {0x30, KEY_SHIFT},      /* } */
+    {0x35, KEY_SHIFT},      /* ~ */
+    {0,0},              /* DEL */
+
+    {0x3a, 0},          /* F1 */
+    {0x3b, 0},          /* F2 */
+    {0x3c, 0},          /* F3 */
+    {0x3d, 0},          /* F4 */
+    {0x3e, 0},          /* F5 */
+    {0x3f, 0},          /* F6 */
+    {0x40, 0},          /* F7 */
+    {0x41, 0},          /* F8 */
+    {0x42, 0},          /* F9 */
+    {0x43, 0},          /* F10 */
+    {0x44, 0},          /* F11 */
+    {0x45, 0},          /* F12 */
+
+    {0x46, 0},          /* PRINT_SCREEN */
+    {0x47, 0},          /* SCROLL_LOCK */
+    {0x39, 0},          /* CAPS_LOCK */
+    {0x53, 0},          /* NUM_LOCK */
+    {0x49, 0},          /* INSERT */
+    {0x4a, 0},          /* HOME */
+    {0x4b, 0},          /* PAGE_UP */
+    {0x4e, 0},          /* PAGE_DOWN */
+};
+
+#else
+/* UK keyboard */
+#define KEYMAP_SIZE (148)
+const KEYMAP keymap[KEYMAP_SIZE] = {
+    {0, 0},             /* NUL */
+    {0, 0},             /* SOH */
+    {0, 0},             /* STX */
+    {0, 0},             /* ETX */
+    {0, 0},             /* EOT */
+    {0, 0},             /* ENQ */
+    {0, 0},             /* ACK */
+    {0, 0},             /* BEL */
+    {0x2a, 0},          /* BS  */  /* Keyboard Delete (Backspace) */
+    {0x2b, 0},          /* TAB */  /* Keyboard Tab */
+    {0x28, 0},          /* LF  */  /* Keyboard Return (Enter) */
+    {0, 0},             /* VT  */
+    {0, 0},             /* FF  */
+    {0, 0},             /* CR  */
+    {0, 0},             /* SO  */
+    {0, 0},             /* SI  */
+    {0, 0},             /* DEL */
+    {0, 0},             /* DC1 */
+    {0, 0},             /* DC2 */
+    {0, 0},             /* DC3 */
+    {0, 0},             /* DC4 */
+    {0, 0},             /* NAK */
+    {0, 0},             /* SYN */
+    {0, 0},             /* ETB */
+    {0, 0},             /* CAN */
+    {0, 0},             /* EM  */
+    {0, 0},             /* SUB */
+    {0, 0},             /* ESC */
+    {0, 0},             /* FS  */
+    {0, 0},             /* GS  */
+    {0, 0},             /* RS  */
+    {0, 0},             /* US  */
+    {0x2c, 0},          /*   */
+    {0x1e, KEY_SHIFT},      /* ! */
+    {0x1f, KEY_SHIFT},      /* " */
+    {0x32, 0},          /* # */
+    {0x21, KEY_SHIFT},      /* $ */
+    {0x22, KEY_SHIFT},      /* % */
+    {0x24, KEY_SHIFT},      /* & */
+    {0x34, 0},          /* ' */
+    {0x26, KEY_SHIFT},      /* ( */
+    {0x27, KEY_SHIFT},      /* ) */
+    {0x25, KEY_SHIFT},      /* * */
+    {0x2e, KEY_SHIFT},      /* + */
+    {0x36, 0},          /* , */
+    {0x2d, 0},          /* - */
+    {0x37, 0},          /* . */
+    {0x38, 0},          /* / */
+    {0x27, 0},          /* 0 */
+    {0x1e, 0},          /* 1 */
+    {0x1f, 0},          /* 2 */
+    {0x20, 0},          /* 3 */
+    {0x21, 0},          /* 4 */
+    {0x22, 0},          /* 5 */
+    {0x23, 0},          /* 6 */
+    {0x24, 0},          /* 7 */
+    {0x25, 0},          /* 8 */
+    {0x26, 0},          /* 9 */
+    {0x33, KEY_SHIFT},      /* : */
+    {0x33, 0},          /* ; */
+    {0x36, KEY_SHIFT},      /* < */
+    {0x2e, 0},          /* = */
+    {0x37, KEY_SHIFT},      /* > */
+    {0x38, KEY_SHIFT},      /* ? */
+    {0x34, KEY_SHIFT},      /* @ */
+    {0x04, KEY_SHIFT},      /* A */
+    {0x05, KEY_SHIFT},      /* B */
+    {0x06, KEY_SHIFT},      /* C */
+    {0x07, KEY_SHIFT},      /* D */
+    {0x08, KEY_SHIFT},      /* E */
+    {0x09, KEY_SHIFT},      /* F */
+    {0x0a, KEY_SHIFT},      /* G */
+    {0x0b, KEY_SHIFT},      /* H */
+    {0x0c, KEY_SHIFT},      /* I */
+    {0x0d, KEY_SHIFT},      /* J */
+    {0x0e, KEY_SHIFT},      /* K */
+    {0x0f, KEY_SHIFT},      /* L */
+    {0x10, KEY_SHIFT},      /* M */
+    {0x11, KEY_SHIFT},      /* N */
+    {0x12, KEY_SHIFT},      /* O */
+    {0x13, KEY_SHIFT},      /* P */
+    {0x14, KEY_SHIFT},      /* Q */
+    {0x15, KEY_SHIFT},      /* R */
+    {0x16, KEY_SHIFT},      /* S */
+    {0x17, KEY_SHIFT},      /* T */
+    {0x18, KEY_SHIFT},      /* U */
+    {0x19, KEY_SHIFT},      /* V */
+    {0x1a, KEY_SHIFT},      /* W */
+    {0x1b, KEY_SHIFT},      /* X */
+    {0x1c, KEY_SHIFT},      /* Y */
+    {0x1d, KEY_SHIFT},      /* Z */
+    {0x2f, 0},          /* [ */
+    {0x64, 0},          /* \ */
+    {0x30, 0},          /* ] */
+    {0x23, KEY_SHIFT},      /* ^ */
+    {0x2d, KEY_SHIFT},      /* _ */
+    {0x35, 0},          /* ` */
+    {0x04, 0},          /* a */
+    {0x05, 0},          /* b */
+    {0x06, 0},          /* c */
+    {0x07, 0},          /* d */
+    {0x08, 0},          /* e */
+    {0x09, 0},          /* f */
+    {0x0a, 0},          /* g */
+    {0x0b, 0},          /* h */
+    {0x0c, 0},          /* i */
+    {0x0d, 0},          /* j */
+    {0x0e, 0},          /* k */
+    {0x0f, 0},          /* l */
+    {0x10, 0},          /* m */
+    {0x11, 0},          /* n */
+    {0x12, 0},          /* o */
+    {0x13, 0},          /* p */
+    {0x14, 0},          /* q */
+    {0x15, 0},          /* r */
+    {0x16, 0},          /* s */
+    {0x17, 0},          /* t */
+    {0x18, 0},          /* u */
+    {0x19, 0},          /* v */
+    {0x1a, 0},          /* w */
+    {0x1b, 0},          /* x */
+    {0x1c, 0},          /* y */
+    {0x1d, 0},          /* z */
+    {0x2f, KEY_SHIFT},      /* { */
+    {0x64, KEY_SHIFT},      /* | */
+    {0x30, KEY_SHIFT},      /* } */
+    {0x32, KEY_SHIFT},      /* ~ */
+    {0,0},             /* DEL */
+
+    {0x3a, 0},          /* F1 */
+    {0x3b, 0},          /* F2 */
+    {0x3c, 0},          /* F3 */
+    {0x3d, 0},          /* F4 */
+    {0x3e, 0},          /* F5 */
+    {0x3f, 0},          /* F6 */
+    {0x40, 0},          /* F7 */
+    {0x41, 0},          /* F8 */
+    {0x42, 0},          /* F9 */
+    {0x43, 0},          /* F10 */
+    {0x44, 0},          /* F11 */
+    {0x45, 0},          /* F12 */
+
+    {0x46, 0},          /* PRINT_SCREEN */
+    {0x47, 0},          /* SCROLL_LOCK */
+    {0x39, 0},          /* CAPS_LOCK */
+    {0x53, 0},          /* NUM_LOCK */
+    {0x49, 0},          /* INSERT */
+    {0x4a, 0},          /* HOME */
+    {0x4b, 0},          /* PAGE_UP */
+    {0x4e, 0},          /* PAGE_DOWN */
+};
+#endif
+
+uint8_t * USBKeyboard::reportDesc() {
+    static uint8_t reportDescriptor[] = {
+        USAGE_PAGE(1), 0x01,                    // Generic Desktop
+        USAGE(1), 0x06,                         // Keyboard
+        COLLECTION(1), 0x01,                    // Application
+        REPORT_ID(1),       REPORT_ID_KEYBOARD,
+
+        USAGE_PAGE(1), 0x07,                    // Key Codes
+        USAGE_MINIMUM(1), 0xE0,
+        USAGE_MAXIMUM(1), 0xE7,
+        LOGICAL_MINIMUM(1), 0x00,
+        LOGICAL_MAXIMUM(1), 0x01,
+        REPORT_SIZE(1), 0x01,
+        REPORT_COUNT(1), 0x08,
+        INPUT(1), 0x02,                         // Data, Variable, Absolute
+        REPORT_COUNT(1), 0x01,
+        REPORT_SIZE(1), 0x08,
+        INPUT(1), 0x01,                         // Constant
+
+
+        REPORT_COUNT(1), 0x05,
+        REPORT_SIZE(1), 0x01,
+        USAGE_PAGE(1), 0x08,                    // LEDs
+        USAGE_MINIMUM(1), 0x01,
+        USAGE_MAXIMUM(1), 0x05,
+        OUTPUT(1), 0x02,                        // Data, Variable, Absolute
+        REPORT_COUNT(1), 0x01,
+        REPORT_SIZE(1), 0x03,
+        OUTPUT(1), 0x01,                        // Constant
+
+
+        REPORT_COUNT(1), 0x06,
+        REPORT_SIZE(1), 0x08,
+        LOGICAL_MINIMUM(1), 0x00,
+        LOGICAL_MAXIMUM(1), 0x65,
+        USAGE_PAGE(1), 0x07,                    // Key Codes
+        USAGE_MINIMUM(1), 0x00,
+        USAGE_MAXIMUM(1), 0x65,
+        INPUT(1), 0x00,                         // Data, Array
+        END_COLLECTION(0),
+
+        // Media Control
+        USAGE_PAGE(1), 0x0C,
+        USAGE(1), 0x01,
+        COLLECTION(1), 0x01,
+        REPORT_ID(1), REPORT_ID_VOLUME,
+        USAGE_PAGE(1), 0x0C,
+        LOGICAL_MINIMUM(1), 0x00,
+        LOGICAL_MAXIMUM(1), 0x01,
+        REPORT_SIZE(1), 0x01,
+        REPORT_COUNT(1), 0x07,
+        USAGE(1), 0xB5,             // Next Track
+        USAGE(1), 0xB6,             // Previous Track
+        USAGE(1), 0xB7,             // Stop
+        USAGE(1), 0xCD,             // Play / Pause
+        USAGE(1), 0xE2,             // Mute
+        USAGE(1), 0xE9,             // Volume Up
+        USAGE(1), 0xEA,             // Volume Down
+        INPUT(1), 0x02,             // Input (Data, Variable, Absolute)
+        REPORT_COUNT(1), 0x01,
+        INPUT(1), 0x01,
+        END_COLLECTION(0),
+    };
+    reportLength = sizeof(reportDescriptor);
+    return reportDescriptor;
+}
+
+
+bool USBKeyboard::EP1_OUT_callback() {
+    uint16_t bytesRead = 0;
+    uint8_t led[65];
+    USBDevice::read(EPINT_OUT, led, &bytesRead, MAX_HID_REPORT_SIZE);
+    
+    // we take led[1] because led[0] is the report ID
+    lock_status = led[1] & 0x07;
+    
+    // We activate the endpoint to be able to recceive data
+    if (!readStart(EPINT_OUT, MAX_HID_REPORT_SIZE))
+        return false;
+    return true;
+}
+
+uint8_t USBKeyboard::lockStatus() {
+    return lock_status;
+}
+
+int USBKeyboard::_putc(int c) {
+    return keyCode(c, keymap[c].modifier);
+}
+
+bool USBKeyboard::keyCode(uint8_t key, uint8_t modifier) {
+    // Send a simulated keyboard keypress. Returns true if successful.
+    HID_REPORT report;
+
+    report.data[0] = REPORT_ID_KEYBOARD;
+    report.data[1] = modifier;
+    report.data[2] = 0;
+    report.data[3] = keymap[key].usage;
+    report.data[4] = 0;
+    report.data[5] = 0;
+    report.data[6] = 0;
+    report.data[7] = 0;
+    report.data[8] = 0;
+
+    report.length = 9;
+
+    if (!send(&report)) {
+        return false;
+    }
+
+    report.data[1] = 0;
+    report.data[3] = 0;
+
+    if (!send(&report)) {
+        return false;
+    }
+
+    return true;
+
+}
+
+
+bool USBKeyboard::mediaControl(MEDIA_KEY key) {
+    HID_REPORT report;
+
+    report.data[0] = REPORT_ID_VOLUME;
+    report.data[1] = (1 << key) & 0x7f;
+
+    report.length = 2;
+
+    if (!send(&report)) {
+        return false;
+    }
+
+    report.data[0] = REPORT_ID_VOLUME;
+    report.data[1] = 0;
+
+    report.length = 2;
+
+    return send(&report);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBHID/USBKeyboard.h	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,170 @@
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef USBKEYBOARD_H
+#define USBKEYBOARD_H
+
+#include "USBHID.h"
+#include "Stream.h"
+
+/* Modifiers */
+enum MODIFIER_KEY
+{
+    KEY_CTRL = 1,
+    KEY_SHIFT = 2,
+    KEY_ALT = 4,
+};
+
+
+enum MEDIA_KEY
+{
+    KEY_NEXT_TRACK,     /*!< next Track Button */
+    KEY_PREVIOUS_TRACK, /*!< Previous track Button */
+    KEY_STOP,           /*!< Stop Button */
+    KEY_PLAY_PAUSE,     /*!< Play/Pause Button */
+    KEY_MUTE,           /*!< Mute Button */
+    KEY_VOLUME_UP,      /*!< Volume Up Button */
+    KEY_VOLUME_DOWN,    /*!< Volume Down Button */
+};
+
+enum FUNCTION_KEY
+{
+    KEY_F1 = 128,   /* F1 key */
+    KEY_F2,         /* F2 key */
+    KEY_F3,         /* F3 key */
+    KEY_F4,         /* F4 key */
+    KEY_F5,         /* F5 key */
+    KEY_F6,         /* F6 key */
+    KEY_F7,         /* F7 key */
+    KEY_F8,         /* F8 key */
+    KEY_F9,         /* F9 key */
+    KEY_F10,        /* F10 key */
+    KEY_F11,        /* F11 key */
+    KEY_F12,        /* F12 key */
+    KEY_PRINT_SCREEN,   /* Print Screen key */
+    KEY_SCROLL_LOCK, /* Scroll lock */
+    KEY_CAPS_LOCK,   /* caps lock */
+    KEY_NUM_LOCK,   /* num lock */
+    KEY_INSERT,         /* Insert key */
+    KEY_HOME,           /* Home key */
+    KEY_PAGE_UP,        /* Page Up key */
+    KEY_PAGE_DOWN,      /* Page Down key */
+};
+
+/** 
+ * USBKeyboard example
+ * @code
+ *
+ * #include "mbed.h"
+ * #include "USBKeyboard.h"
+ *
+ * USBKeyboard key;
+ * 
+ * int main(void)
+ * {
+ *   while (1)
+ *   {
+ *       key.printf("Hello World\r\n");
+ *       wait(1);
+ *   }
+ * }
+ *
+ * @endcode
+ */
+class USBKeyboard: public USBHID, public Stream
+{
+    public:
+    
+        /**
+        *   Constructor
+        *
+        *
+        * @param leds Leds bus: first: NUM_LOCK, second: CAPS_LOCK, third: SCROLL_LOCK
+        * @param vendor_id Your vendor_id (default: 0x1234)
+        * @param product_id Your product_id (default: 0x0001)
+        * @param product_release Your preoduct_release (default: 0x0001)
+        *
+        */
+        USBKeyboard(uint16_t vendor_id = 0x1235, uint16_t product_id = 0x0010, uint16_t product_release = 0x0001): 
+            USBHID(0, 0, vendor_id, product_id, product_release){
+                lock_status = 0;
+            };
+        
+        /**
+        * To send a character defined by a modifier(CTRL, SHIFT, ALT) and the key 
+        *
+        * @code
+        * //To send CTRL + s (save)
+        *  keyboard.keyCode('s', KEY_CTRL);
+        * @endcode
+        *
+        * @param modifier bit 0: KEY_CTRL, bit 1: KEY_SHIFT, bit 2: KEY_ALT (default: 0)
+        * @param key character to send
+        * @returns true if there is no error, false otherwise
+        */
+        bool keyCode(uint8_t key, uint8_t modifier = 0);
+        
+        /**
+        * Send a character
+        *
+        * @param c character to be sent
+        * @returns true if there is no error, false otherwise
+        */
+        virtual int _putc(int c);
+        
+        /**
+        * Control media keys
+        *
+        * @param key media key pressed (KEY_NEXT_TRACK, KEY_PREVIOUS_TRACK, KEY_STOP, KEY_PLAY_PAUSE, KEY_MUTE, KEY_VOLUME_UP, KEY_VOLUME_DOWN)
+        * @returns true if there is no error, false otherwise
+        */
+        bool mediaControl(MEDIA_KEY key);
+        
+        /*
+        * To define the report descriptor. Warning: this method has to store the length of the report descriptor in reportLength.
+        *
+        * @returns pointer to the report descriptor
+        */
+        virtual uint8_t * reportDesc();
+        
+        /*
+        * Called when a data is received on the OUT endpoint. Useful to switch on LED of LOCK keys
+        *
+        * @returns if handle by subclass, return true
+        */
+        virtual bool EP1_OUT_callback();
+        
+        /**
+        * Read status of lock keys. Useful to switch-on/off leds according to key pressed. Only the first three bits of the result is important:
+        *   - First bit: NUM_LOCK
+        *   - Second bit: CAPS_LOCK
+        *   - Third bit: SCROLL_LOCK
+        *
+        * @returns status of lock keys
+        */
+        uint8_t lockStatus();
+        
+   private:
+        //dummy otherwise it doesn,t compile (we must define all methods of an abstract class)
+        virtual int _getc() { return -1;};
+        
+        uint8_t lock_status;
+};
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBHID/USBMouse.cpp	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,190 @@
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include "stdint.h"
+#include "USBMouse.h"
+
+bool USBMouse::update(int16_t x, int16_t y, uint8_t button, int8_t z) {
+    switch (mouse_type) {
+        case REL_MOUSE:
+            while (x > 127) {
+                if (!mouseSend(127, 0, button, z)) return false;
+                x = x - 127;
+            }
+            while (x < -128) {
+                if (!mouseSend(-128, 0, button, z)) return false;
+                x = x + 128;
+            }
+            while (y > 127) {
+                if (!mouseSend(0, 127, button, z)) return false;
+                y = y - 127;
+            }
+            while (y < -128) {
+                if (!mouseSend(0, -128, button, z)) return false;
+                y = y + 128;
+            }
+            return mouseSend(x, y, button, z);
+        case ABS_MOUSE:
+            HID_REPORT report;
+
+            report.data[0] = x & 0xff;
+            report.data[1] = (x >> 8) & 0xff;
+            report.data[2] = y & 0xff;
+            report.data[3] = (y >> 8) & 0xff;
+            report.data[4] = -z;
+            report.data[5] = button & 0x07;
+
+            report.length = 6;
+
+            return send(&report);
+        default:
+            return false;
+    }
+}
+
+bool USBMouse::mouseSend(int8_t x, int8_t y, uint8_t buttons, int8_t z) {
+    HID_REPORT report;
+    report.data[0] = buttons & 0x07;
+    report.data[1] = x;
+    report.data[2] = y;
+    report.data[3] = -z; // >0 to scroll down, <0 to scroll up
+
+    report.length = 4;
+
+    return send(&report);
+}
+
+bool USBMouse::move(int16_t x, int16_t y) {
+    return update(x, y, button, 0);
+}
+
+bool USBMouse::scroll(int8_t z) {
+    return update(0, 0, button, z);
+}
+
+
+bool USBMouse::doubleClick() {
+    if (!click(MOUSE_LEFT))
+        return false;
+    wait(0.1);
+    return click(MOUSE_LEFT);
+}
+
+bool USBMouse::click(uint8_t button) {
+    if (!update(0, 0, button, 0))
+        return false;
+    wait(0.01);
+    return update(0, 0, 0, 0);
+}
+
+bool USBMouse::press(uint8_t button_) {
+    button = button_ & 0x07;
+    return update(0, 0, button, 0);
+}
+
+bool USBMouse::release(uint8_t button_) {
+    button = (button & (~button_)) & 0x07;
+    return update(0, 0, button, 0);
+}
+
+
+uint8_t * USBMouse::reportDesc() {
+
+    if (mouse_type == REL_MOUSE) {
+        static uint8_t reportDescriptor[] = {
+            USAGE_PAGE(1),      0x01,       // Genric Desktop
+            USAGE(1),           0x02,       // Mouse
+            COLLECTION(1),      0x01,       // Application
+            USAGE(1),           0x01,       // Pointer
+            COLLECTION(1),      0x00,       // Physical
+
+            REPORT_COUNT(1),    0x03,
+            REPORT_SIZE(1),     0x01,
+            USAGE_PAGE(1),      0x09,       // Buttons
+            USAGE_MINIMUM(1),       0x1,
+            USAGE_MAXIMUM(1),       0x3,
+            LOGICAL_MINIMUM(1),     0x00,
+            LOGICAL_MAXIMUM(1),     0x01,
+            INPUT(1),           0x02,
+            REPORT_COUNT(1),    0x01,
+            REPORT_SIZE(1),     0x05,
+            INPUT(1),           0x01,
+
+            REPORT_COUNT(1),    0x03,
+            REPORT_SIZE(1),     0x08,
+            USAGE_PAGE(1),      0x01,
+            USAGE(1),           0x30,       // X
+            USAGE(1),           0x31,       // Y
+            USAGE(1),           0x38,       // scroll
+            LOGICAL_MINIMUM(1),     0x81,
+            LOGICAL_MAXIMUM(1),     0x7f,
+            INPUT(1),           0x06,       // Relative data
+
+            END_COLLECTION(0),
+            END_COLLECTION(0),
+        };
+        reportLength = sizeof(reportDescriptor);
+        return reportDescriptor;
+    } else if (mouse_type == ABS_MOUSE) {
+        static uint8_t reportDescriptor[] = {
+
+            USAGE_PAGE(1), 0x01,           // Generic Desktop
+            USAGE(1), 0x02,                // Mouse
+            COLLECTION(1), 0x01,           // Application
+            USAGE(1), 0x01,                // Pointer
+            COLLECTION(1), 0x00,           // Physical
+
+            USAGE_PAGE(1), 0x01,            // Generic Desktop
+            USAGE(1), 0x30,                 // X
+            USAGE(1), 0x31,                 // Y
+            LOGICAL_MINIMUM(1), 0x00,       // 0
+            LOGICAL_MAXIMUM(2), 0xff, 0x7f, // 32767
+            REPORT_SIZE(1), 0x10,
+            REPORT_COUNT(1), 0x02,
+            INPUT(1), 0x02,                 // Data, Variable, Absolute
+
+            USAGE_PAGE(1), 0x01,            // Generic Desktop
+            USAGE(1), 0x38,                 // scroll
+            LOGICAL_MINIMUM(1), 0x81,       // -127
+            LOGICAL_MAXIMUM(1), 0x7f,       // 127
+            REPORT_SIZE(1), 0x08,
+            REPORT_COUNT(1), 0x01,
+            INPUT(1), 0x06,                 // Data, Variable, Relative
+
+            USAGE_PAGE(1), 0x09,            // Buttons
+            USAGE_MINIMUM(1), 0x01,
+            USAGE_MAXIMUM(1), 0x03,
+            LOGICAL_MINIMUM(1), 0x00,       // 0
+            LOGICAL_MAXIMUM(1), 0x01,       // 1
+            REPORT_COUNT(1), 0x03,
+            REPORT_SIZE(1), 0x01,
+            INPUT(1), 0x02,                 // Data, Variable, Absolute
+            REPORT_COUNT(1), 0x01,
+            REPORT_SIZE(1), 0x05,
+            INPUT(1), 0x01,                 // Constant
+
+            END_COLLECTION(0),
+            END_COLLECTION(0)
+        };
+        reportLength = sizeof(reportDescriptor);
+        return reportDescriptor;
+    }
+    return NULL;
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBHID/USBMouse.h	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,200 @@
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef USBMOUSE_H
+#define USBMOUSE_H
+
+#include "USBHID.h"
+
+#define REPORT_ID_MOUSE   2
+
+/* Common usage */
+
+enum MOUSE_BUTTON
+{
+    MOUSE_LEFT = 1,
+    MOUSE_RIGHT = 2,
+    MOUSE_MIDDLE = 4,
+};
+
+/* X and Y limits */
+/* These values do not directly map to screen pixels */
+/* Zero may be interpreted as meaning 'no movement' */
+#define X_MIN_ABS    (1)        /*!< Minimum value on x-axis */  
+#define Y_MIN_ABS    (1)        /*!< Minimum value on y-axis */
+#define X_MAX_ABS    (0x7fff)   /*!< Maximum value on x-axis */
+#define Y_MAX_ABS    (0x7fff)   /*!< Maximum value on y-axis */
+
+#define X_MIN_REL    (-127)     /*!< The maximum value that we can move to the left on the x-axis */
+#define Y_MIN_REL    (-127)     /*!< The maximum value that we can move up on the y-axis */
+#define X_MAX_REL    (127)      /*!< The maximum value that we can move to the right on the x-axis */
+#define Y_MAX_REL    (127)      /*!< The maximum value that we can move down on the y-axis */
+
+enum MOUSE_TYPE
+{
+    ABS_MOUSE,
+    REL_MOUSE,
+};
+
+/**
+ *
+ * USBMouse example
+ * @code
+ * #include "mbed.h"
+ * #include "USBMouse.h"
+ *
+ * USBMouse mouse;
+ *
+ * int main(void)
+ * {
+ *   while (1)
+ *   {
+ *      mouse.move(20, 0);
+ *      wait(0.5);
+ *   }
+ * }
+ *
+ * @endcode
+ *
+ *
+ * @code
+ * #include "mbed.h"
+ * #include "USBMouse.h"
+ * #include <math.h>
+ *
+ * USBMouse mouse(ABS_MOUSE);
+ *
+ * int main(void)
+ * {
+ *   uint16_t x_center = (X_MAX_ABS - X_MIN_ABS)/2;
+ *   uint16_t y_center = (Y_MAX_ABS - Y_MIN_ABS)/2;
+ *   uint16_t x_screen = 0;
+ *   uint16_t y_screen = 0;
+ *   
+ *   uint32_t x_origin = x_center;
+ *   uint32_t y_origin = y_center;
+ *   uint32_t radius = 5000;
+ *   uint32_t angle = 0;
+ *
+ *   while (1)
+ *   {
+ *       x_screen = x_origin + cos((double)angle*3.14/180.0)*radius;
+ *       y_screen = y_origin + sin((double)angle*3.14/180.0)*radius;
+ *       
+ *       mouse.move(x_screen, y_screen);
+ *       angle += 3;
+ *       wait(0.01);
+ *   }
+ * }
+ *
+ * @endcode
+ */
+class USBMouse: public USBHID
+{
+    public:
+        
+        /**
+        *   Constructor
+        *
+        * @param mouse_type Mouse type: ABS_MOUSE (absolute mouse) or REL_MOUSE (relative mouse) (default: REL_MOUSE)
+        * @param vendor_id Your vendor_id (default: 0x1234)
+        * @param product_id Your product_id (default: 0x0001)
+        * @param product_release Your preoduct_release (default: 0x0001)
+        *
+        */
+        USBMouse(MOUSE_TYPE mouse_type = REL_MOUSE, uint16_t vendor_id = 0x1234, uint16_t product_id = 0x0001, uint16_t product_release = 0x0001): 
+            USBHID(0, 0, vendor_id, product_id, product_release)
+            { 
+                button = 0;
+                this->mouse_type = mouse_type;
+            };
+        
+        /**
+        * Write a state of the mouse
+        *
+        * @param x x-axis position
+        * @param y y-axis position
+        * @param buttons buttons state (first bit represents MOUSE_LEFT, second bit MOUSE_RIGHT and third bit MOUSE_MIDDLE)
+        * @param z wheel state (>0 to scroll down, <0 to scroll up)
+        * @returns true if there is no error, false otherwise
+        */
+        bool update(int16_t x, int16_t y, uint8_t buttons, int8_t z);
+        
+        
+        /**
+        * Move the cursor to (x, y)
+        *
+        * @param x-axis position
+        * @param y-axis position
+        * @returns true if there is no error, false otherwise
+        */
+        bool move(int16_t x, int16_t y);
+        
+        /**
+        * Press one or several buttons
+        *
+        * @param button button state (ex: press(MOUSE_LEFT))
+        * @returns true if there is no error, false otherwise
+        */
+        bool press(uint8_t button);
+        
+        /**
+        * Release one or several buttons
+        *
+        * @param button button state (ex: release(MOUSE_LEFT))
+        * @returns true if there is no error, false otherwise
+        */
+        bool release(uint8_t button);
+        
+        /**
+        * Double click (MOUSE_LEFT)
+        *
+        * @returns true if there is no error, false otherwise
+        */
+        bool doubleClick();
+        
+        /**
+        * Click
+        *
+        * @param button state of the buttons ( ex: clic(MOUSE_LEFT))
+        * @returns true if there is no error, false otherwise
+        */
+        bool click(uint8_t button); 
+        
+        /**
+        * Scrolling
+        *
+        * @param z value of the wheel (>0 to go down, <0 to go up)
+        * @returns true if there is no error, false otherwise
+        */
+        bool scroll(int8_t z);
+        
+        /*
+        * To define the report descriptor. Warning: this method has to store the length of the report descriptor in reportLength.
+        *
+        * @returns pointer to the report descriptor
+        */
+        virtual uint8_t * reportDesc();
+        
+    private:
+        MOUSE_TYPE mouse_type;
+        uint8_t button;
+        bool mouseSend(int8_t x, int8_t y, uint8_t buttons, int8_t z);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBHID/USBMouseKeyboard.cpp	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,696 @@
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include "stdint.h"
+#include "USBMouseKeyboard.h"
+
+typedef struct {
+    unsigned char usage;
+    unsigned char modifier;
+} KEYMAP;
+
+#ifdef US_KEYBOARD
+/* US keyboard (as HID standard) */
+#define KEYMAP_SIZE (148)
+const KEYMAP keymap[KEYMAP_SIZE] = {
+    {0, 0},             /* NUL */
+    {0, 0},             /* SOH */
+    {0, 0},             /* STX */
+    {0, 0},             /* ETX */
+    {0, 0},             /* EOT */
+    {0, 0},             /* ENQ */
+    {0, 0},             /* ACK */
+    {0, 0},             /* BEL */
+    {0x2a, 0},          /* BS  */  /* Keyboard Delete (Backspace) */
+    {0x2b, 0},          /* TAB */  /* Keyboard Tab */
+    {0x28, 0},          /* LF  */  /* Keyboard Return (Enter) */
+    {0, 0},             /* VT  */
+    {0, 0},             /* FF  */
+    {0, 0},             /* CR  */
+    {0, 0},             /* SO  */
+    {0, 0},             /* SI  */
+    {0, 0},             /* DEL */
+    {0, 0},             /* DC1 */
+    {0, 0},             /* DC2 */
+    {0, 0},             /* DC3 */
+    {0, 0},             /* DC4 */
+    {0, 0},             /* NAK */
+    {0, 0},             /* SYN */
+    {0, 0},             /* ETB */
+    {0, 0},             /* CAN */
+    {0, 0},             /* EM  */
+    {0, 0},             /* SUB */
+    {0, 0},             /* ESC */
+    {0, 0},             /* FS  */
+    {0, 0},             /* GS  */
+    {0, 0},             /* RS  */
+    {0, 0},             /* US  */
+    {0x2c, 0},          /*   */
+    {0x1e, KEY_SHIFT},      /* ! */
+    {0x34, KEY_SHIFT},      /* " */
+    {0x20, KEY_SHIFT},      /* # */
+    {0x21, KEY_SHIFT},      /* $ */
+    {0x22, KEY_SHIFT},      /* % */
+    {0x24, KEY_SHIFT},      /* & */
+    {0x34, 0},          /* ' */
+    {0x26, KEY_SHIFT},      /* ( */
+    {0x27, KEY_SHIFT},      /* ) */
+    {0x25, KEY_SHIFT},      /* * */
+    {0x2e, KEY_SHIFT},      /* + */
+    {0x36, 0},          /* , */
+    {0x2d, 0},          /* - */
+    {0x37, 0},          /* . */
+    {0x38, 0},          /* / */
+    {0x27, 0},          /* 0 */
+    {0x1e, 0},          /* 1 */
+    {0x1f, 0},          /* 2 */
+    {0x20, 0},          /* 3 */
+    {0x21, 0},          /* 4 */
+    {0x22, 0},          /* 5 */
+    {0x23, 0},          /* 6 */
+    {0x24, 0},          /* 7 */
+    {0x25, 0},          /* 8 */
+    {0x26, 0},          /* 9 */
+    {0x33, KEY_SHIFT},      /* : */
+    {0x33, 0},          /* ; */
+    {0x36, KEY_SHIFT},      /* < */
+    {0x2e, 0},          /* = */
+    {0x37, KEY_SHIFT},      /* > */
+    {0x38, KEY_SHIFT},      /* ? */
+    {0x1f, KEY_SHIFT},      /* @ */
+    {0x04, KEY_SHIFT},      /* A */
+    {0x05, KEY_SHIFT},      /* B */
+    {0x06, KEY_SHIFT},      /* C */
+    {0x07, KEY_SHIFT},      /* D */
+    {0x08, KEY_SHIFT},      /* E */
+    {0x09, KEY_SHIFT},      /* F */
+    {0x0a, KEY_SHIFT},      /* G */
+    {0x0b, KEY_SHIFT},      /* H */
+    {0x0c, KEY_SHIFT},      /* I */
+    {0x0d, KEY_SHIFT},      /* J */
+    {0x0e, KEY_SHIFT},      /* K */
+    {0x0f, KEY_SHIFT},      /* L */
+    {0x10, KEY_SHIFT},      /* M */
+    {0x11, KEY_SHIFT},      /* N */
+    {0x12, KEY_SHIFT},      /* O */
+    {0x13, KEY_SHIFT},      /* P */
+    {0x14, KEY_SHIFT},      /* Q */
+    {0x15, KEY_SHIFT},      /* R */
+    {0x16, KEY_SHIFT},      /* S */
+    {0x17, KEY_SHIFT},      /* T */
+    {0x18, KEY_SHIFT},      /* U */
+    {0x19, KEY_SHIFT},      /* V */
+    {0x1a, KEY_SHIFT},      /* W */
+    {0x1b, KEY_SHIFT},      /* X */
+    {0x1c, KEY_SHIFT},      /* Y */
+    {0x1d, KEY_SHIFT},      /* Z */
+    {0x2f, 0},          /* [ */
+    {0x31, 0},          /* \ */
+    {0x30, 0},          /* ] */
+    {0x23, KEY_SHIFT},      /* ^ */
+    {0x2d, KEY_SHIFT},      /* _ */
+    {0x35, 0},          /* ` */
+    {0x04, 0},          /* a */
+    {0x05, 0},          /* b */
+    {0x06, 0},          /* c */
+    {0x07, 0},          /* d */
+    {0x08, 0},          /* e */
+    {0x09, 0},          /* f */
+    {0x0a, 0},          /* g */
+    {0x0b, 0},          /* h */
+    {0x0c, 0},          /* i */
+    {0x0d, 0},          /* j */
+    {0x0e, 0},          /* k */
+    {0x0f, 0},          /* l */
+    {0x10, 0},          /* m */
+    {0x11, 0},          /* n */
+    {0x12, 0},          /* o */
+    {0x13, 0},          /* p */
+    {0x14, 0},          /* q */
+    {0x15, 0},          /* r */
+    {0x16, 0},          /* s */
+    {0x17, 0},          /* t */
+    {0x18, 0},          /* u */
+    {0x19, 0},          /* v */
+    {0x1a, 0},          /* w */
+    {0x1b, 0},          /* x */
+    {0x1c, 0},          /* y */
+    {0x1d, 0},          /* z */
+    {0x2f, KEY_SHIFT},      /* { */
+    {0x31, KEY_SHIFT},      /* | */
+    {0x30, KEY_SHIFT},      /* } */
+    {0x35, KEY_SHIFT},      /* ~ */
+    {0,0},              /* DEL */
+
+    {0x3a, 0},          /* F1 */
+    {0x3b, 0},          /* F2 */
+    {0x3c, 0},          /* F3 */
+    {0x3d, 0},          /* F4 */
+    {0x3e, 0},          /* F5 */
+    {0x3f, 0},          /* F6 */
+    {0x40, 0},          /* F7 */
+    {0x41, 0},          /* F8 */
+    {0x42, 0},          /* F9 */
+    {0x43, 0},          /* F10 */
+    {0x44, 0},          /* F11 */
+    {0x45, 0},          /* F12 */
+
+    {0x46, 0},          /* PRINT_SCREEN */
+    {0x47, 0},          /* SCROLL_LOCK */
+    {0x39, 0},          /* CAPS_LOCK */
+    {0x53, 0},          /* NUM_LOCK */
+    {0x49, 0},          /* INSERT */
+    {0x4a, 0},          /* HOME */
+    {0x4b, 0},          /* PAGE_UP */
+    {0x4e, 0},          /* PAGE_DOWN */
+};
+
+#else
+/* UK keyboard */
+#define KEYMAP_SIZE (148)
+const KEYMAP keymap[KEYMAP_SIZE] = {
+    {0, 0},             /* NUL */
+    {0, 0},             /* SOH */
+    {0, 0},             /* STX */
+    {0, 0},             /* ETX */
+    {0, 0},             /* EOT */
+    {0, 0},             /* ENQ */
+    {0, 0},             /* ACK */
+    {0, 0},             /* BEL */
+    {0x2a, 0},          /* BS  */  /* Keyboard Delete (Backspace) */
+    {0x2b, 0},          /* TAB */  /* Keyboard Tab */
+    {0x28, 0},          /* LF  */  /* Keyboard Return (Enter) */
+    {0, 0},             /* VT  */
+    {0, 0},             /* FF  */
+    {0, 0},             /* CR  */
+    {0, 0},             /* SO  */
+    {0, 0},             /* SI  */
+    {0, 0},             /* DEL */
+    {0, 0},             /* DC1 */
+    {0, 0},             /* DC2 */
+    {0, 0},             /* DC3 */
+    {0, 0},             /* DC4 */
+    {0, 0},             /* NAK */
+    {0, 0},             /* SYN */
+    {0, 0},             /* ETB */
+    {0, 0},             /* CAN */
+    {0, 0},             /* EM  */
+    {0, 0},             /* SUB */
+    {0, 0},             /* ESC */
+    {0, 0},             /* FS  */
+    {0, 0},             /* GS  */
+    {0, 0},             /* RS  */
+    {0, 0},             /* US  */
+    {0x2c, 0},          /*   */
+    {0x1e, KEY_SHIFT},      /* ! */
+    {0x1f, KEY_SHIFT},      /* " */
+    {0x32, 0},          /* # */
+    {0x21, KEY_SHIFT},      /* $ */
+    {0x22, KEY_SHIFT},      /* % */
+    {0x24, KEY_SHIFT},      /* & */
+    {0x34, 0},          /* ' */
+    {0x26, KEY_SHIFT},      /* ( */
+    {0x27, KEY_SHIFT},      /* ) */
+    {0x25, KEY_SHIFT},      /* * */
+    {0x2e, KEY_SHIFT},      /* + */
+    {0x36, 0},          /* , */
+    {0x2d, 0},          /* - */
+    {0x37, 0},          /* . */
+    {0x38, 0},          /* / */
+    {0x27, 0},          /* 0 */
+    {0x1e, 0},          /* 1 */
+    {0x1f, 0},          /* 2 */
+    {0x20, 0},          /* 3 */
+    {0x21, 0},          /* 4 */
+    {0x22, 0},          /* 5 */
+    {0x23, 0},          /* 6 */
+    {0x24, 0},          /* 7 */
+    {0x25, 0},          /* 8 */
+    {0x26, 0},          /* 9 */
+    {0x33, KEY_SHIFT},      /* : */
+    {0x33, 0},          /* ; */
+    {0x36, KEY_SHIFT},      /* < */
+    {0x2e, 0},          /* = */
+    {0x37, KEY_SHIFT},      /* > */
+    {0x38, KEY_SHIFT},      /* ? */
+    {0x34, KEY_SHIFT},      /* @ */
+    {0x04, KEY_SHIFT},      /* A */
+    {0x05, KEY_SHIFT},      /* B */
+    {0x06, KEY_SHIFT},      /* C */
+    {0x07, KEY_SHIFT},      /* D */
+    {0x08, KEY_SHIFT},      /* E */
+    {0x09, KEY_SHIFT},      /* F */
+    {0x0a, KEY_SHIFT},      /* G */
+    {0x0b, KEY_SHIFT},      /* H */
+    {0x0c, KEY_SHIFT},      /* I */
+    {0x0d, KEY_SHIFT},      /* J */
+    {0x0e, KEY_SHIFT},      /* K */
+    {0x0f, KEY_SHIFT},      /* L */
+    {0x10, KEY_SHIFT},      /* M */
+    {0x11, KEY_SHIFT},      /* N */
+    {0x12, KEY_SHIFT},      /* O */
+    {0x13, KEY_SHIFT},      /* P */
+    {0x14, KEY_SHIFT},      /* Q */
+    {0x15, KEY_SHIFT},      /* R */
+    {0x16, KEY_SHIFT},      /* S */
+    {0x17, KEY_SHIFT},      /* T */
+    {0x18, KEY_SHIFT},      /* U */
+    {0x19, KEY_SHIFT},      /* V */
+    {0x1a, KEY_SHIFT},      /* W */
+    {0x1b, KEY_SHIFT},      /* X */
+    {0x1c, KEY_SHIFT},      /* Y */
+    {0x1d, KEY_SHIFT},      /* Z */
+    {0x2f, 0},          /* [ */
+    {0x64, 0},          /* \ */
+    {0x30, 0},          /* ] */
+    {0x23, KEY_SHIFT},      /* ^ */
+    {0x2d, KEY_SHIFT},      /* _ */
+    {0x35, 0},          /* ` */
+    {0x04, 0},          /* a */
+    {0x05, 0},          /* b */
+    {0x06, 0},          /* c */
+    {0x07, 0},          /* d */
+    {0x08, 0},          /* e */
+    {0x09, 0},          /* f */
+    {0x0a, 0},          /* g */
+    {0x0b, 0},          /* h */
+    {0x0c, 0},          /* i */
+    {0x0d, 0},          /* j */
+    {0x0e, 0},          /* k */
+    {0x0f, 0},          /* l */
+    {0x10, 0},          /* m */
+    {0x11, 0},          /* n */
+    {0x12, 0},          /* o */
+    {0x13, 0},          /* p */
+    {0x14, 0},          /* q */
+    {0x15, 0},          /* r */
+    {0x16, 0},          /* s */
+    {0x17, 0},          /* t */
+    {0x18, 0},          /* u */
+    {0x19, 0},          /* v */
+    {0x1a, 0},          /* w */
+    {0x1b, 0},          /* x */
+    {0x1c, 0},          /* y */
+    {0x1d, 0},          /* z */
+    {0x2f, KEY_SHIFT},      /* { */
+    {0x64, KEY_SHIFT},      /* | */
+    {0x30, KEY_SHIFT},      /* } */
+    {0x32, KEY_SHIFT},      /* ~ */
+    {0,0},             /* DEL */
+
+    {0x3a, 0},          /* F1 */
+    {0x3b, 0},          /* F2 */
+    {0x3c, 0},          /* F3 */
+    {0x3d, 0},          /* F4 */
+    {0x3e, 0},          /* F5 */
+    {0x3f, 0},          /* F6 */
+    {0x40, 0},          /* F7 */
+    {0x41, 0},          /* F8 */
+    {0x42, 0},          /* F9 */
+    {0x43, 0},          /* F10 */
+    {0x44, 0},          /* F11 */
+    {0x45, 0},          /* F12 */
+
+    {0x46, 0},          /* PRINT_SCREEN */
+    {0x47, 0},          /* SCROLL_LOCK */
+    {0x39, 0},          /* CAPS_LOCK */
+    {0x53, 0},          /* NUM_LOCK */
+    {0x49, 0},          /* INSERT */
+    {0x4a, 0},          /* HOME */
+    {0x4b, 0},          /* PAGE_UP */
+    {0x4e, 0},          /* PAGE_DOWN */
+};
+#endif
+
+
+uint8_t * USBMouseKeyboard::reportDesc() {
+    if (mouse_type == REL_MOUSE) {
+        static uint8_t reportDescriptor[] = {
+                // Keyboard
+                USAGE_PAGE(1),      0x01,
+                USAGE(1),           0x06,
+                COLLECTION(1),      0x01,
+                REPORT_ID(1),       REPORT_ID_KEYBOARD,
+                USAGE_PAGE(1),      0x07,
+                USAGE_MINIMUM(1),       0xE0,
+                USAGE_MAXIMUM(1),       0xE7,
+                LOGICAL_MINIMUM(1),     0x00,
+                LOGICAL_MAXIMUM(1),     0x01,
+                REPORT_SIZE(1),     0x01,
+                REPORT_COUNT(1),    0x08,
+                INPUT(1),           0x02,
+                REPORT_COUNT(1),    0x01,
+                REPORT_SIZE(1),     0x08,
+                INPUT(1),           0x01,
+                REPORT_COUNT(1),    0x05,
+                REPORT_SIZE(1),     0x01,
+                USAGE_PAGE(1),      0x08,
+                USAGE_MINIMUM(1),       0x01,
+                USAGE_MAXIMUM(1),       0x05,
+                OUTPUT(1),          0x02,
+                REPORT_COUNT(1),    0x01,
+                REPORT_SIZE(1),     0x03,
+                OUTPUT(1),          0x01,
+                REPORT_COUNT(1),    0x06,
+                REPORT_SIZE(1),     0x08,
+                LOGICAL_MINIMUM(1),     0x00,
+                LOGICAL_MAXIMUM(2),     0xff, 0x00,
+                USAGE_PAGE(1),      0x07,
+                USAGE_MINIMUM(1),       0x00,
+                USAGE_MAXIMUM(2),       0xff, 0x00,
+                INPUT(1),           0x00,
+                END_COLLECTION(0),
+
+                // Mouse
+                USAGE_PAGE(1),      0x01,           // Generic Desktop
+                USAGE(1),           0x02,           // Mouse
+                COLLECTION(1),      0x01,           // Application
+                USAGE(1),           0x01,           // Pointer
+                COLLECTION(1),      0x00,           // Physical
+                REPORT_ID(1),       REPORT_ID_MOUSE,
+                REPORT_COUNT(1),    0x03,
+                REPORT_SIZE(1),     0x01,
+                USAGE_PAGE(1),      0x09,           // Buttons
+                USAGE_MINIMUM(1),       0x1,
+                USAGE_MAXIMUM(1),       0x3,
+                LOGICAL_MINIMUM(1),     0x00,
+                LOGICAL_MAXIMUM(1),     0x01,
+                INPUT(1),           0x02,
+                REPORT_COUNT(1),    0x01,
+                REPORT_SIZE(1),     0x05,
+                INPUT(1),           0x01,
+                REPORT_COUNT(1),    0x03,
+                REPORT_SIZE(1),     0x08,
+                USAGE_PAGE(1),      0x01,
+                USAGE(1),           0x30,           // X
+                USAGE(1),           0x31,           // Y
+                USAGE(1),           0x38,           // scroll
+                LOGICAL_MINIMUM(1),     0x81,
+                LOGICAL_MAXIMUM(1),     0x7f,
+                INPUT(1),           0x06,
+                END_COLLECTION(0),
+                END_COLLECTION(0),
+
+
+                // Media Control
+                USAGE_PAGE(1), 0x0C,
+                USAGE(1), 0x01,
+                COLLECTION(1), 0x01,
+                REPORT_ID(1), REPORT_ID_VOLUME,
+                USAGE_PAGE(1), 0x0C,
+                LOGICAL_MINIMUM(1), 0x00,
+                LOGICAL_MAXIMUM(1), 0x01,
+                REPORT_SIZE(1), 0x01,
+                REPORT_COUNT(1), 0x07,
+                USAGE(1), 0xB5,             // Next Track
+                USAGE(1), 0xB6,             // Previous Track
+                USAGE(1), 0xB7,             // Stop
+                USAGE(1), 0xCD,             // Play / Pause
+                USAGE(1), 0xE2,             // Mute
+                USAGE(1), 0xE9,             // Volume Up
+                USAGE(1), 0xEA,             // Volume Down
+                INPUT(1), 0x02,             // Input (Data, Variable, Absolute)
+                REPORT_COUNT(1), 0x01,
+                INPUT(1), 0x01,
+                END_COLLECTION(0),
+        };
+        reportLength = sizeof(reportDescriptor);
+        return reportDescriptor;
+    } else if (mouse_type == ABS_MOUSE) {
+        static uint8_t reportDescriptor[] = {
+
+                // Keyboard
+                USAGE_PAGE(1),      0x01,
+                USAGE(1),           0x06,
+                COLLECTION(1),      0x01,
+                REPORT_ID(1),       REPORT_ID_KEYBOARD,
+                USAGE_PAGE(1),      0x07,
+                USAGE_MINIMUM(1),       0xE0,
+                USAGE_MAXIMUM(1),       0xE7,
+                LOGICAL_MINIMUM(1),     0x00,
+                LOGICAL_MAXIMUM(1),     0x01,
+                REPORT_SIZE(1),     0x01,
+                REPORT_COUNT(1),    0x08,
+                INPUT(1),           0x02,
+                REPORT_COUNT(1),    0x01,
+                REPORT_SIZE(1),     0x08,
+                INPUT(1),           0x01,
+                REPORT_COUNT(1),    0x05,
+                REPORT_SIZE(1),     0x01,
+                USAGE_PAGE(1),      0x08,
+                USAGE_MINIMUM(1),       0x01,
+                USAGE_MAXIMUM(1),       0x05,
+                OUTPUT(1),          0x02,
+                REPORT_COUNT(1),    0x01,
+                REPORT_SIZE(1),     0x03,
+                OUTPUT(1),          0x01,
+                REPORT_COUNT(1),    0x06,
+                REPORT_SIZE(1),     0x08,
+                LOGICAL_MINIMUM(1),     0x00,
+                LOGICAL_MAXIMUM(2),     0xff, 0x00,
+                USAGE_PAGE(1),      0x07,
+                USAGE_MINIMUM(1),       0x00,
+                USAGE_MAXIMUM(2),       0xff, 0x00,
+                INPUT(1),           0x00,
+                END_COLLECTION(0),
+
+                // Mouse
+                USAGE_PAGE(1), 0x01,               // Generic Desktop
+                USAGE(1), 0x02,                    // Mouse
+                COLLECTION(1), 0x01,               // Application
+                USAGE(1), 0x01,                    // Pointer
+                COLLECTION(1), 0x00,               // Physical
+                REPORT_ID(1),       REPORT_ID_MOUSE,
+
+                USAGE_PAGE(1), 0x01,                // Generic Desktop
+                USAGE(1), 0x30,                     // X
+                USAGE(1), 0x31,                     // Y
+                LOGICAL_MINIMUM(1), 0x00,           // 0
+                LOGICAL_MAXIMUM(2), 0xff, 0x7f,     // 32767
+                REPORT_SIZE(1), 0x10,
+                REPORT_COUNT(1), 0x02,
+                INPUT(1), 0x02,                     // Data, Variable, Absolute
+
+                USAGE_PAGE(1), 0x01,                // Generic Desktop
+                USAGE(1), 0x38,                     // scroll
+                LOGICAL_MINIMUM(1), 0x81,           // -127
+                LOGICAL_MAXIMUM(1), 0x7f,           // 127
+                REPORT_SIZE(1), 0x08,
+                REPORT_COUNT(1), 0x01,
+                INPUT(1), 0x06,                     // Data, Variable, Relative
+
+                USAGE_PAGE(1), 0x09,                // Buttons
+                USAGE_MINIMUM(1), 0x01,
+                USAGE_MAXIMUM(1), 0x03,
+                LOGICAL_MINIMUM(1), 0x00,           // 0
+                LOGICAL_MAXIMUM(1), 0x01,           // 1
+                REPORT_COUNT(1), 0x03,
+                REPORT_SIZE(1), 0x01,
+                INPUT(1), 0x02,                     // Data, Variable, Absolute
+                REPORT_COUNT(1), 0x01,
+                REPORT_SIZE(1), 0x05,
+                INPUT(1), 0x01,                     // Constant
+
+                END_COLLECTION(0),
+                END_COLLECTION(0),
+
+                // Media Control
+                USAGE_PAGE(1), 0x0C,
+                USAGE(1), 0x01,
+                COLLECTION(1), 0x01,
+                REPORT_ID(1), REPORT_ID_VOLUME,
+                USAGE_PAGE(1), 0x0C,
+                LOGICAL_MINIMUM(1), 0x00,
+                LOGICAL_MAXIMUM(1), 0x01,
+                REPORT_SIZE(1), 0x01,
+                REPORT_COUNT(1), 0x07,
+                USAGE(1), 0xB5,             // Next Track
+                USAGE(1), 0xB6,             // Previous Track
+                USAGE(1), 0xB7,             // Stop
+                USAGE(1), 0xCD,             // Play / Pause
+                USAGE(1), 0xE2,             // Mute
+                USAGE(1), 0xE9,             // Volume Up
+                USAGE(1), 0xEA,             // Volume Down
+                INPUT(1), 0x02,             // Input (Data, Variable, Absolute)
+                REPORT_COUNT(1), 0x01,
+                INPUT(1), 0x01,
+                END_COLLECTION(0),
+        };
+        reportLength = sizeof(reportDescriptor);
+        return reportDescriptor;
+    }
+
+    return NULL;
+}
+
+bool USBMouseKeyboard::EP1_OUT_callback() {
+    uint16_t bytesRead = 0;
+    uint8_t led[65];
+    USBDevice::read(EPINT_OUT, led, &bytesRead, MAX_HID_REPORT_SIZE);
+    
+    // we take led[1] because led[0] is the report ID
+    lock_status = led[1] & 0x07;
+    
+    // We activate the endpoint to be able to recceive data
+    if (!readStart(EPINT_OUT, MAX_HID_REPORT_SIZE))
+        return false;
+    return true;
+}
+
+uint8_t USBMouseKeyboard::lockStatus() {
+    return lock_status;
+}
+
+bool USBMouseKeyboard::update(int16_t x, int16_t y, uint8_t button, int8_t z) {
+    switch (mouse_type) {
+    case REL_MOUSE:
+        while (x > 127) {
+            if (!mouseSend(127, 0, button, z)) return false;
+            x = x - 127;
+        }
+        while (x < -128) {
+            if (!mouseSend(-128, 0, button, z)) return false;
+            x = x + 128;
+        }
+        while (y > 127) {
+            if (!mouseSend(0, 127, button, z)) return false;
+            y = y - 127;
+        }
+        while (y < -128) {
+            if (!mouseSend(0, -128, button, z)) return false;
+            y = y + 128;
+        }
+        return mouseSend(x, y, button, z);
+    case ABS_MOUSE:
+        HID_REPORT report;
+
+        report.data[0] = REPORT_ID_MOUSE;
+        report.data[1] = x & 0xff;
+        report.data[2] = (x >> 8) & 0xff;
+        report.data[3] = y & 0xff;
+        report.data[4] = (y >> 8) & 0xff;
+        report.data[5] = -z;
+        report.data[6] = button & 0x07;
+
+        report.length = 7;
+
+        return send(&report);
+    default:
+        return false;
+    }
+}
+
+bool USBMouseKeyboard::mouseSend(int8_t x, int8_t y, uint8_t buttons, int8_t z) {
+    HID_REPORT report;
+    report.data[0] = REPORT_ID_MOUSE;
+    report.data[1] = buttons & 0x07;
+    report.data[2] = x;
+    report.data[3] = y;
+    report.data[4] = -z; // >0 to scroll down, <0 to scroll up
+
+    report.length = 5;
+
+    return send(&report);
+}
+
+bool USBMouseKeyboard::move(int16_t x, int16_t y) {
+    return update(x, y, button, 0);
+}
+
+bool USBMouseKeyboard::scroll(int8_t z) {
+    return update(0, 0, button, z);
+}
+
+bool USBMouseKeyboard::doubleClick() {
+    if (!click(MOUSE_LEFT))
+        return false;
+    wait(0.1);
+    return click(MOUSE_LEFT);
+}
+
+bool USBMouseKeyboard::click(uint8_t button) {
+    if (!update(0, 0, button, 0))
+        return false;
+    wait(0.01);
+    return update(0, 0, 0, 0);
+}
+
+bool USBMouseKeyboard::press(uint8_t button_) {
+    button = button_ & 0x07;
+    return update(0, 0, button, 0);
+}
+
+bool USBMouseKeyboard::release(uint8_t button_) {
+    button = (button & (~button_)) & 0x07;
+    return update(0, 0, button, 0);
+}
+
+int USBMouseKeyboard::_putc(int c) {
+    return keyCode(c, keymap[c].modifier);
+}
+
+bool USBMouseKeyboard::keyCode(uint8_t key, uint8_t modifier) {
+    // Send a simulated keyboard keypress. Returns true if successful.
+
+    HID_REPORT report;
+
+    report.data[0] = REPORT_ID_KEYBOARD;
+    report.data[1] = modifier;
+    report.data[2] = 0;
+    report.data[3] = keymap[key].usage;
+    report.data[4] = 0;
+    report.data[5] = 0;
+    report.data[6] = 0;
+    report.data[7] = 0;
+    report.data[8] = 0;
+
+    report.length = 9;
+
+    if (!send(&report)) {
+        return false;
+    }
+
+    report.data[1] = 0;
+    report.data[3] = 0;
+
+    if (!send(&report)) {
+        return false;
+    }
+
+    return true;
+
+}
+
+
+bool USBMouseKeyboard::mediaControl(MEDIA_KEY key) {
+    HID_REPORT report;
+
+    report.data[0] = REPORT_ID_VOLUME;
+    report.data[1] = (1 << key) & 0x7f;
+
+    report.length = 2;
+
+    send(&report);
+    
+    report.data[0] = REPORT_ID_VOLUME;
+    report.data[1] = 0;
+
+    report.length = 2;
+
+    return send(&report);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBHID/USBMouseKeyboard.h	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,219 @@
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef USBMOUSEKEYBOARD_H
+#define USBMOUSEKEYBOARD_H
+
+#define REPORT_ID_KEYBOARD 1
+#define REPORT_ID_MOUSE 2
+#define REPORT_ID_VOLUME 3
+
+#include "USBMouse.h"
+#include "USBKeyboard.h"
+#include "Stream.h"
+#include "USBHID.h"
+
+/** 
+ * USBMouseKeyboard example
+ * @code
+ *
+ * #include "mbed.h"
+ * #include "USBMouseKeyboard.h"
+ *
+ * USBMouseKeyboard key_mouse;
+ *
+ * int main(void)
+ * {
+ *   while(1)
+ *   {
+ *       key_mouse.move(20, 0);
+ *       key_mouse.printf("Hello From MBED\r\n");
+ *       wait(1);
+ *   }
+ * }
+ * @endcode
+ *
+ *
+ * @code
+ *
+ * #include "mbed.h"
+ * #include "USBMouseKeyboard.h"
+ *
+ * USBMouseKeyboard key_mouse(ABS_MOUSE);
+ *
+ * int main(void)
+ * {
+ *   while(1)
+ *   {
+ *       key_mouse.move(X_MAX_ABS/2, Y_MAX_ABS/2);
+ *       key_mouse.printf("Hello from MBED\r\n");
+ *       wait(1);
+ *   }
+ * }
+ * @endcode
+ */
+class USBMouseKeyboard: public USBHID, public Stream
+{
+    public:
+    
+        /**
+        *   Constructor
+        *
+        * @param mouse_type Mouse type: ABS_MOUSE (absolute mouse) or REL_MOUSE (relative mouse) (default: REL_MOUSE)
+        * @param leds Leds bus: first: NUM_LOCK, second: CAPS_LOCK, third: SCROLL_LOCK
+        * @param vendor_id Your vendor_id (default: 0x1234)
+        * @param product_id Your product_id (default: 0x0001)
+        * @param product_release Your preoduct_release (default: 0x0001)
+        *
+        */
+        USBMouseKeyboard(MOUSE_TYPE mouse_type = REL_MOUSE, uint16_t vendor_id = 0x0021, uint16_t product_id = 0x0011, uint16_t product_release = 0x0001): 
+            USBHID(0, 0, vendor_id, product_id, product_release)
+            {
+                lock_status = 0;
+                button = 0;
+                this->mouse_type = mouse_type;
+            };
+            
+        /**
+        * Write a state of the mouse
+        *
+        * @param x x-axis position
+        * @param y y-axis position
+        * @param buttons buttons state (first bit represents MOUSE_LEFT, second bit MOUSE_RIGHT and third bit MOUSE_MIDDLE)
+        * @param z wheel state (>0 to scroll down, <0 to scroll up)
+        * @returns true if there is no error, false otherwise
+        */
+        bool update(int16_t x, int16_t y, uint8_t buttons, int8_t z);
+        
+        
+        /**
+        * Move the cursor to (x, y)
+        *
+        * @param x x-axis position
+        * @param y y-axis position
+        * @returns true if there is no error, false otherwise
+        */
+        bool move(int16_t x, int16_t y);
+        
+        /**
+        * Press one or several buttons
+        *
+        * @param button button state (ex: press(MOUSE_LEFT))
+        * @returns true if there is no error, false otherwise
+        */
+        bool press(uint8_t button);
+        
+        /**
+        * Release one or several buttons
+        *
+        * @param button button state (ex: release(MOUSE_LEFT))
+        * @returns true if there is no error, false otherwise
+        */
+        bool release(uint8_t button);
+        
+        /**
+        * Double click (MOUSE_LEFT)
+        *
+        * @returns true if there is no error, false otherwise
+        */
+        bool doubleClick();
+        
+        /**
+        * Click
+        *
+        * @param button state of the buttons ( ex: clic(MOUSE_LEFT))
+        * @returns true if there is no error, false otherwise
+        */
+        bool click(uint8_t button); 
+        
+        /**
+        * Scrolling
+        *
+        * @param z value of the wheel (>0 to go down, <0 to go up)
+        * @returns true if there is no error, false otherwise
+        */
+        bool scroll(int8_t z);
+
+        /**
+        * To send a character defined by a modifier(CTRL, SHIFT, ALT) and the key 
+        *
+        * @code
+        * //To send CTRL + s (save)
+        *  keyboard.keyCode('s', KEY_CTRL);
+        * @endcode
+        *
+        * @param modifier bit 0: KEY_CTRL, bit 1: KEY_SHIFT, bit 2: KEY_ALT (default: 0)
+        * @param key character to send
+        * @returns true if there is no error, false otherwise
+        */
+        bool keyCode(uint8_t key, uint8_t modifier = 0);
+        
+        /**
+        * Send a character
+        *
+        * @param c character to be sent
+        * @returns true if there is no error, false otherwise
+        */
+        virtual int _putc(int c);
+        
+        /**
+        * Control media keys
+        *
+        * @param key media key pressed (KEY_NEXT_TRACK, KEY_PREVIOUS_TRACK, KEY_STOP, KEY_PLAY_PAUSE, KEY_MUTE, KEY_VOLUME_UP, KEY_VOLUME_DOWN)
+        * @returns true if there is no error, false otherwise
+        */
+        bool mediaControl(MEDIA_KEY key);
+        
+        /**
+        * Read status of lock keys. Useful to switch-on/off leds according to key pressed. Only the first three bits of the result is important:
+        *   - First bit: NUM_LOCK
+        *   - Second bit: CAPS_LOCK
+        *   - Third bit: SCROLL_LOCK
+        *
+        * @returns status of lock keys
+        */
+        uint8_t lockStatus();
+        
+        /*
+        * To define the report descriptor. Warning: this method has to store the length of the report descriptor in reportLength.
+        *
+        * @returns pointer to the report descriptor
+        */
+        virtual uint8_t * reportDesc();
+        
+        /*
+        * Called when a data is received on the OUT endpoint. Useful to switch on LED of LOCK keys
+        *
+        * @returns if handle by subclass, return true
+        */
+        virtual bool EP1_OUT_callback();
+        
+        
+    private:
+        bool mouseWrite(int8_t x, int8_t y, uint8_t buttons, int8_t z);
+        MOUSE_TYPE mouse_type;
+        uint8_t button;
+        bool mouseSend(int8_t x, int8_t y, uint8_t buttons, int8_t z);
+        
+        uint8_t lock_status;
+        
+        //dummy otherwise it doesn't compile (we must define all methods of an abstract class)
+        virtual int _getc() { return -1;}
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBMIDI/.svn/all-wcprops Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,23 @@ +K 25 +svn:wc:ra_dav:version-url +V 74 +/svn/sdd/mbed/!svn/ver/838/product/libraries/branches/emilmont/usb/USBMIDI +END +MIDIMessage.h +K 25 +svn:wc:ra_dav:version-url +V 88 +/svn/sdd/mbed/!svn/ver/838/product/libraries/branches/emilmont/usb/USBMIDI/MIDIMessage.h +END +USB_MIDI.cpp +K 25 +svn:wc:ra_dav:version-url +V 87 +/svn/sdd/mbed/!svn/ver/838/product/libraries/branches/emilmont/usb/USBMIDI/USB_MIDI.cpp +END +USB_MIDI.h +K 25 +svn:wc:ra_dav:version-url +V 85 +/svn/sdd/mbed/!svn/ver/838/product/libraries/branches/emilmont/usb/USBMIDI/USB_MIDI.h +END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBMIDI/.svn/entries Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,137 @@ +10 + +dir +838 +http://cam-svn2.cambridge.arm.com/svn/sdd/mbed/product/libraries/branches/emilmont/usb/USBMIDI +http://cam-svn2.cambridge.arm.com/svn/sdd/mbed + + + +2011-11-02T18:07:32.701563Z +838 +sammok01 + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +55d82849-f8ce-43ef-8e1a-fbdbc5b469c3 + + + + + + +0 + +MIDIMessage.h +file + + + + +2011-11-02T12:41:31.331000Z +04ae1dccac462b00db77351dea7a41e6 +2011-11-02T18:07:32.701563Z +838 +sammok01 +has-props + + + + + + + + + + + + + + + + + + + + +8250 + +USB_MIDI.cpp +file + + + + +2011-11-02T14:08:48.200000Z +39df5c4e7057e3ef31911dbcfce8350a +2011-11-02T18:07:32.701563Z +838 +sammok01 +has-props + + + + + + + + + + + + + + + + + + + + +3148 + +USB_MIDI.h +file + + + + +2011-11-02T14:08:57.645000Z +94b814582d5b6ee053361d120c65464b +2011-11-02T18:07:32.701563Z +838 +sammok01 +has-props + + + + + + + + + + + + + + + + + + + + +1645 +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBMIDI/.svn/prop-base/MIDIMessage.h.svn-base Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 10 +text/plain +END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBMIDI/.svn/prop-base/USB_MIDI.cpp.svn-base Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 10 +text/plain +END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBMIDI/.svn/prop-base/USB_MIDI.h.svn-base Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 10 +text/plain +END
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBMIDI/.svn/text-base/MIDIMessage.h.svn-base	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,254 @@
+/* @license The MIT License
+ * Copyright (c) 2011 mux, simon
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *  
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *  
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MIDIMESSAGE_H
+#define MIDIMESSAGE_H
+
+#include "mbed.h"
+
+// MIDI Message Format
+// 
+// [ msg(4) | channel(4) ] [ 0 | n(7) ] [ 0 | m(7) ]
+//
+// MIDI Data Messages (Channel Specific)
+//
+// Message               msg n          m
+// ---------------------------------------------
+// Note Off              0x8 Key        Velocity
+// Note On               0x9 Key        Velocity
+// Polyphonic Aftertouch 0xA Key        Pressure
+// Control Change        0xB Controller Value
+// Program Change        0xC Program    -
+// Channel Aftertouch    0xD Pressure   -
+// Pitch Wheel           0xE LSB        MSB
+
+#define CABLE_NUM (0<<4)
+
+/** A MIDI message container */
+class MIDIMessage {
+public:
+    MIDIMessage() {}
+    
+    MIDIMessage(uint8_t *buf) {
+        *((uint32_t *)data) = *((uint32_t *)buf);
+    }
+    
+    // create messages
+    
+    /** Create a NoteOff message 
+     * @param key Key ID
+     * @param velocity Key velocity (0-127, default = 127)
+     * @param channel Key channel (0-15, default 0)
+     * @returns A MIDIMessage
+     */
+    static MIDIMessage NoteOff(int key, int velocity = 127, int channel = 0) {
+        MIDIMessage msg;
+        msg.data[0] = CABLE_NUM | 0x08;
+        msg.data[1] = 0x80 | (channel & 0x0F);
+        msg.data[2] = key & 0x7F;
+        msg.data[3] = velocity & 0x7F; 
+        return msg;
+    }
+    
+    /** Create a NoteOn message 
+     * @param key Key ID
+     * @param velocity Key velocity (0-127, default = 127)
+     * @param channel Key channel (0-15, default 0)
+     * @returns A MIDIMessage
+     */
+    static MIDIMessage NoteOn(int key, int velocity = 127, int channel = 0) {
+        MIDIMessage msg;
+        msg.data[0] = CABLE_NUM | 0x09;
+        msg.data[1] = 0x90 | (channel & 0x0F);
+        msg.data[2] = key & 0x7F;
+        msg.data[3] = velocity & 0x7F;                 
+        return msg;
+    }
+    
+    /** Create a PolyPhonic Aftertouch message 
+     * @param key Key ID
+     * @param pressure Aftertouch pressure (0-127)
+     * @param channel Key channel (0-15, default 0)
+     * @returns A MIDIMessage
+     */    
+    static MIDIMessage PolyphonicAftertouch(int key, int pressure, int channel = 0) {
+        MIDIMessage msg;
+        msg.data[0] = CABLE_NUM | 0x0A;
+        msg.data[1] = 0xA0 | (channel & 0x0F);
+        msg.data[2] = key & 0x7F;
+        msg.data[3] = pressure & 0x7F;         
+        return msg;
+    }
+    
+    /** Create a Control Change message 
+     * @param control Controller ID
+     * @param value Controller value (0-127)
+     * @param channel Controller channel (0-15, default 0)
+     * @returns A MIDIMessage
+     */
+    static MIDIMessage ControlChange(int control, int value, int channel = 0) {
+        MIDIMessage msg;
+        msg.data[0] = CABLE_NUM | 0x0B;
+        msg.data[1] = 0xB0 | (channel & 0x0F);
+        msg.data[2] = control & 0x7F;
+        msg.data[3] = value & 0x7F;         
+        return msg;
+    }
+    
+    /** Create a Program Change message 
+     * @param program Program ID
+     * @param channel Channel (0-15, default 0)
+     * @returns A MIDIMessage
+     */    
+    static MIDIMessage ProgramChange(int program, int channel = 0) {
+        MIDIMessage msg;
+        msg.data[0] = CABLE_NUM | 0x0C;
+        msg.data[1] = 0xC0 | (channel & 0x0F);
+        msg.data[2] = program & 0x7F;
+        msg.data[3] = 0x00;         
+        return msg;
+    }
+    
+    /** Create a Channel Aftertouch message 
+     * @param pressure Pressure 
+     * @param channel Key channel (0-15, default 0)
+     * @returns A MIDIMessage
+     */    
+    static MIDIMessage ChannelAftertouch(int pressure, int channel = 0) {
+        MIDIMessage msg;
+        msg.data[0] = CABLE_NUM | 0x0D;
+        msg.data[1] = 0xD0 | (channel & 0x0F);
+        msg.data[2] = pressure & 0x7F;
+        msg.data[3] = 0x00;         
+        return msg;
+    }
+    
+    /** Create a Pitch Wheel message 
+     * @param pitch Pitch (-8192 - 8191, default = 0)
+     * @param channel Channel (0-15, default 0)
+     * @returns A MIDIMessage
+     */    
+    static MIDIMessage PitchWheel(int pitch = 0, int channel = 0) {
+        MIDIMessage msg;
+        int p = pitch + 8192;    // 0 - 16383, 8192 is center
+        msg.data[0] = CABLE_NUM | 0x0E;
+        msg.data[1] = 0xE0 | (channel & 0x0F);
+        msg.data[2] = p & 0x7F;
+        msg.data[3] = (p >> 7) & 0x7F;                 
+        return msg;
+    }
+    
+    /** Create an All Notes Off message 
+     * @param channel Channel (0-15, default 0)
+     * @returns A MIDIMessage
+     */    
+    static MIDIMessage AllNotesOff(int channel = 0) {
+        return ControlChange(123, 0, channel);
+    }
+    
+    // decode messages
+    
+    /** MIDI Message Types */
+    enum MIDIMessageType {
+        ErrorType,
+        NoteOffType,
+        NoteOnType,
+        PolyphonicAftertouchType,
+        ControlChangeType,
+        ProgramChangeType,
+        ChannelAftertouchType,
+        PitchWheelType,
+        AllNotesOffType
+    };
+    
+    /** Read the message type
+     * @returns MIDIMessageType
+     */    
+    MIDIMessageType type() {
+        switch((data[1] >> 4) & 0xF) {
+            case 0x8: return NoteOffType;
+            case 0x9: return NoteOnType;
+            case 0xA: return PolyphonicAftertouchType;
+            case 0xB: 
+                if(controller() < 120) { // standard controllers
+                    return ControlChangeType;
+                } else if(controller() == 123) {
+                    return AllNotesOffType;
+                } else {
+                    return ErrorType; // unsupported atm
+                }
+            case 0xC: return ProgramChangeType;
+            case 0xD: return ChannelAftertouchType;
+            case 0xE: return PitchWheelType;
+            default: return ErrorType;
+        }
+    }
+
+    /** Read the channel number */    
+    int channel() {
+        return (data[1] & 0x0F);
+    }
+    
+    /** Read the key ID */    
+    int key() {
+        return (data[2] & 0x7F);        
+    }
+        
+    /** Read the velocity */    
+    int velocity() {
+        return (data[3] & 0x7F);        
+    }
+
+    /** Read the controller value */    
+    int value() {
+        return (data[3] & 0x7F);        
+    }
+    
+    /** Read the aftertouch pressure */        
+    int pressure() {
+        if(type() == PolyphonicAftertouchType) {
+            return (data[3] & 0x7F);        
+        } else {
+            return (data[2] & 0x7F);        
+        }
+    }
+
+    /** Read the controller number */    
+    int controller() {
+        return (data[2] & 0x7F);        
+    }
+
+    /** Read the program number */    
+    int program() {
+        return (data[2] & 0x7F);        
+    }
+    
+    /** Read the pitch value */        
+    int pitch() {
+        int p = ((data[3] & 0x7F) << 7) | (data[2] & 0x7F);
+        return p - 8192; // 0 - 16383, 8192 is center
+    }
+    
+    uint8_t data[4];
+};    
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBMIDI/.svn/text-base/USB_MIDI.cpp.svn-base	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,110 @@
+// USB_MIDI.cpp
+// MIDI edvice example
+// Copyright (c) 2011 ARM Limited. All rights reserved.
+
+#include "stdint.h"
+#include "USB_MIDI.h"
+#include "USBBusInterface.h"
+
+
+USB_MIDI::USB_MIDI(uint16_t vendor_id, uint16_t product_id, uint16_t product_release): USBDevice(vendor_id, product_id, product_release) {
+	midi_evt = NULL;
+}
+
+void USB_MIDI::write(MIDIMessage m) {
+	USBDevice::write(EPBULK_OUT, m.data, 4, 64);
+}
+
+
+void USB_MIDI::attach(void (*fptr)(MIDIMessage)) {
+	midi_evt = fptr;
+}
+
+
+bool USB_MIDI::EPBULK_OUT_callback()
+{
+	uint8_t buf[64];
+	uint16_t len;
+	read(EPBULK_OUT, buf, &len, 64);
+
+	if (midi_evt != NULL) {
+		for(int i=0; i<len; i+=4){
+			midi_evt(MIDIMessage(buf+i));
+		}
+	}
+
+	// We reactivate the endpoint to receive next characters
+	readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
+	return true;
+}
+
+
+
+bool USB_MIDI::USBCallback_setConfiguration(uint8_t configuration) {
+	// Called in ISR context
+	// Set configuration. Return false if the
+	// configuration is not supported.
+	if (configuration != DEFAULT_CONFIGURATION) {
+		return false;
+	}
+
+	// Configure endpoints > 0
+	addEndpoint(EPBULK_IN, MAX_PACKET_SIZE_EPBULK);
+	addEndpoint(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
+
+	// We activate the endpoint to be able to recceive data
+	readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
+	return true;
+}
+
+
+uint8_t * USB_MIDI::stringIinterfaceDesc() {
+	static uint8_t stringIinterfaceDescriptor[] = {
+			0x0c,                           //bLength
+			STRING_DESCRIPTOR,              //bDescriptorType 0x03
+			'A',0,'u',0,'d',0,'i',0,'o',0   //bString iInterface - Audio
+	};
+	return stringIinterfaceDescriptor;
+}
+
+uint8_t * USB_MIDI::stringIproductDesc() {
+	static uint8_t stringIproductDescriptor[] = {
+			0x16,                                                   	//bLength
+			STRING_DESCRIPTOR,                                      	//bDescriptorType 0x03
+			'M',0,'b',0,'e',0,'d',0,' ',0,'A',0,'u',0,'d',0,'i',0,'o',0 //bString iProduct - Mbed Audio
+	};
+	return stringIproductDescriptor;
+}
+
+
+#define CONFIG1_DESC_SIZE (9+34+12+18+14+14)
+
+uint8_t * USB_MIDI::configurationDesc() {
+	static uint8_t configDescriptor[] = {
+			// configuration descriptor
+			0x09, 0x02, 0x65, 0x00, 0x02, 0x01, 0x00, 0xc0, 0x50,
+
+			// The Audio Interface Collection
+			0x09, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, // Standard AC Interface Descriptor
+			0x09, 0x24, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x01, // Class-specific AC Interface Descriptor
+			0x09, 0x04, 0x01, 0x00, 0x02, 0x01, 0x03, 0x00, 0x00, // MIDIStreaming Interface Descriptors
+			0x07, 0x24, 0x01, 0x00, 0x01, 0x41, 0x00,             // Class-Specific MS Interface Header Descriptor
+
+			// MIDI IN JACKS
+			0x06, 0x24, 0x02, 0x01, 0x01, 0x00,
+			0x06, 0x24, 0x02, 0x02, 0x02, 0x00,
+
+			// MIDI OUT JACKS
+			0x09, 0x24, 0x03, 0x01, 0x03, 0x01, 0x02, 0x01, 0x00,
+			0x09, 0x24, 0x03, 0x02, 0x06, 0x01, 0x01, 0x01, 0x00,
+
+			// OUT endpoint descriptor
+			0x09, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00,
+			0x05, 0x25, 0x01, 0x01, 0x01,
+
+			// IN endpoint descriptor
+			0x09, 0x05, 0x82, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00,
+			0x05, 0x25, 0x01, 0x01, 0x03,
+	};
+	return configDescriptor;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBMIDI/.svn/text-base/USB_MIDI.h.svn-base	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,77 @@
+/* USB_MIDI.h */
+/* MIDI device example */
+/* Copyright (c) 2011 ARM Limited. All rights reserved. */
+
+#ifndef USB_MIDI_H
+#define USB_MIDI_H
+
+/* These headers are included for child class. */
+#include "USBEndpoints.h"
+#include "USBDescriptor.h"
+#include "USBDevice_Types.h"
+
+#include "USBDevice.h"
+#include "MIDIMessage.h"
+
+#define DEFAULT_CONFIGURATION (1)
+
+
+class USB_MIDI: public USBDevice {
+public:
+
+    /**
+    * Constructor
+    *
+    * @param vendor_id Your vendor_id
+    * @param product_id Your product_id
+    * @param product_release Your preoduct_release
+    */
+    USB_MIDI(uint16_t vendor_id = 0x0768, uint16_t product_id = 0x0100, uint16_t product_release = 0x0001);
+
+    virtual bool USBCallback_setConfiguration(uint8_t configuration);
+    
+    /**
+    * Get string product descriptor
+    *
+    * @returns pointer to the string product descriptor
+    */
+    virtual uint8_t * stringIproductDesc();
+    
+    /**
+    * Get string interface descriptor
+    *
+    * @returns pointer to the string interface descriptor
+    */
+    virtual uint8_t * stringIinterfaceDesc();
+    
+    /**
+    * Get configuration descriptor
+    *
+    * @returns pointer to the configuration descriptor
+    */
+    virtual uint8_t * configurationDesc();
+    
+    /**
+     * Send a MIDIMessage
+     *
+     * @param m The MIDIMessage to send
+     */    
+    void write(MIDIMessage m);
+
+    /**
+     * Attach a callback for when a MIDIEvent is received
+     *
+     * @param fptr function pointer
+     */
+    void attach(void (*fptr)(MIDIMessage));
+    
+protected:
+    virtual bool EPBULK_OUT_callback();
+
+private:
+    void (*midi_evt)(MIDIMessage);
+
+};
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBMIDI/MIDIMessage.h	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,250 @@
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MIDIMESSAGE_H
+#define MIDIMESSAGE_H
+
+#include "mbed.h"
+
+// MIDI Message Format
+// 
+// [ msg(4) | channel(4) ] [ 0 | n(7) ] [ 0 | m(7) ]
+//
+// MIDI Data Messages (Channel Specific)
+//
+// Message               msg n          m
+// ---------------------------------------------
+// Note Off              0x8 Key        Velocity
+// Note On               0x9 Key        Velocity
+// Polyphonic Aftertouch 0xA Key        Pressure
+// Control Change        0xB Controller Value
+// Program Change        0xC Program    -
+// Channel Aftertouch    0xD Pressure   -
+// Pitch Wheel           0xE LSB        MSB
+
+#define CABLE_NUM (0<<4)
+
+/** A MIDI message container */
+class MIDIMessage {
+public:
+    MIDIMessage() {}
+    
+    MIDIMessage(uint8_t *buf) {
+        *((uint32_t *)data) = *((uint32_t *)buf);
+    }
+    
+    // create messages
+    
+    /** Create a NoteOff message 
+     * @param key Key ID
+     * @param velocity Key velocity (0-127, default = 127)
+     * @param channel Key channel (0-15, default 0)
+     * @returns A MIDIMessage
+     */
+    static MIDIMessage NoteOff(int key, int velocity = 127, int channel = 0) {
+        MIDIMessage msg;
+        msg.data[0] = CABLE_NUM | 0x08;
+        msg.data[1] = 0x80 | (channel & 0x0F);
+        msg.data[2] = key & 0x7F;
+        msg.data[3] = velocity & 0x7F; 
+        return msg;
+    }
+    
+    /** Create a NoteOn message 
+     * @param key Key ID
+     * @param velocity Key velocity (0-127, default = 127)
+     * @param channel Key channel (0-15, default 0)
+     * @returns A MIDIMessage
+     */
+    static MIDIMessage NoteOn(int key, int velocity = 127, int channel = 0) {
+        MIDIMessage msg;
+        msg.data[0] = CABLE_NUM | 0x09;
+        msg.data[1] = 0x90 | (channel & 0x0F);
+        msg.data[2] = key & 0x7F;
+        msg.data[3] = velocity & 0x7F;                 
+        return msg;
+    }
+    
+    /** Create a PolyPhonic Aftertouch message 
+     * @param key Key ID
+     * @param pressure Aftertouch pressure (0-127)
+     * @param channel Key channel (0-15, default 0)
+     * @returns A MIDIMessage
+     */    
+    static MIDIMessage PolyphonicAftertouch(int key, int pressure, int channel = 0) {
+        MIDIMessage msg;
+        msg.data[0] = CABLE_NUM | 0x0A;
+        msg.data[1] = 0xA0 | (channel & 0x0F);
+        msg.data[2] = key & 0x7F;
+        msg.data[3] = pressure & 0x7F;         
+        return msg;
+    }
+    
+    /** Create a Control Change message 
+     * @param control Controller ID
+     * @param value Controller value (0-127)
+     * @param channel Controller channel (0-15, default 0)
+     * @returns A MIDIMessage
+     */
+    static MIDIMessage ControlChange(int control, int value, int channel = 0) {
+        MIDIMessage msg;
+        msg.data[0] = CABLE_NUM | 0x0B;
+        msg.data[1] = 0xB0 | (channel & 0x0F);
+        msg.data[2] = control & 0x7F;
+        msg.data[3] = value & 0x7F;         
+        return msg;
+    }
+    
+    /** Create a Program Change message 
+     * @param program Program ID
+     * @param channel Channel (0-15, default 0)
+     * @returns A MIDIMessage
+     */    
+    static MIDIMessage ProgramChange(int program, int channel = 0) {
+        MIDIMessage msg;
+        msg.data[0] = CABLE_NUM | 0x0C;
+        msg.data[1] = 0xC0 | (channel & 0x0F);
+        msg.data[2] = program & 0x7F;
+        msg.data[3] = 0x00;         
+        return msg;
+    }
+    
+    /** Create a Channel Aftertouch message 
+     * @param pressure Pressure 
+     * @param channel Key channel (0-15, default 0)
+     * @returns A MIDIMessage
+     */    
+    static MIDIMessage ChannelAftertouch(int pressure, int channel = 0) {
+        MIDIMessage msg;
+        msg.data[0] = CABLE_NUM | 0x0D;
+        msg.data[1] = 0xD0 | (channel & 0x0F);
+        msg.data[2] = pressure & 0x7F;
+        msg.data[3] = 0x00;         
+        return msg;
+    }
+    
+    /** Create a Pitch Wheel message 
+     * @param pitch Pitch (-8192 - 8191, default = 0)
+     * @param channel Channel (0-15, default 0)
+     * @returns A MIDIMessage
+     */    
+    static MIDIMessage PitchWheel(int pitch = 0, int channel = 0) {
+        MIDIMessage msg;
+        int p = pitch + 8192;    // 0 - 16383, 8192 is center
+        msg.data[0] = CABLE_NUM | 0x0E;
+        msg.data[1] = 0xE0 | (channel & 0x0F);
+        msg.data[2] = p & 0x7F;
+        msg.data[3] = (p >> 7) & 0x7F;                 
+        return msg;
+    }
+    
+    /** Create an All Notes Off message 
+     * @param channel Channel (0-15, default 0)
+     * @returns A MIDIMessage
+     */    
+    static MIDIMessage AllNotesOff(int channel = 0) {
+        return ControlChange(123, 0, channel);
+    }
+    
+    // decode messages
+    
+    /** MIDI Message Types */
+    enum MIDIMessageType {
+        ErrorType,
+        NoteOffType,
+        NoteOnType,
+        PolyphonicAftertouchType,
+        ControlChangeType,
+        ProgramChangeType,
+        ChannelAftertouchType,
+        PitchWheelType,
+        AllNotesOffType
+    };
+    
+    /** Read the message type
+     * @returns MIDIMessageType
+     */    
+    MIDIMessageType type() {
+        switch((data[1] >> 4) & 0xF) {
+            case 0x8: return NoteOffType;
+            case 0x9: return NoteOnType;
+            case 0xA: return PolyphonicAftertouchType;
+            case 0xB: 
+                if(controller() < 120) { // standard controllers
+                    return ControlChangeType;
+                } else if(controller() == 123) {
+                    return AllNotesOffType;
+                } else {
+                    return ErrorType; // unsupported atm
+                }
+            case 0xC: return ProgramChangeType;
+            case 0xD: return ChannelAftertouchType;
+            case 0xE: return PitchWheelType;
+            default: return ErrorType;
+        }
+    }
+
+    /** Read the channel number */    
+    int channel() {
+        return (data[1] & 0x0F);
+    }
+    
+    /** Read the key ID */    
+    int key() {
+        return (data[2] & 0x7F);        
+    }
+        
+    /** Read the velocity */    
+    int velocity() {
+        return (data[3] & 0x7F);        
+    }
+
+    /** Read the controller value */    
+    int value() {
+        return (data[3] & 0x7F);        
+    }
+    
+    /** Read the aftertouch pressure */        
+    int pressure() {
+        if(type() == PolyphonicAftertouchType) {
+            return (data[3] & 0x7F);        
+        } else {
+            return (data[2] & 0x7F);        
+        }
+    }
+
+    /** Read the controller number */    
+    int controller() {
+        return (data[2] & 0x7F);        
+    }
+
+    /** Read the program number */    
+    int program() {
+        return (data[2] & 0x7F);        
+    }
+    
+    /** Read the pitch value */        
+    int pitch() {
+        int p = ((data[3] & 0x7F) << 7) | (data[2] & 0x7F);
+        return p - 8192; // 0 - 16383, 8192 is center
+    }
+    
+    uint8_t data[4];
+};    
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBMIDI/USBMIDI.cpp	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,122 @@
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include "stdint.h"
+#include "USBMIDI.h"
+#include "USBBusInterface.h"
+
+
+USBMIDI::USBMIDI(uint16_t vendor_id, uint16_t product_id, uint16_t product_release): USBDevice(vendor_id, product_id, product_release) {
+    midi_evt = NULL;
+    USBDevice::connect();
+}
+
+void USBMIDI::write(MIDIMessage m) {
+    USBDevice::write(EPBULK_IN, m.data, 4, MAX_PACKET_SIZE_EPBULK);
+}
+
+
+void USBMIDI::attach(void (*fptr)(MIDIMessage)) {
+    midi_evt = fptr;
+}
+
+
+bool USBMIDI::EP2_OUT_callback() {
+    uint8_t buf[64];
+    uint16_t len;
+    read(EPBULK_OUT, buf, &len, 64);
+
+    if (midi_evt != NULL) {
+        for (int i=0; i<len; i+=4) {
+            midi_evt(MIDIMessage(buf+i));
+        }
+    }
+
+    // We reactivate the endpoint to receive next characters
+    readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
+    return true;
+}
+
+
+
+// Called in ISR context
+// Set configuration. Return false if the
+// configuration is not supported.
+bool USBMIDI::USBCallback_setConfiguration(uint8_t configuration) {
+    if (configuration != DEFAULT_CONFIGURATION) {
+        return false;
+    }
+
+    // Configure endpoints > 0
+    addEndpoint(EPBULK_IN, MAX_PACKET_SIZE_EPBULK);
+    addEndpoint(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
+
+    // We activate the endpoint to be able to receive data
+    readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
+    return true;
+}
+
+
+uint8_t * USBMIDI::stringIinterfaceDesc() {
+    static uint8_t stringIinterfaceDescriptor[] = {
+        0x0c,                           //bLength
+        STRING_DESCRIPTOR,              //bDescriptorType 0x03
+        'A',0,'u',0,'d',0,'i',0,'o',0   //bString iInterface - Audio
+    };
+    return stringIinterfaceDescriptor;
+}
+
+uint8_t * USBMIDI::stringIproductDesc() {
+    static uint8_t stringIproductDescriptor[] = {
+        0x16,                                                       //bLength
+        STRING_DESCRIPTOR,                                          //bDescriptorType 0x03
+        'M',0,'b',0,'e',0,'d',0,' ',0,'A',0,'u',0,'d',0,'i',0,'o',0 //bString iProduct - Mbed Audio
+    };
+    return stringIproductDescriptor;
+}
+
+
+uint8_t * USBMIDI::configurationDesc() {
+    static uint8_t configDescriptor[] = {
+        // configuration descriptor
+        0x09, 0x02, 0x65, 0x00, 0x02, 0x01, 0x00, 0xc0, 0x50,
+
+        // The Audio Interface Collection
+        0x09, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, // Standard AC Interface Descriptor
+        0x09, 0x24, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x01, // Class-specific AC Interface Descriptor
+        0x09, 0x04, 0x01, 0x00, 0x02, 0x01, 0x03, 0x00, 0x00, // MIDIStreaming Interface Descriptors
+        0x07, 0x24, 0x01, 0x00, 0x01, 0x41, 0x00,             // Class-Specific MS Interface Header Descriptor
+
+        // MIDI IN JACKS
+        0x06, 0x24, 0x02, 0x01, 0x01, 0x00,
+        0x06, 0x24, 0x02, 0x02, 0x02, 0x00,
+
+        // MIDI OUT JACKS
+        0x09, 0x24, 0x03, 0x01, 0x03, 0x01, 0x02, 0x01, 0x00,
+        0x09, 0x24, 0x03, 0x02, 0x06, 0x01, 0x01, 0x01, 0x00,
+
+        // OUT endpoint descriptor
+        0x09, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00,
+        0x05, 0x25, 0x01, 0x01, 0x01,
+
+        // IN endpoint descriptor
+        0x09, 0x05, 0x82, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00,
+        0x05, 0x25, 0x01, 0x01, 0x03,
+    };
+    return configDescriptor;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBMIDI/USBMIDI.h	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,110 @@
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef USBMIDI_H
+#define USBMIDI_H
+
+/* These headers are included for child class. */
+#include "USBEndpoints.h"
+#include "USBDescriptor.h"
+#include "USBDevice_Types.h"
+
+#include "USBDevice.h"
+#include "MIDIMessage.h"
+
+#define DEFAULT_CONFIGURATION (1)
+
+/** 
+* USBMIDI example
+*
+* @code
+* #include "mbed.h"
+* #include "USBMIDI.h"
+*
+* USBMIDI midi;
+*
+* int main() {            
+*    while (1) {    
+*        for(int i=48; i<83; i++) {     // send some messages!
+*            midi.write(MIDIMessage::NoteOn(i));
+*            wait(0.25);
+*            midi.write(MIDIMessage::NoteOff(i));
+*            wait(0.5);
+*        }
+*    }
+* }
+* @endcode
+*/
+class USBMIDI: public USBDevice {
+public:
+
+    /**
+    * Constructor
+    *
+    * @param vendor_id Your vendor_id
+    * @param product_id Your product_id
+    * @param product_release Your preoduct_release
+    */
+    USBMIDI(uint16_t vendor_id = 0x0700, uint16_t product_id = 0x0101, uint16_t product_release = 0x0001);
+    
+    /**
+     * Send a MIDIMessage
+     *
+     * @param m The MIDIMessage to send
+     */    
+    void write(MIDIMessage m);
+
+    /**
+     * Attach a callback for when a MIDIEvent is received
+     *
+     * @param fptr function pointer
+     */
+    void attach(void (*fptr)(MIDIMessage));
+    
+    
+protected:
+    virtual bool EP2_OUT_callback();
+    virtual bool USBCallback_setConfiguration(uint8_t configuration);
+    /*
+    * Get string product descriptor
+    *
+    * @returns pointer to the string product descriptor
+    */
+    virtual uint8_t * stringIproductDesc();
+    
+    /*
+    * Get string interface descriptor
+    *
+    * @returns pointer to the string interface descriptor
+    */
+    virtual uint8_t * stringIinterfaceDesc();
+    
+    /*
+    * Get configuration descriptor
+    *
+    * @returns pointer to the configuration descriptor
+    */
+    virtual uint8_t * configurationDesc();
+
+private:
+    void (*midi_evt)(MIDIMessage);
+
+};
+
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBSERIAL/.svn/all-wcprops Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,29 @@ +K 25 +svn:wc:ra_dav:version-url +V 76 +/svn/sdd/mbed/!svn/ver/838/product/libraries/branches/emilmont/usb/USBSERIAL +END +USBSerial.h +K 25 +svn:wc:ra_dav:version-url +V 88 +/svn/sdd/mbed/!svn/ver/838/product/libraries/branches/emilmont/usb/USBSERIAL/USBSerial.h +END +USBCDC.cpp +K 25 +svn:wc:ra_dav:version-url +V 87 +/svn/sdd/mbed/!svn/ver/838/product/libraries/branches/emilmont/usb/USBSERIAL/USBCDC.cpp +END +USBCDC.h +K 25 +svn:wc:ra_dav:version-url +V 85 +/svn/sdd/mbed/!svn/ver/838/product/libraries/branches/emilmont/usb/USBSERIAL/USBCDC.h +END +USBSerial.cpp +K 25 +svn:wc:ra_dav:version-url +V 90 +/svn/sdd/mbed/!svn/ver/838/product/libraries/branches/emilmont/usb/USBSERIAL/USBSerial.cpp +END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBSERIAL/.svn/entries Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,171 @@ +10 + +dir +838 +http://cam-svn2.cambridge.arm.com/svn/sdd/mbed/product/libraries/branches/emilmont/usb/USBSERIAL +http://cam-svn2.cambridge.arm.com/svn/sdd/mbed + + + +2011-11-02T18:07:32.701563Z +838 +sammok01 + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +55d82849-f8ce-43ef-8e1a-fbdbc5b469c3 + + + + + + +0 + +USBCDC.cpp +file + + + + +2011-11-02T14:07:52.929000Z +14cd306299124913d12e3dbb6202e5de +2011-11-02T18:07:32.701563Z +838 +sammok01 +has-props + + + + + + + + + + + + + + + + + + + + +7803 + +USBCDC.h +file + + + + +2011-11-02T14:08:10.674000Z +5cf17aa6b0d4f34ac24f832efb4856ca +2011-11-02T18:07:32.701563Z +838 +sammok01 +has-props + + + + + + + + + + + + + + + + + + + + +2868 + +USBSerial.cpp +file + + + + +2011-11-02T12:56:52.551000Z +9cf5ddff2a10fd4d182e8cfdf39dcb06 +2011-11-02T18:07:32.701563Z +838 +sammok01 +has-props + + + + + + + + + + + + + + + + + + + + +783 + +USBSerial.h +file + + + + +2011-11-02T13:03:26.102000Z +95d011ea515e26b97f067ba6a50e8eee +2011-11-02T18:07:32.701563Z +838 +sammok01 +has-props + + + + + + + + + + + + + + + + + + + + +1854 +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBSERIAL/.svn/prop-base/USBCDC.cpp.svn-base Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 10 +text/plain +END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBSERIAL/.svn/prop-base/USBCDC.h.svn-base Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 10 +text/plain +END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBSERIAL/.svn/prop-base/USBSerial.cpp.svn-base Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 10 +text/plain +END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBSERIAL/.svn/prop-base/USBSerial.h.svn-base Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 10 +text/plain +END
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBSERIAL/.svn/text-base/USBCDC.cpp.svn-base	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,222 @@
+/* USBCDC.c */
+/* CDC class */
+/* Copyright (c) 2011 ARM Limited. All rights reserved. */
+
+#include "stdint.h"
+#include "USBCDC.h"
+#include "USBBusInterface.h"
+
+static uint8_t cdc_line_coding[7]={0x80, 0x25, 0x00, 0x00, 0x00, 0x00, 0x08};
+
+USBCDC::USBCDC(uint16_t vendor_id, uint16_t product_id, uint16_t product_release): USBDevice(vendor_id, product_id, product_release) {
+}
+
+bool USBCDC::USBCallback_request(void) {
+	/* Called in ISR context */
+
+	bool success = false;
+	CONTROL_TRANSFER * transfer = getTransferPtr();
+
+	/* Process class-specific requests */
+
+	if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
+		switch (transfer->setup.bRequest) {
+		case CDC_GET_LINE_CODING:
+			transfer->remaining = 7;
+			transfer->ptr = cdc_line_coding;
+			transfer->direction = DEVICE_TO_HOST;
+			success = true;
+			break;
+		case CDC_SET_LINE_CODING:
+			transfer->remaining = 7;
+			success = true;
+			break;
+		default:
+			break;
+		}
+	}
+
+	return success;
+}
+
+/*
+ *  Route callbacks from lower layers to class(es)
+ */
+
+
+bool USBCDC::USBCallback_setConfiguration(uint8_t configuration) {
+	// Called in ISR context
+	// Set configuration. Return false if the
+	// configuration is not supported.
+	if (configuration != DEFAULT_CONFIGURATION) {
+		return false;
+	}
+
+	// Configure endpoints > 0
+	addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);
+	addEndpoint(EPBULK_IN, MAX_PACKET_SIZE_EPBULK);
+	addEndpoint(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
+
+	// We activate the endpoint to be able to recceive data
+	readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
+	return true;
+}
+
+bool USBCDC::send(uint8_t endpoint, uint8_t * buffer, uint16_t size)
+{
+	return write(endpoint, buffer, size, MAX_CDC_REPORT_SIZE);
+}
+
+bool USBCDC::read(uint8_t endpoint, uint8_t * buffer, uint16_t * size, uint16_t maxSize)
+{
+	if(!USBDevice::read(endpoint, buffer, size, maxSize))
+		return false;
+	if(!readStart(endpoint, maxSize))
+		return false;
+	return true;
+}
+
+bool USBCDC::readNB(uint8_t endpoint, uint8_t * buffer, uint16_t * size, uint16_t maxSize)
+{
+	if(!USBDevice::readNB(endpoint, buffer, size, MAX_CDC_REPORT_SIZE))
+		return false;
+	if(!readStart(endpoint, MAX_CDC_REPORT_SIZE))
+		return false;
+	return true;
+}
+
+
+uint8_t * USBCDC::deviceDesc() {
+	static uint8_t deviceDescriptor[] = {
+			18,                    // bLength
+			1,                    // bDescriptorType
+			0x00, 0x02,                // bcdUSB
+			2,                    // bDeviceClass
+			0,                    // bDeviceSubClass
+			0,                    // bDeviceProtocol
+			MAX_PACKET_SIZE_EP0,                // bMaxPacketSize0
+			LSB(VENDOR_ID), MSB(VENDOR_ID),        // idVendor
+			LSB(PRODUCT_ID), MSB(PRODUCT_ID),    // idProduct
+			0x00, 0x01,                // bcdDevice
+			1,                    // iManufacturer
+			2,                    // iProduct
+			3,                    // iSerialNumber
+			1                    // bNumConfigurations
+	};
+	return deviceDescriptor;
+}
+
+uint8_t * USBCDC::stringIinterfaceDesc() {
+	static uint8_t stringIinterfaceDescriptor[] = {
+			0x08,                                                           /*bLength*/
+			STRING_DESCRIPTOR,                                              /*bDescriptorType 0x03*/
+			'C',0,'D',0,'C',0,                                              /*bString iInterface - HID*/
+	};
+	return stringIinterfaceDescriptor;
+}
+
+uint8_t * USBCDC::stringIproductDesc() {
+	static uint8_t stringIproductDescriptor[] = {
+			0x16,                                                   /*bLength*/
+			STRING_DESCRIPTOR,                                      /*bDescriptorType 0x03*/
+			'C',0,'D',0,'C',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0  /*bString iProduct - HID device*/
+	};
+	return stringIproductDescriptor;
+}
+
+
+#define CONFIG1_DESC_SIZE (9+9+5+5+4+5+7+9+7+7)
+
+uint8_t * USBCDC::configurationDesc() {
+	static uint8_t configDescriptor[] = {
+			// configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10
+			9,                     // bLength;
+			2,                    // bDescriptorType;
+			LSB(CONFIG1_DESC_SIZE),        // wTotalLength
+			MSB(CONFIG1_DESC_SIZE),
+			2,                    // bNumInterfaces
+			1,                    // bConfigurationValue
+			0,                    // iConfiguration
+			0xC0,                // bmAttributes
+			50,                    // bMaxPower
+
+			// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
+			9,                    // bLength
+			4,                    // bDescriptorType
+			0,                    // bInterfaceNumber
+			0,                    // bAlternateSetting
+			1,                    // bNumEndpoints
+			0x02,                // bInterfaceClass
+			0x02,                // bInterfaceSubClass
+			0x01,                // bInterfaceProtocol
+			0,                    // iInterface
+
+			// CDC Header Functional Descriptor, CDC Spec 5.2.3.1, Table 26
+			5,                    // bFunctionLength
+			0x24,                // bDescriptorType
+			0x00,                // bDescriptorSubtype
+			0x10, 0x01,            // bcdCDC
+
+			// Call Management Functional Descriptor, CDC Spec 5.2.3.2, Table 27
+			5,                    // bFunctionLength
+			0x24,                // bDescriptorType
+			0x01,                // bDescriptorSubtype
+			0x01,                // bmCapabilities
+			1,                    // bDataInterface
+
+			// Abstract Control Management Functional Descriptor, CDC Spec 5.2.3.3, Table 28
+			4,                    // bFunctionLength
+			0x24,                // bDescriptorType
+			0x02,                // bDescriptorSubtype
+			0x06,                // bmCapabilities
+
+			// Union Functional Descriptor, CDC Spec 5.2.3.8, Table 33
+			5,                    // bFunctionLength
+			0x24,                // bDescriptorType
+			0x06,                // bDescriptorSubtype
+			0,                    // bMasterInterface
+			1,                    // bSlaveInterface0
+
+			// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
+			ENDPOINT_DESCRIPTOR_LENGTH,                    // bLength
+			ENDPOINT_DESCRIPTOR,                    // bDescriptorType
+			PHY_TO_DESC(EPINT_IN),    // bEndpointAddress
+			E_INTERRUPT,                // bmAttributes (0x03=intr)
+			LSB(MAX_PACKET_SIZE_EPINT),     /* wMaxPacketSize (LSB) */
+			MSB(MAX_PACKET_SIZE_EPINT),     /* wMaxPacketSize (MSB) */
+			64,                    // bInterval
+
+
+
+
+			// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
+			9,                    // bLength
+			4,                    // bDescriptorType
+			1,                    // bInterfaceNumber
+			0,                    // bAlternateSetting
+			2,                    // bNumEndpoints
+			0x0A,                // bInterfaceClass
+			0x00,                // bInterfaceSubClass
+			0x00,                // bInterfaceProtocol
+			0,                    // iInterface
+
+			// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
+			7,                    // bLength
+			5,                    // bDescriptorType
+			PHY_TO_DESC(EPBULK_IN),    // bEndpointAddress
+			0x02,                // bmAttributes (0x02=bulk)
+			LSB(MAX_PACKET_SIZE_EPBULK),     /* wMaxPacketSize (LSB) */
+			MSB(MAX_PACKET_SIZE_EPBULK),     /* wMaxPacketSize (MSB) */
+			0,                    // bInterval
+
+			// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
+			7,                    // bLength
+			5,                    // bDescriptorType
+			PHY_TO_DESC(EPBULK_OUT),        // bEndpointAddress
+			0x02,                // bmAttributes (0x02=bulk)
+			LSB(MAX_PACKET_SIZE_EPBULK),     /* wMaxPacketSize (LSB) */
+			MSB(MAX_PACKET_SIZE_EPBULK),     /* wMaxPacketSize (MSB) */
+			0                    // bInterval
+	};
+	return configDescriptor;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBSERIAL/.svn/text-base/USBCDC.h.svn-base	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,102 @@
+/* USBCDC.h */
+/* CDC class */
+/* Copyright (c) 2011 ARM Limited. All rights reserved. */
+
+#ifndef USBCDC_H
+#define USBCDC_H
+
+/* These headers are included for child class. */
+#include "USBEndpoints.h"
+#include "USBDescriptor.h"
+#include "USBDevice_Types.h"
+
+#include "USBDevice.h"
+
+#define DEFAULT_CONFIGURATION (1)
+
+#define CDC_SET_LINE_CODING        0x20
+#define CDC_GET_LINE_CODING        0x21
+#define CDC_SET_CONTROL_LINE_STATE 0x22
+
+#define MAX_CDC_REPORT_SIZE (64)
+
+
+class USBCDC: public USBDevice {
+public:
+
+    /**
+    * Constructor
+    *
+    * @param vendor_id Your vendor_id
+    * @param product_id Your product_id
+    * @param product_release Your preoduct_release
+    */
+    USBCDC(uint16_t vendor_id, uint16_t product_id, uint16_t product_release);
+
+    
+    /**
+    * Get device descriptor. Warning: this method has to store the length of the report descriptor in reportLength.
+    *
+    * @returns pointer to the device descriptor
+    */
+    virtual uint8_t * deviceDesc();
+    
+    /**
+    * Get string product descriptor
+    *
+    * @returns pointer to the string product descriptor
+    */
+    virtual uint8_t * stringIproductDesc();
+    
+    /**
+    * Get string interface descriptor
+    *
+    * @returns pointer to the string interface descriptor
+    */
+    virtual uint8_t * stringIinterfaceDesc();
+    
+    /**
+    * Get configuration descriptor
+    *
+    * @returns pointer to the configuration descriptor
+    */
+    virtual uint8_t * configurationDesc();
+    
+    /**
+    * Send a buffer to a certain endpoint
+    *
+    * @param endpoint endpoint which will be sent the buffer
+    * @param buffer buffer to be sent
+    * @param size length of the buffer
+    * @returns true if successful
+    */
+    bool send(uint8_t endpoint, uint8_t * buffer, uint16_t size);
+    
+    /**
+    * Read a buffer from a certain endpoint. Warning: blocking
+    *
+    * @param endpoint endpoint to read
+    * @param buffer buffer where will be stored bytes
+    * @param size the number of bytes read will be stored in *size
+    * @param maxSize the maximum length that can be read
+    * @returns true if successful
+    */
+    bool read(uint8_t endpoint, uint8_t * buffer, uint16_t * size, uint16_t maxSize);
+    
+    /**
+    * Read a buffer from a certain endpoint. Warning: non blocking
+    *
+    * @param endpoint endpoint to read
+    * @param buffer buffer where will be stored bytes
+    * @param size the number of bytes read will be stored in *size
+    * @param maxSize the maximum length that can be read
+    * @returns true if successful
+    */
+    bool readNB(uint8_t endpoint, uint8_t * buffer, uint16_t * size, uint16_t maxSize);
+
+    virtual bool USBCallback_request();
+    virtual bool USBCallback_setConfiguration(uint8_t configuration);
+
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBSERIAL/.svn/text-base/USBSerial.cpp.svn-base	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,45 @@
+// USBSerial.c
+// USB device example: virtual serial port
+// Copyright (c) 2011 ARM Limited. All rights reserved
+
+#include "stdint.h"
+#include "USBSerial.h"
+#include "USBBusInterface.h"
+
+
+int USBSerial::_putc(int c) {
+	send(EPBULK_IN, (uint8_t *)&c, 1);
+	return 1;
+}
+
+int USBSerial::_getc() {
+	uint16_t size = 0;
+	uint8_t c[65];
+	if (!USBCDC::read(EPBULK_OUT, c, &size, 1))
+		return -1;
+	return c[0];
+}
+
+
+void USBSerial::attach(void (*ptr)(void))
+{
+	handler = true;
+	proc = true;
+	fn = ptr;
+}
+
+bool USBSerial::EPBULK_OUT_callback()
+{
+	if(handler)
+	{
+		if(proc)
+			(*fn)();
+		else
+			rx.call();
+
+		// We reactivate the endpoint to receive next characters
+		readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
+		return true;
+	}
+	return false;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBSERIAL/.svn/text-base/USBSerial.h.svn-base	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,76 @@
+/* USBSerial.h */
+/* USB device example: virtual serial port */
+/* Copyright (c) 2011 ARM Limited. All rights reserved. */
+
+#ifndef USBSERIAL_H
+#define USBSERIAL_H
+
+#include "USBCDC.h"
+#include "Stream.h"
+
+class USBSerial: public USBCDC, public Stream {
+public:
+
+    /**
+    *   Constructor
+    *
+    * @param vendor_id Your vendor_id (default: 0x1234)
+    * @param product_id Your product_id (default: 0x0001)
+    * @param product_release Your preoduct_release (default: 0x0001)
+    *
+    */
+    USBSerial(uint16_t vendor_id = 0x1FC9, uint16_t product_id = 0x2002, uint16_t product_release = 0x0001): USBCDC(vendor_id, product_id, product_release) {
+    	handler = false;
+    	proc = false;
+    };
+
+
+    /**
+    * Send a character. You can use puts, printf.
+    *
+    * @param c character to be sent
+    * @returns true if there is no error, false otherwise
+    */
+    virtual int _putc(int c);
+    
+    /**
+    * Read a character. You can use scanf.
+    *
+    * @returns character read
+    */
+    virtual int _getc();
+
+    /**
+     *  Attach a member function to call when a character is received
+     *
+     *  @param tptr pointer to the object to call the member function on
+     *  @param mptr pointer to the member function to be called
+     */
+    template<typename T>
+    void attach(T* tptr, void (T::*mptr)(void)) {
+        if((mptr != NULL) && (tptr != NULL)) {
+        	proc = false;
+        	handler = true;
+            rx.attach(tptr, mptr);
+        }
+    }
+
+    /**
+     * Attach a callback for when a character is received
+     *
+     * @param fptr function pointer
+     */
+    void attach(void (*fn)(void));
+
+
+protected:
+    virtual bool EPBULK_OUT_callback();
+
+private:
+    FunctionPointer rx;
+    void (*fn)(void);
+    bool handler;
+    bool proc;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBSERIAL/CBuffer.h	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,69 @@
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef CBUFFER_H
+#define CBUFFER_H
+
+#define MAX_BUF 128
+
+class CBuffer {
+public:
+    CBuffer() {
+        write = 0;
+        read = 0;
+        size = MAX_BUF + 1;
+    };
+
+    bool isFull() {
+        return ((write + 1) % size == read);
+    };
+
+    bool isEmpty() {
+        return (read == write);
+    };
+
+    void queue(uint8_t k) {
+        if (isFull()) {
+            read++;
+            read %= size;
+        }
+        buf[write++] = k;
+        write %= size;
+    }
+
+    uint16_t available() {
+        return (write >= read) ? write - read : size - read + write;
+    };
+
+    bool dequeue(uint8_t * c) {
+        if (!isEmpty()) {
+            *c = buf[read++];
+            read %= size;
+        }
+        return(isEmpty());
+    };
+
+
+private:
+    volatile uint16_t write;
+    volatile uint16_t read;
+    uint16_t size;
+    uint8_t buf[MAX_BUF + 1];
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBSERIAL/USBCDC.cpp	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,240 @@
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include "stdint.h"
+#include "USBCDC.h"
+#include "USBBusInterface.h"
+
+static uint8_t cdc_line_coding[7]= {0x80, 0x25, 0x00, 0x00, 0x00, 0x00, 0x08};
+
+#define DEFAULT_CONFIGURATION (1)
+
+#define CDC_SET_LINE_CODING        0x20
+#define CDC_GET_LINE_CODING        0x21
+#define CDC_SET_CONTROL_LINE_STATE 0x22
+
+#define MAX_CDC_REPORT_SIZE MAX_PACKET_SIZE_EPBULK
+
+USBCDC::USBCDC(uint16_t vendor_id, uint16_t product_id, uint16_t product_release): USBDevice(vendor_id, product_id, product_release) {
+    USBDevice::connect();
+}
+
+bool USBCDC::USBCallback_request(void) {
+    /* Called in ISR context */
+
+    bool success = false;
+    CONTROL_TRANSFER * transfer = getTransferPtr();
+
+    /* Process class-specific requests */
+
+    if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
+        switch (transfer->setup.bRequest) {
+            case CDC_GET_LINE_CODING:
+                transfer->remaining = 7;
+                transfer->ptr = cdc_line_coding;
+                transfer->direction = DEVICE_TO_HOST;
+                success = true;
+                break;
+            case CDC_SET_LINE_CODING:
+                transfer->remaining = 7;
+                success = true;
+                break;
+            case CDC_SET_CONTROL_LINE_STATE:
+                success = true;
+                break;
+            default:
+                break;
+        }
+    }
+
+    return success;
+}
+
+
+// Called in ISR context
+// Set configuration. Return false if the
+// configuration is not supported.
+bool USBCDC::USBCallback_setConfiguration(uint8_t configuration) {
+    if (configuration != DEFAULT_CONFIGURATION) {
+        return false;
+    }
+
+    // Configure endpoints > 0
+    addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);
+    addEndpoint(EPBULK_IN, MAX_PACKET_SIZE_EPBULK);
+    addEndpoint(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
+
+    // We activate the endpoint to be able to recceive data
+    readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
+    return true;
+}
+
+bool USBCDC::send(uint8_t endpoint, uint8_t * buffer, uint16_t size) {
+    return write(endpoint, buffer, size, MAX_CDC_REPORT_SIZE);
+}
+
+bool USBCDC::read(uint8_t endpoint, uint8_t * buffer, uint16_t * size, uint16_t maxSize) {
+    if (!USBDevice::read(endpoint, buffer, size, maxSize))
+        return false;
+    if (!readStart(endpoint, maxSize))
+        return false;
+    return true;
+}
+
+bool USBCDC::readNB(uint8_t endpoint, uint8_t * buffer, uint16_t * size, uint16_t maxSize) {
+    if (!USBDevice::readNB(endpoint, buffer, size, MAX_CDC_REPORT_SIZE))
+        return false;
+    if (!readStart(endpoint, MAX_CDC_REPORT_SIZE))
+        return false;
+    return true;
+}
+
+
+uint8_t * USBCDC::deviceDesc() {
+    static uint8_t deviceDescriptor[] = {
+        18,                   // bLength
+        1,                    // bDescriptorType
+        0x10, 0x01,           // bcdUSB
+        2,                    // bDeviceClass
+        0,                    // bDeviceSubClass
+        0,                    // bDeviceProtocol
+        MAX_PACKET_SIZE_EP0,  // bMaxPacketSize0
+        LSB(VENDOR_ID), MSB(VENDOR_ID),  // idVendor
+        LSB(PRODUCT_ID), MSB(PRODUCT_ID),// idProduct
+        0x00, 0x01,           // bcdDevice
+        1,                    // iManufacturer
+        2,                    // iProduct
+        3,                    // iSerialNumber
+        1                     // bNumConfigurations
+    };
+    return deviceDescriptor;
+}
+
+uint8_t * USBCDC::stringIinterfaceDesc() {
+    static uint8_t stringIinterfaceDescriptor[] = {
+        0x08,
+        STRING_DESCRIPTOR,
+        'C',0,'D',0,'C',0,
+    };
+    return stringIinterfaceDescriptor;
+}
+
+uint8_t * USBCDC::stringIproductDesc() {
+    static uint8_t stringIproductDescriptor[] = {
+        0x16,
+        STRING_DESCRIPTOR,
+        'C',0,'D',0,'C',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0
+    };
+    return stringIproductDescriptor;
+}
+
+
+#define CONFIG1_DESC_SIZE (9+9+5+5+4+5+7+9+7+7)
+
+uint8_t * USBCDC::configurationDesc() {
+    static uint8_t configDescriptor[] = {
+        9,                      // bLength;
+        2,                      // bDescriptorType;
+        LSB(CONFIG1_DESC_SIZE), // wTotalLength
+        MSB(CONFIG1_DESC_SIZE),
+        2,                      // bNumInterfaces
+        1,                      // bConfigurationValue
+        0,                      // iConfiguration
+        0x80,                   // bmAttributes
+        50,                     // bMaxPower
+
+        // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
+        9,                      // bLength
+        4,                      // bDescriptorType
+        0,                      // bInterfaceNumber
+        0,                      // bAlternateSetting
+        1,                      // bNumEndpoints
+        0x02,                   // bInterfaceClass
+        0x02,                   // bInterfaceSubClass
+        0x01,                   // bInterfaceProtocol
+        0,                      // iInterface
+
+        // CDC Header Functional Descriptor, CDC Spec 5.2.3.1, Table 26
+        5,                      // bFunctionLength
+        0x24,                   // bDescriptorType
+        0x00,                   // bDescriptorSubtype
+        0x10, 0x01,             // bcdCDC
+
+        // Call Management Functional Descriptor, CDC Spec 5.2.3.2, Table 27
+        5,                      // bFunctionLength
+        0x24,                   // bDescriptorType
+        0x01,                   // bDescriptorSubtype
+        0x03,                   // bmCapabilities
+        1,                      // bDataInterface
+
+        // Abstract Control Management Functional Descriptor, CDC Spec 5.2.3.3, Table 28
+        4,                      // bFunctionLength
+        0x24,                   // bDescriptorType
+        0x02,                   // bDescriptorSubtype
+        0x06,                   // bmCapabilities
+
+        // Union Functional Descriptor, CDC Spec 5.2.3.8, Table 33
+        5,                      // bFunctionLength
+        0x24,                   // bDescriptorType
+        0x06,                   // bDescriptorSubtype
+        0,                      // bMasterInterface
+        1,                      // bSlaveInterface0
+
+        // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
+        ENDPOINT_DESCRIPTOR_LENGTH,     // bLength
+        ENDPOINT_DESCRIPTOR,            // bDescriptorType
+        PHY_TO_DESC(EPINT_IN),          // bEndpointAddress
+        E_INTERRUPT,                    // bmAttributes (0x03=intr)
+        LSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (LSB)
+        MSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (MSB)
+        16,                             // bInterval
+
+
+
+
+        // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
+        9,          // bLength
+        4,          // bDescriptorType
+        1,          // bInterfaceNumber
+        0,          // bAlternateSetting
+        2,          // bNumEndpoints
+        0x0A,       // bInterfaceClass
+        0x00,       // bInterfaceSubClass
+        0x00,       // bInterfaceProtocol
+        0,          // iInterface
+
+        // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
+        7,                      // bLength
+        5,                      // bDescriptorType
+        PHY_TO_DESC(EPBULK_IN), // bEndpointAddress
+        0x02,                   // bmAttributes (0x02=bulk)
+        LSB(MAX_PACKET_SIZE_EPBULK),    // wMaxPacketSize (LSB)
+        MSB(MAX_PACKET_SIZE_EPBULK),    // wMaxPacketSize (MSB)
+        0,                      // bInterval
+
+        // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
+        7,                      // bLength
+        5,                      // bDescriptorType
+        PHY_TO_DESC(EPBULK_OUT),// bEndpointAddress
+        0x02,                   // bmAttributes (0x02=bulk)
+        LSB(MAX_PACKET_SIZE_EPBULK),    // wMaxPacketSize (LSB)
+        MSB(MAX_PACKET_SIZE_EPBULK),     // wMaxPacketSize (MSB)
+        0                       // bInterval
+    };
+    return configDescriptor;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBSERIAL/USBCDC.h	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,109 @@
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef USBCDC_H
+#define USBCDC_H
+
+/* These headers are included for child class. */
+#include "USBEndpoints.h"
+#include "USBDescriptor.h"
+#include "USBDevice_Types.h"
+
+#include "USBDevice.h"
+
+
+
+class USBCDC: public USBDevice {
+public:
+
+    /*
+    * Constructor
+    *
+    * @param vendor_id Your vendor_id
+    * @param product_id Your product_id
+    * @param product_release Your preoduct_release
+    */
+    USBCDC(uint16_t vendor_id, uint16_t product_id, uint16_t product_release);
+
+    
+    /*
+    * Get device descriptor. Warning: this method has to store the length of the report descriptor in reportLength.
+    *
+    * @returns pointer to the device descriptor
+    */
+    virtual uint8_t * deviceDesc();
+    
+    /*
+    * Get string product descriptor
+    *
+    * @returns pointer to the string product descriptor
+    */
+    virtual uint8_t * stringIproductDesc();
+    
+    /*
+    * Get string interface descriptor
+    *
+    * @returns pointer to the string interface descriptor
+    */
+    virtual uint8_t * stringIinterfaceDesc();
+    
+    /*
+    * Get configuration descriptor
+    *
+    * @returns pointer to the configuration descriptor
+    */
+    virtual uint8_t * configurationDesc();
+    
+    /*
+    * Send a buffer to a certain endpoint
+    *
+    * @param endpoint endpoint which will be sent the buffer
+    * @param buffer buffer to be sent
+    * @param size length of the buffer
+    * @returns true if successful
+    */
+    bool send(uint8_t endpoint, uint8_t * buffer, uint16_t size);
+    
+    /*
+    * Read a buffer from a certain endpoint. Warning: blocking
+    *
+    * @param endpoint endpoint to read
+    * @param buffer buffer where will be stored bytes
+    * @param size the number of bytes read will be stored in *size
+    * @param maxSize the maximum length that can be read
+    * @returns true if successful
+    */
+    bool read(uint8_t endpoint, uint8_t * buffer, uint16_t * size, uint16_t maxSize);
+    
+    /*
+    * Read a buffer from a certain endpoint. Warning: non blocking
+    *
+    * @param endpoint endpoint to read
+    * @param buffer buffer where will be stored bytes
+    * @param size the number of bytes read will be stored in *size
+    * @param maxSize the maximum length that can be read
+    * @returns true if successful
+    */
+    bool readNB(uint8_t endpoint, uint8_t * buffer, uint16_t * size, uint16_t maxSize);
+
+    virtual bool USBCallback_request();
+    virtual bool USBCallback_setConfiguration(uint8_t configuration);
+
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBSERIAL/USBSerial.cpp	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,69 @@
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include "stdint.h"
+#include "USBSerial.h"
+#include "USBBusInterface.h"
+
+
+int USBSerial::_putc(int c) {
+    send(EPBULK_IN, (uint8_t *)&c, 1);
+    return 1;
+}
+
+int USBSerial::_getc() {
+    uint8_t c;
+    while (buf.isEmpty());
+    buf.dequeue(&c);
+    return c;
+}
+
+void USBSerial::attach(void (*ptr)(void)) {
+    handler = true;
+    proc = true;
+    fn = ptr;
+}
+
+
+bool USBSerial::EP2_OUT_callback() {
+    uint8_t c[65];
+    uint16_t size = 0;
+
+    //we read the packet received and put it on the circular buffer
+    USBCDC::read(EPBULK_OUT, c, &size, MAX_PACKET_SIZE_EPBULK);
+    for (int i = 0; i < size; i++) {
+        buf.queue(c[i]);
+    }
+
+    //call a potential handler
+    if (handler) {
+        if (proc) {
+            (*fn)();
+        } else {
+            rx.call();
+        }
+    }
+
+    // We reactivate the endpoint to receive next characters
+    readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
+    return true;
+}
+
+uint8_t USBSerial::available() {
+    return buf.available();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBSERIAL/USBSerial.h	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,120 @@
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef USBSERIAL_H
+#define USBSERIAL_H
+
+#include "USBCDC.h"
+#include "Stream.h"
+#include "CBuffer.h"
+
+
+/**
+* USBSerial example
+*
+* @code
+* #include "mbed.h"
+* #include "USBSerial.h"
+*
+* //Virtual serial port over USB
+* USBSerial serial;
+*
+* int main(void) {
+*
+*    while(1)
+*    {
+*        serial.printf("I am a virtual serial port\n");
+*        wait(1);
+*    }
+* }
+* @endcode
+*/
+class USBSerial: public USBCDC, public Stream {
+public:
+
+    /**
+    *   Constructor
+    *
+    * @param vendor_id Your vendor_id (default: 0x1f00)
+    * @param product_id Your product_id (default: 0x2012)
+    * @param product_release Your preoduct_release (default: 0x0001)
+    *
+    */
+    USBSerial(uint16_t vendor_id = 0x1f00, uint16_t product_id = 0x2012, uint16_t product_release = 0x0001): USBCDC(vendor_id, product_id, product_release){
+        handler = false;
+        proc = false;
+    };
+
+
+    /**
+    * Send a character. You can use puts, printf.
+    *
+    * @param c character to be sent
+    * @returns true if there is no error, false otherwise
+    */
+    virtual int _putc(int c);
+    
+    /**
+    * Read a character: blocking
+    *
+    * @returns character read
+    */
+    virtual int _getc();
+    
+    /**
+    * Check the number of bytes available.
+    *
+    * @returns the number of bytes available
+    */
+    uint8_t available(); 
+
+    /**
+     *  Attach a member function to call when a packet is received. 
+     *
+     *  @param tptr pointer to the object to call the member function on
+     *  @param mptr pointer to the member function to be called
+     */
+    template<typename T>
+    void attach(T* tptr, void (T::*mptr)(void)) {
+        if((mptr != NULL) && (tptr != NULL)) {
+            proc = false;
+            handler = true;
+            rx.attach(tptr, mptr);
+        }
+    }
+
+    /**
+     * Attach a callback for when a packet is received
+     *
+     * @param fptr function pointer
+     */
+    void attach(void (*fn)(void));
+
+
+protected:
+    virtual bool EP2_OUT_callback();
+
+private:
+    FunctionPointer rx;
+    CBuffer buf;
+    void (*fn)(void);
+    bool handler;
+    bool proc;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue Nov 29 21:26:20 2011 +0000
@@ -0,0 +1,83 @@
+#include "mbed.h"
+#include "USBKeyboard.h"
+
+// german kezboard?
+#define QWERTZ
+
+// reverse order, since message windows create a stack
+const static char lyrics[][128] = {
+    "never gonna tell a lie and hurt you",
+    "never gonna make you cry never gonna say goodbye ",
+    "never gonna run around and desert you ",
+    "Never gonna give you up never gonna let you down ",
+    "never gonna tell a lie and hurt you",
+    "never gonna make you cry never gonna say goodbye ",
+    "never gonna run around and desert you ",
+    "Never gonna give you up never gonna let you down ",
+    "never gonna tell a lie and hurt you",
+    "never gonna make you cry never gonna say goodbye ",
+    "never gonna run around and desert you ",
+    "Never gonna give you up never gonna let you down ",
+    "gotta make you understand",
+    "I just wanna tell you how I'm feeling ",
+    "we know the game and we're gonna play it",
+    "inside we both know what's been going on ",
+    "your heart's been aching but you're too shy to say it ",
+    "We've known each other for so long ",
+    "never gonna give never gonna give you up",
+    "never gonna give never gonna give you up",
+    "never gonna tell a lie and hurt you",
+    "never gonna make you cry never gonna say goodbye ",
+    "never gonna run around and desert you ",
+    "Never gonna give you up never gonna let you down ",
+    "never gonna tell a lie and hurt you",
+    "never gonna make you cry never gonna say goodbye ",
+    "never gonna run around and desert you ",
+    "Never gonna give you up never gonna let you down ",
+    "don't tell me you're too blind to see",
+    "And if you ask me how I'm feeling ",
+    "we know the game and we're gonna play it",
+    "inside we both know what's been going on ",
+    "your heart's been aching but you're too shy to say it ",
+    "We've known each other for so long ",
+    "never gonna tell a lie and hurt you",
+    "never gonna make you cry never gonna say goodbye ",
+    "never gonna run around and desert you ",
+    "Never gonna give you up never gonna let you down ",
+    "gotta make you understand",
+    "I just wanna tell you how I'm feeling ",
+    "you wouldn't get this from any other guy",
+    "a full commitment's what I'm thinkin' of ",
+    "you know the rules and so do I ",
+    "We're no strangers to love ",
+    ""};
+
+//USBKeyboard
+USBKeyboard keyboard;
+
+int main(void) {
+    wait(2);
+    while (1) {
+        int line;
+        for(line=0;lyrics[line][0];line++) {
+            const char *p = lyrics[line];
+            keyboard.keyCode('l', KEY_ALT);
+            wait_ms(700);
+            for(;*p;p++) {
+                char c = *p;
+#ifdef QWERTZ
+                if (c == 'z')
+                    c = 'y';
+                else if (c == 'y')
+                    c = 'z';
+#endif                    
+                if (c == 0x27)
+                  continue;
+                
+                keyboard._putc(c);
+            }
+            keyboard.keyCode('s', KEY_ALT);
+            wait_ms(700);
+        }
+    }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Tue Nov 29 21:26:20 2011 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/63bcd7ba4912