USB device stack (USBDevice::connect non-blocking)

Fork of USBDevice by mbed official

Files at this revision

API Documentation at this revision

Comitter:
samux
Date:
Fri Mar 01 13:10:29 2013 +0000
Parent:
7:f8f057664123
Child:
9:354942d2fa38
Commit message:
add FRDM-KL25Z support

Changed in this revision

USBDevice/USBDevice.cpp Show annotated file Show diff for this revision Revisions of this file
USBDevice/USBEndpoints.h Show annotated file Show diff for this revision Revisions of this file
USBDevice/USBEndpoints_KL25Z.h Show annotated file Show diff for this revision Revisions of this file
USBDevice/USBHAL.h Show annotated file Show diff for this revision Revisions of this file
USBDevice/USBHAL_KL25Z.cpp Show annotated file Show diff for this revision Revisions of this file
USBDevice/USBHAL_LPC11U.cpp Show annotated file Show diff for this revision Revisions of this file
USBDevice/USBHAL_LPC17.cpp Show annotated file Show diff for this revision Revisions of this file
USBMSD/USBMSD.cpp Show annotated file Show diff for this revision Revisions of this file
USBMSD/USBMSD.h Show annotated file Show diff for this revision Revisions of this file
USBSerial/USBCDC.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/USBDevice/USBDevice.cpp	Mon Jan 21 10:41:28 2013 +0000
+++ b/USBDevice/USBDevice.cpp	Fri Mar 01 13:10:29 2013 +0000
@@ -250,6 +250,7 @@
         }
 
         EP0read();
+        EP0readStage();
 
         /* Completed */
         return true;
--- a/USBDevice/USBEndpoints.h	Mon Jan 21 10:41:28 2013 +0000
+++ b/USBDevice/USBEndpoints.h	Fri Mar 01 13:10:29 2013 +0000
@@ -41,6 +41,8 @@
 #include "USBEndpoints_LPC17_LPC23.h"
 #elif defined(TARGET_LPC11U24)
 #include "USBEndpoints_LPC11U.h"
+#elif defined(TARGET_KL25Z)
+#include "USBEndpoints_KL25Z.h"
 #else
 #error "Unknown target type"
 #endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBEndpoints_KL25Z.h	Fri Mar 01 13:10:29 2013 +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.   */
+/*      ----------------  */
+#define EP0OUT      (0)  
+#define EP0IN       (1)  
+#define EP1OUT      (2)  
+#define EP1IN       (3)  
+#define EP2OUT      (4)  
+#define EP2IN       (5)  
+#define EP3OUT      (6)  
+#define EP3IN       (7)  
+#define EP4OUT      (8)  
+#define EP4IN       (9)  
+#define EP5OUT      (10) 
+#define EP5IN       (11) 
+#define EP6OUT      (12) 
+#define EP6IN       (13) 
+#define EP7OUT      (14) 
+#define EP7IN       (15) 
+#define EP8OUT      (16) 
+#define EP8IN       (17) 
+#define EP9OUT      (18) 
+#define EP9IN       (19) 
+#define EP10OUT     (20) 
+#define EP10IN      (21) 
+#define EP11OUT     (22) 
+#define EP11IN      (23) 
+#define EP12OUT     (24) 
+#define EP12IN      (25) 
+#define EP13OUT     (26) 
+#define EP13IN      (27) 
+#define EP14OUT     (28) 
+#define EP14IN      (29) 
+#define EP15OUT     (30) 
+#define EP15IN      (31) 
+
+/* 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  (64)
+#define MAX_PACKET_SIZE_EP7  (64)
+#define MAX_PACKET_SIZE_EP8  (64)
+#define MAX_PACKET_SIZE_EP9  (64)
+#define MAX_PACKET_SIZE_EP10 (64)
+#define MAX_PACKET_SIZE_EP11 (64)
+#define MAX_PACKET_SIZE_EP12 (64)
+#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)
--- a/USBDevice/USBHAL.h	Mon Jan 21 10:41:28 2013 +0000
+++ b/USBDevice/USBHAL.h	Fri Mar 01 13:10:29 2013 +0000
@@ -37,6 +37,7 @@
     /* Endpoint 0 */
     void EP0setup(uint8_t *buffer);
     void EP0read(void);
+    void EP0readStage(void);
     uint32_t EP0getReadResult(uint8_t *buffer);
     void EP0write(uint8_t *buffer, uint32_t size);
     void EP0getWriteResult(void);
@@ -61,17 +62,52 @@
     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;};
