Changed file extensions from .c to .cpp

Dependents:   FINAL_PROJECT

Fork of USBMIDI by Simon Ford

Files at this revision

API Documentation at this revision

Comitter:
KrissyHam
Date:
Fri Apr 29 01:46:03 2016 +0000
Parent:
2:10d694d6ccdc
Commit message:
Changed file extensions from .c to .cpp

Changed in this revision

usbcore.c Show diff for this revision Revisions of this file
usbcore.cpp Show annotated file Show diff for this revision Revisions of this file
usbdevice.c Show diff for this revision Revisions of this file
usbdevice.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/usbcore.c	Sun Feb 20 13:12:22 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,278 +0,0 @@
-/* @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.
- */
-
-#include "usbcore.h"
-
-#include "mbed.h"
-
-// Serial Interface Engine
-#define SIE_SET_ADDR    (0xD0)
-#define SIE_SET_STATUS  (0xFE)
-#define SIE_GET_STATUS  (0xFE)
-#define SIE_SET_MODE    (0xF3)
-#define SIE_CLR_BUFFER  (0xF2)
-#define SIE_VAL_BUFFER  (0xFA)
-#define SIE_SEL_EP      (0x00)
-#define SIE_SEL_CLR_EP  (0x28)
-#define SIE_SET_EP_STAT (0x40)
-#define SIE_READ_ERROR  (0xFB)
-#define SIE_CONFIG_DEVICE (0xD8)
-
-// EP status
-#define EP_FE           (1<<0) // Full/Empty
-#define EP_ST           (1<<1) // Stalled endpoint
-#define EP_STP          (1<<2) // Setup packet
-#define EP_PO           (1<<3) // packet overwritten
-#define EP_EPN          (1<<4) // EP NAKed
-#define B_1_FULL        (1<<5) // buffer 1 status
-#define B_2_FULL        (1<<6) // buffer 2 status
-
-// USB device interrupts
-#define DEV_FRAME       (1<<0)
-#define EP_FAST         (1<<1)
-#define EP_SLOW         (1<<2)
-#define DEV_STAT        (1<<3)
-#define RxENDPKT        (1<<6)
-#define TxENDPKT        (1<<7)
-#define EP_RLZED        (1<<8)
-#define CCEMPTY         (0x10)
-#define CDFULL          (0x20)
-
-// USB device status bits
-#define STAT_CON        (1<<0)
-#define STAT_CON_CH     (1<<1)
-#define STAT_SUS        (1<<2)
-#define STAT_SUS_CH     (1<<3)
-#define STAT_RST        (1<<4)
-
-// end points interrupts
-#define EP0RX_INT       (1<<0)
-#define EP0TX_INT       (1<<1)
-#define EP1RX_INT       (1<<2)
-#define EP1TX_INT       (1<<3)
-#define EP2RX_INT       (1<<4)
-#define EP2TX_INT       (1<<5)
-
-// USB control register
-#define RD_EN           (1<<0)
-#define WR_EN           (1<<1)
-#define PKT_RDY         (1<<11)
-#define LOG_ENDPOINT(ep) ((ep>>1)<<2)
-
-// configure state
-static int configured = 0;
-
-// USB interrupt handler
-void USB_IRQHandler(void);
-
-// Serial Interface Engine functions
-void sie_command(uint32_t code) {
-    LPC_USB->USBDevIntClr = CCEMPTY;                // clear CCEMPTY     
-    LPC_USB->USBCmdCode   = ((code<<16)|(0x05<<8)); // CMD_PHASE=Command 
-    while (!(LPC_USB->USBDevIntSt & CCEMPTY));      // wait for CCEMPTY 
-}
-
-void sie_write(uint32_t data) {
-    LPC_USB->USBDevIntClr = CCEMPTY;                // clear CCEMPTY     
-    LPC_USB->USBCmdCode   = ((data<<16)|(0x01<<8)); // CMD_PHASE=Write   
-    while (!(LPC_USB->USBDevIntSt & CCEMPTY));      // wait for CCEMPTY  
-}
-
-uint8_t sie_read(uint32_t code) {
-    LPC_USB->USBDevIntClr = CDFULL;                 // clear CCEMPTY     
-    LPC_USB->USBCmdCode   = ((code<<16)|(0x02<<8)); // CMD_PHASE=Read    
-    while (!(LPC_USB->USBDevIntSt & CDFULL));       // wait for CDFULL   
-    return (uint8_t) LPC_USB->USBCmdData;
-
-}
-
-// end point functions
-void ep_realize(uint8_t ep, uint32_t size) {
-    LPC_USB->USBDevIntClr = EP_RLZED;           // clear EP_RLZED
-    LPC_USB->USBReEp    |= (1<<ep);
-    LPC_USB->USBEpInd    = ep;                  // set USBEpIn
-    LPC_USB->USBMaxPSize = size;                // writing to EPn pointed to by USBEpInd
-    while (!(LPC_USB->USBDevIntSt & EP_RLZED)); // wait for EP_RLZED
-    LPC_USB->USBDevIntClr = EP_RLZED;           // clear EP_RLZED
-}
-
-void ep_stall(uint8_t ep) {
-    sie_command(SIE_SET_EP_STAT+ep);
-    sie_write(1);
-}
-
-void ep_unstall(uint8_t ep) {
-    sie_command(SIE_SET_EP_STAT+ep);
-    sie_write(0);
-}
-
-// initializes a pointer to the endpoint buffer
-uint8_t ep_select(uint8_t ep) {
-    sie_command(SIE_SEL_EP+ep);
-    return sie_read(SIE_SEL_EP+ep);
-}
-
-uint8_t ep_select_clear(uint8_t ep) {
-    LPC_USB->USBEpIntClr |= ep;                 // clear ep interrupt   
-    while (!(LPC_USB->USBDevIntSt & CDFULL));   // wait for cmd finish 
-    return LPC_USB->USBCmdData;
-}
-
-int ep_readable(uint8_t ep) {
-    uint8_t st = ep_select(ep);
-    return (st & EP_FE);
-}
-
-int ep_writable(uint8_t ep) {
-    uint8_t st = ep_select(ep);
-    return !(st & EP_FE);
-}
-
-int ep_read(uint8_t ep, uint8_t *tbuf) {
-    uint32_t *buf = (uint32_t*) tbuf;
-    LPC_USB->USBCtrl = LOG_ENDPOINT(ep)|RD_EN;  // RD_EN bit and LOG_ENDPOINT   
-    while (!(LPC_USB->USBRxPLen & PKT_RDY));    // wait for packet to be fetched
-    int len = LPC_USB->USBRxPLen & 0x3FF;       // read and mask packet length  
-    while (!(LPC_USB->USBDevIntSt & RxENDPKT)) {
-        *buf++ = LPC_USB->USBRxData;
-    }
-    LPC_USB->USBCtrl = 0;
-    LPC_USB->USBDevIntClr |= RxENDPKT;
-    sie_command(SIE_SEL_EP+ep);     // select endpoint   
-    sie_command(SIE_CLR_BUFFER);    // clear RX buffer   
-    return len;
-}
-
-void ep_write(uint8_t ep, uint8_t *tbuf, uint32_t len) {
-    uint32_t *buf = (uint32_t*) tbuf;
-    LPC_USB->USBCtrl   = LOG_ENDPOINT(ep)|WR_EN; // RD_EN bit and LOG_ENDPOINT  
-    LPC_USB->USBTxPLen |= (len & 0x3FF);         // write and mask packet length
-    while (!(LPC_USB->USBDevIntSt & TxENDPKT)) {
-        LPC_USB->USBTxData = *buf++;
-    }
-    LPC_USB->USBCtrl = 0;
-    LPC_USB->USBDevIntClr |= TxENDPKT;
-    sie_command(SIE_SEL_EP+ep);     // select endpoint   
-    sie_command(SIE_VAL_BUFFER);    // validate TX buffer
-}
-
-// USB device controller initialization
-void usb_init() {
-    // USB D+/D- pinsel functions
-    LPC_PINCON->PINSEL1 &=   0xC3FFFFFF;
-    LPC_PINCON->PINSEL1 |=   0x14000000;
-
-#if USB_UP_DEBUG
-    // USB_UP_LED pinsel function
-    LPC_PINCON->PINSEL3 &=   0xFFFFFFCF;
-    LPC_PINCON->PINSEL3 |=   0x00000010;
-#endif    
-
-    // USB connect pinsel function
-    LPC_PINCON->PINSEL4 &=   0xFFFCFFFF;
-    LPC_PINCON->PINSEL4 |=   0x00040000;
-    LPC_SC->PCONP       |=   (1UL<<31);         // enable the USB controller
-    LPC_USB->USBClkCtrl |=   ((1<<1)|(1<<4));   // enable the AHB and DEV clocks
-    while ((LPC_USB->USBClkSt & 0x12) != 0x12); // wait for the clocks to init
-
-    NVIC_SetVector(USB_IRQn, (uint32_t)&USB_IRQHandler);
-    NVIC_EnableIRQ(USB_IRQn);    // enable USB interrupts
-
-    usb_reset();
-    usb_set_address(0);          // default address
-}
-
-void usb_reset() {
-    ep_realize(EP0, MAX_EP0_PSIZE);
-    ep_realize(EP1, MAX_EP0_PSIZE);
-    LPC_USB->USBEpIntClr  = 0xFFFFFFFF;         // clear end points interrupts
-    LPC_USB->USBEpIntEn   = 0xFFFFFFFF;         // enable end points interrupts
-    LPC_USB->USBEpIntPri  = 0x0;                // route to EP_SLOW
-    LPC_USB->USBDevIntClr = 0xFFFFFFFF;         // clear USB device interrupts 
-    LPC_USB->USBDevIntEn  = (EP_SLOW|DEV_STAT); // enable USB device interrupts
-}
-
-void usb_configure(uint8_t conf) {
-    sie_command(SIE_CONFIG_DEVICE);
-    sie_write(conf);
-    configured = 1;
-}
-
-int usb_configured() {
-    return configured;
-}
-
-void usb_set_address(uint8_t addr) {
-    sie_command(SIE_SET_ADDR);
-    sie_write(addr|0x80);       // DEV_EN = 1
-}
-
-uint8_t usb_get_status() {
-    sie_command(SIE_GET_STATUS);
-    return sie_read(SIE_GET_STATUS);
-}
-
-void usb_connect() {
-    sie_command(SIE_GET_STATUS); // read current status
-    uint8_t st = sie_read(SIE_GET_STATUS);
-
-    sie_command(SIE_SET_STATUS); // set STAT_CON bit
-    sie_write(st|STAT_CON);
-}
-
-void USB_IRQHandler(void) {
-    if (LPC_USB->USBDevIntSt & DEV_STAT) { // DEV_STAT interrupt
-        LPC_USB->USBDevIntClr |= DEV_STAT;
-        if (usb_get_status() & STAT_RST) { // bus reset
-            usb_reset();
-        }
-        return;
-    }
-
-    if (LPC_USB->USBDevIntSt & EP_SLOW) {  // EP_SLOW interrupt
-        if (LPC_USB->USBEpIntSt & EP0RX_INT) {
-            if (ep_select_clear(EP0RX_INT) & EP_STP) { // setup transfer
-                ep0_setup();
-            } else {
-                ep0_out();
-            }
-        }
-
-        if (LPC_USB->USBEpIntSt & EP0TX_INT) {
-            ep_select_clear(EP0TX_INT);
-            ep0_in();
-        }
-
-        if (LPC_USB->USBEpIntSt & EP2RX_INT) {
-            ep_select_clear(EP2TX_INT);
-            ep2_out();
-        }
-
-        if (LPC_USB->USBEpIntSt & EP2TX_INT) {
-            ep_select_clear(EP2TX_INT);
-            ep2_in();
-        }
-
-        // EP_SLOW should be cleared after clearing EPs interrupts
-        LPC_USB->USBDevIntClr |= EP_SLOW;
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbcore.cpp	Fri Apr 29 01:46:03 2016 +0000
@@ -0,0 +1,278 @@
+/* @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.
+ */
+
+#include "usbcore.h"
+
+#include "mbed.h"
+
+// Serial Interface Engine
+#define SIE_SET_ADDR    (0xD0)
+#define SIE_SET_STATUS  (0xFE)
+#define SIE_GET_STATUS  (0xFE)
+#define SIE_SET_MODE    (0xF3)
+#define SIE_CLR_BUFFER  (0xF2)
+#define SIE_VAL_BUFFER  (0xFA)
+#define SIE_SEL_EP      (0x00)
+#define SIE_SEL_CLR_EP  (0x28)
+#define SIE_SET_EP_STAT (0x40)
+#define SIE_READ_ERROR  (0xFB)
+#define SIE_CONFIG_DEVICE (0xD8)
+
+// EP status
+#define EP_FE           (1<<0) // Full/Empty
+#define EP_ST           (1<<1) // Stalled endpoint
+#define EP_STP          (1<<2) // Setup packet
+#define EP_PO           (1<<3) // packet overwritten
+#define EP_EPN          (1<<4) // EP NAKed
+#define B_1_FULL        (1<<5) // buffer 1 status
+#define B_2_FULL        (1<<6) // buffer 2 status
+
+// USB device interrupts
+#define DEV_FRAME       (1<<0)
+#define EP_FAST         (1<<1)
+#define EP_SLOW         (1<<2)
+#define DEV_STAT        (1<<3)
+#define RxENDPKT        (1<<6)
+#define TxENDPKT        (1<<7)
+#define EP_RLZED        (1<<8)
+#define CCEMPTY         (0x10)
+#define CDFULL          (0x20)
+
+// USB device status bits
+#define STAT_CON        (1<<0)
+#define STAT_CON_CH     (1<<1)
+#define STAT_SUS        (1<<2)
+#define STAT_SUS_CH     (1<<3)
+#define STAT_RST        (1<<4)
+
+// end points interrupts
+#define EP0RX_INT       (1<<0)
+#define EP0TX_INT       (1<<1)
+#define EP1RX_INT       (1<<2)
+#define EP1TX_INT       (1<<3)
+#define EP2RX_INT       (1<<4)
+#define EP2TX_INT       (1<<5)
+
+// USB control register
+#define RD_EN           (1<<0)
+#define WR_EN           (1<<1)
+#define PKT_RDY         (1<<11)
+#define LOG_ENDPOINT(ep) ((ep>>1)<<2)
+
+// configure state
+static int configured = 0;
+
+// USB interrupt handler
+void USB_IRQHandler(void);
+
+// Serial Interface Engine functions
+void sie_command(uint32_t code) {
+    LPC_USB->USBDevIntClr = CCEMPTY;                // clear CCEMPTY     
+    LPC_USB->USBCmdCode   = ((code<<16)|(0x05<<8)); // CMD_PHASE=Command 
+    while (!(LPC_USB->USBDevIntSt & CCEMPTY));      // wait for CCEMPTY 
+}
+
+void sie_write(uint32_t data) {
+    LPC_USB->USBDevIntClr = CCEMPTY;                // clear CCEMPTY     
+    LPC_USB->USBCmdCode   = ((data<<16)|(0x01<<8)); // CMD_PHASE=Write   
+    while (!(LPC_USB->USBDevIntSt & CCEMPTY));      // wait for CCEMPTY  
+}
+
+uint8_t sie_read(uint32_t code) {
+    LPC_USB->USBDevIntClr = CDFULL;                 // clear CCEMPTY     
+    LPC_USB->USBCmdCode   = ((code<<16)|(0x02<<8)); // CMD_PHASE=Read    
+    while (!(LPC_USB->USBDevIntSt & CDFULL));       // wait for CDFULL   
+    return (uint8_t) LPC_USB->USBCmdData;
+
+}
+
+// end point functions
+void ep_realize(uint8_t ep, uint32_t size) {
+    LPC_USB->USBDevIntClr = EP_RLZED;           // clear EP_RLZED
+    LPC_USB->USBReEp    |= (1<<ep);
+    LPC_USB->USBEpInd    = ep;                  // set USBEpIn
+    LPC_USB->USBMaxPSize = size;                // writing to EPn pointed to by USBEpInd
+    while (!(LPC_USB->USBDevIntSt & EP_RLZED)); // wait for EP_RLZED
+    LPC_USB->USBDevIntClr = EP_RLZED;           // clear EP_RLZED
+}
+
+void ep_stall(uint8_t ep) {
+    sie_command(SIE_SET_EP_STAT+ep);
+    sie_write(1);
+}
+
+void ep_unstall(uint8_t ep) {
+    sie_command(SIE_SET_EP_STAT+ep);
+    sie_write(0);
+}
+
+// initializes a pointer to the endpoint buffer
+uint8_t ep_select(uint8_t ep) {
+    sie_command(SIE_SEL_EP+ep);
+    return sie_read(SIE_SEL_EP+ep);
+}
+
+uint8_t ep_select_clear(uint8_t ep) {
+    LPC_USB->USBEpIntClr |= ep;                 // clear ep interrupt   
+    while (!(LPC_USB->USBDevIntSt & CDFULL));   // wait for cmd finish 
+    return LPC_USB->USBCmdData;
+}
+
+int ep_readable(uint8_t ep) {
+    uint8_t st = ep_select(ep);
+    return (st & EP_FE);
+}
+
+int ep_writable(uint8_t ep) {
+    uint8_t st = ep_select(ep);
+    return !(st & EP_FE);
+}
+
+int ep_read(uint8_t ep, uint8_t *tbuf) {
+    uint32_t *buf = (uint32_t*) tbuf;
+    LPC_USB->USBCtrl = LOG_ENDPOINT(ep)|RD_EN;  // RD_EN bit and LOG_ENDPOINT   
+    while (!(LPC_USB->USBRxPLen & PKT_RDY));    // wait for packet to be fetched
+    int len = LPC_USB->USBRxPLen & 0x3FF;       // read and mask packet length  
+    while (!(LPC_USB->USBDevIntSt & RxENDPKT)) {
+        *buf++ = LPC_USB->USBRxData;
+    }
+    LPC_USB->USBCtrl = 0;
+    LPC_USB->USBDevIntClr |= RxENDPKT;
+    sie_command(SIE_SEL_EP+ep);     // select endpoint   
+    sie_command(SIE_CLR_BUFFER);    // clear RX buffer   
+    return len;
+}
+
+void ep_write(uint8_t ep, uint8_t *tbuf, uint32_t len) {
+    uint32_t *buf = (uint32_t*) tbuf;
+    LPC_USB->USBCtrl   = LOG_ENDPOINT(ep)|WR_EN; // RD_EN bit and LOG_ENDPOINT  
+    LPC_USB->USBTxPLen |= (len & 0x3FF);         // write and mask packet length
+    while (!(LPC_USB->USBDevIntSt & TxENDPKT)) {
+        LPC_USB->USBTxData = *buf++;
+    }
+    LPC_USB->USBCtrl = 0;
+    LPC_USB->USBDevIntClr |= TxENDPKT;
+    sie_command(SIE_SEL_EP+ep);     // select endpoint   
+    sie_command(SIE_VAL_BUFFER);    // validate TX buffer
+}
+
+// USB device controller initialization
+void usb_init() {
+    // USB D+/D- pinsel functions
+    LPC_PINCON->PINSEL1 &=   0xC3FFFFFF;
+    LPC_PINCON->PINSEL1 |=   0x14000000;
+
+#if USB_UP_DEBUG
+    // USB_UP_LED pinsel function
+    LPC_PINCON->PINSEL3 &=   0xFFFFFFCF;
+    LPC_PINCON->PINSEL3 |=   0x00000010;
+#endif    
+
+    // USB connect pinsel function
+    LPC_PINCON->PINSEL4 &=   0xFFFCFFFF;
+    LPC_PINCON->PINSEL4 |=   0x00040000;
+    LPC_SC->PCONP       |=   (1UL<<31);         // enable the USB controller
+    LPC_USB->USBClkCtrl |=   ((1<<1)|(1<<4));   // enable the AHB and DEV clocks
+    while ((LPC_USB->USBClkSt & 0x12) != 0x12); // wait for the clocks to init
+
+    NVIC_SetVector(USB_IRQn, (uint32_t)&USB_IRQHandler);
+    NVIC_EnableIRQ(USB_IRQn);    // enable USB interrupts
+
+    usb_reset();
+    usb_set_address(0);          // default address
+}
+
+void usb_reset() {
+    ep_realize(EP0, MAX_EP0_PSIZE);
+    ep_realize(EP1, MAX_EP0_PSIZE);
+    LPC_USB->USBEpIntClr  = 0xFFFFFFFF;         // clear end points interrupts
+    LPC_USB->USBEpIntEn   = 0xFFFFFFFF;         // enable end points interrupts
+    LPC_USB->USBEpIntPri  = 0x0;                // route to EP_SLOW
+    LPC_USB->USBDevIntClr = 0xFFFFFFFF;         // clear USB device interrupts 
+    LPC_USB->USBDevIntEn  = (EP_SLOW|DEV_STAT); // enable USB device interrupts
+}
+
+void usb_configure(uint8_t conf) {
+    sie_command(SIE_CONFIG_DEVICE);
+    sie_write(conf);
+    configured = 1;
+}
+
+int usb_configured() {
+    return configured;
+}
+
+void usb_set_address(uint8_t addr) {
+    sie_command(SIE_SET_ADDR);
+    sie_write(addr|0x80);       // DEV_EN = 1
+}
+
+uint8_t usb_get_status() {
+    sie_command(SIE_GET_STATUS);
+    return sie_read(SIE_GET_STATUS);
+}
+
+void usb_connect() {
+    sie_command(SIE_GET_STATUS); // read current status
+    uint8_t st = sie_read(SIE_GET_STATUS);
+
+    sie_command(SIE_SET_STATUS); // set STAT_CON bit
+    sie_write(st|STAT_CON);
+}
+
+void USB_IRQHandler(void) {
+    if (LPC_USB->USBDevIntSt & DEV_STAT) { // DEV_STAT interrupt
+        LPC_USB->USBDevIntClr |= DEV_STAT;
+        if (usb_get_status() & STAT_RST) { // bus reset
+            usb_reset();
+        }
+        return;
+    }
+
+    if (LPC_USB->USBDevIntSt & EP_SLOW) {  // EP_SLOW interrupt
+        if (LPC_USB->USBEpIntSt & EP0RX_INT) {
+            if (ep_select_clear(EP0RX_INT) & EP_STP) { // setup transfer
+                ep0_setup();
+            } else {
+                ep0_out();
+            }
+        }
+
+        if (LPC_USB->USBEpIntSt & EP0TX_INT) {
+            ep_select_clear(EP0TX_INT);
+            ep0_in();
+        }
+
+        if (LPC_USB->USBEpIntSt & EP2RX_INT) {
+            ep_select_clear(EP2TX_INT);
+            ep2_out();
+        }
+
+        if (LPC_USB->USBEpIntSt & EP2TX_INT) {
+            ep_select_clear(EP2TX_INT);
+            ep2_in();
+        }
+
+        // EP_SLOW should be cleared after clearing EPs interrupts
+        LPC_USB->USBDevIntClr |= EP_SLOW;
+    }
+}
--- a/usbdevice.c	Sun Feb 20 13:12:22 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,181 +0,0 @@
-/* @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.
- */
-
-#include "usbcore.h"
-#include "mbed.h"
-
-#define STANDARD_DEVICE_REQUEST     (0x00)
-#define STANDARD_INTERFACE_REQUEST  (0x01)
-#define STANDARD_ENDPOINT_REQUEST   (0x02)
-#define CLASS_DEVICE_REQUEST        (0x20)
-#define CLASS_INTERFACE_REQUEST     (0x21)
-#define CLASS_ENDPOINT_REQUEST      (0x22)
-#define VENDOR_DEVICE_REQUEST       (0x40)
-#define VENDOR_INTERFACE_REQUEST    (0x41)
-#define VENDOR_ENDPOINT_REQUEST     (0x42)
-#define GET_STATUS                  (0x00)
-#define CLEAR_FEATURE               (0x01)
-#define SET_FEATURE                 (0x03)
-#define SET_ADDRESS                 (0x05)
-#define GET_DESCRIPTOR              (0x06)
-#define SET_DESCRIPTOR              (0x07)
-#define GET_CONFIGURATION           (0x08)
-#define SET_CONFIGURATION           (0x09)
-#define DEVICE_DESCRIPTOR           (0x01)
-#define CONFIG_DESCRIPTOR           (0x02)
-#define STRING_DESCRIPTOR           (0x03)
-#define INTERFACE_DESCRIPTOR        (0x04)
-#define ENDPOINT_DESCRIPTOR         (0x05)
-#define QUALIFIER_DESCRIPTOR        (0x06)
-#define unpack(x) (x & 0xFF),((x >> 8) & 0xFF)
-
-// setup packet
-struct {
-    uint8_t   bmRequestType;
-    uint8_t   bRequest;
-    uint16_t  wValue;
-    uint16_t  wIndex;
-    uint16_t  wLength;
-} __attribute__((packed)) setup = {0};
-
-// data packet
-struct { 
-    uint8_t *data;
-    uint8_t size;
-    uint8_t sent;
-} transfer = {0};
-
-uint8_t device_descriptor[] = {
-    0x12,                       // Descriptor size in bytes (12h)                  
-    DEVICE_DESCRIPTOR,          // The constant DEVICE (01h)                       
-    unpack(0x0200),             // US2B specification release number (BCD)         
-    0x00,                       // Class code                                      
-    0x00,                       // Subclass code                                   
-    0x00,                       // Protocol Code                                   
-    MAX_EP0_PSIZE,              // Maximum packet size for endpoint zero           
-    unpack(0x0763),             // Vendor ID                                       
-    unpack(0x0198),             // Product ID                                      
-    unpack(0x0001),             // Device release number (BCD)                     
-    0x00,                       // Index of string descriptor for the manufacturer 
-    0x00,                       // Index of string descriptor for the product      
-    0x00,                       // Index of string descriptor for the serial number
-    0x01,                       // Number of possible configurations               
-};
-
-uint8_t config_descriptor[]={
-    0x09, 0x02, 0x65, 0x00, 0x02, 0x01, 0x00, 0xc0, 0x50, // configuration descriptor
-    // 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,
-};
-
-void ep0_in();
-
-void data_in_stage(uint8_t *desc, uint8_t length) {
-    transfer.sent = 0;
-    transfer.data = desc;
-    transfer.size = length;
-    ep0_in();
-}
-
-void status_in_stage() {
-    ep_write(EP1, 0, 0); // ZLEP for status stage
-}
-
-void ep0_setup() {
-    ep_read(EP0,(uint8_t*) &setup);
-
-    switch (setup.bmRequestType & 0x7f) { // mask direction
-        case STANDARD_DEVICE_REQUEST:
-            switch (setup.bRequest) {
-                case GET_DESCRIPTOR:
-                    switch ((setup.wValue>>8)) {
-                        case DEVICE_DESCRIPTOR:     // device descriptor request
-                        case QUALIFIER_DESCRIPTOR:  // device qualifier descriptor
-                            data_in_stage(device_descriptor, sizeof(device_descriptor));
-                            break;
-                        case CONFIG_DESCRIPTOR:     // configuration descriptor
-                            data_in_stage(config_descriptor, setup.wLength);
-                            break;
-                        case STRING_DESCRIPTOR:
-                            break;
-                        default:
-                            break;
-                    }
-                    break;
-                case SET_ADDRESS:
-                    usb_set_address((uint8_t) (setup.wValue & 0xFF));
-                    status_in_stage();
-                    break;
-                case SET_CONFIGURATION:
-                    if (!setup.wValue) {
-                        break;
-                    }
-                    ep_realize(EP4, MAX_EPn_PSIZE);
-                    ep_realize(EP5, MAX_EPn_PSIZE);
-                    status_in_stage();
-                    usb_configure(1);
-                    break;
-                default:
-                    break;
-            }
-            break;
-        default:
-            break;
-    }
-}
-
-void ep0_in() {
-    if ((setup.bmRequestType & 0x80) && transfer.size) { // device to host
-        if (transfer.size > MAX_EP0_PSIZE) {
-            transfer.sent = MAX_EP0_PSIZE;
-        } else {
-            transfer.sent = transfer.size;
-        }
-        ep_write(EP1, transfer.data, transfer.sent);
-        transfer.data += transfer.sent;
-        transfer.size -= transfer.sent;
-    }
-}
-
-void ep0_out() {
-    uint8_t buf[64];
-    ep_read(EP0, buf);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbdevice.cpp	Fri Apr 29 01:46:03 2016 +0000
@@ -0,0 +1,181 @@
+/* @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.
+ */
+
+#include "usbcore.h"
+#include "mbed.h"
+
+#define STANDARD_DEVICE_REQUEST     (0x00)
+#define STANDARD_INTERFACE_REQUEST  (0x01)
+#define STANDARD_ENDPOINT_REQUEST   (0x02)
+#define CLASS_DEVICE_REQUEST        (0x20)
+#define CLASS_INTERFACE_REQUEST     (0x21)
+#define CLASS_ENDPOINT_REQUEST      (0x22)
+#define VENDOR_DEVICE_REQUEST       (0x40)
+#define VENDOR_INTERFACE_REQUEST    (0x41)
+#define VENDOR_ENDPOINT_REQUEST     (0x42)
+#define GET_STATUS                  (0x00)
+#define CLEAR_FEATURE               (0x01)
+#define SET_FEATURE                 (0x03)
+#define SET_ADDRESS                 (0x05)
+#define GET_DESCRIPTOR              (0x06)
+#define SET_DESCRIPTOR              (0x07)
+#define GET_CONFIGURATION           (0x08)
+#define SET_CONFIGURATION           (0x09)
+#define DEVICE_DESCRIPTOR           (0x01)
+#define CONFIG_DESCRIPTOR           (0x02)
+#define STRING_DESCRIPTOR           (0x03)
+#define INTERFACE_DESCRIPTOR        (0x04)
+#define ENDPOINT_DESCRIPTOR         (0x05)
+#define QUALIFIER_DESCRIPTOR        (0x06)
+#define unpack(x) (x & 0xFF),((x >> 8) & 0xFF)
+
+// setup packet
+struct {
+    uint8_t   bmRequestType;
+    uint8_t   bRequest;
+    uint16_t  wValue;
+    uint16_t  wIndex;
+    uint16_t  wLength;
+} __attribute__((packed)) setup = {0};
+
+// data packet
+struct { 
+    uint8_t *data;
+    uint8_t size;
+    uint8_t sent;
+} transfer = {0};
+
+uint8_t device_descriptor[] = {
+    0x12,                       // Descriptor size in bytes (12h)                  
+    DEVICE_DESCRIPTOR,          // The constant DEVICE (01h)                       
+    unpack(0x0200),             // US2B specification release number (BCD)         
+    0x00,                       // Class code                                      
+    0x00,                       // Subclass code                                   
+    0x00,                       // Protocol Code                                   
+    MAX_EP0_PSIZE,              // Maximum packet size for endpoint zero           
+    unpack(0x0763),             // Vendor ID                                       
+    unpack(0x0198),             // Product ID                                      
+    unpack(0x0001),             // Device release number (BCD)                     
+    0x00,                       // Index of string descriptor for the manufacturer 
+    0x00,                       // Index of string descriptor for the product      
+    0x00,                       // Index of string descriptor for the serial number
+    0x01,                       // Number of possible configurations               
+};
+
+uint8_t config_descriptor[]={
+    0x09, 0x02, 0x65, 0x00, 0x02, 0x01, 0x00, 0xc0, 0x50, // configuration descriptor
+    // 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,
+};
+
+void ep0_in();
+
+void data_in_stage(uint8_t *desc, uint8_t length) {
+    transfer.sent = 0;
+    transfer.data = desc;
+    transfer.size = length;
+    ep0_in();
+}
+
+void status_in_stage() {
+    ep_write(EP1, 0, 0); // ZLEP for status stage
+}
+
+void ep0_setup() {
+    ep_read(EP0,(uint8_t*) &setup);
+
+    switch (setup.bmRequestType & 0x7f) { // mask direction
+        case STANDARD_DEVICE_REQUEST:
+            switch (setup.bRequest) {
+                case GET_DESCRIPTOR:
+                    switch ((setup.wValue>>8)) {
+                        case DEVICE_DESCRIPTOR:     // device descriptor request
+                        case QUALIFIER_DESCRIPTOR:  // device qualifier descriptor
+                            data_in_stage(device_descriptor, sizeof(device_descriptor));
+                            break;
+                        case CONFIG_DESCRIPTOR:     // configuration descriptor
+                            data_in_stage(config_descriptor, setup.wLength);
+                            break;
+                        case STRING_DESCRIPTOR:
+                            break;
+                        default:
+                            break;
+                    }
+                    break;
+                case SET_ADDRESS:
+                    usb_set_address((uint8_t) (setup.wValue & 0xFF));
+                    status_in_stage();
+                    break;
+                case SET_CONFIGURATION:
+                    if (!setup.wValue) {
+                        break;
+                    }
+                    ep_realize(EP4, MAX_EPn_PSIZE);
+                    ep_realize(EP5, MAX_EPn_PSIZE);
+                    status_in_stage();
+                    usb_configure(1);
+                    break;
+                default:
+                    break;
+            }
+            break;
+        default:
+            break;
+    }
+}
+
+void ep0_in() {
+    if ((setup.bmRequestType & 0x80) && transfer.size) { // device to host
+        if (transfer.size > MAX_EP0_PSIZE) {
+            transfer.sent = MAX_EP0_PSIZE;
+        } else {
+            transfer.sent = transfer.size;
+        }
+        ep_write(EP1, transfer.data, transfer.sent);
+        transfer.data += transfer.sent;
+        transfer.size -= transfer.sent;
+    }
+}
+
+void ep0_out() {
+    uint8_t buf[64];
+    ep_read(EP0, buf);
+}