+    virtual bool EP4_OUT_callback(){return false;};
+    virtual bool EP4_IN_callback(){return false;};
+    
+#if !defined(TARGET_LPC11U24)
+    virtual bool EP5_OUT_callback(){return false;};
+    virtual bool EP5_IN_callback(){return false;};
+    virtual bool EP6_OUT_callback(){return false;};
+    virtual bool EP6_IN_callback(){return false;};
+    virtual bool EP7_OUT_callback(){return false;};
+    virtual bool EP7_IN_callback(){return false;};
+    virtual bool EP8_OUT_callback(){return false;};
+    virtual bool EP8_IN_callback(){return false;};
+    virtual bool EP9_OUT_callback(){return false;};
+    virtual bool EP9_IN_callback(){return false;};
+    virtual bool EP10_OUT_callback(){return false;};
+    virtual bool EP10_IN_callback(){return false;};
+    virtual bool EP11_OUT_callback(){return false;};
+    virtual bool EP11_IN_callback(){return false;};
+    virtual bool EP12_OUT_callback(){return false;};
+    virtual bool EP12_IN_callback(){return false;};
+    virtual bool EP13_OUT_callback(){return false;};
+    virtual bool EP13_IN_callback(){return false;};
+    virtual bool EP14_OUT_callback(){return false;};
+    virtual bool EP14_IN_callback(){return false;};
+    virtual bool EP15_OUT_callback(){return false;};
+    virtual bool EP15_IN_callback(){return false;};
+#endif
     
 private:
     void usbisr(void);
     static void _usbisr(void);
     static USBHAL * instance;
+
+#if defined(TARGET_LPC11U24)
+        bool (USBHAL::*epCallback[10 - 2])(void);
+#else
+        bool (USBHAL::*epCallback[32 - 2])(void);
+#endif
+
+        
 };
 #endif
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBHAL_KL25Z.cpp	Fri Mar 01 13:10:29 2013 +0000
@@ -0,0 +1,514 @@
+/* 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.
+*/
+
+#if defined(TARGET_KL25Z)
+
+#include "USBHAL.h"
+
+USBHAL * USBHAL::instance;
+
+static volatile int epComplete = 0;
+
+// Convert physical endpoint number to register bit
+#define EP(endpoint) (1<<(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)
+
+#define BD_OWN_MASK        (1<<7)
+#define BD_DATA01_MASK     (1<<6)
+#define BD_KEEP_MASK       (1<<5)
+#define BD_NINC_MASK       (1<<4)
+#define BD_DTS_MASK        (1<<3)
+#define BD_STALL_MASK      (1<<2)
+
+#define TX    1
+#define RX    0
+#define ODD   0
+#define EVEN  1
+// this macro waits a physical endpoint number
+#define EP_BDT_IDX(ep, dir, odd) (((ep * 4) + (2 * dir) + (1 *  odd)))
+
+#define SETUP_TOKEN    0x0D
+#define IN_TOKEN       0x09
+#define OUT_TOKEN      0x01
+#define TOK_PID(idx)   ((bdt[idx].info >> 2) & 0x0F)
+
+// for each endpt: 8 bytes
+typedef struct BDT {
+    uint8_t   info;       // BD[0:7]
+    uint8_t   dummy;      // RSVD: BD[8:15]
+    uint16_t  byte_count; // BD[16:32]
+    uint32_t  address;    // Addr
+} BDT; 
+
+
+// there are:
+//    * 16 bidirectionnal endpt -> 32 physical endpt
+//    * as there are ODD and EVEN buffer -> 32*2 bdt
+__attribute__((__aligned__(512))) BDT bdt[NUMBER_OF_PHYSICAL_ENDPOINTS * 2];
+uint8_t endpoint_buffer[(NUMBER_OF_PHYSICAL_ENDPOINTS - 2) * 2][64];
+uint8_t endpoint_buffer_iso[2*2][1023];
+
+static uint8_t set_addr = 0;
+static uint8_t addr = 0;
+
+static uint32_t Data1  = 0x55555555;
+
+static uint32_t frameNumber() {
+    return((USB0->FRMNUML | (USB0->FRMNUMH << 8) & 0x07FF));
+}
+
+uint32_t USBHAL::endpointReadcore(uint8_t endpoint, uint8_t *buffer) {
+    return 0;
+}
+
+USBHAL::USBHAL(void) {    
+    // Disable IRQ
+    NVIC_DisableIRQ(USB0_IRQn);
+    
+    // fill in callback array
+    epCallback[0] = &USBHAL::EP1_OUT_callback;
+    epCallback[1] = &USBHAL::EP1_IN_callback;
+    epCallback[2] = &USBHAL::EP2_OUT_callback;
+    epCallback[3] = &USBHAL::EP2_IN_callback;
+    epCallback[4] = &USBHAL::EP3_OUT_callback;
+    epCallback[5] = &USBHAL::EP3_IN_callback;
+    epCallback[6] = &USBHAL::EP4_OUT_callback;
+    epCallback[7] = &USBHAL::EP4_IN_callback;
+    epCallback[8] = &USBHAL::EP5_OUT_callback;
+    epCallback[9] = &USBHAL::EP5_IN_callback;
+    epCallback[10] = &USBHAL::EP6_OUT_callback;
+    epCallback[11] = &USBHAL::EP6_IN_callback;
+    epCallback[12] = &USBHAL::EP7_OUT_callback;
+    epCallback[13] = &USBHAL::EP7_IN_callback;
+    epCallback[14] = &USBHAL::EP8_OUT_callback;
+    epCallback[15] = &USBHAL::EP8_IN_callback;
+    epCallback[16] = &USBHAL::EP9_OUT_callback;
+    epCallback[17] = &USBHAL::EP9_IN_callback;
+    epCallback[18] = &USBHAL::EP10_OUT_callback;
+    epCallback[19] = &USBHAL::EP10_IN_callback;
+    epCallback[20] = &USBHAL::EP11_OUT_callback;
+    epCallback[21] = &USBHAL::EP11_IN_callback;
+    epCallback[22] = &USBHAL::EP12_OUT_callback;
+    epCallback[23] = &USBHAL::EP12_IN_callback;
+    epCallback[24] = &USBHAL::EP13_OUT_callback;
+    epCallback[25] = &USBHAL::EP13_IN_callback;
+    epCallback[26] = &USBHAL::EP14_OUT_callback;
+    epCallback[27] = &USBHAL::EP14_IN_callback;
+    epCallback[28] = &USBHAL::EP15_OUT_callback;
+    epCallback[29] = &USBHAL::EP15_IN_callback;
+    
+    
+    // choose usb src as PLL
+    SIM->SOPT2 |= (SIM_SOPT2_USBSRC_MASK | SIM_SOPT2_PLLFLLSEL_MASK);
+    
+    // enable OTG clock
+    SIM->SCGC4 |= SIM_SCGC4_USBOTG_MASK;
+
+    // Attach IRQ
+    instance = this;
+    NVIC_SetVector(USB0_IRQn, (uint32_t)&_usbisr);
+    NVIC_EnableIRQ(USB0_IRQn);
+    
+    // USB Module Configuration
+    // Reset USB Module
+    USB0->USBTRC0 |= USB_USBTRC0_USBRESET_MASK;
+    while(USB0->USBTRC0 & USB_USBTRC0_USBRESET_MASK);
+    
+    // Set BDT Base Register
+    USB0->BDTPAGE1=(uint8_t)((uint32_t)bdt>>8);
+    USB0->BDTPAGE2=(uint8_t)((uint32_t)bdt>>16);
+    USB0->BDTPAGE3=(uint8_t)((uint32_t)bdt>>24);
+
+    // Clear interrupt flag
+    USB0->ISTAT = 0xff;
+
+    // USB Interrupt Enablers
+    USB0->INTEN |= USB_INTEN_TOKDNEEN_MASK | 
+                   USB_INTEN_SOFTOKEN_MASK | 
+                   USB_INTEN_ERROREN_MASK  |
+                   USB_INTEN_USBRSTEN_MASK;
+    
+    // Disable weak pull downs 
+    USB0->USBCTRL &= ~(USB_USBCTRL_PDE_MASK | USB_USBCTRL_SUSP_MASK);   
+    
+    USB0->USBTRC0 |= 0x40;
+}
+
+USBHAL::~USBHAL(void) { }
+
+void USBHAL::connect(void) {
+    // enable USB
+    USB0->CTL |= USB_CTL_USBENSOFEN_MASK;
+    // Pull up enable
+    USB0->CONTROL |= USB_CONTROL_DPPULLUPNONOTG_MASK;
+}
+
+void USBHAL::disconnect(void) {
+    // disable USB
+    USB0->CTL &= ~USB_CTL_USBENSOFEN_MASK;
+    // Pull up disable
+    USB0->CONTROL &= ~USB_CONTROL_DPPULLUPNONOTG_MASK;
+}
+
+void USBHAL::configureDevice(void) {
+    // not needed
+}
+
+void USBHAL::unconfigureDevice(void) {
+    // not needed
+}
+
+void USBHAL::setAddress(uint8_t address) {
+    // we don't set the address now otherwise the usb controller does not ack
+    // we set a flag instead
+    // see usbisr when an IN token is received
+    set_addr = 1;
+    addr = address;
+}
+
+bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t flags) {
+    uint32_t handshake_flag = 0;
+    uint8_t * buf;
+
+    if (endpoint > NUMBER_OF_PHYSICAL_ENDPOINTS - 1) {
+        return false;
+    }
+
+    uint32_t log_endpoint = PHY_TO_LOG(endpoint);
+
+    if ((flags & ISOCHRONOUS) == 0) {
+        handshake_flag = USB_ENDPT_EPHSHK_MASK;
+        if (IN_EP(endpoint))
+            buf = &endpoint_buffer[EP_BDT_IDX(log_endpoint, TX, ODD )][0];
+        else
+            buf = &endpoint_buffer[EP_BDT_IDX(log_endpoint, RX, ODD )][0];
+    } else {
+        if (IN_EP(endpoint))
+            buf = &endpoint_buffer_iso[2][0];
+        else
+            buf = &endpoint_buffer_iso[0][0];
+    }
+
+    // IN endpt -> device to host (TX)
+    if (IN_EP(endpoint)) {
+        USB0->ENDPOINT[log_endpoint].ENDPT |= handshake_flag |        // ep handshaking (not if iso endpoint)
+                                              USB_ENDPT_EPTXEN_MASK;  // en TX (IN) tran
+        bdt[EP_BDT_IDX(log_endpoint, TX, ODD )].address = (uint32_t) buf;
+        bdt[EP_BDT_IDX(log_endpoint, TX, EVEN)].address = 0;
+    }
+    // OUT endpt -> host to device (RX)
+    else {
+        USB0->ENDPOINT[log_endpoint].ENDPT |= handshake_flag |        // ep handshaking (not if iso endpoint)
+                                              USB_ENDPT_EPRXEN_MASK;  // en RX (OUT) tran.
+        bdt[EP_BDT_IDX(log_endpoint, RX, ODD )].byte_count = maxPacket;
+        bdt[EP_BDT_IDX(log_endpoint, RX, ODD )].address    = (uint32_t) buf;
+        bdt[EP_BDT_IDX(log_endpoint, RX, ODD )].info       = BD_OWN_MASK | BD_DTS_MASK;
+        bdt[EP_BDT_IDX(log_endpoint, RX, EVEN)].info       = 0;
+    }
+
+    Data1 |= (1 << endpoint);
+
+    return true;
+}
+
+// read setup packet
+void USBHAL::EP0setup(uint8_t *buffer) {
+    uint32_t sz;
+    endpointReadResult(EP0OUT, buffer, &sz);
+}
+
+void USBHAL::EP0readStage(void) {
+    Data1 &= ~1UL;  // set DATA0
+    bdt[0].info = (BD_DTS_MASK | BD_OWN_MASK);
+}
+
+void USBHAL::EP0read(void) {
+    uint32_t idx = EP_BDT_IDX(PHY_TO_LOG(EP0OUT), RX, 0);
+    bdt[idx].byte_count = MAX_PACKET_SIZE_EP0;
+}
+
+uint32_t USBHAL::EP0getReadResult(uint8_t *buffer) {
+    uint32_t sz;
+    endpointReadResult(EP0OUT, buffer, &sz);
+    return sz;
+}
+
+void USBHAL::EP0write(uint8_t *buffer, uint32_t size) {
+    endpointWrite(EP0IN, buffer, size);
+}
+
+void USBHAL::EP0getWriteResult(void) {
+}
+
+void USBHAL::EP0stall(void) {
+    stallEndpoint(EP0OUT);
+}
+
+EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize) {
+    endpoint = PHY_TO_LOG(endpoint);
+    uint32_t idx = EP_BDT_IDX(endpoint, RX, 0);
+    bdt[idx].byte_count = maximumSize;
+    return EP_PENDING;
+}
+
+EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t * buffer, uint32_t *bytesRead) {
+    uint32_t n, sz, idx, setup = 0;
+    uint8_t not_iso;
+    uint8_t * ep_buf;
+    
+    uint32_t log_endpoint = PHY_TO_LOG(endpoint);
+    
+    if (endpoint > NUMBER_OF_PHYSICAL_ENDPOINTS - 1) {
+        return EP_INVALID;
+    }
+
+    // if read on a IN endpoint -> error
+    if (IN_EP(endpoint)) {
+        return EP_INVALID;
+    }
+
+    idx = EP_BDT_IDX(log_endpoint, RX, 0);
+    sz  = bdt[idx].byte_count;
+    not_iso = USB0->ENDPOINT[log_endpoint].ENDPT & USB_ENDPT_EPHSHK_MASK;
+
+    //for isochronous endpoint, we don't wait an interrupt
+    if ((log_endpoint != 0) && not_iso && !(epComplete & EP(endpoint))) {
+        return EP_PENDING;
+    }
+
+    if ((log_endpoint == 0) && (TOK_PID(idx) == SETUP_TOKEN)) {
+        setup = 1;
+    }
+
+    // non iso endpoint
+    if (not_iso) {
+        ep_buf = endpoint_buffer[idx];
+    } else {
+        ep_buf = endpoint_buffer_iso[0];
+    }
+
+    for (n = 0; n < sz; n++) {
+        buffer[n] = ep_buf[n];
+    }
+
+    if (((Data1 >> endpoint) & 1) == ((bdt[idx].info >> 6) & 1)) {
+        if (setup && (buffer[6] == 0))  // if no setup data stage,
+            Data1 &= ~1UL;              // set DATA0
+        else 
+            Data1 ^= (1 << endpoint);
+    }
+
+    if (((Data1 >> endpoint) & 1)) {
+        bdt[idx].info = BD_DTS_MASK | BD_DATA01_MASK | BD_OWN_MASK;
+    }
+    else {
+        bdt[idx].info = BD_DTS_MASK | BD_OWN_MASK;
+    }
+        
+    USB0->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
+    *bytesRead = sz;
+
+    epComplete &= ~EP(endpoint);
+    return EP_COMPLETED;
+}
+
+EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size) {
+    uint32_t idx, n;
+    uint8_t * ep_buf;
+
+    if (endpoint > NUMBER_OF_PHYSICAL_ENDPOINTS - 1) {
+        return EP_INVALID;
+    }
+
+    // if write on a OUT endpoint -> error
+    if (OUT_EP(endpoint)) {
+        return EP_INVALID;
+    }
+
+    idx = EP_BDT_IDX(PHY_TO_LOG(endpoint), TX, 0);
+    bdt[idx].byte_count = size;
+    
+    
+    // non iso endpoint
+    if (USB0->ENDPOINT[PHY_TO_LOG(endpoint)].ENDPT & USB_ENDPT_EPHSHK_MASK) {
+        ep_buf = endpoint_buffer[idx];
+    } else {
+        ep_buf = endpoint_buffer_iso[2];
+    }
+    
+    for (n = 0; n < size; n++) {
+        ep_buf[n] = data[n];
+    }
+    
+    if ((Data1 >> endpoint) & 1) {
+        bdt[idx].info = BD_OWN_MASK | BD_DTS_MASK;
+    } else {
+        bdt[idx].info = BD_OWN_MASK | BD_DTS_MASK | BD_DATA01_MASK;
+    }
+    
+    Data1 ^= (1 << endpoint);
+    
+    return EP_PENDING;
+}
+
+EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint) {
+    if (epComplete & EP(endpoint)) {
+        epComplete &= ~EP(endpoint);
+        return EP_COMPLETED;
+    }
+
+    return EP_PENDING;
+}
+
+void USBHAL::stallEndpoint(uint8_t endpoint) {
+    USB0->ENDPOINT[PHY_TO_LOG(endpoint)].ENDPT |= USB_ENDPT_EPSTALL_MASK;
+}
+
+void USBHAL::unstallEndpoint(uint8_t endpoint) {
+    USB0->ENDPOINT[PHY_TO_LOG(endpoint)].ENDPT &= ~USB_ENDPT_EPSTALL_MASK;
+}
+
+bool USBHAL::getEndpointStallState(uint8_t endpoint) {
+    uint8_t stall = (USB0->ENDPOINT[PHY_TO_LOG(endpoint)].ENDPT & USB_ENDPT_EPSTALL_MASK);
+    return (stall) ? true : false;
+}
+
+void USBHAL::remoteWakeup(void) {
+    // [TODO]
+}
+
+
+void USBHAL::_usbisr(void) {
+    instance->usbisr();
+}
+
+
+void USBHAL::usbisr(void) {
+    uint8_t i;
+    uint8_t istat = USB0->ISTAT;
+
+    // reset interrupt
+    if (istat & USB_ISTAT_USBRST_MASK) {            
+        // disable all endpt
+        for(i = 0; i < 16; i++) {
+            USB0->ENDPOINT[i].ENDPT = 0x00;
+        }
+
+        // enable control endpoint
+        realiseEndpoint(EP0OUT, MAX_PACKET_SIZE_EP0, 0);
+        realiseEndpoint(EP0IN, MAX_PACKET_SIZE_EP0, 0);
+
+        Data1 = 0x55555555;
+        USB0->CTL |=  USB_CTL_ODDRST_MASK;
+
+        USB0->ISTAT   =  0xFF;  // clear all interrupt status flags
+        USB0->ERRSTAT =  0xFF;  // clear all error flags
+        USB0->ERREN   =  0xFF;  // enable error interrupt sources
+        USB0->ADDR    =  0x00;  // set default address
+
+        return;
+    }
+
+    // resume interrupt
+    if (istat & USB_ISTAT_RESUME_MASK) {
+        USB0->ISTAT = USB_ISTAT_RESUME_MASK;
+    }
+
+    // SOF interrupt
+    if (istat & USB_ISTAT_SOFTOK_MASK) {
+        USB0->ISTAT = USB_ISTAT_SOFTOK_MASK;  
+        // SOF event, read frame number
+        SOF(frameNumber());
+    }
+    
+    // stall interrupt
+    if (istat & 1<<7) {
+        if (USB0->ENDPOINT[0].ENDPT & USB_ENDPT_EPSTALL_MASK)
+            USB0->ENDPOINT[0].ENDPT &= ~USB_ENDPT_EPSTALL_MASK;
+        USB0->ISTAT |= USB_ISTAT_STALL_MASK;
+    }
+
+    // token interrupt
+    if (istat & 1<<3) {
+        uint32_t num  = (USB0->STAT >> 4) & 0x0F;
+        uint32_t dir  = (USB0->STAT >> 3) & 0x01;
+        uint32_t ev_odd = (USB0->STAT >> 2) & 0x01;
+
+        // setup packet
+        if ((num == 0) && (TOK_PID((EP_BDT_IDX(num, dir, ev_odd))) == SETUP_TOKEN)) {
+            Data1 &= ~0x02;
+            bdt[EP_BDT_IDX(0, TX, EVEN)].info &= ~BD_OWN_MASK;
+            bdt[EP_BDT_IDX(0, TX, ODD)].info  &= ~BD_OWN_MASK;
+
+            // EP0 SETUP event (SETUP data received)
+            EP0setupCallback();
+                    
+        } else {
+            // OUT packet
+            if (TOK_PID((EP_BDT_IDX(num, dir, ev_odd))) == OUT_TOKEN) {
+                if (num == 0)
+                    EP0out();
+                else {
+                    epComplete |= (1 << EP(num));
+                    if ((instance->*(epCallback[EP(num) - 2]))()) {
+                        epComplete &= ~(1 << EP(num));
+                    }
+                }
+            }
+
+            // IN packet
+            if (TOK_PID((EP_BDT_IDX(num, dir, ev_odd))) == IN_TOKEN) {
+                if (num == 0) {
+                    EP0in();
+                    if (set_addr == 1) {
+                        USB0->ADDR = addr & 0x7F;
+                        set_addr = 0;
+                    }
+                }
+                else {
+                    epComplete |= (1 << (EP(num) + 1));
+                    if ((instance->*(epCallback[EP(num) + 1 - 2]))()) {
+                        epComplete &= ~(1 << (EP(num) + 1));
+                    }
+                }
+            }
+        }
+
+        USB0->ISTAT = USB_ISTAT_TOKDNE_MASK;
+    }
+        
+    // sleep interrupt
+    if (istat & 1<<4) {
+        USB0->ISTAT |= USB_ISTAT_SLEEP_MASK;
+    }    
+
+    // error interrupt
+    if (istat & USB_ISTAT_ERROR_MASK) {
+        USB0->ERRSTAT = 0xFF;
+        USB0->ISTAT |= USB_ISTAT_ERROR_MASK;
+    }
+}
+
+
+#endif
--- a/USBDevice/USBHAL_LPC11U.cpp	Mon Jan 21 10:41:28 2013 +0000
+++ b/USBDevice/USBHAL_LPC11U.cpp	Fri Mar 01 13:10:29 2013 +0000
@@ -22,7 +22,6 @@
 
 USBHAL * USBHAL::instance;
 
-
 // Valid physical endpoint numbers are 0 to (NUMBER_OF_PHYSICAL_ENDPOINTS-1)
 #define LAST_PHYSICAL_ENDPOINT (NUMBER_OF_PHYSICAL_ENDPOINTS-1)
 
@@ -129,6 +128,16 @@
 
 USBHAL::USBHAL(void) {
     NVIC_DisableIRQ(USB_IRQn);
+    
+    // fill in callback array
+    epCallback[0] = &USBHAL::EP1_OUT_callback;
+    epCallback[1] = &USBHAL::EP1_IN_callback;
+    epCallback[2] = &USBHAL::EP2_OUT_callback;
+    epCallback[3] = &USBHAL::EP2_IN_callback;
+    epCallback[4] = &USBHAL::EP3_OUT_callback;
+    epCallback[5] = &USBHAL::EP3_IN_callback;
+    epCallback[6] = &USBHAL::EP4_OUT_callback;
+    epCallback[7] = &USBHAL::EP4_IN_callback;
 
     // nUSB_CONNECT output
     LPC_IOCON->PIO0_6 = 0x00000001;
@@ -181,7 +190,6 @@
 USBHAL::~USBHAL(void) {
     // Ensure device disconnected (DCON not set)
     LPC_USB->DEVCMDSTAT = 0;
-
     // Disable USB interrupts
     NVIC_DisableIRQ(USB_IRQn);
 }
@@ -199,9 +207,11 @@
 }
 
 void USBHAL::configureDevice(void) {
+    // Not required
 }
 
 void USBHAL::unconfigureDevice(void) {
+    // Not required
 }
 
 void USBHAL::EP0setup(uint8_t *buffer) {
@@ -232,6 +242,11 @@
     return bytesRead;
 }
 
+
+void USBHAL::EP0readStage(void) {
+    // Not required
+}
+
 void USBHAL::EP0write(uint8_t *buffer, uint32_t size) {
     // Start and endpoint 0 write
 
@@ -303,10 +318,7 @@
 }
 
 void USBHAL::EP0getWriteResult(void) {
-    // Complete an endpoint 0 write
-
-    // Nothing required for this target
-    return;
+    // Not required
 }
 
 void USBHAL::EP0stall(void) {
@@ -385,8 +397,8 @@
 
 EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint) {
     uint32_t bf;
+    
     // Validate parameters
-
     if (endpoint > LAST_PHYSICAL_ENDPOINT) {
         return EP_INVALID;
     }
@@ -422,8 +434,7 @@
 
 void USBHAL::stallEndpoint(uint8_t endpoint) {
 
-    // TODO: should this clear active bit?
-
+    // FIX: 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;
@@ -441,26 +452,26 @@
             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
+                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
+                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
+                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
+                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
+            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
+            ep[PHY_TO_LOG(endpoint)].out[0] = CMDSTS_TR;    // S = 0, TR = 1, TV = 0
         }
     }
 }
@@ -658,55 +669,15 @@
         // 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);
+    
+    for (uint8_t num = 2; num < 5*2; num++) {
+        if (LPC_USB->INTSTAT & EP(num)) {
+            LPC_USB->INTSTAT = EP(num);
+            epComplete |= EP(num);
+            if ((instance->*(epCallback[num - 2]))()) {
+                epComplete &= ~EP(num);
+            }
+        }
     }
 }
 
--- a/USBDevice/USBHAL_LPC17.cpp	Mon Jan 21 10:41:28 2013 +0000
+++ b/USBDevice/USBHAL_LPC17.cpp	Fri Mar 01 13:10:29 2013 +0000
@@ -16,7 +16,7 @@
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
 
-#ifdef TARGET_LPC1768
+#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
 
 #include "USBHAL.h"
 
@@ -116,8 +116,8 @@
 
 USBHAL * USBHAL::instance;
 
-volatile int epComplete;
-uint32_t endpointStallState;
+static volatile int epComplete;
+static uint32_t endpointStallState;
 
 static void SIECommand(uint32_t command) {
     // The command phase of a SIE transaction
@@ -209,18 +209,14 @@
 
 static void SIEconnect(void) {
     // Connect USB device
-    uint8_t status;
-
-    status = SIEgetDeviceStatus();
+    uint8_t status = SIEgetDeviceStatus();
     SIEsetDeviceStatus(status | SIE_DS_CON);
 }
 
 
 static void SIEdisconnect(void) {
     // Disconnect USB device
-    uint8_t status;
-
-    status = SIEgetDeviceStatus();
+    uint8_t status = SIEgetDeviceStatus();
     SIEsetDeviceStatus(status & ~SIE_DS_CON);
 }
 
@@ -233,9 +229,6 @@
 }
 
 
-
-
-
 static void enableEndpointEvent(uint8_t endpoint) {
     // Enable an endpoint interrupt
     LPC_USB->USBEpIntEn |= EP(endpoint);
@@ -248,8 +241,6 @@
 }
 
 static volatile uint32_t __attribute__((used)) dummyRead;
-
-
 uint32_t USBHAL::endpointReadcore(uint8_t endpoint, uint8_t *buffer) {
     // Read from an OUT endpoint
     uint32_t size;
@@ -333,15 +324,41 @@
     SIEvalidateBuffer();
 }
 
-
-
-
-
-
-
 USBHAL::USBHAL(void) {
     // Disable IRQ
     NVIC_DisableIRQ(USB_IRQn);
+    
+    // fill in callback array
+    epCallback[0] = &USBHAL::EP1_OUT_callback;
+    epCallback[1] = &USBHAL::EP1_IN_callback;
+    epCallback[2] = &USBHAL::EP2_OUT_callback;
+    epCallback[3] = &USBHAL::EP2_IN_callback;
+    epCallback[4] = &USBHAL::EP3_OUT_callback;
+    epCallback[5] = &USBHAL::EP3_IN_callback;
+    epCallback[6] = &USBHAL::EP4_OUT_callback;
+    epCallback[7] = &USBHAL::EP4_IN_callback;
+    epCallback[8] = &USBHAL::EP5_OUT_callback;
+    epCallback[9] = &USBHAL::EP5_IN_callback;
+    epCallback[10] = &USBHAL::EP6_OUT_callback;
+    epCallback[11] = &USBHAL::EP6_IN_callback;
+    epCallback[12] = &USBHAL::EP7_OUT_callback;
+    epCallback[13] = &USBHAL::EP7_IN_callback;
+    epCallback[14] = &USBHAL::EP8_OUT_callback;
+    epCallback[15] = &USBHAL::EP8_IN_callback;
+    epCallback[16] = &USBHAL::EP9_OUT_callback;
+    epCallback[17] = &USBHAL::EP9_IN_callback;
+    epCallback[18] = &USBHAL::EP10_OUT_callback;
+    epCallback[19] = &USBHAL::EP10_IN_callback;
+    epCallback[20] = &USBHAL::EP11_OUT_callback;
+    epCallback[21] = &USBHAL::EP11_IN_callback;
+    epCallback[22] = &USBHAL::EP12_OUT_callback;
+    epCallback[23] = &USBHAL::EP12_IN_callback;
+    epCallback[24] = &USBHAL::EP13_OUT_callback;
+    epCallback[25] = &USBHAL::EP13_IN_callback;
+    epCallback[26] = &USBHAL::EP14_OUT_callback;
+    epCallback[27] = &USBHAL::EP14_IN_callback;
+    epCallback[28] = &USBHAL::EP15_OUT_callback;
+    epCallback[29] = &USBHAL::EP15_IN_callback;
 
     // Enable power to USB device controller
     LPC_SC->PCONP |= PCUSB;
@@ -381,7 +398,6 @@
 USBHAL::~USBHAL(void) {
     // Ensure device disconnected
     SIEdisconnect();
-
     // Disable USB interrupts
     NVIC_DisableIRQ(USB_IRQn);
 }
@@ -418,6 +434,10 @@
     // Not required
 }
 
+void USBHAL::EP0readStage(void) {
+    // Not required
+}
+
 uint32_t USBHAL::EP0getReadResult(uint8_t *buffer) {
     return endpointReadcore(EP0OUT, buffer);
 }
@@ -527,10 +547,6 @@
     SIEsetDeviceStatus(status & ~SIE_DS_SUS);
 }
 
-
-
-
-
 void USBHAL::_usbisr(void) {
     instance->usbisr();
 }
@@ -590,54 +606,16 @@
             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);
+        
+        for (uint8_t num = 2; num < 16*2; num++) {
+            if (LPC_USB->USBEpIntSt & EP(num)) {
+                selectEndpointClearInterrupt(num);
+                epComplete |= EP(num);
+                LPC_USB->USBDevIntClr = EP_SLOW;
+                if ((instance->*(epCallback[num - 2]))()) {
+                    epComplete &= ~EP(num);
+                }
+            }
         }
     }
 }
--- a/USBMSD/USBMSD.cpp	Mon Jan 21 10:41:28 2013 +0000
+++ b/USBMSD/USBMSD.cpp	Fri Mar 01 13:10:29 2013 +0000
@@ -642,4 +642,4 @@
         0                           // bInterval
     };
     return configDescriptor;
-}
\ No newline at end of file
+}
--- a/USBMSD/USBMSD.h	Mon Jan 21 10:41:28 2013 +0000
+++ b/USBMSD/USBMSD.h	Fri Mar 01 13:10:29 2013 +0000
@@ -236,4 +236,4 @@
     void fail();
 };
 
-#endif
\ No newline at end of file
+#endif
--- a/USBSerial/USBCDC.cpp	Mon Jan 21 10:41:28 2013 +0000
+++ b/USBSerial/USBCDC.cpp	Fri Mar 01 13:10:29 2013 +0000
@@ -56,8 +56,7 @@
                 terminal_connected = true;
                 break;
             case CDC_SET_CONTROL_LINE_STATE:
-                if (terminal_connected)
-                    terminal_connected = false;
+                terminal_connected = false;
                 success = true;
                 break;
             default:
@@ -147,12 +146,13 @@
 }
 
 
-#define CONFIG1_DESC_SIZE (9+9+5+5+4+5+7+9+7+7)
+#define CONFIG1_DESC_SIZE (9+8+9+5+5+4+5+7+9+7+7)
 
 uint8_t * USBCDC::configurationDesc() {
     static uint8_t configDescriptor[] = {
-        9,                      // bLength;
-        2,                      // bDescriptorType;
+        // configuration descriptor
+        9,                      // bLength
+        2,                      // bDescriptorType
         LSB(CONFIG1_DESC_SIZE), // wTotalLength
         MSB(CONFIG1_DESC_SIZE),
         2,                      // bNumInterfaces
@@ -160,6 +160,16 @@
         0,                      // iConfiguration
         0x80,                   // bmAttributes
         50,                     // bMaxPower
+        
+        // IAD to associate the two CDC interfaces
+        0x08,                   // bLength
+        0x0b,                   // bDescriptorType
+        0x00,                   // bFirstInterface
+        0x02,                   // bInterfaceCount
+        0x02,                   // bFunctionClass
+        0x02,                   // bFunctionSubClass
+        0,                      // bFunctionProtocol
+        0,                      // iFunction
 
         // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
         9,                      // bLength
@@ -211,33 +221,33 @@
 
 
         // 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
+        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_LENGTH, // bLength
+        ENDPOINT_DESCRIPTOR,        // bDescriptorType
+        PHY_TO_DESC(EPBULK_IN),     // bEndpointAddress
+        E_BULK,                     // 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
+        ENDPOINT_DESCRIPTOR_LENGTH, // bLength
+        ENDPOINT_DESCRIPTOR,        // bDescriptorType
+        PHY_TO_DESC(EPBULK_OUT),    // bEndpointAddress
+        E_BULK,                     // bmAttributes (0x02=bulk)
+        LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB)
+        MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB)
+        0                           // bInterval
     };
     return configDescriptor;
 }