Fork of the official USBDevice library

Fork of USBDevice by mbed official

Files at this revision

API Documentation at this revision

Comitter:
screamer
Date:
Fri Apr 28 11:26:51 2017 +0100
Branch:
github-merge
Parent:
63:01321bd6ff89
Child:
74:13306e96d108
Commit message:
Merge from mbed-os @ github

Changed in this revision

USBAudio/USBAudio.cpp Show annotated file Show diff for this revision Revisions of this file
USBAudio/USBAudio.h Show annotated file Show diff for this revision Revisions of this file
USBAudio/USBAudio_Types.h Show annotated file Show diff for this revision Revisions of this file
USBDevice/TARGET_STM/USBHAL_STM32.cpp Show annotated file Show diff for this revision Revisions of this file
USBDevice/TARGET_Silicon_Labs/inc/em_usb.h Show annotated file Show diff for this revision Revisions of this file
USBDevice/USBDescriptor.h Show annotated file Show diff for this revision Revisions of this file
USBDevice/USBDevice.cpp Show annotated file Show diff for this revision Revisions of this file
USBDevice/USBDevice.h Show annotated file Show diff for this revision Revisions of this file
USBDevice/USBDevice_Types.h 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/USBEndpoints_LPC11U.h Show annotated file Show diff for this revision Revisions of this file
USBDevice/USBEndpoints_LPC17_LPC23.h Show annotated file Show diff for this revision Revisions of this file
USBDevice/USBEndpoints_M453.h Show annotated file Show diff for this revision Revisions of this file
USBDevice/USBEndpoints_NUC472.h Show annotated file Show diff for this revision Revisions of this file
USBDevice/USBEndpoints_STM32.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
USBDevice/USBHAL_LPC40.cpp Show annotated file Show diff for this revision Revisions of this file
USBDevice/USBHAL_M453.cpp Show annotated file Show diff for this revision Revisions of this file
USBDevice/USBHAL_Maxim.cpp Show annotated file Show diff for this revision Revisions of this file
USBDevice/USBHAL_NUC472.cpp Show annotated file Show diff for this revision Revisions of this file
USBDevice/USBHAL_STM32F4.cpp Show annotated file Show diff for this revision Revisions of this file
USBHID/USBHID.cpp Show annotated file Show diff for this revision Revisions of this file
USBHID/USBHID.h Show annotated file Show diff for this revision Revisions of this file
USBHID/USBHID_Types.h Show annotated file Show diff for this revision Revisions of this file
USBHID/USBKeyboard.cpp Show annotated file Show diff for this revision Revisions of this file
USBHID/USBMouse.cpp Show annotated file Show diff for this revision Revisions of this file
USBHID/USBMouse.h Show annotated file Show diff for this revision Revisions of this file
USBHID/USBMouseKeyboard.cpp Show annotated file Show diff for this revision Revisions of this file
USBMIDI/MIDIMessage.h Show annotated file Show diff for this revision Revisions of this file
USBMIDI/USBMIDI.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
USBSerial/USBCDC.h Show annotated file Show diff for this revision Revisions of this file
USBSerial/USBSerial.cpp Show annotated file Show diff for this revision Revisions of this file
USBSerial/USBSerial.h Show annotated file Show diff for this revision Revisions of this file
--- a/USBAudio/USBAudio.cpp	Tue May 03 00:16:32 2016 +0100
+++ b/USBAudio/USBAudio.cpp	Fri Apr 28 11:26:51 2017 +0100
@@ -1,618 +1,637 @@
-/* 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 "USBAudio.h"
-#include "USBAudio_Types.h"
-
-
-
-USBAudio::USBAudio(uint32_t frequency_in, uint8_t channel_nb_in, uint32_t frequency_out, uint8_t channel_nb_out, uint16_t vendor_id, uint16_t product_id, uint16_t product_release): USBDevice(vendor_id, product_id, product_release) {
-    mute = 0;
-    volCur = 0x0080;
-    volMin = 0x0000;
-    volMax = 0x0100;
-    volRes = 0x0004;
-    available = false;
-
-    FREQ_IN = frequency_in;
-    FREQ_OUT = frequency_out;
-
-    this->channel_nb_in = channel_nb_in;
-    this->channel_nb_out = channel_nb_out;
-
-    // stereo -> *2, mono -> *1
-    PACKET_SIZE_ISO_IN = (FREQ_IN / 500) * channel_nb_in;
-    PACKET_SIZE_ISO_OUT = (FREQ_OUT / 500) * channel_nb_out;
-
-    // STEREO -> left and right
-    channel_config_in = (channel_nb_in == 1) ? CHANNEL_M : CHANNEL_L + CHANNEL_R;
-    channel_config_out = (channel_nb_out == 1) ? CHANNEL_M : CHANNEL_L + CHANNEL_R;
-
-    SOF_handler = false;
-
-    buf_stream_out = NULL;
-    buf_stream_in = NULL;
-
-    interruptOUT = false;
-    writeIN = false;
-    interruptIN = false;
-    available = false;
-
-    volume = 0;
-
-    // connect the device
-    USBDevice::connect();
-}
-
-bool USBAudio::read(uint8_t * buf) {
-    buf_stream_in = buf;
-    SOF_handler = false;
-    while (!available || !SOF_handler);
-    available = false;
-    return true;
-}
-
-bool USBAudio::readNB(uint8_t * buf) {
-    buf_stream_in = buf;
-    SOF_handler = false;
-    while (!SOF_handler);
-    if (available) {
-        available = false;
-        buf_stream_in = NULL;
-        return true;
-    }
-    return false;
-}
-
-bool USBAudio::readWrite(uint8_t * buf_read, uint8_t * buf_write) {
-    buf_stream_in = buf_read;
-    SOF_handler = false;
-    writeIN = false;
-    if (interruptIN) {
-        USBDevice::writeNB(EP3IN, buf_write, PACKET_SIZE_ISO_OUT, PACKET_SIZE_ISO_OUT);
-    } else {
-        buf_stream_out = buf_write;
-    }
-    while (!available);
-    if (interruptIN) {
-        while (!writeIN);
-    }
-    while (!SOF_handler);
-    return true;
-}
-
-
-bool USBAudio::write(uint8_t * buf) {
-    writeIN = false;
-    SOF_handler = false;
-    if (interruptIN) {
-        USBDevice::writeNB(EP3IN, buf, PACKET_SIZE_ISO_OUT, PACKET_SIZE_ISO_OUT);
-    } else {
-        buf_stream_out = buf;
-    }
-    while (!SOF_handler);
-    if (interruptIN) {
-        while (!writeIN);
-    }
-    return true;
-}
-
-
-float USBAudio::getVolume() {
-    return (mute) ? 0.0 : volume;
-}
-
-
-bool USBAudio::EPISO_OUT_callback() {
-    uint32_t size = 0;
-    interruptOUT = true;
-    if (buf_stream_in != NULL) {
-        readEP(EP3OUT, (uint8_t *)buf_stream_in, &size, PACKET_SIZE_ISO_IN);
-        available = true;
-        buf_stream_in = NULL;
-    }
-    readStart(EP3OUT, PACKET_SIZE_ISO_IN);
-    return false;
-}
-
-
-bool USBAudio::EPISO_IN_callback() {
-    interruptIN = true;
-    writeIN = true;
-    return true;
-}
-
-
-
-// Called in ISR context on each start of frame
-void USBAudio::SOF(int frameNumber) {
-    uint32_t size = 0;
-
-    if (!interruptOUT) {
-        // read the isochronous endpoint
-        if (buf_stream_in != NULL) {
-            if (USBDevice::readEP_NB(EP3OUT, (uint8_t *)buf_stream_in, &size, PACKET_SIZE_ISO_IN)) {
-                if (size) {
-                    available = true;
-                    readStart(EP3OUT, PACKET_SIZE_ISO_IN);
-                    buf_stream_in = NULL;
-                }
-            }
-        }
-    }
-
-    if (!interruptIN) {
-        // write if needed
-        if (buf_stream_out != NULL) {
-            USBDevice::writeNB(EP3IN, (uint8_t *)buf_stream_out, PACKET_SIZE_ISO_OUT, PACKET_SIZE_ISO_OUT);
-            buf_stream_out = NULL;
-        }
-    }
-
-    SOF_handler = true;
-}
-
-
-// Called in ISR context
-// Set configuration. Return false if the configuration is not supported.
-bool USBAudio::USBCallback_setConfiguration(uint8_t configuration) {
-    if (configuration != DEFAULT_CONFIGURATION) {
-        return false;
-    }
-
-    // Configure isochronous endpoint
-    realiseEndpoint(EP3OUT, PACKET_SIZE_ISO_IN, ISOCHRONOUS);
-    realiseEndpoint(EP3IN, PACKET_SIZE_ISO_OUT, ISOCHRONOUS);
-
-    // activate readings on this endpoint
-    readStart(EP3OUT, PACKET_SIZE_ISO_IN);
-    return true;
-}
-
-
-// Called in ISR context
-// Set alternate setting. Return false if the alternate setting is not supported
-bool USBAudio::USBCallback_setInterface(uint16_t interface, uint8_t alternate) {
-    if (interface == 0 && alternate == 0) {
-        return true;
-    }
-    if (interface == 1 && (alternate == 0 || alternate == 1)) {
-        return true;
-    }
-    if (interface == 2 && (alternate == 0 || alternate == 1)) {
-        return true;
-    }
-    return false;
-}
-
-
-
-// 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 USBAudio::USBCallback_request() {
-    bool success = false;
-    CONTROL_TRANSFER * transfer = getTransferPtr();
-
-    // Process class-specific requests
-    if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
-
-        // Feature Unit: Interface = 0, ID = 2
-        if (transfer->setup.wIndex == 0x0200) {
-
-            // Master Channel
-            if ((transfer->setup.wValue & 0xff) == 0) {
-
-                switch (transfer->setup.wValue >> 8) {
-                    case MUTE_CONTROL:
-                        switch (transfer->setup.bRequest) {
-                            case REQUEST_GET_CUR:
-                                transfer->remaining = 1;
-                                transfer->ptr = &mute;
-                                transfer->direction = DEVICE_TO_HOST;
-                                success = true;
-                                break;
-
-                            case REQUEST_SET_CUR:
-                                transfer->remaining = 1;
-                                transfer->notify = true;
-                                transfer->direction = HOST_TO_DEVICE;
-                                success = true;
-                                break;
-                            default:
-                                break;
-                        }
-                        break;
-                    case VOLUME_CONTROL:
-                        switch (transfer->setup.bRequest) {
-                            case REQUEST_GET_CUR:
-                                transfer->remaining = 2;
-                                transfer->ptr = (uint8_t *)&volCur;
-                                transfer->direction = DEVICE_TO_HOST;
-                                success = true;
-                                break;
-                            case REQUEST_GET_MIN:
-                                transfer->remaining = 2;
-                                transfer->ptr = (uint8_t *)&volMin;
-                                transfer->direction = DEVICE_TO_HOST;
-                                success = true;
-                                break;
-                            case REQUEST_GET_MAX:
-                                transfer->remaining = 2;
-                                transfer->ptr = (uint8_t *)&volMax;
-                                transfer->direction = DEVICE_TO_HOST;
-                                success = true;
-                                break;
-                            case REQUEST_GET_RES:
-                                transfer->remaining = 2;
-                                transfer->ptr = (uint8_t *)&volRes;
-                                transfer->direction = DEVICE_TO_HOST;
-                                success = true;
-                                break;
-
-                            case REQUEST_SET_CUR:
-                                transfer->remaining = 2;
-                                transfer->notify = true;
-                                transfer->direction = HOST_TO_DEVICE;
-                                success = true;
-                                break;
-                            case REQUEST_SET_MIN:
-                                transfer->remaining = 2;
-                                transfer->notify = true;
-                                transfer->direction = HOST_TO_DEVICE;
-                                success = true;
-                                break;
-                            case REQUEST_SET_MAX:
-                                transfer->remaining = 2;
-                                transfer->notify = true;
-                                transfer->direction = HOST_TO_DEVICE;
-                                success = true;
-                                break;
-                            case REQUEST_SET_RES:
-                                transfer->remaining = 2;
-                                transfer->notify = true;
-                                transfer->direction = HOST_TO_DEVICE;
-                                success = true;
-                                break;
-                        }
-                        break;
-                    default:
-                        break;
-                }
-            }
-        }
-    }
-    return success;
-}
-
-
-// Called in ISR context when a data OUT stage has been performed
-void USBAudio::USBCallback_requestCompleted(uint8_t * buf, uint32_t length) {
-    if ((length == 1) || (length == 2)) {
-        uint16_t data = (length == 1) ? *buf : *((uint16_t *)buf);
-        CONTROL_TRANSFER * transfer = getTransferPtr();
-        switch (transfer->setup.wValue >> 8) {
-            case MUTE_CONTROL:
-                switch (transfer->setup.bRequest) {
-                    case REQUEST_SET_CUR:
-                        mute = data & 0xff;
-                        updateVol.call();
-                        break;
-                    default:
-                        break;
-                }
-                break;
-            case VOLUME_CONTROL:
-                switch (transfer->setup.bRequest) {
-                    case REQUEST_SET_CUR:
-                        volCur = data;
-                        volume = (float)volCur/(float)volMax;
-                        updateVol.call();
-                        break;
-                    default:
-                        break;
-                }
-                break;
-            default:
-                break;
-        }
-    }
-}
-
-
-
-#define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
-                               + (5 * INTERFACE_DESCRIPTOR_LENGTH) \
-                               + (1 * CONTROL_INTERFACE_DESCRIPTOR_LENGTH + 1) \
-                               + (2 * INPUT_TERMINAL_DESCRIPTOR_LENGTH) \
-                               + (1 * FEATURE_UNIT_DESCRIPTOR_LENGTH) \
-                               + (2 * OUTPUT_TERMINAL_DESCRIPTOR_LENGTH) \
-                               + (2 * STREAMING_INTERFACE_DESCRIPTOR_LENGTH) \
-                               + (2 * FORMAT_TYPE_I_DESCRIPTOR_LENGTH) \
-                               + (2 * (ENDPOINT_DESCRIPTOR_LENGTH + 2)) \
-                               + (2 * STREAMING_ENDPOINT_DESCRIPTOR_LENGTH) )
-
-#define TOTAL_CONTROL_INTF_LENGTH    (CONTROL_INTERFACE_DESCRIPTOR_LENGTH + 1 + \
-                                      2*INPUT_TERMINAL_DESCRIPTOR_LENGTH     + \
-                                      FEATURE_UNIT_DESCRIPTOR_LENGTH    + \
-                                      2*OUTPUT_TERMINAL_DESCRIPTOR_LENGTH)
-
-uint8_t * USBAudio::configurationDesc() {
-    static uint8_t configDescriptor[] = {
-        // Configuration 1
-        CONFIGURATION_DESCRIPTOR_LENGTH,        // bLength
-        CONFIGURATION_DESCRIPTOR,               // bDescriptorType
-        LSB(TOTAL_DESCRIPTOR_LENGTH),           // wTotalLength (LSB)
-        MSB(TOTAL_DESCRIPTOR_LENGTH),           // wTotalLength (MSB)
-        0x03,                                   // bNumInterfaces
-        DEFAULT_CONFIGURATION,                  // bConfigurationValue
-        0x00,                                   // iConfiguration
-        0x80,                                   // bmAttributes
-        50,                                     // bMaxPower
-
-        // Interface 0, Alternate Setting 0, Audio Control
-        INTERFACE_DESCRIPTOR_LENGTH,            // bLength
-        INTERFACE_DESCRIPTOR,                   // bDescriptorType
-        0x00,                                   // bInterfaceNumber
-        0x00,                                   // bAlternateSetting
-        0x00,                                   // bNumEndpoints
-        AUDIO_CLASS,                            // bInterfaceClass
-        SUBCLASS_AUDIOCONTROL,                  // bInterfaceSubClass
-        0x00,                                   // bInterfaceProtocol
-        0x00,                                   // iInterface
-
-
-        // Audio Control Interface
-        CONTROL_INTERFACE_DESCRIPTOR_LENGTH + 1,// bLength
-        INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
-        CONTROL_HEADER,                         // bDescriptorSubtype
-        LSB(0x0100),                            // bcdADC (LSB)
-        MSB(0x0100),                            // bcdADC (MSB)
-        LSB(TOTAL_CONTROL_INTF_LENGTH),         // wTotalLength
-        MSB(TOTAL_CONTROL_INTF_LENGTH),         // wTotalLength
-        0x02,                                   // bInCollection
-        0x01,                                   // baInterfaceNr
-        0x02,                                   // baInterfaceNr
-
-        // Audio Input Terminal (Speaker)
-        INPUT_TERMINAL_DESCRIPTOR_LENGTH,       // bLength
-        INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
-        CONTROL_INPUT_TERMINAL,                 // bDescriptorSubtype
-        0x01,                                   // bTerminalID
-        LSB(TERMINAL_USB_STREAMING),            // wTerminalType
-        MSB(TERMINAL_USB_STREAMING),            // wTerminalType
-        0x00,                                   // bAssocTerminal
-        channel_nb_in,                          // bNrChannels
-        (uint8_t)(LSB(channel_config_in)),                 // wChannelConfig
-        (uint8_t)(MSB(channel_config_in)),                 // wChannelConfig
-        0x00,                                   // iChannelNames
-        0x00,                                   // iTerminal
-
-        // Audio Feature Unit (Speaker)
-        FEATURE_UNIT_DESCRIPTOR_LENGTH,         // bLength
-        INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
-        CONTROL_FEATURE_UNIT,                   // bDescriptorSubtype
-        0x02,                                   // bUnitID
-        0x01,                                   // bSourceID
-        0x01,                                   // bControlSize
-        CONTROL_MUTE |
-        CONTROL_VOLUME,                         // bmaControls(0)
-        0x00,                                   // bmaControls(1)
-        0x00,                                   // iTerminal
-
-        // Audio Output Terminal (Speaker)
-        OUTPUT_TERMINAL_DESCRIPTOR_LENGTH,      // bLength
-        INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
-        CONTROL_OUTPUT_TERMINAL,                // bDescriptorSubtype
-        0x03,                                   // bTerminalID
-        LSB(TERMINAL_SPEAKER),                  // wTerminalType
-        MSB(TERMINAL_SPEAKER),                  // wTerminalType
-        0x00,                                   // bAssocTerminal
-        0x02,                                   // bSourceID
-        0x00,                                   // iTerminal
-
-
-        // Audio Input Terminal (Microphone)
-        INPUT_TERMINAL_DESCRIPTOR_LENGTH,       // bLength
-        INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
-        CONTROL_INPUT_TERMINAL,                 // bDescriptorSubtype
-        0x04,                                   // bTerminalID
-        LSB(TERMINAL_MICROPHONE),               // wTerminalType
-        MSB(TERMINAL_MICROPHONE),               // wTerminalType
-        0x00,                                   // bAssocTerminal
-        channel_nb_out,                         // bNrChannels
-        (uint8_t)(LSB(channel_config_out)),                // wChannelConfig
-        (uint8_t)(MSB(channel_config_out)),                // wChannelConfig
-        0x00,                                   // iChannelNames
-        0x00,                                   // iTerminal
-
-        // Audio Output Terminal (Microphone)
-        OUTPUT_TERMINAL_DESCRIPTOR_LENGTH,      // bLength
-        INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
-        CONTROL_OUTPUT_TERMINAL,                // bDescriptorSubtype
-        0x05,                                   // bTerminalID
-        LSB(TERMINAL_USB_STREAMING),            // wTerminalType
-        MSB(TERMINAL_USB_STREAMING),            // wTerminalType
-        0x00,                                   // bAssocTerminal
-        0x04,                                   // bSourceID
-        0x00,                                   // iTerminal
-
-
-
-
-
-
-        // Interface 1, Alternate Setting 0, Audio Streaming - Zero Bandwith
-        INTERFACE_DESCRIPTOR_LENGTH,            // bLength
-        INTERFACE_DESCRIPTOR,                   // bDescriptorType
-        0x01,                                   // bInterfaceNumber
-        0x00,                                   // bAlternateSetting
-        0x00,                                   // bNumEndpoints
-        AUDIO_CLASS,                            // bInterfaceClass
-        SUBCLASS_AUDIOSTREAMING,                // bInterfaceSubClass
-        0x00,                                   // bInterfaceProtocol
-        0x00,                                   // iInterface
-
-        // Interface 1, Alternate Setting 1, Audio Streaming - Operational
-        INTERFACE_DESCRIPTOR_LENGTH,            // bLength
-        INTERFACE_DESCRIPTOR,                   // bDescriptorType
-        0x01,                                   // bInterfaceNumber
-        0x01,                                   // bAlternateSetting
-        0x01,                                   // bNumEndpoints
-        AUDIO_CLASS,                            // bInterfaceClass
-        SUBCLASS_AUDIOSTREAMING,                // bInterfaceSubClass
-        0x00,                                   // bInterfaceProtocol
-        0x00,                                   // iInterface
-
-        // Audio Streaming Interface
-        STREAMING_INTERFACE_DESCRIPTOR_LENGTH,  // bLength
-        INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
-        STREAMING_GENERAL,                      // bDescriptorSubtype
-        0x01,                                   // bTerminalLink
-        0x00,                                   // bDelay
-        LSB(FORMAT_PCM),                        // wFormatTag
-        MSB(FORMAT_PCM),                        // wFormatTag
-
-        // Audio Type I Format
-        FORMAT_TYPE_I_DESCRIPTOR_LENGTH,        // bLength
-        INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
-        STREAMING_FORMAT_TYPE,                  // bDescriptorSubtype
-        FORMAT_TYPE_I,                          // bFormatType
-        channel_nb_in,                          // bNrChannels
-        0x02,                                   // bSubFrameSize
-        16,                                     // bBitResolution
-        0x01,                                   // bSamFreqType
-        (uint8_t)(LSB(FREQ_IN)),                           // tSamFreq
-        (uint8_t)((FREQ_IN >> 8) & 0xff),                  // tSamFreq
-        (uint8_t)((FREQ_IN >> 16) & 0xff),                 // tSamFreq
-
-        // Endpoint - Standard Descriptor
-        ENDPOINT_DESCRIPTOR_LENGTH + 2,         // bLength
-        ENDPOINT_DESCRIPTOR,                    // bDescriptorType
-        PHY_TO_DESC(EPISO_OUT),                 // bEndpointAddress
-        E_ISOCHRONOUS,                          // bmAttributes
-        (uint8_t)(LSB(PACKET_SIZE_ISO_IN)),                   // wMaxPacketSize
-        (uint8_t)(MSB(PACKET_SIZE_ISO_IN)),                   // wMaxPacketSize
-        0x01,                                   // bInterval
-        0x00,                                   // bRefresh
-        0x00,                                   // bSynchAddress
-
-        // Endpoint - Audio Streaming
-        STREAMING_ENDPOINT_DESCRIPTOR_LENGTH,   // bLength
-        ENDPOINT_DESCRIPTOR_TYPE,               // bDescriptorType
-        ENDPOINT_GENERAL,                       // bDescriptor
-        0x00,                                   // bmAttributes
-        0x00,                                   // bLockDelayUnits
-        LSB(0x0000),                            // wLockDelay
-        MSB(0x0000),                            // wLockDelay
-
-
-
-
-
-
-
-        // Interface 1, Alternate Setting 0, Audio Streaming - Zero Bandwith
-        INTERFACE_DESCRIPTOR_LENGTH,            // bLength
-        INTERFACE_DESCRIPTOR,                   // bDescriptorType
-        0x02,                                   // bInterfaceNumber
-        0x00,                                   // bAlternateSetting
-        0x00,                                   // bNumEndpoints
-        AUDIO_CLASS,                            // bInterfaceClass
-        SUBCLASS_AUDIOSTREAMING,                // bInterfaceSubClass
-        0x00,                                   // bInterfaceProtocol
-        0x00,                                   // iInterface
-
-        // Interface 1, Alternate Setting 1, Audio Streaming - Operational
-        INTERFACE_DESCRIPTOR_LENGTH,            // bLength
-        INTERFACE_DESCRIPTOR,                   // bDescriptorType
-        0x02,                                   // bInterfaceNumber
-        0x01,                                   // bAlternateSetting
-        0x01,                                   // bNumEndpoints
-        AUDIO_CLASS,                            // bInterfaceClass
-        SUBCLASS_AUDIOSTREAMING,                // bInterfaceSubClass
-        0x00,                                   // bInterfaceProtocol
-        0x00,                                   // iInterface
-
-        // Audio Streaming Interface
-        STREAMING_INTERFACE_DESCRIPTOR_LENGTH,  // bLength
-        INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
-        SUBCLASS_AUDIOCONTROL,                  // bDescriptorSubtype
-        0x05,                                   // bTerminalLink (output terminal microphone)
-        0x01,                                   // bDelay
-        0x01,                                   // wFormatTag
-        0x00,                                   // wFormatTag
-
-        // Audio Type I Format
-        FORMAT_TYPE_I_DESCRIPTOR_LENGTH,        // bLength
-        INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
-        SUBCLASS_AUDIOSTREAMING,                // bDescriptorSubtype
-        FORMAT_TYPE_I,                          // bFormatType
-        channel_nb_out,                         // bNrChannels
-        0x02,                                   // bSubFrameSize
-        0x10,                                   // bBitResolution
-        0x01,                                   // bSamFreqType
-        (uint8_t)(LSB(FREQ_OUT)),                          // tSamFreq
-        (uint8_t)((FREQ_OUT >> 8) & 0xff),                 // tSamFreq
-        (uint8_t)((FREQ_OUT >> 16) & 0xff),                // tSamFreq
-
-        // Endpoint - Standard Descriptor
-        ENDPOINT_DESCRIPTOR_LENGTH + 2,         // bLength
-        ENDPOINT_DESCRIPTOR,                    // bDescriptorType
-        PHY_TO_DESC(EPISO_IN),                  // bEndpointAddress
-        E_ISOCHRONOUS,                          // bmAttributes
-        (uint8_t)(LSB(PACKET_SIZE_ISO_OUT)),                   // wMaxPacketSize
-        (uint8_t)(MSB(PACKET_SIZE_ISO_OUT)),                   // wMaxPacketSize
-        0x01,                                   // bInterval
-        0x00,                                   // bRefresh
-        0x00,                                   // bSynchAddress
-
-        // Endpoint - Audio Streaming
-        STREAMING_ENDPOINT_DESCRIPTOR_LENGTH,   // bLength
-        ENDPOINT_DESCRIPTOR_TYPE,               // bDescriptorType
-        ENDPOINT_GENERAL,                       // bDescriptor
-        0x00,                                   // bmAttributes
-        0x00,                                   // bLockDelayUnits
-        LSB(0x0000),                            // wLockDelay
-        MSB(0x0000),                            // wLockDelay
-
-        // Terminator
-        0                                       // bLength
-    };
-    return configDescriptor;
-}
-
-uint8_t * USBAudio::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 * USBAudio::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;
-}
+/* 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 "USBAudio.h"
+#include "USBAudio_Types.h"
+
+
+
+USBAudio::USBAudio(uint32_t frequency_in, uint8_t channel_nb_in, uint32_t frequency_out, uint8_t channel_nb_out, uint16_t vendor_id, uint16_t product_id, uint16_t product_release): USBDevice(vendor_id, product_id, product_release) {
+    mute = 0;
+    volCur = 0x0080;
+    volMin = 0x0000;
+    volMax = 0x0100;
+    volRes = 0x0004;
+    available = false;
+
+    FREQ_IN = frequency_in;
+    FREQ_OUT = frequency_out;
+
+    this->channel_nb_in = channel_nb_in;
+    this->channel_nb_out = channel_nb_out;
+
+    // stereo -> *2, mono -> *1
+    PACKET_SIZE_ISO_IN = (FREQ_IN / 500) * channel_nb_in;
+    PACKET_SIZE_ISO_OUT = (FREQ_OUT / 500) * channel_nb_out;
+
+    // STEREO -> left and right
+    channel_config_in = (channel_nb_in == 1) ? CHANNEL_M : CHANNEL_L + CHANNEL_R;
+    channel_config_out = (channel_nb_out == 1) ? CHANNEL_M : CHANNEL_L + CHANNEL_R;
+
+    SOF_handler = false;
+
+    buf_stream_out = NULL;
+    buf_stream_in = NULL;
+
+    interruptOUT = false;
+    writeIN = false;
+    interruptIN = false;
+    available = false;
+
+    volume = 0;
+
+    // connect the device
+    USBDevice::connect();
+}
+
+bool USBAudio::read(uint8_t * buf) {
+    buf_stream_in = buf;
+    SOF_handler = false;
+    while (!available || !SOF_handler);
+    available = false;
+    return true;
+}
+
+bool USBAudio::readNB(uint8_t * buf) {
+    buf_stream_in = buf;
+    SOF_handler = false;
+    while (!SOF_handler);
+    if (available) {
+        available = false;
+        buf_stream_in = NULL;
+        return true;
+    }
+    return false;
+}
+
+bool USBAudio::readWrite(uint8_t * buf_read, uint8_t * buf_write) {
+    buf_stream_in = buf_read;
+    SOF_handler = false;
+    writeIN = false;
+    if (interruptIN) {
+        USBDevice::writeNB(EPISO_IN, buf_write, PACKET_SIZE_ISO_OUT, PACKET_SIZE_ISO_OUT);
+    } else {
+        buf_stream_out = buf_write;
+    }
+    while (!available);
+    if (interruptIN) {
+        while (!writeIN);
+    }
+    while (!SOF_handler);
+    return true;
+}
+
+
+bool USBAudio::write(uint8_t * buf) {
+    writeIN = false;
+    SOF_handler = false;
+    if (interruptIN) {
+        USBDevice::writeNB(EPISO_IN, buf, PACKET_SIZE_ISO_OUT, PACKET_SIZE_ISO_OUT);
+    } else {
+        buf_stream_out = buf;
+    }
+    while (!SOF_handler);
+    if (interruptIN) {
+        while (!writeIN);
+    }
+    return true;
+}
+
+void USBAudio::writeSync(uint8_t *buf)
+{
+    USBDevice::writeNB(EPISO_IN, buf, PACKET_SIZE_ISO_OUT, PACKET_SIZE_ISO_OUT);
+}
+
+uint32_t USBAudio::readSync(uint8_t *buf)
+{
+    uint32_t size = 0;
+    USBDevice::readEP(EPISO_OUT, (uint8_t *)buf, &size, PACKET_SIZE_ISO_IN);
+    return size;
+}
+
+float USBAudio::getVolume() {
+    return (mute) ? 0.0 : volume;
+}
+
+
+bool USBAudio::EPISO_OUT_callback() {
+    uint32_t size = 0;
+    interruptOUT = true;
+    if (buf_stream_in != NULL) {
+        readEP(EPISO_OUT, (uint8_t *)buf_stream_in, &size, PACKET_SIZE_ISO_IN);
+        available = true;
+        buf_stream_in = NULL;
+    }
+    else  {
+        if (rxDone)
+            rxDone.call();
+    }
+    readStart(EPISO_OUT, PACKET_SIZE_ISO_IN);
+    return false;
+}
+
+
+bool USBAudio::EPISO_IN_callback() {
+    interruptIN = true;
+    writeIN = true;
+    if (txDone) 
+        txDone.call();
+    return true;
+}
+
+
+
+// Called in ISR context on each start of frame
+void USBAudio::SOF(int frameNumber) {
+    uint32_t size = 0;
+
+    if (!interruptOUT) {
+        // read the isochronous endpoint
+        if (buf_stream_in != NULL) {
+            if (USBDevice::readEP_NB(EPISO_OUT, (uint8_t *)buf_stream_in, &size, PACKET_SIZE_ISO_IN)) {
+                if (size) {
+                    available = true;
+                    readStart(EPISO_OUT, PACKET_SIZE_ISO_IN);
+                    buf_stream_in = NULL;
+                }
+            }
+        }
+    }
+
+    if (!interruptIN) {
+        // write if needed
+        if (buf_stream_out != NULL) {
+            USBDevice::writeNB(EPISO_IN, (uint8_t *)buf_stream_out, PACKET_SIZE_ISO_OUT, PACKET_SIZE_ISO_OUT);
+            buf_stream_out = NULL;
+        }
+    }
+
+    SOF_handler = true;
+}
+
+
+// Called in ISR context
+// Set configuration. Return false if the configuration is not supported.
+bool USBAudio::USBCallback_setConfiguration(uint8_t configuration) {
+    if (configuration != DEFAULT_CONFIGURATION) {
+        return false;
+    }
+
+    // Configure isochronous endpoint
+    realiseEndpoint(EPISO_OUT, PACKET_SIZE_ISO_IN, ISOCHRONOUS);
+    realiseEndpoint(EPISO_IN, PACKET_SIZE_ISO_OUT, ISOCHRONOUS);
+
+    // activate readings on this endpoint
+    readStart(EPISO_OUT, PACKET_SIZE_ISO_IN);
+    return true;
+}
+
+
+// Called in ISR context
+// Set alternate setting. Return false if the alternate setting is not supported
+bool USBAudio::USBCallback_setInterface(uint16_t interface, uint8_t alternate) {
+    if (interface == 0 && alternate == 0) {
+        return true;
+    }
+    if (interface == 1 && (alternate == 0 || alternate == 1)) {
+        return true;
+    }
+    if (interface == 2 && (alternate == 0 || alternate == 1)) {
+        return true;
+    }
+    return false;
+}
+
+
+
+// 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 USBAudio::USBCallback_request() {
+    bool success = false;
+    CONTROL_TRANSFER * transfer = getTransferPtr();
+
+    // Process class-specific requests
+    if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
+
+        // Feature Unit: Interface = 0, ID = 2
+        if (transfer->setup.wIndex == 0x0200) {
+
+            // Master Channel
+            if ((transfer->setup.wValue & 0xff) == 0) {
+
+                switch (transfer->setup.wValue >> 8) {
+                    case MUTE_CONTROL:
+                        switch (transfer->setup.bRequest) {
+                            case REQUEST_GET_CUR:
+                                transfer->remaining = 1;
+                                transfer->ptr = &mute;
+                                transfer->direction = DEVICE_TO_HOST;
+                                success = true;
+                                break;
+
+                            case REQUEST_SET_CUR:
+                                transfer->remaining = 1;
+                                transfer->notify = true;
+                                transfer->direction = HOST_TO_DEVICE;
+                                success = true;
+                                break;
+                            default:
+                                break;
+                        }
+                        break;
+                    case VOLUME_CONTROL:
+                        switch (transfer->setup.bRequest) {
+                            case REQUEST_GET_CUR:
+                                transfer->remaining = 2;
+                                transfer->ptr = (uint8_t *)&volCur;
+                                transfer->direction = DEVICE_TO_HOST;
+                                success = true;
+                                break;
+                            case REQUEST_GET_MIN:
+                                transfer->remaining = 2;
+                                transfer->ptr = (uint8_t *)&volMin;
+                                transfer->direction = DEVICE_TO_HOST;
+                                success = true;
+                                break;
+                            case REQUEST_GET_MAX:
+                                transfer->remaining = 2;
+                                transfer->ptr = (uint8_t *)&volMax;
+                                transfer->direction = DEVICE_TO_HOST;
+                                success = true;
+                                break;
+                            case REQUEST_GET_RES:
+                                transfer->remaining = 2;
+                                transfer->ptr = (uint8_t *)&volRes;
+                                transfer->direction = DEVICE_TO_HOST;
+                                success = true;
+                                break;
+
+                            case REQUEST_SET_CUR:
+                                transfer->remaining = 2;
+                                transfer->notify = true;
+                                transfer->direction = HOST_TO_DEVICE;
+                                success = true;
+                                break;
+                            case REQUEST_SET_MIN:
+                                transfer->remaining = 2;
+                                transfer->notify = true;
+                                transfer->direction = HOST_TO_DEVICE;
+                                success = true;
+                                break;
+                            case REQUEST_SET_MAX:
+                                transfer->remaining = 2;
+                                transfer->notify = true;
+                                transfer->direction = HOST_TO_DEVICE;
+                                success = true;
+                                break;
+                            case REQUEST_SET_RES:
+                                transfer->remaining = 2;
+                                transfer->notify = true;
+                                transfer->direction = HOST_TO_DEVICE;
+                                success = true;
+                                break;
+                        }
+                        break;
+                    default:
+                        break;
+                }
+            }
+        }
+    }
+    return success;
+}
+
+
+// Called in ISR context when a data OUT stage has been performed
+void USBAudio::USBCallback_requestCompleted(uint8_t * buf, uint32_t length) {
+    if ((length == 1) || (length == 2)) {
+        uint16_t data = (length == 1) ? *buf : *((uint16_t *)buf);
+        CONTROL_TRANSFER * transfer = getTransferPtr();
+        switch (transfer->setup.wValue >> 8) {
+            case MUTE_CONTROL:
+                switch (transfer->setup.bRequest) {
+                    case REQUEST_SET_CUR:
+                        mute = data & 0xff;
+                        if (updateVol)
+                            updateVol.call();
+                        break;
+                    default:
+                        break;
+                }
+                break;
+            case VOLUME_CONTROL:
+                switch (transfer->setup.bRequest) {
+                    case REQUEST_SET_CUR:
+                        volCur = data;
+                        volume = (float)volCur/(float)volMax;
+                        if (updateVol)
+                            updateVol.call();
+                        break;
+                    default:
+                        break;
+                }
+                break;
+            default:
+                break;
+        }
+    }
+}
+
+
+
+#define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
+                               + (5 * INTERFACE_DESCRIPTOR_LENGTH) \
+                               + (1 * CONTROL_INTERFACE_DESCRIPTOR_LENGTH + 1) \
+                               + (2 * INPUT_TERMINAL_DESCRIPTOR_LENGTH) \
+                               + (1 * FEATURE_UNIT_DESCRIPTOR_LENGTH) \
+                               + (2 * OUTPUT_TERMINAL_DESCRIPTOR_LENGTH) \
+                               + (2 * STREAMING_INTERFACE_DESCRIPTOR_LENGTH) \
+                               + (2 * FORMAT_TYPE_I_DESCRIPTOR_LENGTH) \
+                               + (2 * (ENDPOINT_DESCRIPTOR_LENGTH + 2)) \
+                               + (2 * STREAMING_ENDPOINT_DESCRIPTOR_LENGTH) )
+
+#define TOTAL_CONTROL_INTF_LENGTH    (CONTROL_INTERFACE_DESCRIPTOR_LENGTH + 1 + \
+                                      2*INPUT_TERMINAL_DESCRIPTOR_LENGTH     + \
+                                      FEATURE_UNIT_DESCRIPTOR_LENGTH    + \
+                                      2*OUTPUT_TERMINAL_DESCRIPTOR_LENGTH)
+
+uint8_t * USBAudio::configurationDesc() {
+    static uint8_t configDescriptor[] = {
+        // Configuration 1
+        CONFIGURATION_DESCRIPTOR_LENGTH,        // bLength
+        CONFIGURATION_DESCRIPTOR,               // bDescriptorType
+        LSB(TOTAL_DESCRIPTOR_LENGTH),           // wTotalLength (LSB)
+        MSB(TOTAL_DESCRIPTOR_LENGTH),           // wTotalLength (MSB)
+        0x03,                                   // bNumInterfaces
+        DEFAULT_CONFIGURATION,                  // bConfigurationValue
+        0x00,                                   // iConfiguration
+        0x80,                                   // bmAttributes
+        50,                                     // bMaxPower
+
+        // Interface 0, Alternate Setting 0, Audio Control
+        INTERFACE_DESCRIPTOR_LENGTH,            // bLength
+        INTERFACE_DESCRIPTOR,                   // bDescriptorType
+        0x00,                                   // bInterfaceNumber
+        0x00,                                   // bAlternateSetting
+        0x00,                                   // bNumEndpoints
+        AUDIO_CLASS,                            // bInterfaceClass
+        SUBCLASS_AUDIOCONTROL,                  // bInterfaceSubClass
+        0x00,                                   // bInterfaceProtocol
+        0x00,                                   // iInterface
+
+
+        // Audio Control Interface
+        CONTROL_INTERFACE_DESCRIPTOR_LENGTH + 1,// bLength
+        INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
+        CONTROL_HEADER,                         // bDescriptorSubtype
+        LSB(0x0100),                            // bcdADC (LSB)
+        MSB(0x0100),                            // bcdADC (MSB)
+        LSB(TOTAL_CONTROL_INTF_LENGTH),         // wTotalLength
+        MSB(TOTAL_CONTROL_INTF_LENGTH),         // wTotalLength
+        0x02,                                   // bInCollection
+        0x01,                                   // baInterfaceNr
+        0x02,                                   // baInterfaceNr
+
+        // Audio Input Terminal (Speaker)
+        INPUT_TERMINAL_DESCRIPTOR_LENGTH,       // bLength
+        INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
+        CONTROL_INPUT_TERMINAL,                 // bDescriptorSubtype
+        0x01,                                   // bTerminalID
+        LSB(TERMINAL_USB_STREAMING),            // wTerminalType
+        MSB(TERMINAL_USB_STREAMING),            // wTerminalType
+        0x00,                                   // bAssocTerminal
+        channel_nb_in,                          // bNrChannels
+        (uint8_t)(LSB(channel_config_in)),                 // wChannelConfig
+        (uint8_t)(MSB(channel_config_in)),                 // wChannelConfig
+        0x00,                                   // iChannelNames
+        0x00,                                   // iTerminal
+
+        // Audio Feature Unit (Speaker)
+        FEATURE_UNIT_DESCRIPTOR_LENGTH,         // bLength
+        INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
+        CONTROL_FEATURE_UNIT,                   // bDescriptorSubtype
+        0x02,                                   // bUnitID
+        0x01,                                   // bSourceID
+        0x01,                                   // bControlSize
+        CONTROL_MUTE |
+        CONTROL_VOLUME,                         // bmaControls(0)
+        0x00,                                   // bmaControls(1)
+        0x00,                                   // iTerminal
+
+        // Audio Output Terminal (Speaker)
+        OUTPUT_TERMINAL_DESCRIPTOR_LENGTH,      // bLength
+        INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
+        CONTROL_OUTPUT_TERMINAL,                // bDescriptorSubtype
+        0x03,                                   // bTerminalID
+        LSB(TERMINAL_SPEAKER),                  // wTerminalType
+        MSB(TERMINAL_SPEAKER),                  // wTerminalType
+        0x00,                                   // bAssocTerminal
+        0x02,                                   // bSourceID
+        0x00,                                   // iTerminal
+
+
+        // Audio Input Terminal (Microphone)
+        INPUT_TERMINAL_DESCRIPTOR_LENGTH,       // bLength
+        INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
+        CONTROL_INPUT_TERMINAL,                 // bDescriptorSubtype
+        0x04,                                   // bTerminalID
+        LSB(TERMINAL_MICROPHONE),               // wTerminalType
+        MSB(TERMINAL_MICROPHONE),               // wTerminalType
+        0x00,                                   // bAssocTerminal
+        channel_nb_out,                         // bNrChannels
+        (uint8_t)(LSB(channel_config_out)),                // wChannelConfig
+        (uint8_t)(MSB(channel_config_out)),                // wChannelConfig
+        0x00,                                   // iChannelNames
+        0x00,                                   // iTerminal
+
+        // Audio Output Terminal (Microphone)
+        OUTPUT_TERMINAL_DESCRIPTOR_LENGTH,      // bLength
+        INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
+        CONTROL_OUTPUT_TERMINAL,                // bDescriptorSubtype
+        0x05,                                   // bTerminalID
+        LSB(TERMINAL_USB_STREAMING),            // wTerminalType
+        MSB(TERMINAL_USB_STREAMING),            // wTerminalType
+        0x00,                                   // bAssocTerminal
+        0x04,                                   // bSourceID
+        0x00,                                   // iTerminal
+
+
+
+
+
+
+        // Interface 1, Alternate Setting 0, Audio Streaming - Zero Bandwith
+        INTERFACE_DESCRIPTOR_LENGTH,            // bLength
+        INTERFACE_DESCRIPTOR,                   // bDescriptorType
+        0x01,                                   // bInterfaceNumber
+        0x00,                                   // bAlternateSetting
+        0x00,                                   // bNumEndpoints
+        AUDIO_CLASS,                            // bInterfaceClass
+        SUBCLASS_AUDIOSTREAMING,                // bInterfaceSubClass
+        0x00,                                   // bInterfaceProtocol
+        0x00,                                   // iInterface
+
+        // Interface 1, Alternate Setting 1, Audio Streaming - Operational
+        INTERFACE_DESCRIPTOR_LENGTH,            // bLength
+        INTERFACE_DESCRIPTOR,                   // bDescriptorType
+        0x01,                                   // bInterfaceNumber
+        0x01,                                   // bAlternateSetting
+        0x01,                                   // bNumEndpoints
+        AUDIO_CLASS,                            // bInterfaceClass
+        SUBCLASS_AUDIOSTREAMING,                // bInterfaceSubClass
+        0x00,                                   // bInterfaceProtocol
+        0x00,                                   // iInterface
+
+        // Audio Streaming Interface
+        STREAMING_INTERFACE_DESCRIPTOR_LENGTH,  // bLength
+        INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
+        STREAMING_GENERAL,                      // bDescriptorSubtype
+        0x01,                                   // bTerminalLink
+        0x00,                                   // bDelay
+        LSB(FORMAT_PCM),                        // wFormatTag
+        MSB(FORMAT_PCM),                        // wFormatTag
+
+        // Audio Type I Format
+        FORMAT_TYPE_I_DESCRIPTOR_LENGTH,        // bLength
+        INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
+        STREAMING_FORMAT_TYPE,                  // bDescriptorSubtype
+        FORMAT_TYPE_I,                          // bFormatType
+        channel_nb_in,                          // bNrChannels
+        0x02,                                   // bSubFrameSize
+        16,                                     // bBitResolution
+        0x01,                                   // bSamFreqType
+        (uint8_t)(LSB(FREQ_IN)),                           // tSamFreq
+        (uint8_t)((FREQ_IN >> 8) & 0xff),                  // tSamFreq
+        (uint8_t)((FREQ_IN >> 16) & 0xff),                 // tSamFreq
+
+        // Endpoint - Standard Descriptor
+        ENDPOINT_DESCRIPTOR_LENGTH + 2,         // bLength
+        ENDPOINT_DESCRIPTOR,                    // bDescriptorType
+        PHY_TO_DESC(EPISO_OUT),                 // bEndpointAddress
+        E_ISOCHRONOUS,                          // bmAttributes
+        (uint8_t)(LSB(PACKET_SIZE_ISO_IN)),                   // wMaxPacketSize
+        (uint8_t)(MSB(PACKET_SIZE_ISO_IN)),                   // wMaxPacketSize
+        0x01,                                   // bInterval
+        0x00,                                   // bRefresh
+        0x00,                                   // bSynchAddress
+
+        // Endpoint - Audio Streaming
+        STREAMING_ENDPOINT_DESCRIPTOR_LENGTH,   // bLength
+        ENDPOINT_DESCRIPTOR_TYPE,               // bDescriptorType
+        ENDPOINT_GENERAL,                       // bDescriptor
+        0x00,                                   // bmAttributes
+        0x00,                                   // bLockDelayUnits
+        LSB(0x0000),                            // wLockDelay
+        MSB(0x0000),                            // wLockDelay
+
+
+
+
+
+
+
+        // Interface 1, Alternate Setting 0, Audio Streaming - Zero Bandwith
+        INTERFACE_DESCRIPTOR_LENGTH,            // bLength
+        INTERFACE_DESCRIPTOR,                   // bDescriptorType
+        0x02,                                   // bInterfaceNumber
+        0x00,                                   // bAlternateSetting
+        0x00,                                   // bNumEndpoints
+        AUDIO_CLASS,                            // bInterfaceClass
+        SUBCLASS_AUDIOSTREAMING,                // bInterfaceSubClass
+        0x00,                                   // bInterfaceProtocol
+        0x00,                                   // iInterface
+
+        // Interface 1, Alternate Setting 1, Audio Streaming - Operational
+        INTERFACE_DESCRIPTOR_LENGTH,            // bLength
+        INTERFACE_DESCRIPTOR,                   // bDescriptorType
+        0x02,                                   // bInterfaceNumber
+        0x01,                                   // bAlternateSetting
+        0x01,                                   // bNumEndpoints
+        AUDIO_CLASS,                            // bInterfaceClass
+        SUBCLASS_AUDIOSTREAMING,                // bInterfaceSubClass
+        0x00,                                   // bInterfaceProtocol
+        0x00,                                   // iInterface
+
+        // Audio Streaming Interface
+        STREAMING_INTERFACE_DESCRIPTOR_LENGTH,  // bLength
+        INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
+        SUBCLASS_AUDIOCONTROL,                  // bDescriptorSubtype
+        0x05,                                   // bTerminalLink (output terminal microphone)
+        0x01,                                   // bDelay
+        0x01,                                   // wFormatTag
+        0x00,                                   // wFormatTag
+
+        // Audio Type I Format
+        FORMAT_TYPE_I_DESCRIPTOR_LENGTH,        // bLength
+        INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
+        SUBCLASS_AUDIOSTREAMING,                // bDescriptorSubtype
+        FORMAT_TYPE_I,                          // bFormatType
+        channel_nb_out,                         // bNrChannels
+        0x02,                                   // bSubFrameSize
+        0x10,                                   // bBitResolution
+        0x01,                                   // bSamFreqType
+        (uint8_t)(LSB(FREQ_OUT)),                          // tSamFreq
+        (uint8_t)((FREQ_OUT >> 8) & 0xff),                 // tSamFreq
+        (uint8_t)((FREQ_OUT >> 16) & 0xff),                // tSamFreq
+
+        // Endpoint - Standard Descriptor
+        ENDPOINT_DESCRIPTOR_LENGTH + 2,         // bLength
+        ENDPOINT_DESCRIPTOR,                    // bDescriptorType
+        PHY_TO_DESC(EPISO_IN),                  // bEndpointAddress
+        E_ISOCHRONOUS,                          // bmAttributes
+        (uint8_t)(LSB(PACKET_SIZE_ISO_OUT)),                   // wMaxPacketSize
+        (uint8_t)(MSB(PACKET_SIZE_ISO_OUT)),                   // wMaxPacketSize
+        0x01,                                   // bInterval
+        0x00,                                   // bRefresh
+        0x00,                                   // bSynchAddress
+
+        // Endpoint - Audio Streaming
+        STREAMING_ENDPOINT_DESCRIPTOR_LENGTH,   // bLength
+        ENDPOINT_DESCRIPTOR_TYPE,               // bDescriptorType
+        ENDPOINT_GENERAL,                       // bDescriptor
+        0x00,                                   // bmAttributes
+        0x00,                                   // bLockDelayUnits
+        LSB(0x0000),                            // wLockDelay
+        MSB(0x0000),                            // wLockDelay
+
+        // Terminator
+        0                                       // bLength
+    };
+    return configDescriptor;
+}
+
+uint8_t * USBAudio::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 * USBAudio::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;
+}
--- a/USBAudio/USBAudio.h	Tue May 03 00:16:32 2016 +0100
+++ b/USBAudio/USBAudio.h	Fri Apr 28 11:26:51 2017 +0100
@@ -1,287 +1,330 @@
-/* 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 USBAudio_H
-#define USBAudio_H
-
-/* These headers are included for child class. */
-#include "USBEndpoints.h"
-#include "USBDescriptor.h"
-#include "USBDevice_Types.h"
-
-#include "USBDevice.h"
-
-
-/**
-* USBAudio example
-*
-* @code
-* #include "mbed.h"
-* #include "USBAudio.h"
-*
-* Serial pc(USBTX, USBRX);
-*
-* // frequency: 48 kHz
-* #define FREQ 48000
-*
-* // 1 channel: mono
-* #define NB_CHA 1
-*
-* // length of an audio packet: each ms, we receive 48 * 16bits ->48 * 2 bytes. as there is one channel, the length will be 48 * 2 * 1
-* #define AUDIO_LENGTH_PACKET 48 * 2 * 1
-*
-* // USBAudio
-* USBAudio audio(FREQ, NB_CHA);
-*
-* int main() {
-*    int16_t buf[AUDIO_LENGTH_PACKET/2];
-*
-*    while (1) {
-*        // read an audio packet
-*        audio.read((uint8_t *)buf);
-*
-*
-*        // print packet received
-*        pc.printf("recv: ");
-*        for(int i = 0; i < AUDIO_LENGTH_PACKET/2; i++) {
-*            pc.printf("%d ", buf[i]);
-*        }
-*        pc.printf("\r\n");
-*    }
-* }
-* @endcode
-*/
-class USBAudio: public USBDevice {
-public:
-
-    /**
-    * Constructor
-    *
-    * @param frequency_in frequency in Hz (default: 48000)
-    * @param channel_nb_in channel number (1 or 2) (default: 1)
-    * @param frequency_out frequency in Hz (default: 8000)
-    * @param channel_nb_out_in channel number (1 or 2) (default: 1)
-    * @param vendor_id Your vendor_id
-    * @param product_id Your product_id
-    * @param product_release Your preoduct_release
-    */
-    USBAudio(uint32_t frequency_in = 48000, uint8_t channel_nb_in = 1, uint32_t frequency_out = 8000, uint8_t channel_nb_out = 1, uint16_t vendor_id = 0x7bb8, uint16_t product_id = 0x1111, uint16_t product_release = 0x0100);
-
-    /**
-    * Get current volume between 0.0 and 1.0
-    *
-    * @returns volume
-    */
-    float getVolume();
-
-    /**
-    * Read an audio packet. During a frame, only a single reading (you can't write and read an audio packet during the same frame)can be done using this method. Warning: Blocking
-    *
-    * @param buf pointer on a buffer which will be filled with an audio packet
-    *
-    * @returns true if successfull
-    */
-    bool read(uint8_t * buf);
-
-    /**
-    * Try to read an audio packet. During a frame, only a single reading (you can't write and read an audio packet during the same frame)can be done using this method. Warning: Non Blocking
-    *
-    * @param buf pointer on a buffer which will be filled if an audio packet is available
-    *
-    * @returns true if successfull
-    */
-    bool readNB(uint8_t * buf);
-
-    /**
-    * Write an audio packet. During a frame, only a single writing (you can't write and read an audio packet during the same frame)can be done using this method.
-    *
-    * @param buf pointer on the audio packet which will be sent
-    * @returns true if successful
-    */
-    bool write(uint8_t * buf);
-
-    /**
-    * Write and read an audio packet at the same time (on the same frame)
-    *
-    * @param buf_read pointer on a buffer which will be filled with an audio packet
-    * @param buf_write pointer on the audio packet which will be sent
-    * @returns true if successful
-    */
-    bool readWrite(uint8_t * buf_read, uint8_t * buf_write);
-
-
-    /** attach a handler to update the volume
-     *
-     * @param function Function to attach
-     *
-     */
-    void attach(void(*fptr)(void)) {
-        updateVol.attach(fptr);
-    }
-
-    /** Attach a nonstatic void/void member function to update the volume
-     *
-     * @param tptr Object pointer
-     * @param mptr Member function pointer
-     *
-     */
-    template<typename T>
-    void attach(T *tptr, void(T::*mptr)(void)) {
-        updateVol.attach(tptr, mptr);
-    }
-
-
-protected:
-
-    /*
-    * 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);
-
-    /*
-    * 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();
-
-    /*
-    * 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();
-
-    /*
-     * Called by USBDevice layer. Set interface/alternate of the device.
-     *
-     * @param interface Number of the interface to be configured
-     * @param alternate Number of the alternate to be configured
-     * @returns true if class handles this request
-     */
-    virtual bool USBCallback_setInterface(uint16_t interface, uint8_t alternate);
-
-    /*
-    * 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
-    *
-    * @param buf buffer received on endpoint 0
-    * @param length length of this buffer
-    */
-    virtual void USBCallback_requestCompleted(uint8_t * buf, uint32_t length);
-
-    /*
-    * Callback called on each Start of Frame event
-    */
-    virtual void SOF(int frameNumber);
-
-    /*
-    * Callback called when a packet is received
-    */
-    virtual bool EPISO_OUT_callback();
-
-    /*
-    * Callback called when a packet has been sent
-    */
-    virtual bool EPISO_IN_callback();
-
-private:
-
-    // stream available ?
-    volatile bool available;
-
-    // interrupt OUT has been received
-    volatile bool interruptOUT;
-
-    // interrupt IN has been received
-    volatile bool interruptIN;
-
-    // audio packet has been written
-    volatile bool writeIN;
-
-    // FREQ
-    uint32_t FREQ_OUT;
-    uint32_t FREQ_IN;
-
-    // size of the maximum packet for the isochronous endpoint
-    uint32_t PACKET_SIZE_ISO_IN;
-    uint32_t PACKET_SIZE_ISO_OUT;
-
-    // mono, stereo,...
-    uint8_t channel_nb_in;
-    uint8_t channel_nb_out;
-
-    // channel config: master, left, right
-    uint8_t channel_config_in;
-    uint8_t channel_config_out;
-
-    // mute state
-    uint8_t mute;
-
-    // Volume Current Value
-    uint16_t volCur;
-
-    // Volume Minimum Value
-    uint16_t volMin;
-
-    // Volume Maximum Value
-    uint16_t volMax;
-
-    // Volume Resolution
-    uint16_t volRes;
-
-    // Buffer containing one audio packet (to be read)
-    volatile uint8_t * buf_stream_in;
-
-    // Buffer containing one audio packet (to be written)
-    volatile uint8_t * buf_stream_out;
-
-    // callback to update volume
-    FunctionPointer updateVol;
-
-    // boolean showing that the SOF handler has been called. Useful for readNB.
-    volatile bool SOF_handler;
-
-    volatile float volume;
-
-};
-
-#endif
+/* 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 USBAudio_H
+#define USBAudio_H
+
+/* These headers are included for child class. */
+#include "USBEndpoints.h"
+#include "USBDescriptor.h"
+#include "USBDevice_Types.h"
+
+#include "USBDevice.h"
+#include "Callback.h"
+
+/**
+* USBAudio example
+*
+* @code
+* #include "mbed.h"
+* #include "USBAudio.h"
+*
+* Serial pc(USBTX, USBRX);
+*
+* // frequency: 48 kHz
+* #define FREQ 48000
+*
+* // 1 channel: mono
+* #define NB_CHA 1
+*
+* // length of an audio packet: each ms, we receive 48 * 16bits ->48 * 2 bytes. as there is one channel, the length will be 48 * 2 * 1
+* #define AUDIO_LENGTH_PACKET 48 * 2 * 1
+*
+* // USBAudio
+* USBAudio audio(FREQ, NB_CHA);
+*
+* int main() {
+*    int16_t buf[AUDIO_LENGTH_PACKET/2];
+*
+*    while (1) {
+*        // read an audio packet
+*        audio.read((uint8_t *)buf);
+*
+*
+*        // print packet received
+*        pc.printf("recv: ");
+*        for(int i = 0; i < AUDIO_LENGTH_PACKET/2; i++) {
+*            pc.printf("%d ", buf[i]);
+*        }
+*        pc.printf("\r\n");
+*    }
+* }
+* @endcode
+*/
+class USBAudio: public USBDevice {
+public:
+
+    /**
+    * Constructor
+    *
+    * @param frequency_in frequency in Hz (default: 48000)
+    * @param channel_nb_in channel number (1 or 2) (default: 1)
+    * @param frequency_out frequency in Hz (default: 8000)
+    * @param channel_nb_out_in channel number (1 or 2) (default: 1)
+    * @param vendor_id Your vendor_id
+    * @param product_id Your product_id
+    * @param product_release Your preoduct_release
+    */
+    USBAudio(uint32_t frequency_in = 48000, uint8_t channel_nb_in = 1, uint32_t frequency_out = 8000, uint8_t channel_nb_out = 1, uint16_t vendor_id = 0x7bb8, uint16_t product_id = 0x1111, uint16_t product_release = 0x0100);
+
+    /**
+    * Get current volume between 0.0 and 1.0
+    *
+    * @returns volume
+    */
+    float getVolume();
+
+    /**
+    * Read an audio packet. During a frame, only a single reading (you can't write and read an audio packet during the same frame)can be done using this method. Warning: Blocking
+    *
+    * @param buf pointer on a buffer which will be filled with an audio packet
+    *
+    * @returns true if successfull
+    */
+    bool read(uint8_t * buf);
+
+    /**
+    * Try to read an audio packet. During a frame, only a single reading (you can't write and read an audio packet during the same frame)can be done using this method. Warning: Non Blocking
+    *
+    * @param buf pointer on a buffer which will be filled if an audio packet is available
+    *
+    * @returns true if successfull
+    */
+    bool readNB(uint8_t * buf);
+
+    /**
+     * read last received packet if some.
+     * @param buf pointer on a buffer which will be filled if an audio packet is available
+     *
+     * @returns the packet length
+     */
+    uint32_t readSync(uint8_t *buf);
+
+    /**
+    * Write an audio packet. During a frame, only a single writing (you can't write and read an audio packet during the same frame)can be done using this method.
+    *
+    * @param buf pointer on the audio packet which will be sent
+    * @returns true if successful
+    */
+    bool write(uint8_t * buf);
+
+    /**
+     * Write packet in endpoint fifo. assuming tx fifo is empty
+     * @param buf pointer on the audio packet which will be sent
+     */
+    void writeSync(uint8_t *buf);
+
+    /**
+    * Write and read an audio packet at the same time (on the same frame)
+    *
+    * @param buf_read pointer on a buffer which will be filled with an audio packet
+    * @param buf_write pointer on the audio packet which will be sent
+    * @returns true if successful
+    */
+    bool readWrite(uint8_t * buf_read, uint8_t * buf_write);
+
+
+    /** attach a handler to update the volume
+     *
+     * @param function Function to attach
+     *
+     */
+    void attach(void(*fptr)(void)) {
+        updateVol.attach(fptr);
+    }
+	/** attach a handler to Tx Done
+     *
+     * @param function Function to attach
+     *
+     */
+    void attachTx(void(*fptr)(void)) {
+        txDone.attach(fptr);
+    }
+    /** attach a handler to Rx Done
+     *
+     * @param function Function to attach
+     *
+     */
+    void attachRx(void(*fptr)(void)) {
+        rxDone.attach(fptr);
+    }
+
+    /** Attach a nonstatic void/void member function to update the volume
+     *
+     * @param tptr Object pointer
+     * @param mptr Member function pointer
+     *
+     */
+    template<typename T>
+    void attach(T *tptr, void(T::*mptr)(void)) {
+        updateVol.attach(tptr, mptr);
+    }
+	template<typename T>
+	void attachTx(T *tptr, void(T::*mptr)(void)) {
+        txDone.attach(tptr, mptr);
+    }
+    template<typename T>
+	void attachRx(T *tptr, void(T::*mptr)(void)) {
+        rxDone.attach(tptr, mptr);
+    }
+
+
+protected:
+
+    /*
+    * 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);
+
+    /*
+    * 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();
+
+    /*
+    * 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();
+
+    /*
+     * Called by USBDevice layer. Set interface/alternate of the device.
+     *
+     * @param interface Number of the interface to be configured
+     * @param alternate Number of the alternate to be configured
+     * @returns true if class handles this request
+     */
+    virtual bool USBCallback_setInterface(uint16_t interface, uint8_t alternate);
+
+    /*
+    * 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
+    *
+    * @param buf buffer received on endpoint 0
+    * @param length length of this buffer
+    */
+    virtual void USBCallback_requestCompleted(uint8_t * buf, uint32_t length);
+
+    /*
+    * Callback called on each Start of Frame event
+    */
+    virtual void SOF(int frameNumber);
+
+    /*
+    * Callback called when a packet is received
+    */
+    virtual bool EPISO_OUT_callback();
+
+    /*
+    * Callback called when a packet has been sent
+    */
+    virtual bool EPISO_IN_callback();
+
+private:
+
+    // stream available ?
+    volatile bool available;
+
+    // interrupt OUT has been received
+    volatile bool interruptOUT;
+
+    // interrupt IN has been received
+    volatile bool interruptIN;
+
+    // audio packet has been written
+    volatile bool writeIN;
+
+    // FREQ
+    uint32_t FREQ_OUT;
+    uint32_t FREQ_IN;
+
+    // size of the maximum packet for the isochronous endpoint
+    uint32_t PACKET_SIZE_ISO_IN;
+    uint32_t PACKET_SIZE_ISO_OUT;
+
+    // mono, stereo,...
+    uint8_t channel_nb_in;
+    uint8_t channel_nb_out;
+
+    // channel config: master, left, right
+    uint8_t channel_config_in;
+    uint8_t channel_config_out;
+
+    // mute state
+    uint8_t mute;
+
+    // Volume Current Value
+    uint16_t volCur;
+
+    // Volume Minimum Value
+    uint16_t volMin;
+
+    // Volume Maximum Value
+    uint16_t volMax;
+
+    // Volume Resolution
+    uint16_t volRes;
+
+    // Buffer containing one audio packet (to be read)
+    volatile uint8_t * buf_stream_in;
+
+    // Buffer containing one audio packet (to be written)
+    volatile uint8_t * buf_stream_out;
+
+    // callback to update volume
+    Callback<void()> updateVol;
+
+    // callback transmit Done
+    Callback<void()> txDone;
+    // callback transmit Done
+    Callback<void()> rxDone;
+
+    // boolean showing that the SOF handler has been called. Useful for readNB.
+    volatile bool SOF_handler;
+
+    volatile float volume;
+
+};
+
+#endif
--- a/USBAudio/USBAudio_Types.h	Tue May 03 00:16:32 2016 +0100
+++ b/USBAudio/USBAudio_Types.h	Fri Apr 28 11:26:51 2017 +0100
@@ -1,97 +1,97 @@
-/* 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 USBAUDIO_TYPES_H
-#define USBAUDIO_TYPES_H
-
-
-#define DEFAULT_CONFIGURATION (1)
-
-// Audio Request Codes
-#define REQUEST_SET_CUR     0x01
-#define REQUEST_GET_CUR     0x81
-#define REQUEST_SET_MIN     0x02
-#define REQUEST_GET_MIN     0x82
-#define REQUEST_SET_MAX     0x03
-#define REQUEST_GET_MAX     0x83
-#define REQUEST_SET_RES     0x04
-#define REQUEST_GET_RES     0x84
-
-#define MUTE_CONTROL        0x01
-#define VOLUME_CONTROL      0x02
-
-
-// Audio Descriptor Sizes
-#define CONTROL_INTERFACE_DESCRIPTOR_LENGTH       0x09
-#define STREAMING_INTERFACE_DESCRIPTOR_LENGTH     0x07
-#define INPUT_TERMINAL_DESCRIPTOR_LENGTH          0x0C
-#define OUTPUT_TERMINAL_DESCRIPTOR_LENGTH         0x09
-#define FEATURE_UNIT_DESCRIPTOR_LENGTH            0x09
-#define STREAMING_ENDPOINT_DESCRIPTOR_LENGTH      0x07
-
-// Audio Format Type Descriptor Sizes
-#define FORMAT_TYPE_I_DESCRIPTOR_LENGTH   0x0b
-
-#define AUDIO_CLASS                       0x01
-#define SUBCLASS_AUDIOCONTROL             0x01
-#define SUBCLASS_AUDIOSTREAMING           0x02
-
-// Audio Descriptor Types
-#define INTERFACE_DESCRIPTOR_TYPE         0x24
-#define ENDPOINT_DESCRIPTOR_TYPE          0x25
-
-// Audio Control Interface Descriptor Subtypes
-#define CONTROL_HEADER                    0x01
-#define CONTROL_INPUT_TERMINAL            0x02
-#define CONTROL_OUTPUT_TERMINAL           0x03
-#define CONTROL_FEATURE_UNIT              0x06
-
-// USB Terminal Types
-#define TERMINAL_USB_STREAMING            0x0101
-
-// Predefined Audio Channel Configuration Bits
-// Mono
-#define CHANNEL_M                         0x0000
-#define CHANNEL_L                         0x0001  /* Left Front */
-#define CHANNEL_R                         0x0002  /* Right Front */
-
-// Feature Unit Control Bits
-#define CONTROL_MUTE                      0x0001
-#define CONTROL_VOLUME                    0x0002
-
-// Input Terminal Types
-#define TERMINAL_MICROPHONE               0x0201
-
-// Output Terminal Types
-#define TERMINAL_SPEAKER                  0x0301
-#define TERMINAL_HEADPHONES               0x0302
-
-// Audio Streaming Interface Descriptor Subtypes
-#define STREAMING_GENERAL                 0x01
-#define STREAMING_FORMAT_TYPE             0x02
-
-// Audio Data Format Type I Codes
-#define FORMAT_PCM                        0x0001
-
-// Audio Format Types
-#define FORMAT_TYPE_I                     0x01
-
-// Audio Endpoint Descriptor Subtypes
-#define ENDPOINT_GENERAL                  0x01
-
-#endif
+/* 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 USBAUDIO_TYPES_H
+#define USBAUDIO_TYPES_H
+
+
+#define DEFAULT_CONFIGURATION (1)
+
+// Audio Request Codes
+#define REQUEST_SET_CUR     0x01
+#define REQUEST_GET_CUR     0x81
+#define REQUEST_SET_MIN     0x02
+#define REQUEST_GET_MIN     0x82
+#define REQUEST_SET_MAX     0x03
+#define REQUEST_GET_MAX     0x83
+#define REQUEST_SET_RES     0x04
+#define REQUEST_GET_RES     0x84
+
+#define MUTE_CONTROL        0x01
+#define VOLUME_CONTROL      0x02
+
+
+// Audio Descriptor Sizes
+#define CONTROL_INTERFACE_DESCRIPTOR_LENGTH       0x09
+#define STREAMING_INTERFACE_DESCRIPTOR_LENGTH     0x07
+#define INPUT_TERMINAL_DESCRIPTOR_LENGTH          0x0C
+#define OUTPUT_TERMINAL_DESCRIPTOR_LENGTH         0x09
+#define FEATURE_UNIT_DESCRIPTOR_LENGTH            0x09
+#define STREAMING_ENDPOINT_DESCRIPTOR_LENGTH      0x07
+
+// Audio Format Type Descriptor Sizes
+#define FORMAT_TYPE_I_DESCRIPTOR_LENGTH   0x0b
+
+#define AUDIO_CLASS                       0x01
+#define SUBCLASS_AUDIOCONTROL             0x01
+#define SUBCLASS_AUDIOSTREAMING           0x02
+
+// Audio Descriptor Types
+#define INTERFACE_DESCRIPTOR_TYPE         0x24
+#define ENDPOINT_DESCRIPTOR_TYPE          0x25
+
+// Audio Control Interface Descriptor Subtypes
+#define CONTROL_HEADER                    0x01
+#define CONTROL_INPUT_TERMINAL            0x02
+#define CONTROL_OUTPUT_TERMINAL           0x03
+#define CONTROL_FEATURE_UNIT              0x06
+
+// USB Terminal Types
+#define TERMINAL_USB_STREAMING            0x0101
+
+// Predefined Audio Channel Configuration Bits
+// Mono
+#define CHANNEL_M                         0x0000
+#define CHANNEL_L                         0x0001  /* Left Front */
+#define CHANNEL_R                         0x0002  /* Right Front */
+
+// Feature Unit Control Bits
+#define CONTROL_MUTE                      0x0001
+#define CONTROL_VOLUME                    0x0002
+
+// Input Terminal Types
+#define TERMINAL_MICROPHONE               0x0201
+
+// Output Terminal Types
+#define TERMINAL_SPEAKER                  0x0301
+#define TERMINAL_HEADPHONES               0x0302
+
+// Audio Streaming Interface Descriptor Subtypes
+#define STREAMING_GENERAL                 0x01
+#define STREAMING_FORMAT_TYPE             0x02
+
+// Audio Data Format Type I Codes
+#define FORMAT_PCM                        0x0001
+
+// Audio Format Types
+#define FORMAT_TYPE_I                     0x01
+
+// Audio Endpoint Descriptor Subtypes
+#define ENDPOINT_GENERAL                  0x01
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/TARGET_STM/USBHAL_STM32.cpp	Fri Apr 28 11:26:51 2017 +0100
@@ -0,0 +1,332 @@
+/* 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.
+*/
+/* TARGET NOT STM does not support this HAL */
+#ifndef TARGET_STM
+#define USBSTM_HAL_UNSUPPORTED
+#endif
+/* F4 famlily wihtout USB_STM_HAL use another HAL*/
+#if defined(TARGET_STM) && defined(TARGET_STM32F4) && !defined(USB_STM_HAL)
+#define USBSTM_HAL_UNSUPPORTED
+#endif
+
+#ifndef USBSTM_HAL_UNSUPPORTED
+#include "USBHAL.h"
+#include "pinmap.h"
+/* mbed endpoint definition to hal definition   */
+#define EP_ADDR(ep) (((ep) >> 1)|((ep) & 1) << 7)
+/* from hal definition to mbed definition */
+#define ADDR_EPIN(ep) (((ep) << 1) | 1)
+#define ADDR_EPOUT(ep) (((ep) << 1))
+/* id to detect if rx buffer is used or not  */
+
+#include "USBHAL_STM_TARGET.h"
+
+
+/*  this call at device reception completion on a Out Enpoint  */
+void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
+{
+    USBHAL_Private_t *priv=((USBHAL_Private_t *)(hpcd->pData));
+    USBHAL *obj= priv->inst;
+    uint8_t endpoint = ADDR_EPOUT(epnum);
+    priv->epComplete[endpoint] = 1;
+    /* -2 endpoint 0 In out are not in call back list */
+    if (epnum) {
+        bool (USBHAL::*func)(void) = priv->epCallback[endpoint-2];
+        (obj->*func)();
+    } else {
+        void (USBHAL::*func)(void) = priv->ep0_out;
+        (obj->*func)();
+    }
+}
+
+/*  this is call at device transmission completion on In endpoint */
+void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
+{
+    USBHAL_Private_t *priv=((USBHAL_Private_t *)(hpcd->pData));
+    USBHAL *obj= priv->inst;
+    uint8_t endpoint = ADDR_EPIN(epnum);
+    priv->epComplete[endpoint] = 1;
+    /*  -2 endpoint 0 In out are not in call back list */
+    if (epnum) {
+        bool (USBHAL::*func)(void) = priv->epCallback[endpoint-2];
+        (obj->*func)();
+    } else {
+        void (USBHAL::*func)(void) = priv->ep0_in;
+        (obj->*func)();
+    }
+}
+/*  This is call at device set up reception  */
+void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
+{
+    USBHAL_Private_t *priv=((USBHAL_Private_t *)(hpcd->pData));
+    USBHAL *obj= priv->inst;
+    void (USBHAL::*func)(void)=priv->ep0_setup;
+    void (USBHAL::*func1)(void)=priv->ep0_read;
+    (obj->*func)();
+    (obj->*func1)();
+}
+
+void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
+{
+    USBHAL_Private_t *priv=((USBHAL_Private_t *)(hpcd->pData));
+    USBHAL *obj= priv->inst;
+    void (USBHAL::*func)(unsigned int suspended) = priv->suspend_change;
+    (obj->*func)(1);
+}
+
+void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
+{
+    USBHAL_Private_t *priv=((USBHAL_Private_t *)(hpcd->pData));
+    USBHAL *obj= priv->inst;
+    void (USBHAL::*func)(unsigned int suspended) = priv->suspend_change;
+    (obj->*func)(0);
+}
+
+void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
+{
+    USBHAL_Private_t *priv=((USBHAL_Private_t *)(hpcd->pData));
+    USBHAL *obj= priv->inst;
+    void (USBHAL::*func)(unsigned int suspended) = priv->connect_change;
+    (obj->*func)(1);
+}
+
+void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
+{
+    USBHAL_Private_t *priv=((USBHAL_Private_t *)(hpcd->pData));
+    USBHAL *obj= priv->inst;
+    void (USBHAL::*func)(unsigned int suspended) = priv->connect_change;
+    (obj->*func)(0);
+}
+
+void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
+{
+    USBHAL_Private_t *priv=((USBHAL_Private_t *)(hpcd->pData));
+    USBHAL *obj= priv->inst;
+    unsigned int i;
+    for(i=0;i<hpcd->Init.dev_endpoints;i++) {
+        priv->epComplete[2*i]=0;
+        HAL_PCD_EP_Close(hpcd,EP_ADDR(2*i));
+        HAL_PCD_EP_Flush(hpcd,EP_ADDR(2*i));
+        priv->epComplete[2*i+1]=0;
+        HAL_PCD_EP_Close(hpcd,EP_ADDR(2*i+1));
+        HAL_PCD_EP_Flush(hpcd,EP_ADDR(2*i+1));
+
+    }
+    void (USBHAL::*func)(void)=priv->bus_reset;
+    bool (USBHAL::*ep_realise)(uint8_t endpoint, uint32_t maxPacket, uint32_t flags) = priv->ep_realise;
+    (obj->*func)();
+    (obj->*ep_realise)(EP0IN, MAX_PACKET_SIZE_EP0,0);
+    (obj->*ep_realise)(EP0OUT, MAX_PACKET_SIZE_EP0,0);
+}
+
+
+/* hal pcd handler , used for STM32 HAL PCD Layer */
+
+uint32_t USBHAL::endpointReadcore(uint8_t endpoint, uint8_t *buffer) {
+    return 0;
+}
+
+USBHAL::~USBHAL(void) {
+	USBHAL_Private_t *HALPriv = (USBHAL_Private_t *)(hpcd.pData);
+	HAL_PCD_DeInit(&hpcd);
+	delete HALPriv;
+}
+
+void USBHAL::connect(void) {
+    NVIC_EnableIRQ(USBHAL_IRQn);
+}
+
+void USBHAL::disconnect(void) {
+    NVIC_DisableIRQ(USBHAL_IRQn);
+}
+
+void USBHAL::configureDevice(void) {
+    // Not needed
+}
+
+void USBHAL::unconfigureDevice(void) {
+    // Not needed
+}
+
+void USBHAL::setAddress(uint8_t address) {
+	HAL_PCD_SetAddress(&hpcd, address);
+    EP0write(0, 0);
+}
+
+bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t flags) {
+    uint32_t epIndex = EP_ADDR(endpoint);
+    uint32_t type;
+    uint32_t len;
+    HAL_StatusTypeDef ret;
+    switch (endpoint) {
+    case EP0IN:
+    case EP0OUT:
+        type =  0;
+        break;
+    case EPISO_IN:
+    case EPISO_OUT:
+        type = 1;
+        break;
+    case EPBULK_IN:
+    case EPBULK_OUT:
+        type =  2;
+        break;
+    case EPINT_IN:
+    case EPINT_OUT:
+        type =  3;
+        break;
+    }
+    if (maxPacket > MAXTRANSFER_SIZE) return false;
+    if (epIndex & 0x80) {
+        len = HAL_PCDEx_GetTxFiFo(&hpcd,epIndex & 0x7f);
+        MBED_ASSERT(len >= maxPacket);
+    }
+    ret = HAL_PCD_EP_Open(&hpcd, epIndex,  maxPacket, type);
+    MBED_ASSERT(ret!=HAL_BUSY);
+    return (ret == HAL_OK) ? true:false;
+}
+
+// read setup packet
+void USBHAL::EP0setup(uint8_t *buffer) {
+    memcpy(buffer,  hpcd.Setup, MAX_PACKET_SIZE_SETUP);
+	memset(hpcd.Setup,0,MAX_PACKET_SIZE_SETUP);
+}
+
+void USBHAL::EP0readStage(void) {
+}
+
+void USBHAL::EP0read(void) {
+     USBHAL_Private_t *HALPriv =  (USBHAL_Private_t *)hpcd.pData;
+	 uint32_t epIndex = EP_ADDR(EP0OUT);
+	 uint8_t *pBuf = (uint8_t *)HALPriv->pBufRx0;
+	 HAL_StatusTypeDef ret;
+	 HALPriv->epComplete[EP0OUT] = 2;
+	 ret = HAL_PCD_EP_Receive(&hpcd, epIndex, pBuf, MAX_PACKET_SIZE_EP0 );
+	 MBED_ASSERT(ret!=HAL_BUSY);
+
+}
+
+uint32_t USBHAL::EP0getReadResult(uint8_t *buffer) {
+    USBHAL_Private_t *HALPriv =  (USBHAL_Private_t *)hpcd.pData;
+    uint32_t length = (uint32_t) HAL_PCD_EP_GetRxCount(&hpcd, 0);
+	HALPriv->epComplete[EP0OUT] = 0;
+    if (length) {
+        uint8_t  *buff = (uint8_t *)HALPriv->pBufRx0;
+        memcpy(buffer, buff, length);
+    }
+    return length;
+}
+
+void USBHAL::EP0write(uint8_t *buffer, uint32_t size) {
+    /*  check that endpoint maximum size is not exceeding TX fifo */
+    MBED_ASSERT(hpcd.IN_ep[0].maxpacket >= size);
+    endpointWrite(EP0IN, buffer, size);
+}
+
+void USBHAL::EP0getWriteResult(void) {
+
+}
+
+void USBHAL::EP0stall(void) {
+    stallEndpoint(EP0IN);
+}
+
+EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize) {
+    USBHAL_Private_t *HALPriv =  (USBHAL_Private_t *)(hpcd.pData);
+    uint32_t epIndex = EP_ADDR(endpoint);
+    uint8_t* pBuf = (uint8_t *)HALPriv->pBufRx;
+	HAL_StatusTypeDef ret;
+    // clean reception end flag before requesting reception
+    HALPriv->epComplete[endpoint] = 2;
+    ret = HAL_PCD_EP_Receive(&hpcd, epIndex, pBuf, maximumSize);
+	MBED_ASSERT(ret!=HAL_BUSY);
+    return EP_PENDING;
+}
+
+EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t * buffer, uint32_t *bytesRead) {
+    USBHAL_Private_t *HALPriv =  (USBHAL_Private_t *)(hpcd.pData);
+	if (HALPriv->epComplete[endpoint]==0) {
+		/*  no reception possible !!! */
+		bytesRead = 0;
+        return EP_COMPLETED;
+    }else if ((HALPriv->epComplete[endpoint]!=1))
+	return EP_PENDING;
+    uint32_t epIndex = EP_ADDR(endpoint);
+    uint8_t  *buff = (uint8_t *)HALPriv->pBufRx;
+    uint32_t length = (uint32_t) HAL_PCD_EP_GetRxCount(&hpcd, epIndex);
+    memcpy(buffer, buff, length);
+    *bytesRead = length;
+	HALPriv->epComplete[endpoint]= 0;
+    return EP_COMPLETED;
+}
+
+EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size) {
+	USBHAL_Private_t *HALPriv =  (USBHAL_Private_t *)(hpcd.pData);
+    uint32_t epIndex = EP_ADDR(endpoint);
+    HAL_StatusTypeDef ret;
+    // clean transmission end flag before requesting transmission
+    HALPriv->epComplete[endpoint] = 2;
+    ret = HAL_PCD_EP_Transmit(&hpcd, epIndex, data, size);
+	MBED_ASSERT(ret!=HAL_BUSY);
+    // update the status
+    if (ret != HAL_OK) return EP_INVALID; 
+    // fix me return is too simple
+    return EP_PENDING;
+}
+
+EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint) {
+	USBHAL_Private_t *HALPriv =  (USBHAL_Private_t *)(hpcd.pData);
+    if (HALPriv->epComplete[endpoint] == 1)
+        return EP_COMPLETED;
+    return EP_PENDING;
+}
+
+void USBHAL::stallEndpoint(uint8_t endpoint) {
+    USBHAL_Private_t *HALPriv =  (USBHAL_Private_t *)(hpcd.pData);
+	HAL_StatusTypeDef ret;
+	HALPriv->epComplete[endpoint] = 0;
+	ret = HAL_PCD_EP_SetStall(&hpcd, EP_ADDR(endpoint));
+	MBED_ASSERT(ret!=HAL_BUSY);
+}
+
+void USBHAL::unstallEndpoint(uint8_t endpoint) {
+	HAL_StatusTypeDef ret;
+    ret = HAL_PCD_EP_ClrStall(&hpcd, EP_ADDR(endpoint));
+	MBED_ASSERT(ret!=HAL_BUSY);
+
+}
+
+bool USBHAL::getEndpointStallState(uint8_t endpoint) {
+    return false;
+}
+
+void USBHAL::remoteWakeup(void) {
+}
+
+
+void USBHAL::_usbisr(void) {
+    instance->usbisr();
+}
+
+
+void USBHAL::usbisr(void) {
+
+    HAL_PCD_IRQHandler(&instance->hpcd);
+}
+#endif
+
--- a/USBDevice/TARGET_Silicon_Labs/inc/em_usb.h	Tue May 03 00:16:32 2016 +0100
+++ b/USBDevice/TARGET_Silicon_Labs/inc/em_usb.h	Fri Apr 28 11:26:51 2017 +0100
@@ -33,6 +33,18 @@
 #include <string.h>
 #include <stddef.h>
 #include "em_common.h"
+/* Workaround for em_common naming change so that we don't need to rework the
+   entire USB HAL */
+#define EFM32_PACK_START(x)        SL_PACK_START(x)
+#define EFM32_PACK_END()           SL_PACK_END()
+#define EFM32_MIN(a, b)            SL_MIN(a, b)
+#define EFM32_MAX(a, b)            SL_MAX(a, b)
+#define EFM32_ATTRIBUTE_PACKED     SL_ATTRIBUTE_PACKED
+#define EFM32_ATTRIBUTE_ALIGN(X)   SL_ATTRIBUTE_ALIGN(X)
+#define EFM32_ALIGN(X)             SL_ALIGN(X)
+#define EFM32_WEAK                 SL_WEAK
+#define EFM32_ATTRIBUTE_SECTION(X) SL_ATTRIBUTE_SECTION(X)
+
 #include "em_int.h"
 
 #if defined( USB_USE_PRINTF )
--- a/USBDevice/USBDescriptor.h	Tue May 03 00:16:32 2016 +0100
+++ b/USBDevice/USBDescriptor.h	Fri Apr 28 11:26:51 2017 +0100
@@ -1,74 +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)
+/* 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)
--- a/USBDevice/USBDevice.cpp	Tue May 03 00:16:32 2016 +0100
+++ b/USBDevice/USBDevice.cpp	Fri Apr 28 11:26:51 2017 +0100
@@ -1,1005 +1,1005 @@
-/* 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"
-
-//#define DEBUG
-
-/* 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;
-#ifdef DEBUG
-    printf("get descr: type: %d\r\n", DESCRIPTOR_TYPE(transfer.setup.wValue));
-#endif
-    switch (DESCRIPTOR_TYPE(transfer.setup.wValue))
-    {
-        case DEVICE_DESCRIPTOR:
-            if (deviceDesc() != NULL)
-            {
-                if ((deviceDesc()[0] == DEVICE_DESCRIPTOR_LENGTH) \
-                    && (deviceDesc()[1] == DEVICE_DESCRIPTOR))
-                {
-#ifdef DEBUG
-                    printf("device descr\r\n");
-#endif
-                    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))
-                {
-#ifdef DEBUG
-                    printf("conf descr request\r\n");
-#endif
-                    /* Get wTotalLength */
-                    transfer.remaining = configurationDesc()[2] \
-                        | (configurationDesc()[3] << 8);
-
-                    transfer.ptr = configurationDesc();
-                    transfer.direction = DEVICE_TO_HOST;
-                    success = true;
-                }
-            }
-            break;
-        case STRING_DESCRIPTOR:
-#ifdef DEBUG
-            printf("str descriptor\r\n");
-#endif
-            switch (DESCRIPTOR_INDEX(transfer.setup.wValue))
-            {
-                            case STRING_OFFSET_LANGID:
-#ifdef DEBUG
-                                printf("1\r\n");
-#endif
-                                transfer.remaining = stringLangidDesc()[0];
-                                transfer.ptr = stringLangidDesc();
-                                transfer.direction = DEVICE_TO_HOST;
-                                success = true;
-                                break;
-                            case STRING_OFFSET_IMANUFACTURER:
-#ifdef DEBUG
-                                printf("2\r\n");
-#endif
-                                transfer.remaining =  stringImanufacturerDesc()[0];
-                                transfer.ptr = stringImanufacturerDesc();
-                                transfer.direction = DEVICE_TO_HOST;
-                                success = true;
-                                break;
-                            case STRING_OFFSET_IPRODUCT:
-#ifdef DEBUG
-                                printf("3\r\n");
-#endif
-                                transfer.remaining = stringIproductDesc()[0];
-                                transfer.ptr = stringIproductDesc();
-                                transfer.direction = DEVICE_TO_HOST;
-                                success = true;
-                                break;
-                            case STRING_OFFSET_ISERIAL:
-#ifdef DEBUG
-                                printf("4\r\n");
-#endif
-                                transfer.remaining = stringIserialDesc()[0];
-                                transfer.ptr = stringIserialDesc();
-                                transfer.direction = DEVICE_TO_HOST;
-                                success = true;
-                                break;
-                            case STRING_OFFSET_ICONFIGURATION:
-#ifdef DEBUG
-                                printf("5\r\n");
-#endif
-                                transfer.remaining = stringIConfigurationDesc()[0];
-                                transfer.ptr = stringIConfigurationDesc();
-                                transfer.direction = DEVICE_TO_HOST;
-                                success = true;
-                                break;
-                            case STRING_OFFSET_IINTERFACE:
-#ifdef DEBUG
-                                printf("6\r\n");
-#endif
-                                transfer.remaining = stringIinterfaceDesc()[0];
-                                transfer.ptr = stringIinterfaceDesc();
-                                transfer.direction = DEVICE_TO_HOST;
-                                success = true;
-                                break;
-            }
-            break;
-        case INTERFACE_DESCRIPTOR:
-#ifdef DEBUG
-            printf("interface descr\r\n");
-#endif
-        case ENDPOINT_DESCRIPTOR:
-#ifdef DEBUG
-            printf("endpoint descr\r\n");
-#endif
-            /* TODO: Support is optional, not implemented here */
-            break;
-        default:
-#ifdef DEBUG
-            printf("ERROR\r\n");
-#endif
-            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)
-    {
-#if defined(TARGET_KL25Z) | defined(TARGET_KL43Z) | defined(TARGET_KL46Z) | defined(TARGET_K20D5M) | defined(TARGET_K64F) | defined(TARGET_K22F) | defined(TARGET_TEENSY3_1)
-        /*
-         * We seem to have a pending device-to-host transfer.  The host must have
-         * sent a new control request without waiting for us to finish processing
-         * the previous one.  This appears to happen when we're connected to certain 
-         * USB 3.0 host chip set. Do a zeor-length send to tell the host we're not
-         * ready for the new request - that'll make it resend - and then just
-         * pretend we were successful here so that the pending transfer can finish.
-         */
-         uint8_t buf[1] = { 0 };
-         EP0write(buf, 0);
-         
-         /* execute our pending ttransfer */
-         controlIn();
-         
-         /* indicate success */
-         return true;
- #else
-         /* for other platforms, count on the HAL to handle this case */
-         return false;
- #endif
-    }
-
-    /* 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(buffer, packetSize);
-            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(NULL, 0);
-            transfer.notify = false;
-        }
-
-        EP0read();
-        EP0readStage();
-
-        /* 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)
-{
-    /* Return the selected alternate setting for an interface */
-
-    if (device.state != CONFIGURED)
-    {
-        return false;
-    }
-
-    /* Send the alternate setting */
-    transfer.setup.wIndex = currentInterface;
-    transfer.ptr = &currentAlternate;
-    transfer.remaining = sizeof(currentAlternate);
-    transfer.direction = DEVICE_TO_HOST;
-    return true;
-}
-
-bool USBDevice::requestSetInterface(void)
-{
-    bool success = false;
-    if(USBCallback_setInterface(transfer.setup.wIndex, transfer.setup.wValue))
-    {
-        success = true;
-        currentInterface = transfer.setup.wIndex;
-        currentAlternate = transfer.setup.wValue;
-    }
-    return success;
-}
-
-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;
-
-#ifdef DEBUG
-    printf("dataTransferDirection: %d\r\nType: %d\r\nRecipient: %d\r\nbRequest: %d\r\nwValue: %d\r\nwIndex: %d\r\nwLength: %d\r\n",transfer.setup.bmRequestType.dataTransferDirection,
-                                                                                                                                   transfer.setup.bmRequestType.Type,
-                                                                                                                                   transfer.setup.bmRequestType.Recipient,
-                                                                                                                                   transfer.setup.bRequest,
-                                                                                                                                   transfer.setup.wValue,
-                                                                                                                                   transfer.setup.wIndex,
-                                                                                                                                   transfer.setup.wLength);
-#endif
-
-    /* Class / vendor specific */
-    success = USBCallback_request();
-
-    if (!success)
-    {
-        /* Standard requests */
-        if (!requestSetup())
-        {
-#ifdef DEBUG
-            printf("fail!!!!\r\n");
-#endif
-            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)
-{
-#ifdef DEBUG
-    printf("EP0IN\r\n");
-#endif
-    /* 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(bool blocking)
-{
-    /* Connect device */
-    USBHAL::connect();
-
-    if (blocking) {
-        /* Block if not configured */
-        while (!configured());
-    }
-}
-
-void USBDevice::disconnect(void)
-{
-    /* Disconnect device */
-    USBHAL::disconnect();
-    
-    /* Set initial device state */
-    device.state = POWERED;
-    device.configuration = 0;
-    device.suspended = false;
-}
-
-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 NULL;
-    }
-
-    /* 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::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, uint32_t maxSize)
-{
-    return endpointRead(endpoint, maxSize) == EP_PENDING;
-}
-
-
-bool USBDevice::write(uint8_t endpoint, uint8_t * buffer, uint32_t size, uint32_t maxSize)
-{
-    EP_STATUS result;
-
-    if (size > maxSize)
-    {
-        return false;
-    }
-
-
-    if(!configured()) {
-        return false;
-    }
-
-    /* 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, uint32_t size, uint32_t maxSize)
-{
-    EP_STATUS result;
-
-    if (size > maxSize)
-    {
-        return false;
-    }
-
-    if(!configured()) {
-        return false;
-    }
-
-    /* Send report */
-    result = endpointWrite(endpoint, buffer, size);
-
-    if (result != EP_PENDING)
-    {
-        return false;
-    }
-
-    result = endpointWriteResult(endpoint);
-
-    return (result == EP_COMPLETED);
-}
-
-
-
-bool USBDevice::readEP(uint8_t endpoint, uint8_t * buffer, uint32_t * size, uint32_t maxSize)
-{
-    EP_STATUS result;
-
-    if(!configured()) {
-        return false;
-    }
-
-    /* Wait for completion */
-    do {
-        result = endpointReadResult(endpoint, buffer, size);
-    } while ((result == EP_PENDING) && configured());
-
-    return (result == EP_COMPLETED);
-}
-
-
-bool USBDevice::readEP_NB(uint8_t endpoint, uint8_t * buffer, uint32_t * size, uint32_t maxSize)
-{
-    EP_STATUS result;
-
-    if(!configured()) {
-        return false;
-    }
-
-    result = endpointReadResult(endpoint, buffer, 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 */
-        (uint8_t)(LSB(VENDOR_ID)),                 /* idVendor (LSB) */
-        (uint8_t)(MSB(VENDOR_ID)),                 /* idVendor (MSB) */
-        (uint8_t)(LSB(PRODUCT_ID)),                /* idProduct (LSB) */
-        (uint8_t)(MSB(PRODUCT_ID)),                /* idProduct (MSB) */
-        (uint8_t)(LSB(PRODUCT_RELEASE)),           /* bcdDevice (LSB) */
-        (uint8_t)(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,0x04,          /*bString Lang ID - 0x0409 - 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;
-}
+/* 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"
+
+//#define DEBUG
+
+/* 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;
+#ifdef DEBUG
+    printf("get descr: type: %d\r\n", DESCRIPTOR_TYPE(transfer.setup.wValue));
+#endif
+    switch (DESCRIPTOR_TYPE(transfer.setup.wValue))
+    {
+        case DEVICE_DESCRIPTOR:
+            if (deviceDesc() != NULL)
+            {
+                if ((deviceDesc()[0] == DEVICE_DESCRIPTOR_LENGTH) \
+                    && (deviceDesc()[1] == DEVICE_DESCRIPTOR))
+                {
+#ifdef DEBUG
+                    printf("device descr\r\n");
+#endif
+                    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))
+                {
+#ifdef DEBUG
+                    printf("conf descr request\r\n");
+#endif
+                    /* Get wTotalLength */
+                    transfer.remaining = configurationDesc()[2] \
+                        | (configurationDesc()[3] << 8);
+
+                    transfer.ptr = configurationDesc();
+                    transfer.direction = DEVICE_TO_HOST;
+                    success = true;
+                }
+            }
+            break;
+        case STRING_DESCRIPTOR:
+#ifdef DEBUG
+            printf("str descriptor\r\n");
+#endif
+            switch (DESCRIPTOR_INDEX(transfer.setup.wValue))
+            {
+                            case STRING_OFFSET_LANGID:
+#ifdef DEBUG
+                                printf("1\r\n");
+#endif
+                                transfer.remaining = stringLangidDesc()[0];
+                                transfer.ptr = stringLangidDesc();
+                                transfer.direction = DEVICE_TO_HOST;
+                                success = true;
+                                break;
+                            case STRING_OFFSET_IMANUFACTURER:
+#ifdef DEBUG
+                                printf("2\r\n");
+#endif
+                                transfer.remaining =  stringImanufacturerDesc()[0];
+                                transfer.ptr = stringImanufacturerDesc();
+                                transfer.direction = DEVICE_TO_HOST;
+                                success = true;
+                                break;
+                            case STRING_OFFSET_IPRODUCT:
+#ifdef DEBUG
+                                printf("3\r\n");
+#endif
+                                transfer.remaining = stringIproductDesc()[0];
+                                transfer.ptr = stringIproductDesc();
+                                transfer.direction = DEVICE_TO_HOST;
+                                success = true;
+                                break;
+                            case STRING_OFFSET_ISERIAL:
+#ifdef DEBUG
+                                printf("4\r\n");
+#endif
+                                transfer.remaining = stringIserialDesc()[0];
+                                transfer.ptr = stringIserialDesc();
+                                transfer.direction = DEVICE_TO_HOST;
+                                success = true;
+                                break;
+                            case STRING_OFFSET_ICONFIGURATION:
+#ifdef DEBUG
+                                printf("5\r\n");
+#endif
+                                transfer.remaining = stringIConfigurationDesc()[0];
+                                transfer.ptr = stringIConfigurationDesc();
+                                transfer.direction = DEVICE_TO_HOST;
+                                success = true;
+                                break;
+                            case STRING_OFFSET_IINTERFACE:
+#ifdef DEBUG
+                                printf("6\r\n");
+#endif
+                                transfer.remaining = stringIinterfaceDesc()[0];
+                                transfer.ptr = stringIinterfaceDesc();
+                                transfer.direction = DEVICE_TO_HOST;
+                                success = true;
+                                break;
+            }
+            break;
+        case INTERFACE_DESCRIPTOR:
+#ifdef DEBUG
+            printf("interface descr\r\n");
+#endif
+        case ENDPOINT_DESCRIPTOR:
+#ifdef DEBUG
+            printf("endpoint descr\r\n");
+#endif
+            /* TODO: Support is optional, not implemented here */
+            break;
+        default:
+#ifdef DEBUG
+            printf("ERROR\r\n");
+#endif
+            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)
+    {
+#if defined(TARGET_KL25Z) | defined(TARGET_KL43Z) | defined(TARGET_KL46Z) | defined(TARGET_K20D5M) | defined(TARGET_K64F) | defined(TARGET_K22F) | defined(TARGET_TEENSY3_1)
+        /*
+         * We seem to have a pending device-to-host transfer.  The host must have
+         * sent a new control request without waiting for us to finish processing
+         * the previous one.  This appears to happen when we're connected to certain 
+         * USB 3.0 host chip set. Do a zeor-length send to tell the host we're not
+         * ready for the new request - that'll make it resend - and then just
+         * pretend we were successful here so that the pending transfer can finish.
+         */
+         uint8_t buf[1] = { 0 };
+         EP0write(buf, 0);
+         
+         /* execute our pending ttransfer */
+         controlIn();
+         
+         /* indicate success */
+         return true;
+ #else
+         /* for other platforms, count on the HAL to handle this case */
+         return false;
+ #endif
+    }
+
+    /* 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(buffer, packetSize);
+            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(NULL, 0);
+            transfer.notify = false;
+        }
+
+        EP0read();
+        EP0readStage();
+
+        /* 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)
+{
+    /* Return the selected alternate setting for an interface */
+
+    if (device.state != CONFIGURED)
+    {
+        return false;
+    }
+
+    /* Send the alternate setting */
+    transfer.setup.wIndex = currentInterface;
+    transfer.ptr = &currentAlternate;
+    transfer.remaining = sizeof(currentAlternate);
+    transfer.direction = DEVICE_TO_HOST;
+    return true;
+}
+
+bool USBDevice::requestSetInterface(void)
+{
+    bool success = false;
+    if(USBCallback_setInterface(transfer.setup.wIndex, transfer.setup.wValue))
+    {
+        success = true;
+        currentInterface = transfer.setup.wIndex;
+        currentAlternate = transfer.setup.wValue;
+    }
+    return success;
+}
+
+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;
+
+#ifdef DEBUG
+    printf("dataTransferDirection: %d\r\nType: %d\r\nRecipient: %d\r\nbRequest: %d\r\nwValue: %d\r\nwIndex: %d\r\nwLength: %d\r\n",transfer.setup.bmRequestType.dataTransferDirection,
+                                                                                                                                   transfer.setup.bmRequestType.Type,
+                                                                                                                                   transfer.setup.bmRequestType.Recipient,
+                                                                                                                                   transfer.setup.bRequest,
+                                                                                                                                   transfer.setup.wValue,
+                                                                                                                                   transfer.setup.wIndex,
+                                                                                                                                   transfer.setup.wLength);
+#endif
+
+    /* Class / vendor specific */
+    success = USBCallback_request();
+
+    if (!success)
+    {
+        /* Standard requests */
+        if (!requestSetup())
+        {
+#ifdef DEBUG
+            printf("fail!!!!\r\n");
+#endif
+            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)
+{
+#ifdef DEBUG
+    printf("EP0IN\r\n");
+#endif
+    /* 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(bool blocking)
+{
+    /* Connect device */
+    USBHAL::connect();
+
+    if (blocking) {
+        /* Block if not configured */
+        while (!configured());
+    }
+}
+
+void USBDevice::disconnect(void)
+{
+    /* Disconnect device */
+    USBHAL::disconnect();
+    
+    /* Set initial device state */
+    device.state = POWERED;
+    device.configuration = 0;
+    device.suspended = false;
+}
+
+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 NULL;
+    }
+
+    /* 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::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, uint32_t maxSize)
+{
+    return endpointRead(endpoint, maxSize) == EP_PENDING;
+}
+
+
+bool USBDevice::write(uint8_t endpoint, uint8_t * buffer, uint32_t size, uint32_t maxSize)
+{
+    EP_STATUS result;
+
+    if (size > maxSize)
+    {
+        return false;
+    }
+
+
+    if(!configured()) {
+        return false;
+    }
+
+    /* 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, uint32_t size, uint32_t maxSize)
+{
+    EP_STATUS result;
+
+    if (size > maxSize)
+    {
+        return false;
+    }
+
+    if(!configured()) {
+        return false;
+    }
+
+    /* Send report */
+    result = endpointWrite(endpoint, buffer, size);
+
+    if (result != EP_PENDING)
+    {
+        return false;
+    }
+
+    result = endpointWriteResult(endpoint);
+
+    return (result == EP_COMPLETED);
+}
+
+
+
+bool USBDevice::readEP(uint8_t endpoint, uint8_t * buffer, uint32_t * size, uint32_t maxSize)
+{
+    EP_STATUS result;
+
+    if(!configured()) {
+        return false;
+    }
+
+    /* Wait for completion */
+    do {
+        result = endpointReadResult(endpoint, buffer, size);
+    } while ((result == EP_PENDING) && configured());
+
+    return (result == EP_COMPLETED);
+}
+
+
+bool USBDevice::readEP_NB(uint8_t endpoint, uint8_t * buffer, uint32_t * size, uint32_t maxSize)
+{
+    EP_STATUS result;
+
+    if(!configured()) {
+        return false;
+    }
+
+    result = endpointReadResult(endpoint, buffer, 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 */
+        (uint8_t)(LSB(VENDOR_ID)),                 /* idVendor (LSB) */
+        (uint8_t)(MSB(VENDOR_ID)),                 /* idVendor (MSB) */
+        (uint8_t)(LSB(PRODUCT_ID)),                /* idProduct (LSB) */
+        (uint8_t)(MSB(PRODUCT_ID)),                /* idProduct (MSB) */
+        (uint8_t)(LSB(PRODUCT_RELEASE)),           /* bcdDevice (LSB) */
+        (uint8_t)(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,0x04,          /*bString Lang ID - 0x0409 - 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;
+}
--- a/USBDevice/USBDevice.h	Tue May 03 00:16:32 2016 +0100
+++ b/USBDevice/USBDevice.h	Fri Apr 28 11:26:51 2017 +0100
@@ -1,271 +1,271 @@
-/* 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 "USBHAL.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
-    *
-    * @param blocking: block if not configured
-    */
-    void connect(bool blocking = true);
-
-    /*
-    * 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, uint32_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 readEP(uint8_t endpoint, uint8_t * buffer, uint32_t * size, uint32_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 readEP_NB(uint8_t endpoint, uint8_t * buffer, uint32_t * size, uint32_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, uint32_t size, uint32_t maxSize);
-
-
-    /*
-    * Write a certain endpoint.
-    *
-    * Warning: non 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 writeNB(uint8_t endpoint, uint8_t * buffer, uint32_t size, uint32_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
-    *
-    * @param buf buffer received on endpoint 0
-    * @param length length of this buffer
-    */
-    virtual void USBCallback_requestCompleted(uint8_t * buf, uint32_t length) {};
-
-    /*
-    * 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; };
-
-    /*
-     * Called by USBDevice layer. Set interface/alternate of the device.
-     *
-     * @param interface Number of the interface to be configured
-     * @param alternate Number of the alternate to be configured
-     * @returns true if class handles this request
-     */
-    virtual bool USBCallback_setInterface(uint16_t interface, uint8_t alternate) { 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 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;
-
-    uint16_t currentInterface;
-    uint8_t currentAlternate;
-};
-
-
-#endif
+/* 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 "USBHAL.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
+    *
+    * @param blocking: block if not configured
+    */
+    void connect(bool blocking = true);
+
+    /*
+    * 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, uint32_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 readEP(uint8_t endpoint, uint8_t * buffer, uint32_t * size, uint32_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 readEP_NB(uint8_t endpoint, uint8_t * buffer, uint32_t * size, uint32_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, uint32_t size, uint32_t maxSize);
+
+
+    /*
+    * Write a certain endpoint.
+    *
+    * Warning: non 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 writeNB(uint8_t endpoint, uint8_t * buffer, uint32_t size, uint32_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
+    *
+    * @param buf buffer received on endpoint 0
+    * @param length length of this buffer
+    */
+    virtual void USBCallback_requestCompleted(uint8_t * buf, uint32_t length) {};
+
+    /*
+    * 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; };
+
+    /*
+     * Called by USBDevice layer. Set interface/alternate of the device.
+     *
+     * @param interface Number of the interface to be configured
+     * @param alternate Number of the alternate to be configured
+     * @returns true if class handles this request
+     */
+    virtual bool USBCallback_setInterface(uint16_t interface, uint8_t alternate) { 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 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;
+
+    uint16_t currentInterface;
+    uint8_t currentAlternate;
+};
+
+
+#endif
--- a/USBDevice/USBDevice_Types.h	Tue May 03 00:16:32 2016 +0100
+++ b/USBDevice/USBDevice_Types.h	Fri Apr 28 11:26:51 2017 +0100
@@ -1,83 +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 & 0xff)
-
-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
+/* 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 & 0xff)
+
+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
--- a/USBDevice/USBEndpoints.h	Tue May 03 00:16:32 2016 +0100
+++ b/USBDevice/USBEndpoints.h	Fri Apr 28 11:26:51 2017 +0100
@@ -1,58 +1,64 @@
-/* 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) || defined(TARGET_LPC4088) || defined(TARGET_LPC2460) || defined(TARGET_LPC4088_DM)
-#include "USBEndpoints_LPC17_LPC23.h"
-#elif defined(TARGET_LPC11UXX) || defined(TARGET_LPC1347) || defined (TARGET_LPC11U6X) || defined (TARGET_LPC1549)
-#include "USBEndpoints_LPC11U.h"
-#elif defined(TARGET_KL25Z) | defined(TARGET_KL26Z) | defined(TARGET_KL27Z) | defined(TARGET_KL43Z) | defined(TARGET_KL46Z) | defined(TARGET_K20D50M) | defined(TARGET_K64F) | defined(TARGET_K22F) | defined(TARGET_TEENSY3_1)
-#include "USBEndpoints_KL25Z.h"
-#elif defined (TARGET_STM32F4)
-#include "USBEndpoints_STM32F4.h"
-#elif defined (TARGET_RZ_A1H) || defined (TARGET_VK_RZ_A1H)
-#include "USBEndpoints_RZ_A1H.h"
-#elif defined(TARGET_Maxim)
-#include "USBEndpoints_Maxim.h"
-#elif defined(TARGET_EFM32GG_STK3700) || defined(TARGET_EFM32LG_STK3600) || defined(TARGET_EFM32WG_STK3800) || defined(TARGET_EFM32HG_STK3400)
-#include "USBEndpoints_EFM32.h"
-#else
-#error "Unknown target type"
-#endif
-
-#endif
+/* 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) || defined(TARGET_LPC4088) || defined(TARGET_LPC2460) || defined(TARGET_LPC4088_DM)
+#include "USBEndpoints_LPC17_LPC23.h"
+#elif defined(TARGET_LPC11UXX) || defined(TARGET_LPC1347) || defined (TARGET_LPC11U6X) || defined (TARGET_LPC1549)
+#include "USBEndpoints_LPC11U.h"
+#elif defined(TARGET_KL25Z) | defined(TARGET_KL26Z) | defined(TARGET_KL27Z) | defined(TARGET_KL43Z) | defined(TARGET_KL46Z) | defined(TARGET_K20D50M) | defined(TARGET_K64F) | defined(TARGET_K22F) | defined(TARGET_TEENSY3_1)
+#include "USBEndpoints_KL25Z.h"
+#elif !defined(USB_STM_HAL) && defined(TARGET_STM32F4)
+#include "USBEndpoints_STM32F4.h"
+#elif defined (TARGET_STM32F4) || defined (TARGET_STM32F2) || defined (TARGET_STM32F7) || defined (TARGET_STM32F3) || defined(TARGET_STM32L4) || defined(TARGET_STM32F1)
+#include "USBEndpoints_STM32.h"
+#elif defined (TARGET_RZ_A1H) || defined (TARGET_VK_RZ_A1H)
+#include "USBEndpoints_RZ_A1H.h"
+#elif defined(TARGET_Maxim)
+#include "USBEndpoints_Maxim.h"
+#elif defined(TARGET_EFM32GG_STK3700) || defined(TARGET_EFM32LG_STK3600) || defined(TARGET_EFM32WG_STK3800) || defined(TARGET_EFM32HG_STK3400)
+#include "USBEndpoints_EFM32.h"
+#elif defined(TARGET_NUMAKER_PFM_NUC472)
+#include "USBEndpoints_NUC472.h"
+#elif defined(TARGET_NUMAKER_PFM_M453)
+#include "USBEndpoints_M453.h"
+#else
+#error "Unknown target type"
+#endif
+
+#endif
--- a/USBDevice/USBEndpoints_KL25Z.h	Tue May 03 00:16:32 2016 +0100
+++ b/USBDevice/USBEndpoints_KL25Z.h	Fri Apr 28 11:26:51 2017 +0100
@@ -1,99 +1,99 @@
-/* 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)
-#define EPBULK_OUT_callback   EP2_OUT_callback
-#define EPBULK_IN_callback    EP2_IN_callback
-/* Interrupt endpoints */
-#define EPINT_OUT   (EP1OUT)
-#define EPINT_IN    (EP1IN)
-#define EPINT_OUT_callback    EP1_OUT_callback
-#define EPINT_IN_callback     EP1_IN_callback
-/* Isochronous endpoints */
-#define EPISO_OUT   (EP3OUT)
-#define EPISO_IN    (EP3IN)
-#define EPISO_OUT_callback    EP3_OUT_callback
-#define EPISO_IN_callback     EP3_IN_callback
-
-#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)
+/* 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)
+#define EPBULK_OUT_callback   EP2_OUT_callback
+#define EPBULK_IN_callback    EP2_IN_callback
+/* Interrupt endpoints */
+#define EPINT_OUT   (EP1OUT)
+#define EPINT_IN    (EP1IN)
+#define EPINT_OUT_callback    EP1_OUT_callback
+#define EPINT_IN_callback     EP1_IN_callback
+/* Isochronous endpoints */
+#define EPISO_OUT   (EP3OUT)
+#define EPISO_IN    (EP3IN)
+#define EPISO_OUT_callback    EP3_OUT_callback
+#define EPISO_IN_callback     EP3_IN_callback
+
+#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/USBEndpoints_LPC11U.h	Tue May 03 00:16:32 2016 +0100
+++ b/USBDevice/USBEndpoints_LPC11U.h	Fri Apr 28 11:26:51 2017 +0100
@@ -1,71 +1,71 @@
-/* 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)
-#define EPBULK_OUT_callback   EP2_OUT_callback
-#define EPBULK_IN_callback    EP2_IN_callback
-/* Interrupt endpoint */
-#define EPINT_OUT   (EP1OUT)
-#define EPINT_IN    (EP1IN)
-#define EPINT_OUT_callback    EP1_OUT_callback
-#define EPINT_IN_callback     EP1_IN_callback
-/* Isochronous endpoint */
-#define EPISO_OUT   (EP3OUT)
-#define EPISO_IN    (EP3IN)
-#define EPISO_OUT_callback    EP3_OUT_callback
-#define EPISO_IN_callback     EP3_IN_callback
-
-#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)
+/* 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)
+#define EPBULK_OUT_callback   EP2_OUT_callback
+#define EPBULK_IN_callback    EP2_IN_callback
+/* Interrupt endpoint */
+#define EPINT_OUT   (EP1OUT)
+#define EPINT_IN    (EP1IN)
+#define EPINT_OUT_callback    EP1_OUT_callback
+#define EPINT_IN_callback     EP1_IN_callback
+/* Isochronous endpoint */
+#define EPISO_OUT   (EP3OUT)
+#define EPISO_IN    (EP3IN)
+#define EPISO_OUT_callback    EP3_OUT_callback
+#define EPISO_IN_callback     EP3_IN_callback
+
+#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)
--- a/USBDevice/USBEndpoints_LPC17_LPC23.h	Tue May 03 00:16:32 2016 +0100
+++ b/USBDevice/USBEndpoints_LPC17_LPC23.h	Fri Apr 28 11:26:51 2017 +0100
@@ -1,99 +1,99 @@
-/* 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)
-#define EPBULK_OUT_callback   EP2_OUT_callback
-#define EPBULK_IN_callback    EP2_IN_callback
-/* Interrupt endpoints */
-#define EPINT_OUT   (EP1OUT)
-#define EPINT_IN    (EP1IN)
-#define EPINT_OUT_callback    EP1_OUT_callback
-#define EPINT_IN_callback     EP1_IN_callback
-/* Isochronous endpoints */
-#define EPISO_OUT   (EP3OUT)
-#define EPISO_IN    (EP3IN)
-#define EPISO_OUT_callback    EP3_OUT_callback
-#define EPISO_IN_callback     EP3_IN_callback
-
-#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)
+/* 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)
+#define EPBULK_OUT_callback   EP2_OUT_callback
+#define EPBULK_IN_callback    EP2_IN_callback
+/* Interrupt endpoints */
+#define EPINT_OUT   (EP1OUT)
+#define EPINT_IN    (EP1IN)
+#define EPINT_OUT_callback    EP1_OUT_callback
+#define EPINT_IN_callback     EP1_IN_callback
+/* Isochronous endpoints */
+#define EPISO_OUT   (EP3OUT)
+#define EPISO_IN    (EP3IN)
+#define EPISO_OUT_callback    EP3_OUT_callback
+#define EPISO_IN_callback     EP3_IN_callback
+
+#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/USBEndpoints_M453.h	Fri Apr 28 11:26:51 2017 +0100
@@ -0,0 +1,79 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2015-2016 Nuvoton
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define NU_MAX_EPX_BUFSIZE      4096
+#define NU_EP2EPL(ep)           ((ep) >> 1)
+#define NU_EP2EPH(ep)           (((ep) >> 1) + 1)
+#define NU_EPL2EPH(ep)          ((ep) + 1)
+#define NU_EPH2EPL(ep)          ((ep) - 1)
+#define NU_EP_DIR_Pos           0
+#define NU_EP_DIR_Msk           (1 << NU_EP_DIR_Pos)
+#define NU_EP_DIR_OUT           0
+#define NU_EP_DIR_IN            1
+
+#define NU_EP_TYPE(ep)          (((ep) & NU_EP_TYPE_Msk) >> NU_EP_TYPE_Pos)
+#define NU_EP_NUM(ep)           (((ep) & NU_EP_NUM_Msk) >> NU_EP_NUM_Pos)
+#define NU_EP_DIR(ep)           (((ep) & NU_EP_DIR_Msk) >> NU_EP_DIR_Pos)
+#define NU_EP_NUM_DIR(ep)       ((NU_EP_NUM(ep) << 1) | NU_EP_DIR(ep))
+
+#define NUMBER_OF_PHYSICAL_ENDPOINTS    8
+#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)
+
+/* 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     0x60
+#define MAX_PACKET_SIZE_EP4     64
+#define MAX_PACKET_SIZE_EP5     64
+#define MAX_PACKET_SIZE_EP6     64
+#define MAX_PACKET_SIZE_EP7     64
+
+/* Generic endpoints - intended to be portable accross devices */
+/* and be suitable for simple USB devices. */
+
+/* Bulk endpoints */
+#define EPBULK_OUT            EP5OUT
+#define EPBULK_IN             EP6IN
+#define EPBULK_OUT_callback   EP5_OUT_callback
+#define EPBULK_IN_callback    EP6_IN_callback
+/* Interrupt endpoints */
+#define EPINT_OUT             EP1OUT
+#define EPINT_IN              EP2IN
+#define EPINT_OUT_callback    EP1_OUT_callback
+#define EPINT_IN_callback     EP2_IN_callback
+/* Isochronous endpoints */
+#define EPISO_OUT             EP3OUT
+#define EPISO_IN              EP4IN
+#define EPISO_OUT_callback    EP3_OUT_callback
+#define EPISO_IN_callback     EP4_IN_callback
+
+#define MAX_PACKET_SIZE_EPBULK  64
+#define MAX_PACKET_SIZE_EPINT   64
+#define MAX_PACKET_SIZE_EPISO   1023
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBEndpoints_NUC472.h	Fri Apr 28 11:26:51 2017 +0100
@@ -0,0 +1,89 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2015-2016 Nuvoton
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define NU_MAX_EPX_BUFSIZE      4096
+#define NU_EP2EPL(ep)           ((ep) >> 1)
+#define NU_EP2EPH(ep)           (((ep) >> 1) - 1)
+#define NU_EPX2EP(ep)           ((ep == CEP) ? EP0OUT : ((ep) - EPA + EP1OUT))
+#define NU_EPL2EPH(ep)          ((ep) - 1)
+#define NU_EPH2EPL(ep)          ((ep) + 1)
+#define NU_EP_DIR_Pos           0
+#define NU_EP_DIR_Msk           (1 << NU_EP_DIR_Pos)
+#define NU_EP_DIR_OUT           0
+#define NU_EP_DIR_IN            1
+
+#define NU_EP_TYPE(ep)          (((ep) & NU_EP_TYPE_Msk) >> NU_EP_TYPE_Pos)
+#define NU_EP_NUM(ep)           (((ep) & NU_EP_NUM_Msk) >> NU_EP_NUM_Pos)
+#define NU_EP_DIR(ep)           (((ep) & NU_EP_DIR_Msk) >> NU_EP_DIR_Pos)
+#define NU_EP_NUM_DIR(ep)       ((NU_EP_NUM(ep) << 1) | NU_EP_DIR(ep))
+
+#define NUMBER_OF_PHYSICAL_ENDPOINTS    12
+
+#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)
+
+/* 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     0x60
+#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
+
+/* Generic endpoints - intended to be portable accross devices */
+/* and be suitable for simple USB devices. */
+
+/* Bulk endpoints */
+#define EPBULK_OUT            EP5OUT
+#define EPBULK_IN             EP6IN
+#define EPBULK_OUT_callback   EP5_OUT_callback
+#define EPBULK_IN_callback    EP6_IN_callback
+/* Interrupt endpoints */
+#define EPINT_OUT             EP1OUT
+#define EPINT_IN              EP2IN
+#define EPINT_OUT_callback    EP1_OUT_callback
+#define EPINT_IN_callback     EP2_IN_callback
+/* Isochronous endpoints */
+#define EPISO_OUT             EP3OUT
+#define EPISO_IN              EP4IN
+#define EPISO_OUT_callback    EP3_OUT_callback
+#define EPISO_IN_callback     EP4_IN_callback
+
+#define MAX_PACKET_SIZE_EPBULK  64
+#define MAX_PACKET_SIZE_EPINT   64
+#define MAX_PACKET_SIZE_EPISO   1023
+
+#define USBD_GET_EP_MAX_PAYLOAD(ep)     (*((__IO uint32_t *) ((uint32_t)&USBD->EPAMPS + (uint32_t)((ep)*0x28)))) 
+#define USBD_GET_EP_DATA_COUNT(ep)      ((*((__IO uint32_t *) ((uint32_t)&USBD->EPADATCNT + (uint32_t)((ep)*0x28)))) & 0xFFFFF)
+#define USBD_SET_EP_SHORT_PACKET(ep)    (*((__IO uint32_t *) ((uint32_t)&USBD->EPARSPCTL + (uint32_t)((ep)*0x28))) = (*((__IO uint32_t *) ((uint32_t)&USBD->EPARSPCTL + (uint32_t)((ep)*0x28)))) & 0x10 | 0x40)
+#define USBD_GET_EP_INT_EN(ep)          (*((__IO uint32_t *) ((uint32_t)&USBD->EPAINTEN + (uint32_t)((ep)*0x28))))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBEndpoints_STM32.h	Fri Apr 28 11:26:51 2017 +0100
@@ -0,0 +1,67 @@
+/* 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 (4)
+#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           */
+
+/* Maximum Packet sizes */
+#define MAX_PACKET_SIZE_SETUP (48)
+#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 (200) /* Int/Bulk/iso (44100 stereo 16 bits) */
+
+#define MAX_PACKET_SIZE_EP1_ISO (1023) /* Isochronous */
+#define MAX_PACKET_SIZE_EP2_ISO (1023) /* Isochronous */
+#define MAX_PACKET_SIZE_EP3_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)
+#define EPBULK_OUT_callback   EP2_OUT_callback
+#define EPBULK_IN_callback    EP2_IN_callback
+/* Interrupt endpoint */
+#define EPINT_OUT   (EP1OUT)
+#define EPINT_IN    (EP1IN)
+#define EPINT_OUT_callback    EP1_OUT_callback
+#define EPINT_IN_callback     EP1_IN_callback
+/* Isochronous endpoint */
+#define EPISO_OUT   (EP3OUT)
+#define EPISO_IN    (EP3IN)
+#define EPISO_OUT_callback    EP3_OUT_callback
+#define EPISO_IN_callback     EP3_IN_callback
+
+#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)
--- a/USBDevice/USBHAL.h	Tue May 03 00:16:32 2016 +0100
+++ b/USBDevice/USBHAL.h	Fri Apr 28 11:26:51 2017 +0100
@@ -1,121 +1,143 @@
-/* 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"
-#include "toolchain.h"
-
-//#ifdef __GNUC__
-//#define __packed __attribute__ ((__packed__))
-//#endif
-
-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);
-    void EP0readStage(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);
-    uint32_t endpointReadcore(uint8_t endpoint, uint8_t *buffer);
-
-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;};
-#if !defined(TARGET_STM32F4)
-    virtual bool EP4_OUT_callback(){return false;};
-    virtual bool EP4_IN_callback(){return false;};
-#if !(defined(TARGET_LPC11UXX) || defined(TARGET_LPC11U6X) || defined(TARGET_LPC1347) || defined(TARGET_LPC1549))
-    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
-#endif
-
-private:
-    void usbisr(void);
-    static void _usbisr(void);
-    static USBHAL * instance;
-
-#if defined(TARGET_LPC11UXX) || defined(TARGET_LPC11U6X) || defined(TARGET_LPC1347) || defined(TARGET_LPC1549)
-        bool (USBHAL::*epCallback[10 - 2])(void);
-#elif defined(TARGET_STM32F4)
-        bool (USBHAL::*epCallback[8 - 2])(void);
-#else
-        bool (USBHAL::*epCallback[32 - 2])(void);
-#endif
-
-
-};
-#endif
+/* 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"
+#include "mbed_toolchain.h"
+
+//#ifdef __GNUC__
+//#define __packed __attribute__ ((__packed__))
+//#endif
+
+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);
+    void EP0readStage(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);
+    uint32_t endpointReadcore(uint8_t endpoint, uint8_t *buffer);
+
+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){};
+
+#if defined(TARGET_NUMAKER_PFM_NUC472) || defined(TARGET_NUMAKER_PFM_M453)
+    // NUC472/M453 USB doesn't support configuration of the same EP number for IN/OUT simultaneously.
+    virtual bool EP1_OUT_callback(){return false;};
+    virtual bool EP2_IN_callback(){return false;};
+    virtual bool EP3_OUT_callback(){return false;};
+    virtual bool EP4_IN_callback(){return false;};
+    virtual bool EP5_OUT_callback(){return false;};
+    virtual bool EP6_IN_callback(){return false;};
+#if ! (defined(TARGET_NUMAKER_PFM_M453))
+    virtual bool EP7_OUT_callback(){return false;};
+    virtual bool EP8_IN_callback(){return false;};
+    virtual bool EP9_OUT_callback(){return false;};
+    virtual bool EP10_IN_callback(){return false;};
+    virtual bool EP11_OUT_callback(){return false;};
+    virtual bool EP12_IN_callback(){return false;};
+#endif
+#else
+    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;};
+#if !defined(TARGET_STM32F4)
+    virtual bool EP4_OUT_callback(){return false;};
+    virtual bool EP4_IN_callback(){return false;};
+#if !(defined(TARGET_LPC11UXX) || defined(TARGET_LPC11U6X) || defined(TARGET_LPC1347) || defined(TARGET_LPC1549))
+    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
+#endif
+#endif
+
+private:
+    void usbisr(void);
+    static void _usbisr(void);
+    static USBHAL * instance;
+
+#if defined(TARGET_LPC11UXX) || defined(TARGET_LPC11U6X) || defined(TARGET_LPC1347) || defined(TARGET_LPC1549)
+    bool (USBHAL::*epCallback[10 - 2])(void);
+#elif (defined(TARGET_STM32F4) && !defined(USB_STM_HAL)) || defined(TARGET_NUMAKER_PFM_M453)
+    bool (USBHAL::*epCallback[8 - 2])(void);
+#elif defined(TARGET_STM)
+    PCD_HandleTypeDef hpcd;
+#elif defined(TARGET_NUMAKER_PFM_NUC472)
+    bool (USBHAL::*epCallback[14 - 2])(void);
+#else
+    bool (USBHAL::*epCallback[32 - 2])(void);
+#endif
+
+
+};
+#endif
--- a/USBDevice/USBHAL_KL25Z.cpp	Tue May 03 00:16:32 2016 +0100
+++ b/USBDevice/USBHAL_KL25Z.cpp	Fri Apr 28 11:26:51 2017 +0100
@@ -1,552 +1,543 @@
-/* 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) | defined(TARGET_KL43Z) | defined(TARGET_KL46Z) | defined(TARGET_K20D50M) | defined(TARGET_K64F) | defined(TARGET_K22F) | defined(TARGET_TEENSY3_1)
-
-#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];
-uint8_t * endpoint_buffer_iso[2*2];
-
-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);
-
-#if defined(TARGET_K64F)
-    MPU->CESR=0;
-#endif
-    // 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;
-
-#if defined(TARGET_KL43Z)
-    // enable USBFS clock
-    SIM->SCGC4 |= SIM_SCGC4_USBFS_MASK;
-
-    // enable the IRC48M clock
-    USB0->CLK_RECOVER_IRC_EN |= USB_CLK_RECOVER_IRC_EN_IRC_EN_MASK;
-
-    // enable the USB clock recovery tuning
-    USB0->CLK_RECOVER_CTRL |= USB_CLK_RECOVER_CTRL_CLOCK_RECOVER_EN_MASK;
-
-    // choose usb src clock
-    SIM->SOPT2 |= SIM_SOPT2_USBSRC_MASK;
-#else
-    // choose usb src as PLL
-    SIM->SOPT2 &= ~SIM_SOPT2_PLLFLLSEL_MASK;
-    SIM->SOPT2 |= (SIM_SOPT2_USBSRC_MASK | (1 << SIM_SOPT2_PLLFLLSEL_SHIFT));
-
-    // enable OTG clock
-    SIM->SCGC4 |= SIM_SCGC4_USBOTG_MASK;
-#endif
-
-    // 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;
-
-    //Free buffers if required:
-    for (int i = 0; i<(NUMBER_OF_PHYSICAL_ENDPOINTS - 2) * 2; i++) {
-        free(endpoint_buffer[i]);
-        endpoint_buffer[i] = NULL;
-    }
-    free(endpoint_buffer_iso[2]);
-    endpoint_buffer_iso[2] = NULL;
-    free(endpoint_buffer_iso[0]);
-    endpoint_buffer_iso[0] = NULL;
-}
-
-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)) {
-            if (endpoint_buffer[EP_BDT_IDX(log_endpoint, TX, ODD)] == NULL)
-                endpoint_buffer[EP_BDT_IDX(log_endpoint, TX, ODD)] = (uint8_t *) malloc (64);
-            buf = &endpoint_buffer[EP_BDT_IDX(log_endpoint, TX, ODD)][0];
-        } else {
-            if (endpoint_buffer[EP_BDT_IDX(log_endpoint, RX, ODD)] == NULL)
-                endpoint_buffer[EP_BDT_IDX(log_endpoint, RX, ODD)] = (uint8_t *) malloc (64);
-            buf = &endpoint_buffer[EP_BDT_IDX(log_endpoint, RX, ODD)][0];
-        }
-    } else {
-        if (IN_EP(endpoint)) {
-            if (endpoint_buffer_iso[2] == NULL)
-                endpoint_buffer_iso[2] = (uint8_t *) malloc (1023);
-            buf = &endpoint_buffer_iso[2][0];
-        } else {
-            if (endpoint_buffer_iso[0] == NULL)
-                endpoint_buffer_iso[0] = (uint8_t *) malloc (1023);
-            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;
-        int endpoint = (num << 1) | dir;
-
-        // 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 |= EP(endpoint);
-                    if ((instance->*(epCallback[endpoint - 2]))()) {
-                        epComplete &= ~EP(endpoint);
-                    }
-                }
-            }
-
-            // 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 |= EP(endpoint);
-                    if ((instance->*(epCallback[endpoint - 2]))()) {
-                        epComplete &= ~EP(endpoint);
-                    }
-                }
-            }
-        }
-
-        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
+/* 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) | defined(TARGET_KL43Z) | defined(TARGET_KL46Z) | defined(TARGET_K20D50M) | defined(TARGET_K64F) | defined(TARGET_K22F) | defined(TARGET_TEENSY3_1)
+
+#if defined(TARGET_KSDK2_MCUS)
+#include "fsl_common.h"
+#endif
+#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
+MBED_ALIGN(512) BDT bdt[NUMBER_OF_PHYSICAL_ENDPOINTS * 2];  // 512 bytes aligned!
+
+uint8_t * endpoint_buffer[(NUMBER_OF_PHYSICAL_ENDPOINTS - 2) * 2];
+uint8_t * endpoint_buffer_iso[2*2];
+
+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);
+
+#if (defined(FSL_FEATURE_SOC_MPU_COUNT) && (FSL_FEATURE_SOC_MPU_COUNT > 0U))
+    MPU->CESR=0;
+#endif
+    // 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;
+
+#if defined(TARGET_KL43Z) || defined(TARGET_K22F) || defined(TARGET_K64F)
+    // enable USBFS clock
+    CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcIrc48M, 48000000U);
+#else
+    // choose usb src as PLL
+    SIM->SOPT2 &= ~SIM_SOPT2_PLLFLLSEL_MASK;
+    SIM->SOPT2 |= (SIM_SOPT2_USBSRC_MASK | (1 << SIM_SOPT2_PLLFLLSEL_SHIFT));
+
+    // enable OTG clock
+    SIM->SCGC4 |= SIM_SCGC4_USBOTG_MASK;
+#endif
+
+    // Attach IRQ
+    instance = this;
+    NVIC_SetVector(USB0_IRQn, (uint32_t)&_usbisr);
+    NVIC_EnableIRQ(USB0_IRQn);
+
+    // USB Module Configuration
+    // 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;
+
+    //Free buffers if required:
+    for (int i = 0; i<(NUMBER_OF_PHYSICAL_ENDPOINTS - 2) * 2; i++) {
+        free(endpoint_buffer[i]);
+        endpoint_buffer[i] = NULL;
+    }
+    free(endpoint_buffer_iso[2]);
+    endpoint_buffer_iso[2] = NULL;
+    free(endpoint_buffer_iso[0]);
+    endpoint_buffer_iso[0] = NULL;
+}
+
+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)) {
+            if (endpoint_buffer[EP_BDT_IDX(log_endpoint, TX, ODD)] == NULL)
+                endpoint_buffer[EP_BDT_IDX(log_endpoint, TX, ODD)] = (uint8_t *) malloc (64);
+            buf = &endpoint_buffer[EP_BDT_IDX(log_endpoint, TX, ODD)][0];
+        } else {
+            if (endpoint_buffer[EP_BDT_IDX(log_endpoint, RX, ODD)] == NULL)
+                endpoint_buffer[EP_BDT_IDX(log_endpoint, RX, ODD)] = (uint8_t *) malloc (64);
+            buf = &endpoint_buffer[EP_BDT_IDX(log_endpoint, RX, ODD)][0];
+        }
+    } else {
+        if (IN_EP(endpoint)) {
+            if (endpoint_buffer_iso[2] == NULL)
+                endpoint_buffer_iso[2] = (uint8_t *) malloc (1023);
+            buf = &endpoint_buffer_iso[2][0];
+        } else {
+            if (endpoint_buffer_iso[0] == NULL)
+                endpoint_buffer_iso[0] = (uint8_t *) malloc (1023);
+            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;
+        int endpoint = (num << 1) | dir;
+
+        // 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 |= EP(endpoint);
+                    if ((instance->*(epCallback[endpoint - 2]))()) {
+                        epComplete &= ~EP(endpoint);
+                    }
+                }
+            }
+
+            // 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 |= EP(endpoint);
+                    if ((instance->*(epCallback[endpoint - 2]))()) {
+                        epComplete &= ~EP(endpoint);
+                    }
+                }
+            }
+        }
+
+        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	Tue May 03 00:16:32 2016 +0100
+++ b/USBDevice/USBHAL_LPC11U.cpp	Fri Apr 28 11:26:51 2017 +0100
@@ -1,738 +1,738 @@
-/* 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_LPC11UXX) || defined(TARGET_LPC11U6X) || defined(TARGET_LPC1347) || defined(TARGET_LPC1549)
-
-#if defined(TARGET_LPC1347) || defined(TARGET_LPC1549)
-#define USB_IRQ USB_IRQ_IRQn
-#else
-#define USB_IRQ USB_IRQn
-#endif
-
-#include "USBHAL.h"
-
-USBHAL * USBHAL::instance;
-#if defined(TARGET_LPC1549)
-static uint8_t usbmem[2048] __attribute__((aligned(2048)));
-#endif
-
-// 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
-#if defined(TARGET_LPC1549)
-#define USB_RAM_START ((uint32_t)usbmem)
-#define USB_RAM_SIZE  sizeof(usbmem)
-#else
-#define USB_RAM_START (0x20004000)
-#define USB_RAM_SIZE  (0x00000800)
-#endif
-
-// SYSAHBCLKCTRL
-#if defined(TARGET_LPC1549)
-#define CLK_USB     (1UL<<23)
-#else
-#define CLK_USB     (1UL<<14)
-#define CLK_USBRAM  (1UL<<27)
-#endif
-
-// 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 volatile 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 struct {
-    uint32_t out[2];
-    uint32_t in[2];
-} PACKED EP_COMMAND_STATUS;
-
-typedef struct {
-    uint8_t out[MAX_PACKET_SIZE_EP0];
-    uint8_t in[MAX_PACKET_SIZE_EP0];
-    uint8_t setup[SETUP_PACKET_SIZE];
-} PACKED CONTROL_TRANSFER;
-
-typedef struct {
-    uint32_t    maxPacket;
-    uint32_t    buffer[2];
-    uint32_t    options;
-} PACKED 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_IRQ);
-
-    // 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;
-
-#if defined(TARGET_LPC1549)
-    /* Set USB PLL input to system oscillator */
-    LPC_SYSCON->USBPLLCLKSEL = 0x01;
-
-    /* Setup USB PLL  (FCLKIN = 12MHz) * 4 = 48MHz
-       MSEL = 3 (this is pre-decremented), PSEL = 1 (for P = 2)
-       FCLKOUT = FCLKIN * (MSEL + 1) = 12MHz * 4 = 48MHz
-       FCCO = FCLKOUT * 2 * P = 48MHz * 2 * 2 = 192MHz (within FCCO range) */
-    LPC_SYSCON->USBPLLCTRL = (0x3 | (1UL << 6));
-
-    /* Powerup USB PLL */
-    LPC_SYSCON->PDRUNCFG &= ~(CLK_USB);
-
-    /* Wait for PLL to lock */
-    while(!(LPC_SYSCON->USBPLLSTAT & 0x01));
-
-    /* enable USB main clock */
-    LPC_SYSCON->USBCLKSEL = 0x02;
-    LPC_SYSCON->USBCLKDIV = 1;
-
-    /* Enable AHB clock to the USB block. */
-    LPC_SYSCON->SYSAHBCLKCTRL1 |= CLK_USB;
-
-    /* power UP USB Phy */
-    LPC_SYSCON->PDRUNCFG &= ~(1UL << 9);
-
-    /* Reset USB block */
-    LPC_SYSCON->PRESETCTRL1 |= (CLK_USB);
-    LPC_SYSCON->PRESETCTRL1 &= ~(CLK_USB);
-
-#else
-    #if defined(TARGET_LPC11U35_401) || defined(TARGET_LPC11U35_501)
-    // USB_VBUS input with pull-down
-    LPC_IOCON->PIO0_3 = 0x00000009;
-    #endif
-
-    // 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;
-#endif
-    // 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) | FRAME_INT;
-    instance = this;
-
-    //attach IRQ handler and enable interrupts
-    NVIC_SetVector(USB_IRQ, (uint32_t)&_usbisr);
-}
-
-USBHAL::~USBHAL(void) {
-    // Ensure device disconnected (DCON not set)
-    LPC_USB->DEVCMDSTAT = 0;
-    // Disable USB interrupts
-    NVIC_DisableIRQ(USB_IRQ);
-}
-
-void USBHAL::connect(void) {
-    NVIC_EnableIRQ(USB_IRQ);
-    devCmdStat |= DCON;
-    LPC_USB->DEVCMDSTAT = devCmdStat;
-}
-
-void USBHAL::disconnect(void) {
-    NVIC_DisableIRQ(USB_IRQ);
-    devCmdStat &= ~DCON;
-    LPC_USB->DEVCMDSTAT = devCmdStat;
-}
-
-void USBHAL::configureDevice(void) {
-    // Not required
-}
-
-void USBHAL::unconfigureDevice(void) {
-    // Not required
-}
-
-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::EP0readStage(void) {
-    // Not required
-}
-
-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;
-    uint32_t flags = 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;
-        }
-    }
-
-    // if isochronous endpoint, T = 1
-    if(endpointState[endpoint].options & ISOCHRONOUS)
-    {
-        flags |= CMDSTS_T;
-    }
-
-    //Active the endpoint for reading
-    ep[PHY_TO_LOG(endpoint)].out[bf] = CMDSTS_A | CMDSTS_NBYTES(maximumSize) \
-                                       | CMDSTS_ADDRESS_OFFSET((uint32_t)ct->out) | flags;
-    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) {
-    // Not required
-}
-
-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) {
-
-    // 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;
-    } 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 & DSUS_C) {
-            // Suspend status changed
-            LPC_USB->DEVCMDSTAT = devCmdStat | DSUS_C;
-            if (LPC_USB->DEVCMDSTAT & DSUS) {
-                suspendStateChanged(1);
-            } else {
-                suspendStateChanged(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();
-    }
-
-    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);
-            }
-        }
-    }
-}
-
-#endif
+/* 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_LPC11UXX) || defined(TARGET_LPC11U6X) || defined(TARGET_LPC1347) || defined(TARGET_LPC1549)
+
+#if defined(TARGET_LPC1347) || defined(TARGET_LPC1549)
+#define USB_IRQ USB_IRQ_IRQn
+#else
+#define USB_IRQ USB_IRQn
+#endif
+
+#include "USBHAL.h"
+
+USBHAL * USBHAL::instance;
+#if defined(TARGET_LPC1549)
+static uint8_t usbmem[2048] __attribute__((aligned(2048)));
+#endif
+
+// 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
+#if defined(TARGET_LPC1549)
+#define USB_RAM_START ((uint32_t)usbmem)
+#define USB_RAM_SIZE  sizeof(usbmem)
+#else
+#define USB_RAM_START (0x20004000)
+#define USB_RAM_SIZE  (0x00000800)
+#endif
+
+// SYSAHBCLKCTRL
+#if defined(TARGET_LPC1549)
+#define CLK_USB     (1UL<<23)
+#else
+#define CLK_USB     (1UL<<14)
+#define CLK_USBRAM  (1UL<<27)
+#endif
+
+// 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 volatile 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 struct {
+    uint32_t out[2];
+    uint32_t in[2];
+} PACKED EP_COMMAND_STATUS;
+
+typedef struct {
+    uint8_t out[MAX_PACKET_SIZE_EP0];
+    uint8_t in[MAX_PACKET_SIZE_EP0];
+    uint8_t setup[SETUP_PACKET_SIZE];
+} PACKED CONTROL_TRANSFER;
+
+typedef struct {
+    uint32_t    maxPacket;
+    uint32_t    buffer[2];
+    uint32_t    options;
+} PACKED 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_IRQ);
+
+    // 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;
+
+#if defined(TARGET_LPC1549)
+    /* Set USB PLL input to system oscillator */
+    LPC_SYSCON->USBPLLCLKSEL = 0x01;
+
+    /* Setup USB PLL  (FCLKIN = 12MHz) * 4 = 48MHz
+       MSEL = 3 (this is pre-decremented), PSEL = 1 (for P = 2)
+       FCLKOUT = FCLKIN * (MSEL + 1) = 12MHz * 4 = 48MHz
+       FCCO = FCLKOUT * 2 * P = 48MHz * 2 * 2 = 192MHz (within FCCO range) */
+    LPC_SYSCON->USBPLLCTRL = (0x3 | (1UL << 6));
+
+    /* Powerup USB PLL */
+    LPC_SYSCON->PDRUNCFG &= ~(CLK_USB);
+
+    /* Wait for PLL to lock */
+    while(!(LPC_SYSCON->USBPLLSTAT & 0x01));
+
+    /* enable USB main clock */
+    LPC_SYSCON->USBCLKSEL = 0x02;
+    LPC_SYSCON->USBCLKDIV = 1;
+
+    /* Enable AHB clock to the USB block. */
+    LPC_SYSCON->SYSAHBCLKCTRL1 |= CLK_USB;
+
+    /* power UP USB Phy */
+    LPC_SYSCON->PDRUNCFG &= ~(1UL << 9);
+
+    /* Reset USB block */
+    LPC_SYSCON->PRESETCTRL1 |= (CLK_USB);
+    LPC_SYSCON->PRESETCTRL1 &= ~(CLK_USB);
+
+#else
+    #if defined(TARGET_LPC11U35_401) || defined(TARGET_LPC11U35_501)
+    // USB_VBUS input with pull-down
+    LPC_IOCON->PIO0_3 = 0x00000009;
+    #endif
+
+    // 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;
+#endif
+    // 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) | FRAME_INT;
+    instance = this;
+
+    //attach IRQ handler and enable interrupts
+    NVIC_SetVector(USB_IRQ, (uint32_t)&_usbisr);
+}
+
+USBHAL::~USBHAL(void) {
+    // Ensure device disconnected (DCON not set)
+    LPC_USB->DEVCMDSTAT = 0;
+    // Disable USB interrupts
+    NVIC_DisableIRQ(USB_IRQ);
+}
+
+void USBHAL::connect(void) {
+    NVIC_EnableIRQ(USB_IRQ);
+    devCmdStat |= DCON;
+    LPC_USB->DEVCMDSTAT = devCmdStat;
+}
+
+void USBHAL::disconnect(void) {
+    NVIC_DisableIRQ(USB_IRQ);
+    devCmdStat &= ~DCON;
+    LPC_USB->DEVCMDSTAT = devCmdStat;
+}
+
+void USBHAL::configureDevice(void) {
+    // Not required
+}
+
+void USBHAL::unconfigureDevice(void) {
+    // Not required
+}
+
+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::EP0readStage(void) {
+    // Not required
+}
+
+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;
+    uint32_t flags = 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;
+        }
+    }
+
+    // if isochronous endpoint, T = 1
+    if(endpointState[endpoint].options & ISOCHRONOUS)
+    {
+        flags |= CMDSTS_T;
+    }
+
+    //Active the endpoint for reading
+    ep[PHY_TO_LOG(endpoint)].out[bf] = CMDSTS_A | CMDSTS_NBYTES(maximumSize) \
+                                       | CMDSTS_ADDRESS_OFFSET((uint32_t)ct->out) | flags;
+    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) {
+    // Not required
+}
+
+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) {
+
+    // 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;
+    } 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 & DSUS_C) {
+            // Suspend status changed
+            LPC_USB->DEVCMDSTAT = devCmdStat | DSUS_C;
+            if (LPC_USB->DEVCMDSTAT & DSUS) {
+                suspendStateChanged(1);
+            } else {
+                suspendStateChanged(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();
+    }
+
+    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);
+            }
+        }
+    }
+}
+
+#endif
--- a/USBDevice/USBHAL_LPC17.cpp	Tue May 03 00:16:32 2016 +0100
+++ b/USBDevice/USBHAL_LPC17.cpp	Fri Apr 28 11:26:51 2017 +0100
@@ -1,623 +1,623 @@
-/* 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_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC2460)
-
-#include "USBHAL.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 volatile int epComplete;
-static 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 = SIEgetDeviceStatus();
-    SIEsetDeviceStatus(status | SIE_DS_CON);
-}
-
-
-static void SIEdisconnect(void) {
-    // Disconnect USB device
-    uint8_t 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;
-uint32_t USBHAL::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;
-    }
-
-    LPC_USB->USBCtrl = 0;
-
-    if ((endpoint >> 1) % 3 || (endpoint >> 1) == 0) {
-        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);
-
-    // 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;
-
-    // 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);
-
-    // Enable interrupts for device events and EP0
-    LPC_USB->USBDevIntEn = EP_SLOW | DEV_STAT | FRAME;
-    enableEndpointEvent(EP0IN);
-    enableEndpointEvent(EP0OUT);
-}
-
-USBHAL::~USBHAL(void) {
-    // Ensure device disconnected
-    SIEdisconnect();
-    // Disable USB interrupts
-    NVIC_DisableIRQ(USB_IRQn);
-}
-
-void USBHAL::connect(void) {
-    NVIC_EnableIRQ(USB_IRQn);
-    // Connect USB device
-    SIEconnect();
-}
-
-void USBHAL::disconnect(void) {
-    NVIC_DisableIRQ(USB_IRQn);
-    // 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
-}
-
-void USBHAL::EP0readStage(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) {
-
-    //for isochronous endpoint, we don't wait an interrupt
-    if ((endpoint >> 1) % 3 || (endpoint >> 1) == 0) {
-        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();
-        //printf("devStat: %d\r\n", devStat);
-
-        if (devStat & SIE_DS_SUS_CH) {
-            // Suspend status changed
-            if((devStat & SIE_DS_SUS) != 0) {
-                suspendStateChanged(0);
-            }
-        }
-
-        if (devStat & SIE_DS_RST) {
-            // Bus reset
-            if((devStat & SIE_DS_SUS) == 0) {
-                suspendStateChanged(1);
-            }
-            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();
-        }
-
-        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);
-                }
-            }
-        }
-    }
-}
-
-#endif
+/* 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_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC2460)
+
+#include "USBHAL.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 volatile int epComplete;
+static 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 = SIEgetDeviceStatus();
+    SIEsetDeviceStatus(status | SIE_DS_CON);
+}
+
+
+static void SIEdisconnect(void) {
+    // Disconnect USB device
+    uint8_t 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;
+uint32_t USBHAL::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;
+    }
+
+    LPC_USB->USBCtrl = 0;
+
+    if ((endpoint >> 1) % 3 || (endpoint >> 1) == 0) {
+        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);
+
+    // 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;
+
+    // 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);
+
+    // Enable interrupts for device events and EP0
+    LPC_USB->USBDevIntEn = EP_SLOW | DEV_STAT | FRAME;
+    enableEndpointEvent(EP0IN);
+    enableEndpointEvent(EP0OUT);
+}
+
+USBHAL::~USBHAL(void) {
+    // Ensure device disconnected
+    SIEdisconnect();
+    // Disable USB interrupts
+    NVIC_DisableIRQ(USB_IRQn);
+}
+
+void USBHAL::connect(void) {
+    NVIC_EnableIRQ(USB_IRQn);
+    // Connect USB device
+    SIEconnect();
+}
+
+void USBHAL::disconnect(void) {
+    NVIC_DisableIRQ(USB_IRQn);
+    // 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
+}
+
+void USBHAL::EP0readStage(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) {
+
+    //for isochronous endpoint, we don't wait an interrupt
+    if ((endpoint >> 1) % 3 || (endpoint >> 1) == 0) {
+        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();
+        //printf("devStat: %d\r\n", devStat);
+
+        if (devStat & SIE_DS_SUS_CH) {
+            // Suspend status changed
+            if((devStat & SIE_DS_SUS) != 0) {
+                suspendStateChanged(0);
+            }
+        }
+
+        if (devStat & SIE_DS_RST) {
+            // Bus reset
+            if((devStat & SIE_DS_SUS) == 0) {
+                suspendStateChanged(1);
+            }
+            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();
+        }
+
+        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);
+                }
+            }
+        }
+    }
+}
+
+#endif
--- a/USBDevice/USBHAL_LPC40.cpp	Tue May 03 00:16:32 2016 +0100
+++ b/USBDevice/USBHAL_LPC40.cpp	Fri Apr 28 11:26:51 2017 +0100
@@ -1,628 +1,628 @@
-/* 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_LPC4088) || defined(TARGET_LPC4088_DM)
-
-#include "USBHAL.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 PORT_CLK_EN (1UL<<3)
-#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 volatile int epComplete;
-static uint32_t endpointStallState;
-
-static void SIECommand(uint32_t command) {
-    // The command phase of a SIE transaction
-    LPC_USB->DevIntClr = CCEMPTY;
-    LPC_USB->CmdCode = SIE_CMD_CODE(SIE_COMMAND, command);
-    while (!(LPC_USB->DevIntSt & CCEMPTY));
-}
-
-static void SIEWriteData(uint8_t data) {
-    // The data write phase of a SIE transaction
-    LPC_USB->DevIntClr = CCEMPTY;
-    LPC_USB->CmdCode = SIE_CMD_CODE(SIE_WRITE, data);
-    while (!(LPC_USB->DevIntSt & CCEMPTY));
-}
-
-static uint8_t SIEReadData(uint32_t command) {
-    // The data read phase of a SIE transaction
-    LPC_USB->DevIntClr = CDFULL;
-    LPC_USB->CmdCode = SIE_CMD_CODE(SIE_READ, command);
-    while (!(LPC_USB->DevIntSt & CDFULL));
-    return (uint8_t)LPC_USB->CmdData;
-}
-
-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 = SIEgetDeviceStatus();
-    SIEsetDeviceStatus(status | SIE_DS_CON);
-}
-
-
-static void SIEdisconnect(void) {
-    // Disconnect USB device
-    uint8_t status = SIEgetDeviceStatus();
-    SIEsetDeviceStatus(status & ~SIE_DS_CON);
-}
-
-
-static uint8_t selectEndpointClearInterrupt(uint8_t endpoint) {
-    // Implemented using using EP_INT_CLR.
-    LPC_USB->EpIntClr = EP(endpoint);
-    while (!(LPC_USB->DevIntSt & CDFULL));
-    return (uint8_t)LPC_USB->CmdData;
-}
-
-
-static void enableEndpointEvent(uint8_t endpoint) {
-    // Enable an endpoint interrupt
-    LPC_USB->EpIntEn |= EP(endpoint);
-}
-
-static void disableEndpointEvent(uint8_t endpoint) __attribute__ ((unused));
-static void disableEndpointEvent(uint8_t endpoint) {
-    // Disable an endpoint interrupt
-    LPC_USB->EpIntEn &= ~EP(endpoint);
-}
-
-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;
-    uint32_t i;
-    uint32_t data = 0;
-    uint8_t offset;
-
-    LPC_USB->Ctrl = LOG_ENDPOINT(endpoint) | RD_EN;
-    while (!(LPC_USB->RxPLen & PKT_RDY));
-
-    size = LPC_USB->RxPLen & 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->RxData;
-            }
-
-            // extract a byte
-            *buffer = (data>>offset) & 0xff;
-            buffer++;
-
-            // move on to the next byte
-            offset = (offset + 8) % 32;
-        }
-    } else {
-        dummyRead = LPC_USB->RxData;
-    }
-
-    LPC_USB->Ctrl = 0;
-
-    if ((endpoint >> 1) % 3 || (endpoint >> 1) == 0) {
-        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->Ctrl = LOG_ENDPOINT(endpoint) | WR_EN;
-
-    LPC_USB->TxPLen = 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->TxData = data;
-                data = 0;
-            }
-        } while (size>0);
-    } else {
-        LPC_USB->TxData = 0;
-    }
-
-    // Clear WR_EN to cover zero length packet case
-    LPC_USB->Ctrl=0;
-
-    SIEselectEndpoint(endpoint);
-    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;
-
-    // Enable USB clocks
-    LPC_USB->USBClkCtrl |= DEV_CLK_EN | AHB_CLK_EN | PORT_CLK_EN;
-    while ((LPC_USB->USBClkSt & (DEV_CLK_EN | AHB_CLK_EN | PORT_CLK_EN)) != (DEV_CLK_ON | AHB_CLK_ON | PORT_CLK_EN));
-
-    // Select port USB2
-    LPC_USB->StCtrl |= 3;
-
-
-    // Configure pin P0.31 to be USB2
-    LPC_IOCON->P0_31 &= ~0x07;
-    LPC_IOCON->P0_31 |= 0x01;
-
-    // Disconnect USB device
-    SIEdisconnect();
-
-    // Configure pin P0.14 to be Connect
-    LPC_IOCON->P0_14 &= ~0x07;
-    LPC_IOCON->P0_14 |= 0x03;
-
-    // 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);
-
-    // Enable interrupts for device events and EP0
-    LPC_USB->DevIntEn = EP_SLOW | DEV_STAT | FRAME;
-    enableEndpointEvent(EP0IN);
-    enableEndpointEvent(EP0OUT);
-}
-
-USBHAL::~USBHAL(void) {
-    // Ensure device disconnected
-    SIEdisconnect();
-    // Disable USB interrupts
-    NVIC_DisableIRQ(USB_IRQn);
-}
-
-void USBHAL::connect(void) {
-    NVIC_EnableIRQ(USB_IRQn);
-    // Connect USB device
-    SIEconnect();
-}
-
-void USBHAL::disconnect(void) {
-    NVIC_DisableIRQ(USB_IRQn);
-    // 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
-}
-
-void USBHAL::EP0readStage(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) {
-
-    //for isochronous endpoint, we don't wait an interrupt
-    if ((endpoint >> 1) % 3 || (endpoint >> 1) == 0) {
-        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->DevIntClr = EP_RLZED;
-    LPC_USB->ReEp |= EP(endpoint);
-    LPC_USB->EpInd = endpoint;
-    LPC_USB->MaxPSize = maxPacket;
-
-    while (!(LPC_USB->DevIntSt & EP_RLZED));
-    LPC_USB->DevIntClr = 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->DevIntSt & FRAME) {
-        // Start of frame event
-        SOF(SIEgetFrameNumber());
-        // Clear interrupt status flag
-        LPC_USB->DevIntClr = FRAME;
-    }
-
-    if (LPC_USB->DevIntSt & DEV_STAT) {
-        // Device Status interrupt
-        // Must clear the interrupt status flag before reading the device status from the SIE
-        LPC_USB->DevIntClr = DEV_STAT;
-
-        // Read device status from SIE
-        devStat = SIEgetDeviceStatus();
-        //printf("devStat: %d\r\n", devStat);
-
-        if (devStat & SIE_DS_SUS_CH) {
-            // Suspend status changed
-            if((devStat & SIE_DS_SUS) != 0) {
-                suspendStateChanged(0);
-            }
-        }
-
-        if (devStat & SIE_DS_RST) {
-            // Bus reset
-            if((devStat & SIE_DS_SUS) == 0) {
-                suspendStateChanged(1);
-            }
-            busReset();
-        }
-    }
-
-    if (LPC_USB->DevIntSt & EP_SLOW) {
-        // (Slow) Endpoint Interrupt
-
-        // Process each endpoint interrupt
-        if (LPC_USB->EpIntSt & EP(EP0OUT)) {
-            if (selectEndpointClearInterrupt(EP0OUT) & SIE_SE_STP) {
-                // this is a setup packet
-                EP0setupCallback();
-            } else {
-                EP0out();
-            }
-            LPC_USB->DevIntClr = EP_SLOW;
-        }
-
-        if (LPC_USB->EpIntSt & EP(EP0IN)) {
-            selectEndpointClearInterrupt(EP0IN);
-            LPC_USB->DevIntClr = EP_SLOW;
-            EP0in();
-        }
-
-        for (uint8_t num = 2; num < 16*2; num++) {
-            if (LPC_USB->EpIntSt & EP(num)) {
-                selectEndpointClearInterrupt(num);
-                epComplete |= EP(num);
-                LPC_USB->DevIntClr = EP_SLOW;
-                if ((instance->*(epCallback[num - 2]))()) {
-                    epComplete &= ~EP(num);
-                }
-            }
-        }
-    }
-}
-
-#endif
+/* 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_LPC4088) || defined(TARGET_LPC4088_DM)
+
+#include "USBHAL.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 PORT_CLK_EN (1UL<<3)
+#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 volatile int epComplete;
+static uint32_t endpointStallState;
+
+static void SIECommand(uint32_t command) {
+    // The command phase of a SIE transaction
+    LPC_USB->DevIntClr = CCEMPTY;
+    LPC_USB->CmdCode = SIE_CMD_CODE(SIE_COMMAND, command);
+    while (!(LPC_USB->DevIntSt & CCEMPTY));
+}
+
+static void SIEWriteData(uint8_t data) {
+    // The data write phase of a SIE transaction
+    LPC_USB->DevIntClr = CCEMPTY;
+    LPC_USB->CmdCode = SIE_CMD_CODE(SIE_WRITE, data);
+    while (!(LPC_USB->DevIntSt & CCEMPTY));
+}
+
+static uint8_t SIEReadData(uint32_t command) {
+    // The data read phase of a SIE transaction
+    LPC_USB->DevIntClr = CDFULL;
+    LPC_USB->CmdCode = SIE_CMD_CODE(SIE_READ, command);
+    while (!(LPC_USB->DevIntSt & CDFULL));
+    return (uint8_t)LPC_USB->CmdData;
+}
+
+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 = SIEgetDeviceStatus();
+    SIEsetDeviceStatus(status | SIE_DS_CON);
+}
+
+
+static void SIEdisconnect(void) {
+    // Disconnect USB device
+    uint8_t status = SIEgetDeviceStatus();
+    SIEsetDeviceStatus(status & ~SIE_DS_CON);
+}
+
+
+static uint8_t selectEndpointClearInterrupt(uint8_t endpoint) {
+    // Implemented using using EP_INT_CLR.
+    LPC_USB->EpIntClr = EP(endpoint);
+    while (!(LPC_USB->DevIntSt & CDFULL));
+    return (uint8_t)LPC_USB->CmdData;
+}
+
+
+static void enableEndpointEvent(uint8_t endpoint) {
+    // Enable an endpoint interrupt
+    LPC_USB->EpIntEn |= EP(endpoint);
+}
+
+static void disableEndpointEvent(uint8_t endpoint) __attribute__ ((unused));
+static void disableEndpointEvent(uint8_t endpoint) {
+    // Disable an endpoint interrupt
+    LPC_USB->EpIntEn &= ~EP(endpoint);
+}
+
+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;
+    uint32_t i;
+    uint32_t data = 0;
+    uint8_t offset;
+
+    LPC_USB->Ctrl = LOG_ENDPOINT(endpoint) | RD_EN;
+    while (!(LPC_USB->RxPLen & PKT_RDY));
+
+    size = LPC_USB->RxPLen & 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->RxData;
+            }
+
+            // extract a byte
+            *buffer = (data>>offset) & 0xff;
+            buffer++;
+
+            // move on to the next byte
+            offset = (offset + 8) % 32;
+        }
+    } else {
+        dummyRead = LPC_USB->RxData;
+    }
+
+    LPC_USB->Ctrl = 0;
+
+    if ((endpoint >> 1) % 3 || (endpoint >> 1) == 0) {
+        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->Ctrl = LOG_ENDPOINT(endpoint) | WR_EN;
+
+    LPC_USB->TxPLen = 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->TxData = data;
+                data = 0;
+            }
+        } while (size>0);
+    } else {
+        LPC_USB->TxData = 0;
+    }
+
+    // Clear WR_EN to cover zero length packet case
+    LPC_USB->Ctrl=0;
+
+    SIEselectEndpoint(endpoint);
+    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;
+
+    // Enable USB clocks
+    LPC_USB->USBClkCtrl |= DEV_CLK_EN | AHB_CLK_EN | PORT_CLK_EN;
+    while ((LPC_USB->USBClkSt & (DEV_CLK_EN | AHB_CLK_EN | PORT_CLK_EN)) != (DEV_CLK_ON | AHB_CLK_ON | PORT_CLK_EN));
+
+    // Select port USB2
+    LPC_USB->StCtrl |= 3;
+
+
+    // Configure pin P0.31 to be USB2
+    LPC_IOCON->P0_31 &= ~0x07;
+    LPC_IOCON->P0_31 |= 0x01;
+
+    // Disconnect USB device
+    SIEdisconnect();
+
+    // Configure pin P0.14 to be Connect
+    LPC_IOCON->P0_14 &= ~0x07;
+    LPC_IOCON->P0_14 |= 0x03;
+
+    // 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);
+
+    // Enable interrupts for device events and EP0
+    LPC_USB->DevIntEn = EP_SLOW | DEV_STAT | FRAME;
+    enableEndpointEvent(EP0IN);
+    enableEndpointEvent(EP0OUT);
+}
+
+USBHAL::~USBHAL(void) {
+    // Ensure device disconnected
+    SIEdisconnect();
+    // Disable USB interrupts
+    NVIC_DisableIRQ(USB_IRQn);
+}
+
+void USBHAL::connect(void) {
+    NVIC_EnableIRQ(USB_IRQn);
+    // Connect USB device
+    SIEconnect();
+}
+
+void USBHAL::disconnect(void) {
+    NVIC_DisableIRQ(USB_IRQn);
+    // 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
+}
+
+void USBHAL::EP0readStage(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) {
+
+    //for isochronous endpoint, we don't wait an interrupt
+    if ((endpoint >> 1) % 3 || (endpoint >> 1) == 0) {
+        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->DevIntClr = EP_RLZED;
+    LPC_USB->ReEp |= EP(endpoint);
+    LPC_USB->EpInd = endpoint;
+    LPC_USB->MaxPSize = maxPacket;
+
+    while (!(LPC_USB->DevIntSt & EP_RLZED));
+    LPC_USB->DevIntClr = 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->DevIntSt & FRAME) {
+        // Start of frame event
+        SOF(SIEgetFrameNumber());
+        // Clear interrupt status flag
+        LPC_USB->DevIntClr = FRAME;
+    }
+
+    if (LPC_USB->DevIntSt & DEV_STAT) {
+        // Device Status interrupt
+        // Must clear the interrupt status flag before reading the device status from the SIE
+        LPC_USB->DevIntClr = DEV_STAT;
+
+        // Read device status from SIE
+        devStat = SIEgetDeviceStatus();
+        //printf("devStat: %d\r\n", devStat);
+
+        if (devStat & SIE_DS_SUS_CH) {
+            // Suspend status changed
+            if((devStat & SIE_DS_SUS) != 0) {
+                suspendStateChanged(0);
+            }
+        }
+
+        if (devStat & SIE_DS_RST) {
+            // Bus reset
+            if((devStat & SIE_DS_SUS) == 0) {
+                suspendStateChanged(1);
+            }
+            busReset();
+        }
+    }
+
+    if (LPC_USB->DevIntSt & EP_SLOW) {
+        // (Slow) Endpoint Interrupt
+
+        // Process each endpoint interrupt
+        if (LPC_USB->EpIntSt & EP(EP0OUT)) {
+            if (selectEndpointClearInterrupt(EP0OUT) & SIE_SE_STP) {
+                // this is a setup packet
+                EP0setupCallback();
+            } else {
+                EP0out();
+            }
+            LPC_USB->DevIntClr = EP_SLOW;
+        }
+
+        if (LPC_USB->EpIntSt & EP(EP0IN)) {
+            selectEndpointClearInterrupt(EP0IN);
+            LPC_USB->DevIntClr = EP_SLOW;
+            EP0in();
+        }
+
+        for (uint8_t num = 2; num < 16*2; num++) {
+            if (LPC_USB->EpIntSt & EP(num)) {
+                selectEndpointClearInterrupt(num);
+                epComplete |= EP(num);
+                LPC_USB->DevIntClr = EP_SLOW;
+                if ((instance->*(epCallback[num - 2]))()) {
+                    epComplete &= ~EP(num);
+                }
+            }
+        }
+    }
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBHAL_M453.cpp	Fri Apr 28 11:26:51 2017 +0100
@@ -0,0 +1,465 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2015-2016 Nuvoton
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#if defined(TARGET_NUMAKER_PFM_M453)
+
+#include "USBHAL.h"
+#include "M451Series.h"
+#include "pinmap.h"
+
+/**
+ * EP: mbed USBD defined endpoint, e.g. EP0OUT/IN, EP1OUT/IN, EP2OUT/IN.
+ * EPX: BSP defined endpoint, e.g. CEP, EPA, EPB, EPC.
+ */
+
+USBHAL * USBHAL::instance;
+
+/* Global variables for Control Pipe */
+extern uint8_t g_usbd_SetupPacket[];        /*!< Setup packet buffer */
+
+static volatile uint32_t s_ep_compl = 0;
+static volatile uint32_t s_ep_buf_ind = 8;
+static volatile uint8_t s_usb_addr = 0;
+static volatile uint8_t s_ep_data_bit[NUMBER_OF_PHYSICAL_ENDPOINTS] = {1};
+static volatile uint8_t s_ep_mxp[NUMBER_OF_PHYSICAL_ENDPOINTS] = {0};
+
+extern volatile uint8_t *g_usbd_CtrlInPointer;
+extern volatile uint32_t g_usbd_CtrlInSize;
+extern volatile uint8_t *g_usbd_CtrlOutPointer;
+extern volatile uint32_t g_usbd_CtrlOutSize;
+extern volatile uint32_t g_usbd_CtrlOutSizeLimit;
+extern volatile uint32_t g_usbd_UsbConfig;
+extern volatile uint32_t g_usbd_CtrlMaxPktSize;
+extern volatile uint32_t g_usbd_UsbAltInterface;
+volatile uint32_t g_usbd_CepTransferLen = 0;
+volatile uint32_t frame_cnt = 0;
+USBHAL::USBHAL(void)
+{
+    SYS_UnlockReg();
+
+    s_ep_buf_ind = 8;
+
+    memset(epCallback, 0x00, sizeof (epCallback));
+    epCallback[0] = &USBHAL::EP1_OUT_callback;
+    epCallback[1] = &USBHAL::EP2_IN_callback;
+    epCallback[2] = &USBHAL::EP3_OUT_callback;
+    epCallback[3] = &USBHAL::EP4_IN_callback;
+    epCallback[4] = &USBHAL::EP5_OUT_callback;
+    epCallback[5] = &USBHAL::EP6_IN_callback;
+
+    instance = this;
+    /* Enable USBD module clock */
+    CLK_EnableModuleClock(USBD_MODULE);
+
+    CLK_SetModuleClock(USBD_MODULE, 0, CLK_CLKDIV0_USB(3));
+
+    /* Enable USB LDO33 */
+    SYS->USBPHY = SYS_USBPHY_LDO33EN_Msk;
+
+    /* Initial USB engine */
+    USBD->ATTR = 0x7D0;
+
+    /* Set SE0 (disconnect) */
+    USBD_SET_SE0();
+
+    //NVIC_SetVector(OTG_FS_IRQn, (uint32_t) &_usbisr);
+    NVIC_SetVector(USBD_IRQn, (uint32_t) &_usbisr);
+    NVIC_EnableIRQ(USBD_IRQn);
+}
+
+USBHAL::~USBHAL(void)
+{
+    NVIC_DisableIRQ(USBD_IRQn);
+    USBD_SET_SE0();
+    USBD_DISABLE_PHY();
+}
+
+void USBHAL::connect(void)
+{
+    USBD->STBUFSEG = 0;
+    frame_cnt = 0;
+    /* EP0 ==> control IN endpoint, address 0 */
+    USBD_CONFIG_EP(EP0, USBD_CFG_CSTALL | USBD_CFG_EPMODE_IN | 0);
+    /* Buffer range for EP0 */
+    USBD_SET_EP_BUF_ADDR(EP0, s_ep_buf_ind);
+
+    /* EP1 ==> control OUT endpoint, address 0 */
+    USBD_CONFIG_EP(EP1, USBD_CFG_CSTALL | USBD_CFG_EPMODE_OUT | 0);
+    /* Buffer range for EP1 */
+    USBD_SET_EP_BUF_ADDR(EP1, s_ep_buf_ind);
+
+    s_ep_buf_ind += MAX_PACKET_SIZE_EP0;
+
+    /* Disable software-disconnect function */
+    USBD_CLR_SE0();
+
+    /* Clear USB-related interrupts before enable interrupt */
+    USBD_CLR_INT_FLAG(USBD_INT_BUS | USBD_INT_USB | USBD_INT_FLDET | USBD_INT_WAKEUP);
+
+    /* Enable USB-related interrupts. */
+    USBD_ENABLE_INT(USBD_INT_BUS | USBD_INT_USB | USBD_INT_FLDET | USBD_INT_WAKEUP);
+}
+
+void USBHAL::disconnect(void)
+{
+    /* Set SE0 (disconnect) */
+    USBD_SET_SE0();
+}
+
+void USBHAL::configureDevice(void)
+{
+    /**
+     * In USBDevice.cpp > USBDevice::requestSetConfiguration, configureDevice() is called after realiseEndpoint() (in USBCallback_setConfiguration()).
+     * So we have the following USB buffer management policy:
+     *  1. Allocate for CEP on connect().
+     *  2. Allocate for EPX in realiseEndpoint().
+     *  3. Deallocate all except for CEP in unconfigureDevice().
+     */
+}
+
+void USBHAL::unconfigureDevice(void)
+{
+    s_ep_buf_ind = 8;
+}
+
+void USBHAL::setAddress(uint8_t address)
+{
+    // NOTE: Delay address setting; otherwise, USB controller won't ack.
+    s_usb_addr = address;
+}
+
+void USBHAL::remoteWakeup(void)
+{
+#if 0
+    USBD->OPER |= USBD_OPER_RESUMEEN_Msk;
+#endif
+}
+
+bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t options)
+{
+    uint32_t ep_type = 0;
+    uint32_t ep_hw_index = NU_EP2EPH(endpoint);
+    uint32_t ep_logic_index = NU_EP2EPL(endpoint);
+    uint32_t ep_dir = (NU_EP_DIR(endpoint) == NU_EP_DIR_IN) ? USBD_CFG_EPMODE_IN : USBD_CFG_EPMODE_OUT;
+
+    if (ep_logic_index == 3 || ep_logic_index == 4)
+        ep_type = USBD_CFG_TYPE_ISO;
+
+    USBD_CONFIG_EP(ep_hw_index, ep_dir | ep_type | ep_logic_index);
+    /* Buffer range */
+    USBD_SET_EP_BUF_ADDR(ep_hw_index, s_ep_buf_ind);
+
+    if (ep_dir == USBD_CFG_EPMODE_OUT)
+        USBD_SET_PAYLOAD_LEN(ep_hw_index, maxPacket);
+
+    s_ep_mxp[ep_logic_index] = maxPacket;
+
+    s_ep_buf_ind += maxPacket;
+
+    return true;
+}
+
+void USBHAL::EP0setup(uint8_t *buffer)
+{
+    uint32_t sz;
+    endpointReadResult(EP0OUT, buffer, &sz);
+}
+
+void USBHAL::EP0read(void)
+{
+
+
+}
+
+void USBHAL::EP0readStage(void)
+{
+    // N/A
+
+    USBD_PrepareCtrlOut(0,0);
+}
+
+uint32_t USBHAL::EP0getReadResult(uint8_t *buffer)
+{
+    uint32_t i;
+    uint8_t *buf = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP1));
+    uint32_t ceprxcnt = USBD_GET_PAYLOAD_LEN(EP1);
+    for (i = 0; i < ceprxcnt; i ++)
+        buffer[i] = buf[i];
+    USBD_SET_PAYLOAD_LEN(EP1, MAX_PACKET_SIZE_EP0);
+    return ceprxcnt;
+}
+
+void USBHAL::EP0write(uint8_t *buffer, uint32_t size)
+{
+    if (buffer && size)
+    {
+        if (s_ep_data_bit[0] & 1)
+            USBD_SET_DATA1(EP0);
+        else
+            USBD_SET_DATA0(EP0);
+        s_ep_data_bit[0]++;
+
+        USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), buffer, size);
+        USBD_SET_PAYLOAD_LEN(EP0, size);
+        if (size < MAX_PACKET_SIZE_EP0)
+            s_ep_data_bit[0] = 1;
+
+    }
+    else
+    {
+        if (g_usbd_SetupPacket[0] & 0x80)   //Device to Host
+        {
+            // Status stage
+            //          USBD_PrepareCtrlOut(0,0);
+        } else
+        {
+            USBD_SET_DATA1(EP0);
+            USBD_SET_PAYLOAD_LEN(EP0, 0);
+        }
+    }
+}
+
+void USBHAL::EP0getWriteResult(void)
+{
+    // N/A
+}
+
+void USBHAL::EP0stall(void)
+{
+    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) //spcheng
+{
+    if (endpoint == EP0OUT)
+    {
+        USBD_MemCopy(g_usbd_SetupPacket, (uint8_t *)USBD_BUF_BASE, 8);
+        if (buffer) {
+            USBD_MemCopy(buffer, g_usbd_SetupPacket, 8);
+        }
+        USBD_SET_PAYLOAD_LEN(EP1, MAX_PACKET_SIZE_EP0);
+    }
+    else
+    {
+        uint32_t i;
+        uint8_t *buf = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(NU_EP2EPH(endpoint)));
+        uint32_t eprxcnt = USBD_GET_PAYLOAD_LEN(NU_EP2EPH(endpoint));
+        for (i = 0; i < eprxcnt; i ++)
+            buffer[i] = buf[i];
+
+        *bytesRead = eprxcnt;
+
+        USBD_SET_PAYLOAD_LEN(NU_EP2EPH(endpoint),s_ep_mxp[NU_EPH2EPL(NU_EP2EPL(endpoint))]);
+    }
+    return EP_COMPLETED;
+}
+
+
+uint32_t USBHAL::endpointReadcore(uint8_t endpoint, uint8_t *buffer)
+{
+    return 0;
+}
+
+EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size)
+{
+    uint32_t ep_logic_index = NU_EP2EPL(endpoint);
+    if (ep_logic_index == 0)
+        return EP_INVALID;
+    else
+    {
+        uint8_t *buf;
+        uint32_t i=0;
+        uint32_t ep_hw_index = NU_EP2EPH(endpoint);
+        s_ep_compl |= (1 << ep_logic_index);
+        buf = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(ep_hw_index));
+        for (i=0;i<size;i++)
+            buf[i] = data[i];
+
+        /* Set transfer length and trigger IN transfer */
+        USBD_SET_PAYLOAD_LEN(ep_hw_index, size);
+
+    }
+    return EP_PENDING;
+}
+
+EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint)
+{
+    if (!(s_ep_compl & (1 << NU_EP2EPL(endpoint))))
+        return EP_COMPLETED;
+    return EP_PENDING;
+}
+
+void USBHAL::stallEndpoint(uint8_t endpoint)
+{
+    uint32_t ep_hw_index = NU_EP2EPH(endpoint);
+    if (ep_hw_index >= NUMBER_OF_PHYSICAL_ENDPOINTS)
+        return;
+
+    USBD_SetStall(NU_EPH2EPL(ep_hw_index));
+
+}
+
+void USBHAL::unstallEndpoint(uint8_t endpoint)
+{
+    uint32_t ep_hw_index = NU_EP2EPH(endpoint);
+    if (ep_hw_index >= NUMBER_OF_PHYSICAL_ENDPOINTS)
+        return;
+    USBD_ClearStall(NU_EPH2EPL(ep_hw_index));
+}
+
+bool USBHAL::getEndpointStallState(uint8_t endpoint)
+{
+    uint32_t ep_hw_index = NU_EP2EPH(endpoint);
+    if (ep_hw_index >= NUMBER_OF_PHYSICAL_ENDPOINTS)
+        return false;
+
+    return USBD_GetStall(NU_EPH2EPL(ep_hw_index)) ? 1 : 0;
+}
+
+void USBHAL::_usbisr(void)
+{
+    MBED_ASSERT(instance);
+    instance->usbisr();
+}
+
+void USBHAL::usbisr(void)
+{
+    uint32_t u32IntSts = USBD_GET_INT_FLAG();
+    uint32_t u32State = USBD_GET_BUS_STATE();
+
+//------------------------------------------------------------------
+    if (u32IntSts & USBD_INTSTS_VBDETIF_Msk)
+    {
+        // Floating detect
+        USBD_CLR_INT_FLAG(USBD_INTSTS_VBDETIF_Msk);
+
+        if (USBD_IS_ATTACHED())
+        {
+            /* USB Plug In */
+            USBD_ENABLE_USB();
+        }
+        else
+        {
+            /* USB Un-plug */
+            USBD_DISABLE_USB();
+        }
+    }
+
+//------------------------------------------------------------------
+    if (u32IntSts & USBD_INTSTS_BUSIF_Msk)
+    {
+        /* Clear event flag */
+        USBD_CLR_INT_FLAG(USBD_INTSTS_BUSIF_Msk);
+
+        if (u32State & USBD_ATTR_USBRST_Msk)
+        {
+            /* Bus reset */
+            USBD_ENABLE_USB();
+            USBD_SwReset();
+        }
+        if (u32State & USBD_ATTR_SUSPEND_Msk)
+        {
+            /* Enable USB but disable PHY */
+            USBD_DISABLE_PHY();
+        }
+        if (u32State & USBD_ATTR_RESUME_Msk)
+        {
+            /* Enable USB and enable PHY */
+            USBD_ENABLE_USB();
+        }
+    }
+
+    if (u32IntSts & USBD_INTSTS_USBIF_Msk)
+    {
+        // USB event
+        if (u32IntSts & USBD_INTSTS_SETUP_Msk)
+        {
+            // Setup packet
+            /* Clear event flag */
+            USBD_CLR_INT_FLAG(USBD_INTSTS_SETUP_Msk);
+
+            /* Clear the data IN/OUT ready flag of control end-points */
+            USBD_STOP_TRANSACTION(EP0);
+            USBD_STOP_TRANSACTION(EP1);
+            EP0setupCallback();
+        }
+
+        // EP events
+        if (u32IntSts & USBD_INTSTS_EP0)
+        {
+            /* Clear event flag */
+            USBD_CLR_INT_FLAG(USBD_INTSTS_EP0);
+            // control IN
+            EP0in();
+
+            // In ACK for Set address
+            if ((g_usbd_SetupPacket[0] == REQ_STANDARD) && (g_usbd_SetupPacket[1] == USBD_SET_ADDRESS))
+            {
+                if ((USBD_GET_ADDR() != s_usb_addr) && (USBD_GET_ADDR() == 0))
+                {
+                    USBD_SET_ADDR(s_usb_addr);
+                }
+            }
+        }
+        if (u32IntSts & USBD_INTSTS_EP1)
+        {
+            /* Clear event flag */
+            USBD_CLR_INT_FLAG(USBD_INTSTS_EP1);
+
+            // control OUT
+            EP0out();
+        }
+
+        uint32_t gintsts_epx = (u32IntSts >> 18) & 0x3F;
+        uint32_t ep_hw_index = 2;
+        while (gintsts_epx) {
+            if (gintsts_epx & 0x01)
+            {
+                uint32_t ep_status = (USBD_GET_EP_FLAG() >> (ep_hw_index * 3 + 8)) & 0x7;
+                /* Clear event flag */
+                USBD_CLR_INT_FLAG(1 << (ep_hw_index + 16));
+
+                if (ep_status == 0x02 || ep_status == 0x06 || (ep_status == 0x07 && NU_EPH2EPL(ep_hw_index) == 3))  //RX
+                {
+                    if (ep_status == 0x07)
+                        SOF(frame_cnt++);
+                    if ((instance->*(epCallback[ep_hw_index-2]))())
+                    {
+
+                    }
+                    USBD_SET_PAYLOAD_LEN(ep_hw_index,s_ep_mxp[NU_EPH2EPL(ep_hw_index)]);
+                }
+                else if (ep_status == 0x00 || ep_status == 0x07)    //TX
+                {
+                    s_ep_compl &= ~(1 << (NU_EPH2EPL(ep_hw_index)));
+                    if ((instance->*(epCallback[ep_hw_index-2]))())
+                    {
+                    }
+                }
+            }
+
+            gintsts_epx = gintsts_epx >> 1;
+            ep_hw_index++;
+        }
+    }
+}
+#endif
+
--- a/USBDevice/USBHAL_Maxim.cpp	Tue May 03 00:16:32 2016 +0100
+++ b/USBDevice/USBHAL_Maxim.cpp	Fri Apr 28 11:26:51 2017 +0100
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (C) 2015 Maxim Integrated Products, Inc., All Rights Reserved.
+ * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -58,7 +58,7 @@
     ep_buffer_t ep[MXC_USB_NUM_EP - 1];
 } ep_buffer_descriptor_t;
 
-// Static storage for endpoint buffer descriptor table. Must be 512 byte alligned for DMA.
+// Static storage for endpoint buffer descriptor table. Must be 512 byte aligned for DMA.
 #ifdef __IAR_SYSTEMS_ICC__
 #pragma data_alignment = 512
 #else
@@ -66,7 +66,7 @@
 #endif
 ep_buffer_descriptor_t ep_buffer_descriptor;
 
-// static storage for temporary data buffers. Must be 32 byte alligned.
+// static storage for temporary data buffers. Must be 32 byte aligned.
 #ifdef __IAR_SYSTEMS_ICC__
 #pragma data_alignment = 4
 #else
@@ -74,7 +74,7 @@
 #endif
 static uint8_t aligned_buffer[NUMBER_OF_LOGICAL_ENDPOINTS][MXC_USB_MAX_PACKET];
 
-// contorl packet state
+// control packet state
 static enum {
     CTRL_NONE = 0,
     CTRL_SETUP,
@@ -86,15 +86,20 @@
 {
     NVIC_DisableIRQ(USB_IRQn);
 
+#if defined(TARGET_MAX32600)
     // The PLL must be enabled for USB
     MBED_ASSERT(MXC_CLKMAN->clk_config & MXC_F_CLKMAN_CLK_CONFIG_PLL_ENABLE);
 
     // Enable the USB clock
     MXC_CLKMAN->clk_ctrl |= MXC_F_CLKMAN_CLK_CTRL_USB_GATE_N;
+#elif defined(TARGET_MAX32620)
+    // Enable the USB clock
+    MXC_CLKMAN->clk_ctrl |= MXC_F_CLKMAN_CLK_CTRL_USB_CLOCK_ENABLE;
+#endif
 
     // reset the device
     MXC_USB->cn = 0;
-    MXC_USB->cn = 1;
+    MXC_USB->cn = MXC_F_USB_CN_USB_EN;
     MXC_USB->dev_inten = 0;
     MXC_USB->dev_cn = 0;
     MXC_USB->dev_cn = MXC_F_USB_DEV_CN_URST;
@@ -124,6 +129,9 @@
     // set the descriptor location
     MXC_USB->ep_base = (uint32_t)&ep_buffer_descriptor;
 
+    // enable VBUS interrupts
+    MXC_USB->dev_inten = MXC_F_USB_DEV_INTEN_NO_VBUS | MXC_F_USB_DEV_INTEN_VBUS;
+
     // attach IRQ handler and enable interrupts
     instance = this;
     NVIC_SetVector(USB_IRQn, (uint32_t)&_usbisr);
@@ -203,7 +211,11 @@
 
 void USBHAL::EP0setup(uint8_t *buffer)
 {
-    memcpy(buffer, (void*)&MXC_USB->setup0, 8); // setup packet is fixed at 8 bytes
+    // Setup packet is fixed at 8 bytes
+    // Setup registers cannot be read in byte mode
+    uint32_t *ptr32 = (uint32_t*)buffer;
+    ptr32[0] = (uint32_t)MXC_USB->setup0;
+    ptr32[1] = (uint32_t)MXC_USB->setup1;
 }
 
 void USBHAL::EP0read(void)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBHAL_NUC472.cpp	Fri Apr 28 11:26:51 2017 +0100
@@ -0,0 +1,730 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2015-2016 Nuvoton
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#if defined(TARGET_NUMAKER_PFM_NUC472)
+
+#include "USBHAL.h"
+#include "NUC472_442.h"
+#include "pinmap.h"
+
+/**
+ * EP: mbed USBD defined endpoint, e.g. EP0OUT/IN, EP1OUT/IN, EP2OUT/IN.
+ * EPX: BSP defined endpoint, e.g. CEP, EPA, EPB, EPC.
+ */
+
+USBHAL * USBHAL::instance;
+
+static volatile uint32_t s_ep_compl = 0;
+static volatile uint32_t s_ep_buf_ind = 0;
+static volatile uint8_t s_usb_addr = 0;
+static volatile S_USBD_CMD_T s_setup;
+static volatile uint16_t s_ctrlin_packetsize;
+static uint8_t *g_usbd_CtrlInPointer = 0;
+static uint32_t g_usbd_CtrlMaxPktSize = 64;
+static uint32_t g_usbd_ShortPkt = 0;
+static uint32_t gEpRead = 0;
+static uint32_t gEpReadCnt = 0;
+
+void USBD_CtrlInput(void)
+{
+    int volatile i;
+    uint32_t volatile count;
+
+    // Process remained data
+    if (g_usbd_CtrlInSize >= g_usbd_CtrlMaxPktSize)
+    {
+        // Data size > MXPLD
+        for (i=0; i<(g_usbd_CtrlMaxPktSize >> 2); i++, g_usbd_CtrlInPointer+=4)
+            USBD->CEPDAT = *(uint32_t *)g_usbd_CtrlInPointer;
+        USBD_START_CEP_IN(g_usbd_CtrlMaxPktSize);
+        g_usbd_CtrlInSize -= g_usbd_CtrlMaxPktSize;
+    }
+    else
+    {
+        // Data size <= MXPLD
+        for (i=0; i<(g_usbd_CtrlInSize >> 2); i++, g_usbd_CtrlInPointer+=4)
+            USBD->CEPDAT = *(uint32_t *)g_usbd_CtrlInPointer;
+
+        count = g_usbd_CtrlInSize % 4;
+        for (i=0; i<count; i++)
+            USBD->CEPDAT_BYTE = *(uint8_t *)(g_usbd_CtrlInPointer + i);
+
+        USBD_START_CEP_IN(g_usbd_CtrlInSize);
+        g_usbd_CtrlInPointer = 0;
+        g_usbd_CtrlInSize = 0;
+    }
+}
+
+USBHAL::USBHAL(void)
+{
+    SYS_UnlockReg();
+
+    s_ep_buf_ind = 0;
+
+    memset(epCallback, 0x00, sizeof (epCallback));
+    epCallback[0] = &USBHAL::EP1_OUT_callback;
+    epCallback[1] = &USBHAL::EP2_IN_callback;
+    epCallback[2] = &USBHAL::EP3_OUT_callback;
+    epCallback[3] = &USBHAL::EP4_IN_callback;
+    epCallback[4] = &USBHAL::EP5_OUT_callback;
+    epCallback[5] = &USBHAL::EP6_IN_callback;
+    epCallback[6] = &USBHAL::EP7_OUT_callback;
+    epCallback[7] = &USBHAL::EP8_IN_callback;
+    epCallback[8] = &USBHAL::EP9_OUT_callback;
+    epCallback[9] = &USBHAL::EP10_IN_callback;
+    epCallback[10] = &USBHAL::EP11_OUT_callback;
+    epCallback[11] = &USBHAL::EP12_IN_callback;
+
+    instance = this;
+
+    /* Enable USBD module clock */
+    CLK_EnableModuleClock(USBD_MODULE);
+
+    /* Enable USB PHY's LDO33. Run as USB device. */
+    SYS->USBPHY = SYS_USBPHY_USBROLE_OTG_V33_EN | SYS_USBPHY_USBROLE_STD_USBD;
+
+    /* Enable USB PHY and wait for it ready */
+    USBD_ENABLE_PHY();
+    while (1)
+    {
+        USBD->EPAMPS = 0x20;
+        if (USBD->EPAMPS == 0x20)
+            break;
+    }
+
+    /* Force to full-speed */
+    USBD->OPER = 0;//USBD_OPER_HISPDEN_Msk;
+
+    /* Set SE0 (disconnect) */
+    USBD_SET_SE0();
+
+    NVIC_SetVector(USBD_IRQn, (uint32_t) &_usbisr);
+    NVIC_EnableIRQ(USBD_IRQn);
+}
+
+USBHAL::~USBHAL(void)
+{
+    NVIC_DisableIRQ(USBD_IRQn);
+    USBD_SET_SE0();
+    USBD_DISABLE_PHY();
+}
+
+void USBHAL::connect(void)
+{
+    USBD_ResetDMA();
+    USBD_SET_ADDR(0);
+
+    /**
+      * Control Transfer Packet Size Constraints
+      * low-speed: 8
+      * full-speed: 8, 16, 32, 64
+      * high-speed: 64
+      */
+    /* Control endpoint */
+    USBD_SetEpBufAddr(CEP, s_ep_buf_ind, MAX_PACKET_SIZE_EP0);
+    s_ep_buf_ind = MAX_PACKET_SIZE_EP0;
+
+    /* Enable USB/CEP interrupt */
+    USBD_ENABLE_USB_INT(USBD_GINTEN_USBIE_Msk | USBD_GINTEN_CEPIE_Msk);
+    USBD_ENABLE_CEP_INT(USBD_CEPINTEN_SETUPPKIEN_Msk|USBD_CEPINTEN_STSDONEIEN_Msk);
+
+    /* Enable BUS interrupt */
+    USBD_ENABLE_BUS_INT(
+        USBD_BUSINTEN_DMADONEIEN_Msk |
+        USBD_BUSINTEN_RESUMEIEN_Msk |
+        USBD_BUSINTEN_RSTIEN_Msk |
+        USBD_BUSINTEN_VBUSDETIEN_Msk |
+        USBD_BUSINTEN_SOFIEN_Msk
+    );
+
+    /* Clear SE0 (connect) */
+    USBD_CLR_SE0();
+}
+
+void USBHAL::disconnect(void)
+{
+    /* Set SE0 (disconnect) */
+    USBD_SET_SE0();
+}
+
+void USBHAL::configureDevice(void)
+{
+    /**
+     * In USBDevice.cpp > USBDevice::requestSetConfiguration, configureDevice() is called after realiseEndpoint() (in USBCallback_setConfiguration()).
+     * So we have the following USB buffer management policy:
+     *  1. Allocate for CEP on connect().
+     *  2. Allocate for EPX in realiseEndpoint().
+     *  3. Deallocate all except for CEP in unconfigureDevice().
+     */
+}
+
+void USBHAL::unconfigureDevice(void)
+{
+    s_ep_buf_ind = MAX_PACKET_SIZE_EP0;
+}
+
+void USBHAL::setAddress(uint8_t address)
+{
+    // NOTE: Delay address setting; otherwise, USB controller won't ack.
+    s_usb_addr = address;
+}
+
+void USBHAL::remoteWakeup(void)
+{
+    USBD->OPER |= USBD_OPER_RESUMEEN_Msk;
+}
+
+bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t options)
+{
+    uint32_t ep_type;
+    uint32_t ep_hw_index = NU_EP2EPH(endpoint);
+
+    USBD_SetEpBufAddr(ep_hw_index, s_ep_buf_ind, maxPacket);
+    s_ep_buf_ind += maxPacket;
+    USBD_SET_MAX_PAYLOAD(ep_hw_index, maxPacket);
+
+    switch (NU_EP2EPL(endpoint))
+    {
+    case 1:    case 2:
+        ep_type = USB_EP_CFG_TYPE_INT;
+        break;
+
+    case 3:    case 4:
+        ep_type = USB_EP_CFG_TYPE_ISO;
+        break;
+
+    default:
+        ep_type = USB_EP_CFG_TYPE_BULK;
+    }
+    uint32_t ep_dir = (NU_EP_DIR(endpoint) == NU_EP_DIR_IN) ? USB_EP_CFG_DIR_IN : USB_EP_CFG_DIR_OUT;
+    USBD_ConfigEp(ep_hw_index, NU_EP2EPL(endpoint), ep_type, ep_dir);
+
+    /* Enable USB/EPX interrupt */
+    // NOTE: Require USBD_GINTEN_EPAIE_Pos, USBD_GINTEN_EPBIE_Pos, ... USBD_GINTEN_EPLIE_Pos to be consecutive.
+    USBD_ENABLE_USB_INT(USBD->GINTEN | USBD_GINTEN_USBIE_Msk |
+                        USBD_GINTEN_CEPIE_Msk |
+                        1 << (ep_hw_index + USBD_GINTEN_EPAIE_Pos));  // Added USB/EPX interrupt
+
+    if (ep_dir == 0)
+        USBD_ENABLE_EP_INT(ep_hw_index, USBD_EPINTEN_RXPKIEN_Msk);
+    else
+        USBD_ENABLE_EP_INT(ep_hw_index, USBD_EPINTEN_TXPKIEN_Msk);
+    return true;
+}
+
+void USBHAL::EP0setup(uint8_t *buffer)
+{
+    uint32_t sz;
+    endpointReadResult(EP0OUT, buffer, &sz);
+}
+
+void USBHAL::EP0read(void)
+{
+    if (s_setup.wLength && ! (s_setup.bmRequestType & 0x80))
+    {
+        // Control OUT
+        USBD_ENABLE_CEP_INT(USBD_CEPINTEN_SETUPPKIEN_Msk | USBD_CEPINTEN_RXPKIEN_Msk);
+    }
+    else
+    {
+        // Status stage
+        USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_STSDONEIF_Msk);
+        USBD_SET_CEP_STATE(USB_CEPCTL_NAKCLR);
+        USBD_ENABLE_CEP_INT(USBD_CEPINTEN_STSDONEIEN_Msk);
+    }
+}
+
+void USBHAL::EP0readStage(void)
+{
+    // N/A
+}
+
+uint32_t USBHAL::EP0getReadResult(uint8_t *buffer)
+{
+    uint32_t i;
+    uint32_t ceprxcnt = USBD->CEPRXCNT;
+    for (i = 0; i < ceprxcnt; i ++)
+        *buffer ++ = USBD->CEPDAT_BYTE;
+    return ceprxcnt;
+}
+
+void USBHAL::EP0write(uint8_t *buffer, uint32_t size)
+{
+    if (buffer && size)
+    {
+        g_usbd_CtrlInPointer = buffer;
+        g_usbd_CtrlInSize = size;
+        USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_INTKIF_Msk);
+        USBD_ENABLE_CEP_INT(USBD_CEPINTEN_INTKIEN_Msk);
+    }
+    else
+    {
+        /* Status stage */
+        s_ctrlin_packetsize = 0;
+        USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_STSDONEIF_Msk);
+        USBD_SET_CEP_STATE(USB_CEPCTL_NAKCLR);
+        USBD_ENABLE_CEP_INT(USBD_CEPINTEN_STSDONEIEN_Msk);
+    }
+}
+
+void USBHAL::EP0getWriteResult(void)
+{
+    // N/A
+}
+
+void USBHAL::EP0stall(void)
+{
+    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) //spcheng
+{
+    if (endpoint == EP0OUT)
+    {
+        if (buffer) {
+            *((uint16_t *) (buffer + 0)) = (uint16_t) USBD->SETUP1_0;
+            *((uint16_t *) (buffer + 2)) = (uint16_t) USBD->SETUP3_2;
+            *((uint16_t *) (buffer + 4)) = (uint16_t) USBD->SETUP5_4;
+            *((uint16_t *) (buffer + 6)) = (uint16_t) USBD->SETUP7_6;
+        }
+
+        s_setup.bmRequestType = (uint8_t) (USBD->SETUP1_0 & 0xff);
+        s_setup.bRequest = (int8_t) (USBD->SETUP1_0 >> 8) & 0xff;
+        s_setup.wValue = (uint16_t) USBD->SETUP3_2;
+        s_setup.wIndex = (uint16_t) USBD->SETUP5_4;
+        s_setup.wLength = (uint16_t) USBD->SETUP7_6;
+    }
+    else
+    {
+        if (!(s_ep_compl & (1 << NU_EP2EPL(endpoint))))
+        {
+            while (1)
+            {
+                if (!(USBD->DMACTL & USBD_DMACTL_DMAEN_Msk))
+                    break;
+                else
+                    if (!USBD_IS_ATTACHED())
+                        break;
+            }
+            gEpReadCnt = USBD_GET_EP_DATA_COUNT(NU_EP2EPH(endpoint));
+            if (gEpReadCnt == 0)
+            {
+                *bytesRead = 0;
+                return EP_COMPLETED;
+            }
+            s_ep_compl |= (1 << NU_EP2EPL(endpoint));
+            USBD_SET_DMA_LEN(gEpReadCnt);
+            USBD_SET_DMA_ADDR((uint32_t)buffer);
+            USBD_SET_DMA_WRITE(NU_EP2EPL(endpoint));
+            USBD_ENABLE_DMA();
+            return EP_PENDING;;
+
+        }
+        else
+        {
+            if ((USBD->DMACTL & USBD_DMACTL_DMAEN_Msk))
+                return EP_PENDING;;
+
+            USBD_CLR_BUS_INT_FLAG(USBD_BUSINTSTS_DMADONEIF_Msk);
+            s_ep_compl &= ~(1 << NU_EP2EPL(endpoint));
+            *bytesRead = gEpReadCnt;
+        }
+    }
+    return EP_COMPLETED;
+}
+
+
+uint32_t USBHAL::endpointReadcore(uint8_t endpoint, uint8_t *buffer)
+{
+    return 0;
+}
+
+EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size)
+{
+    uint32_t ep_logic_index = NU_EP2EPL(endpoint);
+    if (ep_logic_index == 0)
+        return EP_INVALID;
+    else
+    {
+        uint32_t ep_hw_index = NU_EP2EPH(endpoint);
+        uint32_t mps = USBD_GET_EP_MAX_PAYLOAD(ep_hw_index);
+        if (size > mps) {
+            return EP_INVALID;
+        }
+        if (size < mps)
+            g_usbd_ShortPkt = 1;
+        if (!(s_ep_compl & (1 << NU_EP2EPL(endpoint))))
+        {
+            s_ep_compl |= (1 << ep_logic_index);
+
+            while (1)
+            {
+                if (!(USBD->DMACTL & USBD_DMACTL_DMAEN_Msk))
+                    break;
+                else
+                    if (!USBD_IS_ATTACHED())
+                        break;
+            }
+            USBD_SET_DMA_LEN(size);
+            USBD_SET_DMA_ADDR((uint32_t)data);
+            USBD_SET_DMA_READ(ep_logic_index);
+            USBD_ENABLE_DMA();
+        }
+    }
+    return EP_PENDING;
+}
+
+EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint)
+{
+    if (!(s_ep_compl & (1 << NU_EP2EPL(endpoint))))
+        return EP_COMPLETED;
+    else
+    {
+        if ((USBD_GET_EP_DATA_COUNT(NU_EP2EPH(endpoint))) == 0 && !(USBD->DMACTL & USBD_DMACTL_DMAEN_Msk))
+        {
+            s_ep_compl &= ~(s_ep_compl & (1 << NU_EP2EPL(endpoint)));
+            return EP_COMPLETED;
+        }
+    }
+    return EP_PENDING;
+}
+
+void USBHAL::stallEndpoint(uint8_t endpoint)
+{
+    uint32_t ep_hw_index = NU_EP2EPH(endpoint);
+    if (ep_hw_index >= NUMBER_OF_PHYSICAL_ENDPOINTS)
+        return;
+    USBD_SetStall(ep_hw_index);
+}
+
+void USBHAL::unstallEndpoint(uint8_t endpoint)
+{
+    uint32_t ep_hw_index = NU_EP2EPH(endpoint);
+    if (ep_hw_index >= NUMBER_OF_PHYSICAL_ENDPOINTS)
+        return;
+    USBD_ClearStall(ep_hw_index);
+}
+
+bool USBHAL::getEndpointStallState(uint8_t endpoint)
+{
+    uint32_t ep_hw_index = NU_EP2EPH(endpoint);
+    if (ep_hw_index >= NUMBER_OF_PHYSICAL_ENDPOINTS)
+        return false;
+    return USBD_GetStall(ep_hw_index) ? 1 : 0;
+}
+
+void USBHAL::_usbisr(void)
+{
+    MBED_ASSERT(instance);
+    instance->usbisr();
+}
+
+void USBHAL::usbisr(void)
+{
+    uint32_t gintsts = USBD->GINTSTS & USBD->GINTEN;
+    if (! gintsts)
+        return;
+
+    if (gintsts & USBD_GINTSTS_USBIF_Msk)
+    {
+        uint32_t busintsts = USBD->BUSINTSTS & USBD->BUSINTEN;
+
+        /* SOF */
+        if (busintsts & USBD_BUSINTSTS_SOFIF_Msk)
+        {
+            USBD_CLR_BUS_INT_FLAG(USBD_BUSINTSTS_SOFIF_Msk);
+            // TODO
+            SOF(USBD->FRAMECNT >> 3);
+        }
+
+        /* Reset */
+        if (busintsts & USBD_BUSINTSTS_RSTIF_Msk)
+        {
+            connect();
+            USBD_CLR_BUS_INT_FLAG(USBD_BUSINTSTS_RSTIF_Msk);
+            USBD_CLR_CEP_INT_FLAG(0x1ffc);
+        }
+
+        /* Resume */
+        if (busintsts & USBD_BUSINTSTS_RESUMEIF_Msk)
+        {
+            USBD_ENABLE_BUS_INT(USBD_BUSINTEN_RSTIEN_Msk|USBD_BUSINTEN_SUSPENDIEN_Msk | USBD_BUSINTEN_SOFIEN_Msk | USBD_BUSINTEN_SOFIEN_Msk);
+            USBD_CLR_BUS_INT_FLAG(USBD_BUSINTSTS_RESUMEIF_Msk);
+        }
+
+        /* Suspend */
+        if (busintsts & USBD_BUSINTSTS_SUSPENDIF_Msk)
+        {
+            USBD_ENABLE_BUS_INT(USBD_BUSINTEN_RSTIEN_Msk | USBD_BUSINTEN_RESUMEIEN_Msk |USBD_BUSINTEN_SOFIEN_Msk);
+            USBD_CLR_BUS_INT_FLAG(USBD_BUSINTSTS_SUSPENDIF_Msk);
+        }
+
+        /* High-speed */
+        if (busintsts & USBD_BUSINTSTS_HISPDIF_Msk)
+        {
+            USBD_ENABLE_CEP_INT(USBD_CEPINTEN_SETUPPKIEN_Msk);
+            USBD_CLR_BUS_INT_FLAG(USBD_BUSINTSTS_HISPDIF_Msk);
+        }
+
+        /* DMA */
+        if (busintsts & USBD_BUSINTSTS_DMADONEIF_Msk)
+        {
+            if (USBD->DMACTL & 0x10) /* IN - Read */
+            {
+                if (g_usbd_ShortPkt)
+                {
+                    uint32_t ep_hw_index = NU_EPL2EPH((USBD->DMACTL & 0xF));
+                    USBD_SET_EP_SHORT_PACKET(ep_hw_index);
+                    g_usbd_ShortPkt = 0;
+                }
+            }
+            USBD_CLR_BUS_INT_FLAG(USBD_BUSINTSTS_DMADONEIF_Msk);
+        }
+
+        /* PHY clock available */
+        if (busintsts & USBD_BUSINTSTS_PHYCLKVLDIF_Msk)
+        {
+            USBD_CLR_BUS_INT_FLAG(USBD_BUSINTSTS_PHYCLKVLDIF_Msk);
+        }
+
+        /* VBUS plug-in */
+        if (busintsts & USBD_BUSINTSTS_VBUSDETIF_Msk)
+        {
+            if (USBD_IS_ATTACHED())
+            {
+                // USB plug-in
+                USBD_ENABLE_USB();
+            }
+            else
+            {
+                // USB unplug-out
+                USBD_DISABLE_USB();
+            }
+            USBD_CLR_BUS_INT_FLAG(USBD_BUSINTSTS_VBUSDETIF_Msk);
+        }
+    }
+
+    /* CEP interrupts */
+    if (gintsts & USBD_GINTSTS_CEPIF_Msk)
+    {
+        uint32_t cepintsts =  USBD->CEPINTSTS & USBD->CEPINTEN;
+
+        /* SETUP token packet */
+        if (cepintsts & USBD_CEPINTSTS_SETUPTKIF_Msk)
+        {
+            USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_SETUPTKIF_Msk);
+            return;
+        }
+
+        /* SETUP transaction */
+        if (cepintsts & USBD_CEPINTSTS_SETUPPKIF_Msk)
+        {
+            USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_SETUPPKIF_Msk);
+            EP0setupCallback();
+            return;
+        }
+
+        /* OUT token packet */
+        if (cepintsts & USBD_CEPINTSTS_OUTTKIF_Msk)
+        {
+            USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_OUTTKIF_Msk);
+            USBD_ENABLE_CEP_INT(USBD_CEPINTEN_STSDONEIEN_Msk);
+            return;
+        }
+
+        /* IN token packet */
+        if (cepintsts & USBD_CEPINTSTS_INTKIF_Msk)
+        {
+            USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_INTKIF_Msk);
+            if (!(cepintsts & USBD_CEPINTSTS_STSDONEIF_Msk))
+            {
+                USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_TXPKIF_Msk);
+                USBD_ENABLE_CEP_INT(USBD_CEPINTEN_TXPKIEN_Msk);
+                USBD_CtrlInput();
+            }
+            else
+            {
+                USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_TXPKIF_Msk);
+                USBD_ENABLE_CEP_INT(USBD_CEPINTEN_TXPKIEN_Msk|USBD_CEPINTEN_STSDONEIEN_Msk);
+            }
+            return;
+        }
+
+        /* PING packet */
+        if (cepintsts & USBD_CEPINTSTS_PINGIF_Msk)
+        {
+            USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_PINGIF_Msk);
+            return;
+        }
+
+        /* IN transaction */
+        if (cepintsts & USBD_CEPINTSTS_TXPKIF_Msk)
+        {
+            EP0in();
+            USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_TXPKIF_Msk);
+            return;
+        }
+
+        /* OUT transaction */
+        if (cepintsts & USBD_CEPINTSTS_RXPKIF_Msk)
+        {
+            EP0out();
+            USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_RXPKIF_Msk);
+            return;
+        }
+
+        /* NAK handshake packet */
+        if (cepintsts & USBD_CEPINTSTS_NAKIF_Msk)
+        {
+            USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_NAKIF_Msk);
+            return;
+        }
+
+        /* STALL handshake packet */
+        if (cepintsts & USBD_CEPINTSTS_STALLIF_Msk)
+        {
+            USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_STALLIF_Msk);
+            return;
+        }
+
+        /* ERR special packet */
+        if (cepintsts & USBD_CEPINTSTS_ERRIF_Msk)
+        {
+            USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_ERRIF_Msk);
+            return;
+        }
+
+        /* Status stage transaction */
+        if (cepintsts & USBD_CEPINTSTS_STSDONEIF_Msk)
+        {
+            if (s_usb_addr)
+            {
+                USBD_SET_ADDR(s_usb_addr);
+                s_usb_addr = 0;
+            }
+            USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_STSDONEIF_Msk);
+            USBD_ENABLE_CEP_INT(USBD_CEPINTEN_SETUPPKIEN_Msk);
+            return;
+        }
+
+        /* Buffer Full */
+        if (cepintsts & USBD_CEPINTSTS_BUFFULLIF_Msk)
+        {
+            USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_BUFFULLIF_Msk);
+            return;
+        }
+
+        /* Buffer Empty */
+        if (cepintsts & USBD_CEPINTSTS_BUFEMPTYIF_Msk)
+        {
+            USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_BUFEMPTYIF_Msk);
+            return;
+        }
+    }
+    /* EPA, EPB, EPC, ... EPL interrupts */
+    uint32_t gintsts_epx = gintsts >> 2;
+    uint32_t ep_hw_index = 0;
+    while (gintsts_epx) {
+        if (gintsts_epx & 0x01)
+        {
+            uint32_t epxintsts = USBD_GET_EP_INT_FLAG(ep_hw_index) & USBD_GET_EP_INT_EN(ep_hw_index);
+
+            USBD_CLR_EP_INT_FLAG(ep_hw_index, epxintsts);
+
+            /* Buffer Full */
+            if (epxintsts & USBD_EPINTSTS_BUFFULLIF_Msk)
+            {
+            }
+
+            /* Buffer Empty */
+            if (epxintsts & USBD_EPINTSTS_BUFEMPTYIF_Msk)
+            {
+            }
+
+            /* Short Packet Transferred */
+            if (epxintsts & USBD_EPINTSTS_SHORTTXIF_Msk)
+            {
+            }
+
+            /* Data Packet Transmitted */
+            if (epxintsts & USBD_EPINTSTS_TXPKIF_Msk)
+            {
+                s_ep_compl &= ~(1 << (NU_EPH2EPL(ep_hw_index)));
+                if ((instance->*(epCallback[ep_hw_index]))())
+                {
+                }
+            }
+
+            /* Data Packet Received */
+            if (epxintsts & USBD_EPINTSTS_RXPKIF_Msk)
+            {
+                if ((instance->*(epCallback[ep_hw_index]))())
+                {
+
+                }
+            }
+
+            /* OUT token packet */
+            if (epxintsts & USBD_EPINTSTS_OUTTKIF_Msk)
+            {
+            }
+
+            /* IN token packet */
+            if (epxintsts & USBD_EPINTSTS_INTKIF_Msk)
+            {
+            }
+
+            /* PING packet */
+            if (epxintsts & USBD_EPINTSTS_PINGIF_Msk)
+            {
+            }
+
+            /* NAK handshake packet sent to Host */
+            if (epxintsts & USBD_EPINTSTS_NAKIF_Msk)
+            {
+            }
+
+            /* STALL handshake packet sent to Host */
+            if (epxintsts & USBD_EPINTSTS_STALLIF_Msk)
+            {
+            }
+
+            /* NYET handshake packet sent to Host */
+            if (epxintsts & USBD_EPINTSTS_NYETIF_Msk)
+            {
+            }
+
+            /* ERR packet sent to Host */
+            if (epxintsts & USBD_EPINTSTS_ERRIF_Msk)
+            {
+            }
+
+            /* Bulk Out Short Packet Received */
+            if (epxintsts & USBD_EPINTSTS_SHORTRXIF_Msk)
+            {
+            }
+        }
+        gintsts_epx = gintsts_epx >> 1;
+        ep_hw_index++;
+    }
+}
+#endif
+
--- a/USBDevice/USBHAL_STM32F4.cpp	Tue May 03 00:16:32 2016 +0100
+++ b/USBDevice/USBHAL_STM32F4.cpp	Fri Apr 28 11:26:51 2017 +0100
@@ -16,7 +16,7 @@
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
 
-#if defined(TARGET_STM32F4)
+#if defined(TARGET_STM32F4) && !defined(USB_STM_HAL)
 
 #include "USBHAL.h"
 #include "USBRegs_STM32.h"
@@ -48,7 +48,7 @@
     // Enable power and clocking
     RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
 
-#if defined(TARGET_STM32F407VG) || defined(TARGET_STM32F401RE) || defined(TARGET_STM32F411RE) || defined(TARGET_STM32F429ZI)
+#if defined(TARGET_STM32F407VG) || defined(TARGET_STM32F401RE) || defined(TARGET_STM32F411RE) || defined(TARGET_STM32F412ZG) || defined(TARGET_STM32F429ZI)
     pin_function(PA_8, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF10_OTG_FS));
     pin_function(PA_9, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLDOWN, GPIO_AF10_OTG_FS));
     pin_function(PA_10, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_PULLUP, GPIO_AF10_OTG_FS));
@@ -367,7 +367,7 @@
             else {
                 epComplete |= (1 << endpoint);
                 if ((instance->*(epCallback[endpoint - 2]))()) {
-                    epComplete &= (1 << endpoint);
+                    epComplete &= ~(1 << endpoint);
                 }
             }
         }
--- a/USBHID/USBHID.cpp	Tue May 03 00:16:32 2016 +0100
+++ b/USBHID/USBHID.cpp	Fri Apr 28 11:26:51 2017 +0100
@@ -1,276 +1,279 @@
-/* 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 "USBHAL.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, bool connect): USBDevice(vendor_id, product_id, product_release)
-{
-    output_length = output_report_length;
-    input_length = input_report_length;
-    if(connect) {
-        USBDevice::connect();
-    }
-}
-
-
-bool USBHID::send(HID_REPORT *report)
-{
-    return write(EPINT_IN, report->data, report->length, MAX_HID_REPORT_SIZE);
-}
-
-bool USBHID::sendNB(HID_REPORT *report)
-{
-    return writeNB(EPINT_IN, report->data, report->length, MAX_HID_REPORT_SIZE);
-}
-
-
-bool USBHID::read(HID_REPORT *report)
-{
-    uint32_t bytesRead = 0;
-    bool result;
-    result = USBDevice::readEP(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)
-{
-    uint32_t bytesRead = 0;
-    bool result;
-    result = USBDevice::readEP_NB(EPINT_OUT, report->data, &bytesRead, MAX_HID_REPORT_SIZE);
-    // if readEP_NB did not succeed, does not issue a readStart
-    if (!result)
-        return false;
-    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;
-}
-
-
-#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
-        (uint8_t)(LSB(this->reportDescLength())),  // wDescriptorLength (LSB)
-        (uint8_t)(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)
-        1,                             // 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)
-        1,                             // bInterval (milliseconds)
-    };
-    return configurationDescriptor;
-}
+/* 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 "USBHAL.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, bool connect): USBDevice(vendor_id, product_id, product_release)
+{
+    output_length = output_report_length;
+    input_length = input_report_length;
+    if(connect) {
+        USBDevice::connect();
+    }
+}
+
+
+bool USBHID::send(HID_REPORT *report)
+{
+    return write(EPINT_IN, report->data, report->length, MAX_HID_REPORT_SIZE);
+}
+
+bool USBHID::sendNB(HID_REPORT *report)
+{
+    return writeNB(EPINT_IN, report->data, report->length, MAX_HID_REPORT_SIZE);
+}
+
+
+bool USBHID::read(HID_REPORT *report)
+{
+    uint32_t bytesRead = 0;
+    bool result;
+    result = USBDevice::readEP(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)
+{
+    uint32_t bytesRead = 0;
+    bool result;
+    result = USBDevice::readEP_NB(EPINT_OUT, report->data, &bytesRead, MAX_HID_REPORT_SIZE);
+    // if readEP_NB did not succeed, does not issue a readStart
+    if (!result)
+        return false;
+    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;
+}
+
+
+#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[] = {
+        USAGE_PAGE(2), LSB(0xFFAB), MSB(0xFFAB),
+        USAGE(2), LSB(0x0200), MSB(0x0200),
+        COLLECTION(1), 0x01, // Collection (Application)
+
+        REPORT_SIZE(1), 0x08, // 8 bits
+        LOGICAL_MINIMUM(1), 0x00,
+        LOGICAL_MAXIMUM(1), 0xFF,
+
+        REPORT_COUNT(1), input_length,
+        USAGE(1), 0x01,
+        INPUT(1), 0x02, // Data, Var, Abs
+
+        REPORT_COUNT(1), output_length,
+        USAGE(1), 0x02,
+        OUTPUT(1), 0x02, // Data, Var, Abs
+
+        END_COLLECTION(0),
+    };
+    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
+        (uint8_t)(LSB(reportDescLength())), // wDescriptorLength (LSB)
+        (uint8_t)(MSB(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)
+        1,                                  // 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)
+        1,                                  // bInterval (milliseconds)
+    };
+    return configurationDescriptor;
+}
--- a/USBHID/USBHID.h	Tue May 03 00:16:32 2016 +0100
+++ b/USBHID/USBHID.h	Fri Apr 28 11:26:51 2017 +0100
@@ -1,172 +1,172 @@
-/* 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
-    * @param connect Connect the device
-    */
-    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, bool connect = true);
-
-
-    /**
-    * Send a Report. warning: blocking
-    *
-    * @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);
-
-
-    /**
-    * Send a Report. warning: non blocking
-    *
-    * @param report Report which will be sent (a report is defined by all data and the length)
-    * @returns true if successful
-    */
-    bool sendNB(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 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
+/* 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
+    * @param connect Connect the device
+    */
+    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, bool connect = true);
+
+
+    /**
+    * Send a Report. warning: blocking
+    *
+    * @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);
+
+
+    /**
+    * Send a Report. warning: non blocking
+    *
+    * @param report Report which will be sent (a report is defined by all data and the length)
+    * @returns true if successful
+    */
+    bool sendNB(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 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
--- a/USBHID/USBHID_Types.h	Tue May 03 00:16:32 2016 +0100
+++ b/USBHID/USBHID_Types.h	Fri Apr 28 11:26:51 2017 +0100
@@ -1,91 +1,94 @@
-/* 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
+/* 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_SUBCLASS_BOOT     (1)
+#define HID_PROTOCOL_NONE     (0)
+#define HID_PROTOCOL_KEYBOARD (1)
+#define HID_PROTOCOL_MOUSE    (2)
+
+/* 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
--- a/USBHID/USBKeyboard.cpp	Tue May 03 00:16:32 2016 +0100
+++ b/USBHID/USBKeyboard.cpp	Fri Apr 28 11:26:51 2017 +0100
@@ -1,553 +1,553 @@
-/* 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 (152)
-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 */
-
-    {0x4f, 0},          /* RIGHT_ARROW */
-    {0x50, 0},          /* LEFT_ARROW */
-    {0x51, 0},          /* DOWN_ARROW */
-    {0x52, 0},          /* UP_ARROW */
-};
-
-#else
-/* UK keyboard */
-#define KEYMAP_SIZE (152)
-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 */
-
-    {0x4f, 0},          /* RIGHT_ARROW */
-    {0x50, 0},          /* LEFT_ARROW */
-    {0x51, 0},          /* DOWN_ARROW */
-    {0x52, 0},          /* UP_ARROW */
-};
-#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::EPINT_OUT_callback() {
-    uint32_t bytesRead = 0;
-    uint8_t led[65];
-    USBDevice::readEP(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);
-}
-
-
-#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 * USBKeyboard::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),                     // bMaxPowerHello World from Mbed
-
-        INTERFACE_DESCRIPTOR_LENGTH,    // bLength
-        INTERFACE_DESCRIPTOR,           // bDescriptorType
-        0x00,                           // bInterfaceNumber
-        0x00,                           // bAlternateSetting
-        0x02,                           // bNumEndpoints
-        HID_CLASS,                      // bInterfaceClass
-        1,                              // bInterfaceSubClass
-        1,                              // bInterfaceProtocol (keyboard)
-        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
-        (uint8_t)(LSB(reportDescLength())),  // wDescriptorLength (LSB)
-        (uint8_t)(MSB(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)
-        1,                             // 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)
-        1,                             // bInterval (milliseconds)
-    };
-    return configurationDescriptor;
-}
+/* 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 (152)
+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 */
+
+    {0x4f, 0},          /* RIGHT_ARROW */
+    {0x50, 0},          /* LEFT_ARROW */
+    {0x51, 0},          /* DOWN_ARROW */
+    {0x52, 0},          /* UP_ARROW */
+};
+
+#else
+/* UK keyboard */
+#define KEYMAP_SIZE (152)
+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 */
+
+    {0x4f, 0},          /* RIGHT_ARROW */
+    {0x50, 0},          /* LEFT_ARROW */
+    {0x51, 0},          /* DOWN_ARROW */
+    {0x52, 0},          /* UP_ARROW */
+};
+#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::EPINT_OUT_callback() {
+    uint32_t bytesRead = 0;
+    uint8_t led[65];
+    USBDevice::readEP(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);
+}
+
+
+#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 * USBKeyboard::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_BOOT,                  // bInterfaceSubClass
+        HID_PROTOCOL_KEYBOARD,              // 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
+        (uint8_t)(LSB(reportDescLength())), // wDescriptorLength (LSB)
+        (uint8_t)(MSB(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)
+        1,                                  // 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)
+        1,                                  // bInterval (milliseconds)
+    };
+    return configurationDescriptor;
+}
--- a/USBHID/USBMouse.cpp	Tue May 03 00:16:32 2016 +0100
+++ b/USBHID/USBMouse.cpp	Fri Apr 28 11:26:51 2017 +0100
@@ -1,245 +1,244 @@
-/* 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;
-}
-
-#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 * USBMouse::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),                     // bMaxPowerHello World from Mbed
-
-        INTERFACE_DESCRIPTOR_LENGTH,    // bLength
-        INTERFACE_DESCRIPTOR,           // bDescriptorType
-        0x00,                           // bInterfaceNumber
-        0x00,                           // bAlternateSetting
-        0x02,                           // bNumEndpoints
-        HID_CLASS,                      // bInterfaceClass
-        1,                              // bInterfaceSubClass
-        2,                              // bInterfaceProtocol (mouse)
-        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
-        (uint8_t)(LSB(reportDescLength())),        // wDescriptorLength (LSB)
-        (uint8_t)(MSB(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)
-        1,                              // 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)
-        1,                              // bInterval (milliseconds)
-    };
-    return configurationDescriptor;
-}
+/* 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;
+}
+
+#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 * USBMouse::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_BOOT,                  // bInterfaceSubClass
+        HID_PROTOCOL_MOUSE,                 // 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
+        (uint8_t)(LSB(reportDescLength())), // wDescriptorLength (LSB)
+        (uint8_t)(MSB(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)
+        1,                                  // 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)
+        1,                                  // bInterval (milliseconds)
+    };
+    return configurationDescriptor;
+}
--- a/USBHID/USBMouse.h	Tue May 03 00:16:32 2016 +0100
+++ b/USBHID/USBMouse.h	Fri Apr 28 11:26:51 2017 +0100
@@ -1,209 +1,209 @@
-/* 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, false)
-            {
-                button = 0;
-                this->mouse_type = mouse_type;
-                connect();
-            };
-
-        /**
-        * 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();
-
-    protected:
-        /*
-        * Get configuration descriptor
-        *
-        * @returns pointer to the configuration descriptor
-        */
-        virtual uint8_t * configurationDesc();
-
-    private:
-        MOUSE_TYPE mouse_type;
-        uint8_t button;
-        bool mouseSend(int8_t x, int8_t y, uint8_t buttons, int8_t z);
-};
-
-#endif
+/* 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, false)
+            {
+                button = 0;
+                this->mouse_type = mouse_type;
+                connect();
+            };
+
+        /**
+        * 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();
+
+    protected:
+        /*
+        * Get configuration descriptor
+        *
+        * @returns pointer to the configuration descriptor
+        */
+        virtual uint8_t * configurationDesc();
+
+    private:
+        MOUSE_TYPE mouse_type;
+        uint8_t button;
+        bool mouseSend(int8_t x, int8_t y, uint8_t buttons, int8_t z);
+};
+
+#endif
--- a/USBHID/USBMouseKeyboard.cpp	Tue May 03 00:16:32 2016 +0100
+++ b/USBHID/USBMouseKeyboard.cpp	Fri Apr 28 11:26:51 2017 +0100
@@ -1,706 +1,706 @@
-/* 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 (152)
-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 */
-
-    {0x4f, 0},          /* RIGHT_ARROW */
-    {0x50, 0},          /* LEFT_ARROW */
-    {0x51, 0},          /* DOWN_ARROW */
-    {0x52, 0},          /* UP_ARROW */
-};
-
-#else
-/* UK keyboard */
-#define KEYMAP_SIZE (152)
-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 */
-
-    {0x4f, 0},          /* RIGHT_ARROW */
-    {0x50, 0},          /* LEFT_ARROW */
-    {0x51, 0},          /* DOWN_ARROW */
-    {0x52, 0},          /* UP_ARROW */
-};
-#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::EPINT_OUT_callback() {
-    uint32_t bytesRead = 0;
-    uint8_t led[65];
-    USBDevice::readEP(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);
-}
+/* 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 (152)
+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 */
+
+    {0x4f, 0},          /* RIGHT_ARROW */
+    {0x50, 0},          /* LEFT_ARROW */
+    {0x51, 0},          /* DOWN_ARROW */
+    {0x52, 0},          /* UP_ARROW */
+};
+
+#else
+/* UK keyboard */
+#define KEYMAP_SIZE (152)
+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 */
+
+    {0x4f, 0},          /* RIGHT_ARROW */
+    {0x50, 0},          /* LEFT_ARROW */
+    {0x51, 0},          /* DOWN_ARROW */
+    {0x52, 0},          /* UP_ARROW */
+};
+#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::EPINT_OUT_callback() {
+    uint32_t bytesRead = 0;
+    uint8_t led[65];
+    USBDevice::readEP(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);
+}
--- a/USBMIDI/MIDIMessage.h	Tue May 03 00:16:32 2016 +0100
+++ b/USBMIDI/MIDIMessage.h	Fri Apr 28 11:26:51 2017 +0100
@@ -1,276 +1,276 @@
-/* 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"
-
-#define MAX_MIDI_MESSAGE_SIZE 256 // Max message size. SysEx can be up to 65536 but 256 should be fine for most usage
-
-// 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() : length(4) {}
-
-    MIDIMessage(uint8_t *buf) : length(4) {
-        for (int i = 0; i < 4; i++)
-            data[i] = buf[i];
-    }
-
-    // New constructor, buf is a true MIDI message (not USBMidi message) and buf_len true message length.
-    MIDIMessage(uint8_t *buf, int buf_len) {
-        length=buf_len+1;
-        // first byte keeped for retro-compatibility
-        data[0]=0;
-
-        for (int i = 0; i < buf_len; i++)
-            data[i+1] = buf[i];
-    }
-
-    // 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);
-    }
-
-     /** Create a SysEx message
-     * @param data SysEx data (including 0xF0 .. 0xF7)
-     * @param len SysEx data length
-     * @returns A MIDIMessage
-     */
-    static MIDIMessage SysEx(uint8_t *data, int len) {
-        MIDIMessage msg=MIDIMessage(data,len);
-        return msg;
-    }
-
-    // decode messages
-
-    /** MIDI Message Types */
-    enum MIDIMessageType {
-        ErrorType,
-        NoteOffType,
-        NoteOnType,
-        PolyphonicAftertouchType,
-        ControlChangeType,
-        ProgramChangeType,
-        ChannelAftertouchType,
-        PitchWheelType,
-        AllNotesOffType,
-        SysExType
-    };
-
-    /** 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;
-            case 0xF: return SysExType;
-            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[MAX_MIDI_MESSAGE_SIZE+1];
-    uint8_t length;
-};
-
-#endif
+/* 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"
+
+#define MAX_MIDI_MESSAGE_SIZE 256 // Max message size. SysEx can be up to 65536 but 256 should be fine for most usage
+
+// 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() : length(4) {}
+
+    MIDIMessage(uint8_t *buf) : length(4) {
+        for (int i = 0; i < 4; i++)
+            data[i] = buf[i];
+    }
+
+    // New constructor, buf is a true MIDI message (not USBMidi message) and buf_len true message length.
+    MIDIMessage(uint8_t *buf, int buf_len) {
+        length=buf_len+1;
+        // first byte keeped for retro-compatibility
+        data[0]=0;
+
+        for (int i = 0; i < buf_len; i++)
+            data[i+1] = buf[i];
+    }
+
+    // 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);
+    }
+
+     /** Create a SysEx message
+     * @param data SysEx data (including 0xF0 .. 0xF7)
+     * @param len SysEx data length
+     * @returns A MIDIMessage
+     */
+    static MIDIMessage SysEx(uint8_t *data, int len) {
+        MIDIMessage msg=MIDIMessage(data,len);
+        return msg;
+    }
+
+    // decode messages
+
+    /** MIDI Message Types */
+    enum MIDIMessageType {
+        ErrorType,
+        NoteOffType,
+        NoteOnType,
+        PolyphonicAftertouchType,
+        ControlChangeType,
+        ProgramChangeType,
+        ChannelAftertouchType,
+        PitchWheelType,
+        AllNotesOffType,
+        SysExType
+    };
+
+    /** 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;
+            case 0xF: return SysExType;
+            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[MAX_MIDI_MESSAGE_SIZE+1];
+    uint8_t length;
+};
+
+#endif
--- a/USBMIDI/USBMIDI.cpp	Tue May 03 00:16:32 2016 +0100
+++ b/USBMIDI/USBMIDI.cpp	Fri Apr 28 11:26:51 2017 +0100
@@ -1,207 +1,207 @@
-/* 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"
-
-
-USBMIDI::USBMIDI(uint16_t vendor_id, uint16_t product_id, uint16_t product_release)
- : USBDevice(vendor_id, product_id, product_release), cur_data(0), data_end(true)
-{
-    midi_evt = NULL;
-    USBDevice::connect();
-}
-
-// write plain MIDIMessage that will be converted to USBMidi event packet
-void USBMIDI::write(MIDIMessage m) {
-    // first byte keeped for retro-compatibility
-    for(int p=1; p < m.length; p+=3) {
-        uint8_t buf[4];
-        // Midi message to USBMidi event packet
-        buf[0]=m.data[1] >> 4;
-        // SysEx
-        if(buf[0] == 0xF) {
-            if((m.length - p) > 3) {
-                // SysEx start or continue
-                buf[0]=0x4;
-            } else {
-                switch(m.length - p) {
-                    case 1:
-                        // SysEx end with one byte
-                        buf[0]=0x5;
-                        break;
-                    case 2:
-                        // SysEx end with two bytes
-                        buf[0]=0x6;
-                        break;
-                    case 3:
-                        // SysEx end with three bytes
-                        buf[0]=0x7;
-                        break;
-                }
-            }
-        }
-        buf[1]=m.data[p];
-
-        if(p+1 < m.length)
-            buf[2]=m.data[p+1];
-        else
-            buf[2]=0;
-
-        if(p+2 < m.length)
-            buf[3]=m.data[p+2];
-        else
-            buf[3]=0;
-
-        USBDevice::write(EPBULK_IN, buf, 4, MAX_PACKET_SIZE_EPBULK);
-    }
-}
-
-
-void USBMIDI::attach(void (*fptr)(MIDIMessage)) {
-    midi_evt = fptr;
-}
-
-bool USBMIDI::EPBULK_OUT_callback() {
-    uint8_t buf[64];
-    uint32_t len;
-    readEP(EPBULK_OUT, buf, &len, 64);
-
-    if (midi_evt != NULL) {
-        for (uint32_t i=0; i<len; i+=4) {   
-            uint8_t data_read;
-            data_end=true;
-            switch(buf[i]) {
-            case 0x2:
-                // Two-bytes System Common Message - undefined in USBMidi 1.0
-                data_read=2;
-                break;
-            case 0x4:
-                // SysEx start or continue
-                data_end=false;
-                data_read=3;
-                break;
-            case 0x5:
-                 // Single-byte System Common Message or SysEx end with one byte
-                data_read=1;
-                break;
-            case 0x6:
-                // SysEx end with two bytes
-                data_read=2;
-                break;
-            case 0xC:
-                // Program change
-                data_read=2;
-                break;
-            case 0xD:
-                // Channel pressure
-                data_read=2;
-                break;      
-            case 0xF:
-                // Single byte
-                data_read=1;
-                break;    
-            default:
-                // Others three-bytes messages
-                data_read=3;
-                break;      
-            } 
-        
-            for(uint8_t j=1;j<data_read+1;j++) {
-                data[cur_data]=buf[i+j];
-                cur_data++;
-            }
-        
-            if(data_end) {
-                 midi_evt(MIDIMessage(data,cur_data));
-                 cur_data=0;            
-            }
-       }
-    }
-
-    // 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;
-}
+/* 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"
+
+
+USBMIDI::USBMIDI(uint16_t vendor_id, uint16_t product_id, uint16_t product_release)
+ : USBDevice(vendor_id, product_id, product_release), cur_data(0), data_end(true)
+{
+    midi_evt = NULL;
+    USBDevice::connect();
+}
+
+// write plain MIDIMessage that will be converted to USBMidi event packet
+void USBMIDI::write(MIDIMessage m) {
+    // first byte keeped for retro-compatibility
+    for(int p=1; p < m.length; p+=3) {
+        uint8_t buf[4];
+        // Midi message to USBMidi event packet
+        buf[0]=m.data[1] >> 4;
+        // SysEx
+        if(buf[0] == 0xF) {
+            if((m.length - p) > 3) {
+                // SysEx start or continue
+                buf[0]=0x4;
+            } else {
+                switch(m.length - p) {
+                    case 1:
+                        // SysEx end with one byte
+                        buf[0]=0x5;
+                        break;
+                    case 2:
+                        // SysEx end with two bytes
+                        buf[0]=0x6;
+                        break;
+                    case 3:
+                        // SysEx end with three bytes
+                        buf[0]=0x7;
+                        break;
+                }
+            }
+        }
+        buf[1]=m.data[p];
+
+        if(p+1 < m.length)
+            buf[2]=m.data[p+1];
+        else
+            buf[2]=0;
+
+        if(p+2 < m.length)
+            buf[3]=m.data[p+2];
+        else
+            buf[3]=0;
+
+        USBDevice::write(EPBULK_IN, buf, 4, MAX_PACKET_SIZE_EPBULK);
+    }
+}
+
+
+void USBMIDI::attach(void (*fptr)(MIDIMessage)) {
+    midi_evt = fptr;
+}
+
+bool USBMIDI::EPBULK_OUT_callback() {
+    uint8_t buf[64];
+    uint32_t len;
+    readEP(EPBULK_OUT, buf, &len, 64);
+
+    if (midi_evt != NULL) {
+        for (uint32_t i=0; i<len; i+=4) {   
+            uint8_t data_read;
+            data_end=true;
+            switch(buf[i]) {
+            case 0x2:
+                // Two-bytes System Common Message - undefined in USBMidi 1.0
+                data_read=2;
+                break;
+            case 0x4:
+                // SysEx start or continue
+                data_end=false;
+                data_read=3;
+                break;
+            case 0x5:
+                 // Single-byte System Common Message or SysEx end with one byte
+                data_read=1;
+                break;
+            case 0x6:
+                // SysEx end with two bytes
+                data_read=2;
+                break;
+            case 0xC:
+                // Program change
+                data_read=2;
+                break;
+            case 0xD:
+                // Channel pressure
+                data_read=2;
+                break;      
+            case 0xF:
+                // Single byte
+                data_read=1;
+                break;    
+            default:
+                // Others three-bytes messages
+                data_read=3;
+                break;      
+            } 
+        
+            for(uint8_t j=1;j<data_read+1;j++) {
+                data[cur_data]=buf[i+j];
+                cur_data++;
+            }
+        
+            if(data_end) {
+                 midi_evt(MIDIMessage(data,cur_data));
+                 cur_data=0;            
+            }
+       }
+    }
+
+    // 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;
+}
--- a/USBMSD/USBMSD.cpp	Tue May 03 00:16:32 2016 +0100
+++ b/USBMSD/USBMSD.cpp	Fri Apr 28 11:26:51 2017 +0100
@@ -1,655 +1,655 @@
-/* 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 "USBMSD.h"
-
-#define DISK_OK         0x00
-#define NO_INIT         0x01
-#define NO_DISK         0x02
-#define WRITE_PROTECT   0x04
-
-#define CBW_Signature   0x43425355
-#define CSW_Signature   0x53425355
-
-// SCSI Commands
-#define TEST_UNIT_READY            0x00
-#define REQUEST_SENSE              0x03
-#define FORMAT_UNIT                0x04
-#define INQUIRY                    0x12
-#define MODE_SELECT6               0x15
-#define MODE_SENSE6                0x1A
-#define START_STOP_UNIT            0x1B
-#define MEDIA_REMOVAL              0x1E
-#define READ_FORMAT_CAPACITIES     0x23
-#define READ_CAPACITY              0x25
-#define READ10                     0x28
-#define WRITE10                    0x2A
-#define VERIFY10                   0x2F
-#define READ12                     0xA8
-#define WRITE12                    0xAA
-#define MODE_SELECT10              0x55
-#define MODE_SENSE10               0x5A
-
-// MSC class specific requests
-#define MSC_REQUEST_RESET          0xFF
-#define MSC_REQUEST_GET_MAX_LUN    0xFE
-
-#define DEFAULT_CONFIGURATION (1)
-
-// max packet size
-#define MAX_PACKET  MAX_PACKET_SIZE_EPBULK
-
-// CSW Status
-enum Status {
-    CSW_PASSED,
-    CSW_FAILED,
-    CSW_ERROR,
-};
-
-
-USBMSD::USBMSD(uint16_t vendor_id, uint16_t product_id, uint16_t product_release): USBDevice(vendor_id, product_id, product_release) {
-    stage = READ_CBW;
-    memset((void *)&cbw, 0, sizeof(CBW));
-    memset((void *)&csw, 0, sizeof(CSW));
-    page = NULL;
-}
-
-USBMSD::~USBMSD() {
-    disconnect();
-}
-
-
-// Called in ISR context to process a class specific request
-bool USBMSD::USBCallback_request(void) {
-
-    bool success = false;
-    CONTROL_TRANSFER * transfer = getTransferPtr();
-    static uint8_t maxLUN[1] = {0};
-
-    if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
-        switch (transfer->setup.bRequest) {
-            case MSC_REQUEST_RESET:
-                reset();
-                success = true;
-                break;
-            case MSC_REQUEST_GET_MAX_LUN:
-                transfer->remaining = 1;
-                transfer->ptr = maxLUN;
-                transfer->direction = DEVICE_TO_HOST;
-                success = true;
-                break;
-            default:
-                break;
-        }
-    }
-
-    return success;
-}
-
-
-bool USBMSD::connect(bool blocking) {
-    //disk initialization
-    if (disk_status() & NO_INIT) {
-        if (disk_initialize()) {
-            return false;
-        }
-    }
-
-    // get number of blocks
-    BlockCount = disk_sectors();
-
-    // get memory size
-    MemorySize = disk_size();
-
-    if (BlockCount > 0) {
-        BlockSize = MemorySize / BlockCount;
-        if (BlockSize != 0) {
-            free(page);
-            page = (uint8_t *)malloc(BlockSize * sizeof(uint8_t));
-            if (page == NULL)
-                return false;
-        }
-    } else {
-        return false;
-    }
-
-    //connect the device
-    USBDevice::connect(blocking);
-    return true;
-}
-
-void USBMSD::disconnect() {
-    USBDevice::disconnect();
-    //De-allocate MSD page size:
-    free(page);
-    page = NULL;
-}
-
-void USBMSD::reset() {
-    stage = READ_CBW;
-}
-
-
-// Called in ISR context called when a data is received
-bool USBMSD::EPBULK_OUT_callback() {
-    uint32_t size = 0;
-    uint8_t buf[MAX_PACKET_SIZE_EPBULK];
-    readEP(EPBULK_OUT, buf, &size, MAX_PACKET_SIZE_EPBULK);
-    switch (stage) {
-            // the device has to decode the CBW received
-        case READ_CBW:
-            CBWDecode(buf, size);
-            break;
-
-            // the device has to receive data from the host
-        case PROCESS_CBW:
-            switch (cbw.CB[0]) {
-                case WRITE10:
-                case WRITE12:
-                    memoryWrite(buf, size);
-                    break;
-                case VERIFY10:
-                    memoryVerify(buf, size);
-                    break;
-            }
-            break;
-
-            // an error has occured: stall endpoint and send CSW
-        default:
-            stallEndpoint(EPBULK_OUT);
-            csw.Status = CSW_ERROR;
-            sendCSW();
-            break;
-    }
-
-    //reactivate readings on the OUT bulk endpoint
-    readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
-    return true;
-}
-
-// Called in ISR context when a data has been transferred
-bool USBMSD::EPBULK_IN_callback() {
-    switch (stage) {
-
-            // the device has to send data to the host
-        case PROCESS_CBW:
-            switch (cbw.CB[0]) {
-                case READ10:
-                case READ12:
-                    memoryRead();
-                    break;
-            }
-            break;
-
-            //the device has to send a CSW
-        case SEND_CSW:
-            sendCSW();
-            break;
-
-        // the host has received the CSW -> we wait a CBW
-        case WAIT_CSW:
-            stage = READ_CBW;
-            break;
-
-        // an error has occured
-        default:
-            stallEndpoint(EPBULK_IN);
-            sendCSW();
-            break;
-    }
-    return true;
-}
-
-
-void USBMSD::memoryWrite (uint8_t * buf, uint16_t size) {
-
-    if ((addr + size) > MemorySize) {
-        size = MemorySize - addr;
-        stage = ERROR;
-        stallEndpoint(EPBULK_OUT);
-    }
-
-    // we fill an array in RAM of 1 block before writing it in memory
-    for (int i = 0; i < size; i++)
-        page[addr%BlockSize + i] = buf[i];
-
-    // if the array is filled, write it in memory
-    if (!((addr + size)%BlockSize)) {
-        if (!(disk_status() & WRITE_PROTECT)) {
-            disk_write(page, addr/BlockSize, 1);
-        }
-    }
-
-    addr += size;
-    length -= size;
-    csw.DataResidue -= size;
-
-    if ((!length) || (stage != PROCESS_CBW)) {
-        csw.Status = (stage == ERROR) ? CSW_FAILED : CSW_PASSED;
-        sendCSW();
-    }
-}
-
-void USBMSD::memoryVerify (uint8_t * buf, uint16_t size) {
-    uint32_t n;
-
-    if ((addr + size) > MemorySize) {
-        size = MemorySize - addr;
-        stage = ERROR;
-        stallEndpoint(EPBULK_OUT);
-    }
-
-    // beginning of a new block -> load a whole block in RAM
-    if (!(addr%BlockSize))
-        disk_read(page, addr/BlockSize, 1);
-
-    // info are in RAM -> no need to re-read memory
-    for (n = 0; n < size; n++) {
-        if (page[addr%BlockSize + n] != buf[n]) {
-            memOK = false;
-            break;
-        }
-    }
-
-    addr += size;
-    length -= size;
-    csw.DataResidue -= size;
-
-    if ( !length || (stage != PROCESS_CBW)) {
-        csw.Status = (memOK && (stage == PROCESS_CBW)) ? CSW_PASSED : CSW_FAILED;
-        sendCSW();
-    }
-}
-
-
-bool USBMSD::inquiryRequest (void) {
-    uint8_t inquiry[] = { 0x00, 0x80, 0x00, 0x01,
-                          36 - 4, 0x80, 0x00, 0x00,
-                          'M', 'B', 'E', 'D', '.', 'O', 'R', 'G',
-                          'M', 'B', 'E', 'D', ' ', 'U', 'S', 'B', ' ', 'D', 'I', 'S', 'K', ' ', ' ', ' ',
-                          '1', '.', '0', ' ',
-                        };
-    if (!write(inquiry, sizeof(inquiry))) {
-        return false;
-    }
-    return true;
-}
-
-
-bool USBMSD::readFormatCapacity() {
-    uint8_t capacity[] = { 0x00, 0x00, 0x00, 0x08,
-                           (uint8_t)((BlockCount >> 24) & 0xff),
-                           (uint8_t)((BlockCount >> 16) & 0xff),
-                           (uint8_t)((BlockCount >> 8) & 0xff),
-                           (uint8_t)((BlockCount >> 0) & 0xff),
-
-                           0x02,
-                           (uint8_t)((BlockSize >> 16) & 0xff),
-                           (uint8_t)((BlockSize >> 8) & 0xff),
-                           (uint8_t)((BlockSize >> 0) & 0xff),
-                         };
-    if (!write(capacity, sizeof(capacity))) {
-        return false;
-    }
-    return true;
-}
-
-
-bool USBMSD::readCapacity (void) {
-    uint8_t capacity[] = {
-        (uint8_t)(((BlockCount - 1) >> 24) & 0xff),
-        (uint8_t)(((BlockCount - 1) >> 16) & 0xff),
-        (uint8_t)(((BlockCount - 1) >> 8) & 0xff),
-        (uint8_t)(((BlockCount - 1) >> 0) & 0xff),
-
-        (uint8_t)((BlockSize >> 24) & 0xff),
-        (uint8_t)((BlockSize >> 16) & 0xff),
-        (uint8_t)((BlockSize >> 8) & 0xff),
-        (uint8_t)((BlockSize >> 0) & 0xff),
-    };
-    if (!write(capacity, sizeof(capacity))) {
-        return false;
-    }
-    return true;
-}
-
-bool USBMSD::write (uint8_t * buf, uint16_t size) {
-
-    if (size >= cbw.DataLength) {
-        size = cbw.DataLength;
-    }
-    stage = SEND_CSW;
-
-    if (!writeNB(EPBULK_IN, buf, size, MAX_PACKET_SIZE_EPBULK)) {
-        return false;
-    }
-
-    csw.DataResidue -= size;
-    csw.Status = CSW_PASSED;
-    return true;
-}
-
-
-bool USBMSD::modeSense6 (void) {
-    uint8_t sense6[] = { 0x03, 0x00, 0x00, 0x00 };
-    if (!write(sense6, sizeof(sense6))) {
-        return false;
-    }
-    return true;
-}
-
-void USBMSD::sendCSW() {
-    csw.Signature = CSW_Signature;
-    writeNB(EPBULK_IN, (uint8_t *)&csw, sizeof(CSW), MAX_PACKET_SIZE_EPBULK);
-    stage = WAIT_CSW;
-}
-
-bool USBMSD::requestSense (void) {
-    uint8_t request_sense[] = {
-        0x70,
-        0x00,
-        0x05,   // Sense Key: illegal request
-        0x00,
-        0x00,
-        0x00,
-        0x00,
-        0x0A,
-        0x00,
-        0x00,
-        0x00,
-        0x00,
-        0x30,
-        0x01,
-        0x00,
-        0x00,
-        0x00,
-        0x00,
-    };
-
-    if (!write(request_sense, sizeof(request_sense))) {
-        return false;
-    }
-
-    return true;
-}
-
-void USBMSD::fail() {
-    csw.Status = CSW_FAILED;
-    sendCSW();
-}
-
-
-void USBMSD::CBWDecode(uint8_t * buf, uint16_t size) {
-    if (size == sizeof(cbw)) {
-        memcpy((uint8_t *)&cbw, buf, size);
-        if (cbw.Signature == CBW_Signature) {
-            csw.Tag = cbw.Tag;
-            csw.DataResidue = cbw.DataLength;
-            if ((cbw.CBLength <  1) || (cbw.CBLength > 16) ) {
-                fail();
-            } else {
-                switch (cbw.CB[0]) {
-                    case TEST_UNIT_READY:
-                        testUnitReady();
-                        break;
-                    case REQUEST_SENSE:
-                        requestSense();
-                        break;
-                    case INQUIRY:
-                        inquiryRequest();
-                        break;
-                    case MODE_SENSE6:
-                        modeSense6();
-                        break;
-                    case READ_FORMAT_CAPACITIES:
-                        readFormatCapacity();
-                        break;
-                    case READ_CAPACITY:
-                        readCapacity();
-                        break;
-                    case READ10:
-                    case READ12:
-                        if (infoTransfer()) {
-                            if ((cbw.Flags & 0x80)) {
-                                stage = PROCESS_CBW;
-                                memoryRead();
-                            } else {
-                                stallEndpoint(EPBULK_OUT);
-                                csw.Status = CSW_ERROR;
-                                sendCSW();
-                            }
-                        }
-                        break;
-                    case WRITE10:
-                    case WRITE12:
-                        if (infoTransfer()) {
-                            if (!(cbw.Flags & 0x80)) {
-                                stage = PROCESS_CBW;
-                            } else {
-                                stallEndpoint(EPBULK_IN);
-                                csw.Status = CSW_ERROR;
-                                sendCSW();
-                            }
-                        }
-                        break;
-                    case VERIFY10:
-                        if (!(cbw.CB[1] & 0x02)) {
-                            csw.Status = CSW_PASSED;
-                            sendCSW();
-                            break;
-                        }
-                        if (infoTransfer()) {
-                            if (!(cbw.Flags & 0x80)) {
-                                stage = PROCESS_CBW;
-                                memOK = true;
-                            } else {
-                                stallEndpoint(EPBULK_IN);
-                                csw.Status = CSW_ERROR;
-                                sendCSW();
-                            }
-                        }
-                        break;
-                    case MEDIA_REMOVAL:
-                        csw.Status = CSW_PASSED;
-                        sendCSW();
-                        break;
-                    default:
-                        fail();
-                        break;
-                }
-            }
-        }
-    }
-}
-
-void USBMSD::testUnitReady (void) {
-
-    if (cbw.DataLength != 0) {
-        if ((cbw.Flags & 0x80) != 0) {
-            stallEndpoint(EPBULK_IN);
-        } else {
-            stallEndpoint(EPBULK_OUT);
-        }
-    }
-
-    csw.Status = CSW_PASSED;
-    sendCSW();
-}
-
-
-void USBMSD::memoryRead (void) {
-    uint32_t n;
-
-    n = (length > MAX_PACKET) ? MAX_PACKET : length;
-
-    if ((addr + n) > MemorySize) {
-        n = MemorySize - addr;
-        stage = ERROR;
-    }
-
-    // we read an entire block
-    if (!(addr%BlockSize))
-        disk_read(page, addr/BlockSize, 1);
-
-    // write data which are in RAM
-    writeNB(EPBULK_IN, &page[addr%BlockSize], n, MAX_PACKET_SIZE_EPBULK);
-
-    addr += n;
-    length -= n;
-
-    csw.DataResidue -= n;
-
-    if ( !length || (stage != PROCESS_CBW)) {
-        csw.Status = (stage == PROCESS_CBW) ? CSW_PASSED : CSW_FAILED;
-        stage = (stage == PROCESS_CBW) ? SEND_CSW : stage;
-    }
-}
-
-
-bool USBMSD::infoTransfer (void) {
-    uint32_t n;
-
-    // Logical Block Address of First Block
-    n = (cbw.CB[2] << 24) | (cbw.CB[3] << 16) | (cbw.CB[4] <<  8) | (cbw.CB[5] <<  0);
-
-    addr = n * BlockSize;
-
-    // Number of Blocks to transfer
-    switch (cbw.CB[0]) {
-        case READ10:
-        case WRITE10:
-        case VERIFY10:
-            n = (cbw.CB[7] <<  8) | (cbw.CB[8] <<  0);
-            break;
-
-        case READ12:
-        case WRITE12:
-            n = (cbw.CB[6] << 24) | (cbw.CB[7] << 16) | (cbw.CB[8] <<  8) | (cbw.CB[9] <<  0);
-            break;
-    }
-
-    length = n * BlockSize;
-
-    if (!cbw.DataLength) {              // host requests no data
-        csw.Status = CSW_FAILED;
-        sendCSW();
-        return false;
-    }
-
-    if (cbw.DataLength != length) {
-        if ((cbw.Flags & 0x80) != 0) {
-            stallEndpoint(EPBULK_IN);
-        } else {
-            stallEndpoint(EPBULK_OUT);
-        }
-
-        csw.Status = CSW_FAILED;
-        sendCSW();
-        return false;
-    }
-
-    return true;
-}
-
-
-
-
-
-// Called in ISR context
-// Set configuration. Return false if the
-// configuration is not supported.
-bool USBMSD::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);
-
-    //activate readings
-    readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
-    return true;
-}
-
-
-uint8_t * USBMSD::stringIinterfaceDesc() {
-    static uint8_t stringIinterfaceDescriptor[] = {
-        0x08,                           //bLength
-        STRING_DESCRIPTOR,              //bDescriptorType 0x03
-        'M',0,'S',0,'D',0               //bString iInterface - MSD
-    };
-    return stringIinterfaceDescriptor;
-}
-
-uint8_t * USBMSD::stringIproductDesc() {
-    static uint8_t stringIproductDescriptor[] = {
-        0x12,                                           //bLength
-        STRING_DESCRIPTOR,                              //bDescriptorType 0x03
-        'M',0,'b',0,'e',0,'d',0,' ',0,'M',0,'S',0,'D',0 //bString iProduct - Mbed Audio
-    };
-    return stringIproductDescriptor;
-}
-
-
-uint8_t * USBMSD::configurationDesc() {
-    static uint8_t configDescriptor[] = {
-
-        // Configuration 1
-        9,      // bLength
-        2,      // bDescriptorType
-        LSB(9 + 9 + 7 + 7), // wTotalLength
-        MSB(9 + 9 + 7 + 7),
-        0x01,   // bNumInterfaces
-        0x01,   // bConfigurationValue: 0x01 is used to select this configuration
-        0x00,   // iConfiguration: no string to describe this configuration
-        0xC0,   // bmAttributes
-        100,    // bMaxPower, device power consumption is 100 mA
-
-        // Interface 0, Alternate Setting 0, MSC Class
-        9,      // bLength
-        4,      // bDescriptorType
-        0x00,   // bInterfaceNumber
-        0x00,   // bAlternateSetting
-        0x02,   // bNumEndpoints
-        0x08,   // bInterfaceClass
-        0x06,   // bInterfaceSubClass
-        0x50,   // bInterfaceProtocol
-        0x04,   // 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;
-}
+/* 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 "USBMSD.h"
+
+#define DISK_OK         0x00
+#define NO_INIT         0x01
+#define NO_DISK         0x02
+#define WRITE_PROTECT   0x04
+
+#define CBW_Signature   0x43425355
+#define CSW_Signature   0x53425355
+
+// SCSI Commands
+#define TEST_UNIT_READY            0x00
+#define REQUEST_SENSE              0x03
+#define FORMAT_UNIT                0x04
+#define INQUIRY                    0x12
+#define MODE_SELECT6               0x15
+#define MODE_SENSE6                0x1A
+#define START_STOP_UNIT            0x1B
+#define MEDIA_REMOVAL              0x1E
+#define READ_FORMAT_CAPACITIES     0x23
+#define READ_CAPACITY              0x25
+#define READ10                     0x28
+#define WRITE10                    0x2A
+#define VERIFY10                   0x2F
+#define READ12                     0xA8
+#define WRITE12                    0xAA
+#define MODE_SELECT10              0x55
+#define MODE_SENSE10               0x5A
+
+// MSC class specific requests
+#define MSC_REQUEST_RESET          0xFF
+#define MSC_REQUEST_GET_MAX_LUN    0xFE
+
+#define DEFAULT_CONFIGURATION (1)
+
+// max packet size
+#define MAX_PACKET  MAX_PACKET_SIZE_EPBULK
+
+// CSW Status
+enum Status {
+    CSW_PASSED,
+    CSW_FAILED,
+    CSW_ERROR,
+};
+
+
+USBMSD::USBMSD(uint16_t vendor_id, uint16_t product_id, uint16_t product_release): USBDevice(vendor_id, product_id, product_release) {
+    stage = READ_CBW;
+    memset((void *)&cbw, 0, sizeof(CBW));
+    memset((void *)&csw, 0, sizeof(CSW));
+    page = NULL;
+}
+
+USBMSD::~USBMSD() {
+    disconnect();
+}
+
+
+// Called in ISR context to process a class specific request
+bool USBMSD::USBCallback_request(void) {
+
+    bool success = false;
+    CONTROL_TRANSFER * transfer = getTransferPtr();
+    static uint8_t maxLUN[1] = {0};
+
+    if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
+        switch (transfer->setup.bRequest) {
+            case MSC_REQUEST_RESET:
+                reset();
+                success = true;
+                break;
+            case MSC_REQUEST_GET_MAX_LUN:
+                transfer->remaining = 1;
+                transfer->ptr = maxLUN;
+                transfer->direction = DEVICE_TO_HOST;
+                success = true;
+                break;
+            default:
+                break;
+        }
+    }
+
+    return success;
+}
+
+
+bool USBMSD::connect(bool blocking) {
+    //disk initialization
+    if (disk_status() & NO_INIT) {
+        if (disk_initialize()) {
+            return false;
+        }
+    }
+
+    // get number of blocks
+    BlockCount = disk_sectors();
+
+    // get memory size
+    MemorySize = disk_size();
+
+    if (BlockCount > 0) {
+        BlockSize = MemorySize / BlockCount;
+        if (BlockSize != 0) {
+            free(page);
+            page = (uint8_t *)malloc(BlockSize * sizeof(uint8_t));
+            if (page == NULL)
+                return false;
+        }
+    } else {
+        return false;
+    }
+
+    //connect the device
+    USBDevice::connect(blocking);
+    return true;
+}
+
+void USBMSD::disconnect() {
+    USBDevice::disconnect();
+    //De-allocate MSD page size:
+    free(page);
+    page = NULL;
+}
+
+void USBMSD::reset() {
+    stage = READ_CBW;
+}
+
+
+// Called in ISR context called when a data is received
+bool USBMSD::EPBULK_OUT_callback() {
+    uint32_t size = 0;
+    uint8_t buf[MAX_PACKET_SIZE_EPBULK];
+    readEP(EPBULK_OUT, buf, &size, MAX_PACKET_SIZE_EPBULK);
+    switch (stage) {
+            // the device has to decode the CBW received
+        case READ_CBW:
+            CBWDecode(buf, size);
+            break;
+
+            // the device has to receive data from the host
+        case PROCESS_CBW:
+            switch (cbw.CB[0]) {
+                case WRITE10:
+                case WRITE12:
+                    memoryWrite(buf, size);
+                    break;
+                case VERIFY10:
+                    memoryVerify(buf, size);
+                    break;
+            }
+            break;
+
+            // an error has occured: stall endpoint and send CSW
+        default:
+            stallEndpoint(EPBULK_OUT);
+            csw.Status = CSW_ERROR;
+            sendCSW();
+            break;
+    }
+
+    //reactivate readings on the OUT bulk endpoint
+    readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
+    return true;
+}
+
+// Called in ISR context when a data has been transferred
+bool USBMSD::EPBULK_IN_callback() {
+    switch (stage) {
+
+            // the device has to send data to the host
+        case PROCESS_CBW:
+            switch (cbw.CB[0]) {
+                case READ10:
+                case READ12:
+                    memoryRead();
+                    break;
+            }
+            break;
+
+            //the device has to send a CSW
+        case SEND_CSW:
+            sendCSW();
+            break;
+
+        // the host has received the CSW -> we wait a CBW
+        case WAIT_CSW:
+            stage = READ_CBW;
+            break;
+
+        // an error has occured
+        default:
+            stallEndpoint(EPBULK_IN);
+            sendCSW();
+            break;
+    }
+    return true;
+}
+
+
+void USBMSD::memoryWrite (uint8_t * buf, uint16_t size) {
+
+    if ((addr + size) > MemorySize) {
+        size = MemorySize - addr;
+        stage = ERROR;
+        stallEndpoint(EPBULK_OUT);
+    }
+
+    // we fill an array in RAM of 1 block before writing it in memory
+    for (int i = 0; i < size; i++)
+        page[addr%BlockSize + i] = buf[i];
+
+    // if the array is filled, write it in memory
+    if (!((addr + size)%BlockSize)) {
+        if (!(disk_status() & WRITE_PROTECT)) {
+            disk_write(page, addr/BlockSize, 1);
+        }
+    }
+
+    addr += size;
+    length -= size;
+    csw.DataResidue -= size;
+
+    if ((!length) || (stage != PROCESS_CBW)) {
+        csw.Status = (stage == ERROR) ? CSW_FAILED : CSW_PASSED;
+        sendCSW();
+    }
+}
+
+void USBMSD::memoryVerify (uint8_t * buf, uint16_t size) {
+    uint32_t n;
+
+    if ((addr + size) > MemorySize) {
+        size = MemorySize - addr;
+        stage = ERROR;
+        stallEndpoint(EPBULK_OUT);
+    }
+
+    // beginning of a new block -> load a whole block in RAM
+    if (!(addr%BlockSize))
+        disk_read(page, addr/BlockSize, 1);
+
+    // info are in RAM -> no need to re-read memory
+    for (n = 0; n < size; n++) {
+        if (page[addr%BlockSize + n] != buf[n]) {
+            memOK = false;
+            break;
+        }
+    }
+
+    addr += size;
+    length -= size;
+    csw.DataResidue -= size;
+
+    if ( !length || (stage != PROCESS_CBW)) {
+        csw.Status = (memOK && (stage == PROCESS_CBW)) ? CSW_PASSED : CSW_FAILED;
+        sendCSW();
+    }
+}
+
+
+bool USBMSD::inquiryRequest (void) {
+    uint8_t inquiry[] = { 0x00, 0x80, 0x00, 0x01,
+                          36 - 4, 0x80, 0x00, 0x00,
+                          'M', 'B', 'E', 'D', '.', 'O', 'R', 'G',
+                          'M', 'B', 'E', 'D', ' ', 'U', 'S', 'B', ' ', 'D', 'I', 'S', 'K', ' ', ' ', ' ',
+                          '1', '.', '0', ' ',
+                        };
+    if (!write(inquiry, sizeof(inquiry))) {
+        return false;
+    }
+    return true;
+}
+
+
+bool USBMSD::readFormatCapacity() {
+    uint8_t capacity[] = { 0x00, 0x00, 0x00, 0x08,
+                           (uint8_t)((BlockCount >> 24) & 0xff),
+                           (uint8_t)((BlockCount >> 16) & 0xff),
+                           (uint8_t)((BlockCount >> 8) & 0xff),
+                           (uint8_t)((BlockCount >> 0) & 0xff),
+
+                           0x02,
+                           (uint8_t)((BlockSize >> 16) & 0xff),
+                           (uint8_t)((BlockSize >> 8) & 0xff),
+                           (uint8_t)((BlockSize >> 0) & 0xff),
+                         };
+    if (!write(capacity, sizeof(capacity))) {
+        return false;
+    }
+    return true;
+}
+
+
+bool USBMSD::readCapacity (void) {
+    uint8_t capacity[] = {
+        (uint8_t)(((BlockCount - 1) >> 24) & 0xff),
+        (uint8_t)(((BlockCount - 1) >> 16) & 0xff),
+        (uint8_t)(((BlockCount - 1) >> 8) & 0xff),
+        (uint8_t)(((BlockCount - 1) >> 0) & 0xff),
+
+        (uint8_t)((BlockSize >> 24) & 0xff),
+        (uint8_t)((BlockSize >> 16) & 0xff),
+        (uint8_t)((BlockSize >> 8) & 0xff),
+        (uint8_t)((BlockSize >> 0) & 0xff),
+    };
+    if (!write(capacity, sizeof(capacity))) {
+        return false;
+    }
+    return true;
+}
+
+bool USBMSD::write (uint8_t * buf, uint16_t size) {
+
+    if (size >= cbw.DataLength) {
+        size = cbw.DataLength;
+    }
+    stage = SEND_CSW;
+
+    if (!writeNB(EPBULK_IN, buf, size, MAX_PACKET_SIZE_EPBULK)) {
+        return false;
+    }
+
+    csw.DataResidue -= size;
+    csw.Status = CSW_PASSED;
+    return true;
+}
+
+
+bool USBMSD::modeSense6 (void) {
+    uint8_t sense6[] = { 0x03, 0x00, 0x00, 0x00 };
+    if (!write(sense6, sizeof(sense6))) {
+        return false;
+    }
+    return true;
+}
+
+void USBMSD::sendCSW() {
+    csw.Signature = CSW_Signature;
+    writeNB(EPBULK_IN, (uint8_t *)&csw, sizeof(CSW), MAX_PACKET_SIZE_EPBULK);
+    stage = WAIT_CSW;
+}
+
+bool USBMSD::requestSense (void) {
+    uint8_t request_sense[] = {
+        0x70,
+        0x00,
+        0x05,   // Sense Key: illegal request
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x0A,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x30,
+        0x01,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+    };
+
+    if (!write(request_sense, sizeof(request_sense))) {
+        return false;
+    }
+
+    return true;
+}
+
+void USBMSD::fail() {
+    csw.Status = CSW_FAILED;
+    sendCSW();
+}
+
+
+void USBMSD::CBWDecode(uint8_t * buf, uint16_t size) {
+    if (size == sizeof(cbw)) {
+        memcpy((uint8_t *)&cbw, buf, size);
+        if (cbw.Signature == CBW_Signature) {
+            csw.Tag = cbw.Tag;
+            csw.DataResidue = cbw.DataLength;
+            if ((cbw.CBLength <  1) || (cbw.CBLength > 16) ) {
+                fail();
+            } else {
+                switch (cbw.CB[0]) {
+                    case TEST_UNIT_READY:
+                        testUnitReady();
+                        break;
+                    case REQUEST_SENSE:
+                        requestSense();
+                        break;
+                    case INQUIRY:
+                        inquiryRequest();
+                        break;
+                    case MODE_SENSE6:
+                        modeSense6();
+                        break;
+                    case READ_FORMAT_CAPACITIES:
+                        readFormatCapacity();
+                        break;
+                    case READ_CAPACITY:
+                        readCapacity();
+                        break;
+                    case READ10:
+                    case READ12:
+                        if (infoTransfer()) {
+                            if ((cbw.Flags & 0x80)) {
+                                stage = PROCESS_CBW;
+                                memoryRead();
+                            } else {
+                                stallEndpoint(EPBULK_OUT);
+                                csw.Status = CSW_ERROR;
+                                sendCSW();
+                            }
+                        }
+                        break;
+                    case WRITE10:
+                    case WRITE12:
+                        if (infoTransfer()) {
+                            if (!(cbw.Flags & 0x80)) {
+                                stage = PROCESS_CBW;
+                            } else {
+                                stallEndpoint(EPBULK_IN);
+                                csw.Status = CSW_ERROR;
+                                sendCSW();
+                            }
+                        }
+                        break;
+                    case VERIFY10:
+                        if (!(cbw.CB[1] & 0x02)) {
+                            csw.Status = CSW_PASSED;
+                            sendCSW();
+                            break;
+                        }
+                        if (infoTransfer()) {
+                            if (!(cbw.Flags & 0x80)) {
+                                stage = PROCESS_CBW;
+                                memOK = true;
+                            } else {
+                                stallEndpoint(EPBULK_IN);
+                                csw.Status = CSW_ERROR;
+                                sendCSW();
+                            }
+                        }
+                        break;
+                    case MEDIA_REMOVAL:
+                        csw.Status = CSW_PASSED;
+                        sendCSW();
+                        break;
+                    default:
+                        fail();
+                        break;
+                }
+            }
+        }
+    }
+}
+
+void USBMSD::testUnitReady (void) {
+
+    if (cbw.DataLength != 0) {
+        if ((cbw.Flags & 0x80) != 0) {
+            stallEndpoint(EPBULK_IN);
+        } else {
+            stallEndpoint(EPBULK_OUT);
+        }
+    }
+
+    csw.Status = CSW_PASSED;
+    sendCSW();
+}
+
+
+void USBMSD::memoryRead (void) {
+    uint32_t n;
+
+    n = (length > MAX_PACKET) ? MAX_PACKET : length;
+
+    if ((addr + n) > MemorySize) {
+        n = MemorySize - addr;
+        stage = ERROR;
+    }
+
+    // we read an entire block
+    if (!(addr%BlockSize))
+        disk_read(page, addr/BlockSize, 1);
+
+    // write data which are in RAM
+    writeNB(EPBULK_IN, &page[addr%BlockSize], n, MAX_PACKET_SIZE_EPBULK);
+
+    addr += n;
+    length -= n;
+
+    csw.DataResidue -= n;
+
+    if ( !length || (stage != PROCESS_CBW)) {
+        csw.Status = (stage == PROCESS_CBW) ? CSW_PASSED : CSW_FAILED;
+        stage = (stage == PROCESS_CBW) ? SEND_CSW : stage;
+    }
+}
+
+
+bool USBMSD::infoTransfer (void) {
+    uint32_t n;
+
+    // Logical Block Address of First Block
+    n = (cbw.CB[2] << 24) | (cbw.CB[3] << 16) | (cbw.CB[4] <<  8) | (cbw.CB[5] <<  0);
+
+    addr = n * BlockSize;
+
+    // Number of Blocks to transfer
+    switch (cbw.CB[0]) {
+        case READ10:
+        case WRITE10:
+        case VERIFY10:
+            n = (cbw.CB[7] <<  8) | (cbw.CB[8] <<  0);
+            break;
+
+        case READ12:
+        case WRITE12:
+            n = (cbw.CB[6] << 24) | (cbw.CB[7] << 16) | (cbw.CB[8] <<  8) | (cbw.CB[9] <<  0);
+            break;
+    }
+
+    length = n * BlockSize;
+
+    if (!cbw.DataLength) {              // host requests no data
+        csw.Status = CSW_FAILED;
+        sendCSW();
+        return false;
+    }
+
+    if (cbw.DataLength != length) {
+        if ((cbw.Flags & 0x80) != 0) {
+            stallEndpoint(EPBULK_IN);
+        } else {
+            stallEndpoint(EPBULK_OUT);
+        }
+
+        csw.Status = CSW_FAILED;
+        sendCSW();
+        return false;
+    }
+
+    return true;
+}
+
+
+
+
+
+// Called in ISR context
+// Set configuration. Return false if the
+// configuration is not supported.
+bool USBMSD::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);
+
+    //activate readings
+    readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
+    return true;
+}
+
+
+uint8_t * USBMSD::stringIinterfaceDesc() {
+    static uint8_t stringIinterfaceDescriptor[] = {
+        0x08,                           //bLength
+        STRING_DESCRIPTOR,              //bDescriptorType 0x03
+        'M',0,'S',0,'D',0               //bString iInterface - MSD
+    };
+    return stringIinterfaceDescriptor;
+}
+
+uint8_t * USBMSD::stringIproductDesc() {
+    static uint8_t stringIproductDescriptor[] = {
+        0x12,                                           //bLength
+        STRING_DESCRIPTOR,                              //bDescriptorType 0x03
+        'M',0,'b',0,'e',0,'d',0,' ',0,'M',0,'S',0,'D',0 //bString iProduct - Mbed Audio
+    };
+    return stringIproductDescriptor;
+}
+
+
+uint8_t * USBMSD::configurationDesc() {
+    static uint8_t configDescriptor[] = {
+
+        // Configuration 1
+        9,      // bLength
+        2,      // bDescriptorType
+        LSB(9 + 9 + 7 + 7), // wTotalLength
+        MSB(9 + 9 + 7 + 7),
+        0x01,   // bNumInterfaces
+        0x01,   // bConfigurationValue: 0x01 is used to select this configuration
+        0x00,   // iConfiguration: no string to describe this configuration
+        0xC0,   // bmAttributes
+        100,    // bMaxPower, device power consumption is 100 mA
+
+        // Interface 0, Alternate Setting 0, MSC Class
+        9,      // bLength
+        4,      // bDescriptorType
+        0x00,   // bInterfaceNumber
+        0x00,   // bAlternateSetting
+        0x02,   // bNumEndpoints
+        0x08,   // bInterfaceClass
+        0x06,   // bInterfaceSubClass
+        0x50,   // bInterfaceProtocol
+        0x04,   // 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;
+}
--- a/USBMSD/USBMSD.h	Tue May 03 00:16:32 2016 +0100
+++ b/USBMSD/USBMSD.h	Fri Apr 28 11:26:51 2017 +0100
@@ -1,251 +1,251 @@
-/* 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 USBMSD_H
-#define USBMSD_H
-
-/* These headers are included for child class. */
-#include "USBEndpoints.h"
-#include "USBDescriptor.h"
-#include "USBDevice_Types.h"
-
-#include "USBDevice.h"
-
-/**
- * USBMSD class: generic class in order to use all kinds of blocks storage chip
- *
- * Introduction
- *
- * The USBMSD implements the MSD protocol. It permits to access a memory chip (flash, sdcard,...)
- * from a computer over USB. But this class doesn't work standalone, you need to subclass this class
- * and define virtual functions which are called in USBMSD.
- *
- * How to use this class with your chip ?
- *
- * You have to inherit and define some pure virtual functions (mandatory step):
- *   - virtual int disk_read(char * data, int block): function to read a block
- *   - virtual int disk_write(const char * data, int block): function to write a block
- *   - virtual int disk_initialize(): function to initialize the memory
- *   - virtual int disk_sectors(): return the number of blocks
- *   - virtual int disk_size(): return the memory size
- *   - virtual int disk_status(): return the status of the storage chip (0: OK, 1: not initialized, 2: no medium in the drive, 4: write protection)
- *
- * All functions names are compatible with the fat filesystem library. So you can imagine using your own class with
- * USBMSD and the fat filesystem library in the same program. Just be careful because there are two different parts which
- * will access the sd card. You can do a master/slave system using the disk_status method.
- *
- * Once these functions defined, you can call connect() (at the end of the constructor of your class for instance)
- * of USBMSD to connect your mass storage device. connect() will first call disk_status() to test the status of the disk.
- * If disk_status() returns 1 (disk not initialized), then disk_initialize() is called. After this step, connect() will collect information
- * such as the number of blocks and the memory size.
- */
-class USBMSD: public USBDevice {
-public:
-
-    /**
-    * Constructor
-    *
-    * @param vendor_id Your vendor_id
-    * @param product_id Your product_id
-    * @param product_release Your preoduct_release
-    */
-    USBMSD(uint16_t vendor_id = 0x0703, uint16_t product_id = 0x0104, uint16_t product_release = 0x0001);
-
-    /**
-    * Connect the USB MSD device. Establish disk initialization before really connect the device.
-    *
-    * @param blocking if not configured
-    * @returns true if successful
-    */
-    bool connect(bool blocking = true);
-
-    /**
-    * Disconnect the USB MSD device.
-    */
-    void disconnect();
-
-    /**
-    * Destructor
-    */
-    ~USBMSD();
-
-protected:
-
-    /*
-    * read one or more blocks on a storage chip
-    *
-    * @param data pointer where will be stored read data
-    * @param block starting block number
-    * @param count number of blocks to read
-    * @returns 0 if successful
-    */
-    virtual int disk_read(uint8_t* data, uint64_t block, uint8_t count) = 0;
-
-    /*
-    * write one or more blocks on a storage chip
-    *
-    * @param data data to write
-    * @param block starting block number
-    * @param count number of blocks to write
-    * @returns 0 if successful
-    */
-    virtual int disk_write(const uint8_t* data, uint64_t block, uint8_t count) = 0;
-
-    /*
-    * Disk initilization
-    */
-    virtual int disk_initialize() = 0;
-
-    /*
-    * Return the number of blocks
-    *
-    * @returns number of blocks
-    */
-    virtual uint64_t disk_sectors() = 0;
-
-    /*
-    * Return memory size
-    *
-    * @returns memory size
-    */
-    virtual uint64_t disk_size() = 0;
-
-
-    /*
-    * To check the status of the storage chip
-    *
-    * @returns status: 0: OK, 1: disk not initialized, 2: no medium in the drive, 4: write protected
-    */
-    virtual int disk_status() = 0;
-
-    /*
-    * 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();
-
-    /*
-    * Callback called when a packet is received
-    */
-    virtual bool EPBULK_OUT_callback();
-
-    /*
-    * Callback called when a packet has been sent
-    */
-    virtual bool EPBULK_IN_callback();
-
-    /*
-    * Set configuration of device. Add endpoints
-    */
-    virtual bool USBCallback_setConfiguration(uint8_t configuration);
-
-    /*
-    * Callback called to process class specific requests
-    */
-    virtual bool USBCallback_request();
-
-
-private:
-
-    // MSC Bulk-only Stage
-    enum Stage {
-        READ_CBW,     // wait a CBW
-        ERROR,        // error
-        PROCESS_CBW,  // process a CBW request
-        SEND_CSW,     // send a CSW
-        WAIT_CSW,     // wait that a CSW has been effectively sent
-    };
-
-    // Bulk-only CBW
-    typedef struct {
-        uint32_t Signature;
-        uint32_t Tag;
-        uint32_t DataLength;
-        uint8_t  Flags;
-        uint8_t  LUN;
-        uint8_t  CBLength;
-        uint8_t  CB[16];
-    } PACKED CBW;
-
-    // Bulk-only CSW
-    typedef struct {
-        uint32_t Signature;
-        uint32_t Tag;
-        uint32_t DataResidue;
-        uint8_t  Status;
-    } PACKED CSW;
-
-    //state of the bulk-only state machine
-    Stage stage;
-
-    // current CBW
-    CBW cbw;
-
-    // CSW which will be sent
-    CSW csw;
-
-    // addr where will be read or written data
-    uint32_t addr;
-
-    // length of a reading or writing
-    uint32_t length;
-
-    // memory OK (after a memoryVerify)
-    bool memOK;
-
-    // cache in RAM before writing in memory. Useful also to read a block.
-    uint8_t * page;
-
-    int BlockSize;
-    uint64_t MemorySize;
-    uint64_t BlockCount;
-
-    void CBWDecode(uint8_t * buf, uint16_t size);
-    void sendCSW (void);
-    bool inquiryRequest (void);
-    bool write (uint8_t * buf, uint16_t size);
-    bool readFormatCapacity();
-    bool readCapacity (void);
-    bool infoTransfer (void);
-    void memoryRead (void);
-    bool modeSense6 (void);
-    void testUnitReady (void);
-    bool requestSense (void);
-    void memoryVerify (uint8_t * buf, uint16_t size);
-    void memoryWrite (uint8_t * buf, uint16_t size);
-    void reset();
-    void fail();
-};
-
-#endif
+/* 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 USBMSD_H
+#define USBMSD_H
+
+/* These headers are included for child class. */
+#include "USBEndpoints.h"
+#include "USBDescriptor.h"
+#include "USBDevice_Types.h"
+
+#include "USBDevice.h"
+
+/**
+ * USBMSD class: generic class in order to use all kinds of blocks storage chip
+ *
+ * Introduction
+ *
+ * The USBMSD implements the MSD protocol. It permits to access a memory chip (flash, sdcard,...)
+ * from a computer over USB. But this class doesn't work standalone, you need to subclass this class
+ * and define virtual functions which are called in USBMSD.
+ *
+ * How to use this class with your chip ?
+ *
+ * You have to inherit and define some pure virtual functions (mandatory step):
+ *   - virtual int disk_read(char * data, int block): function to read a block
+ *   - virtual int disk_write(const char * data, int block): function to write a block
+ *   - virtual int disk_initialize(): function to initialize the memory
+ *   - virtual int disk_sectors(): return the number of blocks
+ *   - virtual int disk_size(): return the memory size
+ *   - virtual int disk_status(): return the status of the storage chip (0: OK, 1: not initialized, 2: no medium in the drive, 4: write protection)
+ *
+ * All functions names are compatible with the fat filesystem library. So you can imagine using your own class with
+ * USBMSD and the fat filesystem library in the same program. Just be careful because there are two different parts which
+ * will access the sd card. You can do a master/slave system using the disk_status method.
+ *
+ * Once these functions defined, you can call connect() (at the end of the constructor of your class for instance)
+ * of USBMSD to connect your mass storage device. connect() will first call disk_status() to test the status of the disk.
+ * If disk_status() returns 1 (disk not initialized), then disk_initialize() is called. After this step, connect() will collect information
+ * such as the number of blocks and the memory size.
+ */
+class USBMSD: public USBDevice {
+public:
+
+    /**
+    * Constructor
+    *
+    * @param vendor_id Your vendor_id
+    * @param product_id Your product_id
+    * @param product_release Your preoduct_release
+    */
+    USBMSD(uint16_t vendor_id = 0x0703, uint16_t product_id = 0x0104, uint16_t product_release = 0x0001);
+
+    /**
+    * Connect the USB MSD device. Establish disk initialization before really connect the device.
+    *
+    * @param blocking if not configured
+    * @returns true if successful
+    */
+    bool connect(bool blocking = true);
+
+    /**
+    * Disconnect the USB MSD device.
+    */
+    void disconnect();
+
+    /**
+    * Destructor
+    */
+    ~USBMSD();
+
+protected:
+
+    /*
+    * read one or more blocks on a storage chip
+    *
+    * @param data pointer where will be stored read data
+    * @param block starting block number
+    * @param count number of blocks to read
+    * @returns 0 if successful
+    */
+    virtual int disk_read(uint8_t* data, uint64_t block, uint8_t count) = 0;
+
+    /*
+    * write one or more blocks on a storage chip
+    *
+    * @param data data to write
+    * @param block starting block number
+    * @param count number of blocks to write
+    * @returns 0 if successful
+    */
+    virtual int disk_write(const uint8_t* data, uint64_t block, uint8_t count) = 0;
+
+    /*
+    * Disk initilization
+    */
+    virtual int disk_initialize() = 0;
+
+    /*
+    * Return the number of blocks
+    *
+    * @returns number of blocks
+    */
+    virtual uint64_t disk_sectors() = 0;
+
+    /*
+    * Return memory size
+    *
+    * @returns memory size
+    */
+    virtual uint64_t disk_size() = 0;
+
+
+    /*
+    * To check the status of the storage chip
+    *
+    * @returns status: 0: OK, 1: disk not initialized, 2: no medium in the drive, 4: write protected
+    */
+    virtual int disk_status() = 0;
+
+    /*
+    * 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();
+
+    /*
+    * Callback called when a packet is received
+    */
+    virtual bool EPBULK_OUT_callback();
+
+    /*
+    * Callback called when a packet has been sent
+    */
+    virtual bool EPBULK_IN_callback();
+
+    /*
+    * Set configuration of device. Add endpoints
+    */
+    virtual bool USBCallback_setConfiguration(uint8_t configuration);
+
+    /*
+    * Callback called to process class specific requests
+    */
+    virtual bool USBCallback_request();
+
+
+private:
+
+    // MSC Bulk-only Stage
+    enum Stage {
+        READ_CBW,     // wait a CBW
+        ERROR,        // error
+        PROCESS_CBW,  // process a CBW request
+        SEND_CSW,     // send a CSW
+        WAIT_CSW,     // wait that a CSW has been effectively sent
+    };
+
+    // Bulk-only CBW
+    typedef struct {
+        uint32_t Signature;
+        uint32_t Tag;
+        uint32_t DataLength;
+        uint8_t  Flags;
+        uint8_t  LUN;
+        uint8_t  CBLength;
+        uint8_t  CB[16];
+    } PACKED CBW;
+
+    // Bulk-only CSW
+    typedef struct {
+        uint32_t Signature;
+        uint32_t Tag;
+        uint32_t DataResidue;
+        uint8_t  Status;
+    } PACKED CSW;
+
+    //state of the bulk-only state machine
+    Stage stage;
+
+    // current CBW
+    CBW cbw;
+
+    // CSW which will be sent
+    CSW csw;
+
+    // addr where will be read or written data
+    uint32_t addr;
+
+    // length of a reading or writing
+    uint32_t length;
+
+    // memory OK (after a memoryVerify)
+    bool memOK;
+
+    // cache in RAM before writing in memory. Useful also to read a block.
+    uint8_t * page;
+
+    int BlockSize;
+    uint64_t MemorySize;
+    uint64_t BlockCount;
+
+    void CBWDecode(uint8_t * buf, uint16_t size);
+    void sendCSW (void);
+    bool inquiryRequest (void);
+    bool write (uint8_t * buf, uint16_t size);
+    bool readFormatCapacity();
+    bool readCapacity (void);
+    bool infoTransfer (void);
+    void memoryRead (void);
+    bool modeSense6 (void);
+    void testUnitReady (void);
+    bool requestSense (void);
+    void memoryVerify (uint8_t * buf, uint16_t size);
+    void memoryWrite (uint8_t * buf, uint16_t size);
+    void reset();
+    void fail();
+};
+
+#endif
--- a/USBSerial/USBCDC.cpp	Tue May 03 00:16:32 2016 +0100
+++ b/USBSerial/USBCDC.cpp	Fri Apr 28 11:26:51 2017 +0100
@@ -1,286 +1,286 @@
-/* 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"
-
-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
-
-// Control Line State bits
-#define CLS_DTR   (1 << 0)
-#define CLS_RTS   (1 << 1)
-
-#define MAX_CDC_REPORT_SIZE MAX_PACKET_SIZE_EPBULK
-
-USBCDC::USBCDC(uint16_t vendor_id, uint16_t product_id, uint16_t product_release, bool connect_blocking): USBDevice(vendor_id, product_id, product_release) {
-    terminal_connected = false;
-    USBDevice::connect(connect_blocking);
-}
-
-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;
-                transfer->notify = true;
-                success = true;
-                break;
-            case CDC_SET_CONTROL_LINE_STATE:
-                if (transfer->setup.wValue & CLS_DTR) {
-                    terminal_connected = true;
-                } else {
-                    terminal_connected = false;
-                }
-                success = true;
-                break;
-            default:
-                break;
-        }
-    }
-
-    return success;
-}
-
-void USBCDC::USBCallback_requestCompleted(uint8_t *buf, uint32_t length) {
-    // Request of setting line coding has 7 bytes
-    if (length != 7) {
-        return;
-    }
-
-    CONTROL_TRANSFER * transfer = getTransferPtr();
-
-    /* Process class-specific requests */
-    if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
-        if (transfer->setup.bRequest == CDC_SET_LINE_CODING) {
-            if (memcmp(cdc_line_coding, buf, 7)) {
-                memcpy(cdc_line_coding, buf, 7);
-
-                int baud = buf[0] + (buf[1] << 8)
-                         + (buf[2] << 16) + (buf[3] << 24);
-                int stop = buf[4];
-                int bits = buf[6];
-                int parity = buf[5];
-
-                lineCodingChanged(baud, bits, parity, stop);
-            }
-        }
-    }
-}
-
-// 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 * buffer, uint32_t size) {
-    return USBDevice::write(EPBULK_IN, buffer, size, MAX_CDC_REPORT_SIZE);
-}
-
-bool USBCDC::readEP(uint8_t * buffer, uint32_t * size) {
-    if (!USBDevice::readEP(EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE))
-        return false;
-    if (!readStart(EPBULK_OUT, MAX_CDC_REPORT_SIZE))
-        return false;
-    return true;
-}
-
-bool USBCDC::readEP_NB(uint8_t * buffer, uint32_t * size) {
-    if (!USBDevice::readEP_NB(EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE))
-        return false;
-    if (!readStart(EPBULK_OUT, 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
-        (uint8_t)(LSB(VENDOR_ID)), (uint8_t)(MSB(VENDOR_ID)),  // idVendor
-        (uint8_t)(LSB(PRODUCT_ID)), (uint8_t)(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+8+9+5+5+4+5+7+9+7+7)
-
-uint8_t * USBCDC::configurationDesc() {
-    static uint8_t configDescriptor[] = {
-        // configuration descriptor
-        9,                      // bLength
-        2,                      // bDescriptorType
-        LSB(CONFIG1_DESC_SIZE), // wTotalLength
-        MSB(CONFIG1_DESC_SIZE),
-        2,                      // bNumInterfaces
-        1,                      // bConfigurationValue
-        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
-        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
-        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
-        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;
-}
+/* 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"
+
+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
+
+// Control Line State bits
+#define CLS_DTR   (1 << 0)
+#define CLS_RTS   (1 << 1)
+
+#define MAX_CDC_REPORT_SIZE MAX_PACKET_SIZE_EPBULK
+
+USBCDC::USBCDC(uint16_t vendor_id, uint16_t product_id, uint16_t product_release, bool connect_blocking): USBDevice(vendor_id, product_id, product_release) {
+    terminal_connected = false;
+    USBDevice::connect(connect_blocking);
+}
+
+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;
+                transfer->notify = true;
+                success = true;
+                break;
+            case CDC_SET_CONTROL_LINE_STATE:
+                if (transfer->setup.wValue & CLS_DTR) {
+                    terminal_connected = true;
+                } else {
+                    terminal_connected = false;
+                }
+                success = true;
+                break;
+            default:
+                break;
+        }
+    }
+
+    return success;
+}
+
+void USBCDC::USBCallback_requestCompleted(uint8_t *buf, uint32_t length) {
+    // Request of setting line coding has 7 bytes
+    if (length != 7) {
+        return;
+    }
+
+    CONTROL_TRANSFER * transfer = getTransferPtr();
+
+    /* Process class-specific requests */
+    if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
+        if (transfer->setup.bRequest == CDC_SET_LINE_CODING) {
+            if (memcmp(cdc_line_coding, buf, 7)) {
+                memcpy(cdc_line_coding, buf, 7);
+
+                int baud = buf[0] + (buf[1] << 8)
+                         + (buf[2] << 16) + (buf[3] << 24);
+                int stop = buf[4];
+                int bits = buf[6];
+                int parity = buf[5];
+
+                lineCodingChanged(baud, bits, parity, stop);
+            }
+        }
+    }
+}
+
+// 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 * buffer, uint32_t size) {
+    return USBDevice::write(EPBULK_IN, buffer, size, MAX_CDC_REPORT_SIZE);
+}
+
+bool USBCDC::readEP(uint8_t * buffer, uint32_t * size) {
+    if (!USBDevice::readEP(EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE))
+        return false;
+    if (!readStart(EPBULK_OUT, MAX_CDC_REPORT_SIZE))
+        return false;
+    return true;
+}
+
+bool USBCDC::readEP_NB(uint8_t * buffer, uint32_t * size) {
+    if (!USBDevice::readEP_NB(EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE))
+        return false;
+    if (!readStart(EPBULK_OUT, 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
+        (uint8_t)(LSB(VENDOR_ID)), (uint8_t)(MSB(VENDOR_ID)),  // idVendor
+        (uint8_t)(LSB(PRODUCT_ID)), (uint8_t)(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+8+9+5+5+4+5+7+9+7+7)
+
+uint8_t * USBCDC::configurationDesc() {
+    static uint8_t configDescriptor[] = {
+        // configuration descriptor
+        9,                      // bLength
+        2,                      // bDescriptorType
+        LSB(CONFIG1_DESC_SIZE), // wTotalLength
+        MSB(CONFIG1_DESC_SIZE),
+        2,                      // bNumInterfaces
+        1,                      // bConfigurationValue
+        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
+        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
+        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
+        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;
+}
--- a/USBSerial/USBCDC.h	Tue May 03 00:16:32 2016 +0100
+++ b/USBSerial/USBCDC.h	Fri Apr 28 11:26:51 2017 +0100
@@ -1,123 +1,123 @@
-/* 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
-    * @param connect_blocking define if the connection must be blocked if USB not plugged in
-    */
-    USBCDC(uint16_t vendor_id, uint16_t product_id, uint16_t product_release, bool connect_blocking);
-
-protected:
-
-    /*
-    * 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
-    *
-    * @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 * buffer, uint32_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 readEP(uint8_t * buffer, uint32_t * size);
-
-    /*
-    * 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 readEP_NB(uint8_t * buffer, uint32_t * size);
-
-    /*
-    * Called by USBCallback_requestCompleted when CDC line coding is changed
-    * Warning: Called in ISR
-    *
-    * @param baud The baud rate
-    * @param bits The number of bits in a word (5-8)
-    * @param parity The parity
-    * @param stop The number of stop bits (1 or 2)
-    */
-    virtual void lineCodingChanged(int baud, int bits, int parity, int stop) {};
-
-protected:
-    virtual bool USBCallback_request();
-    virtual void USBCallback_requestCompleted(uint8_t *buf, uint32_t length);
-    virtual bool USBCallback_setConfiguration(uint8_t configuration);
-    volatile bool terminal_connected;
-
-};
-
-#endif
+/* 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
+    * @param connect_blocking define if the connection must be blocked if USB not plugged in
+    */
+    USBCDC(uint16_t vendor_id, uint16_t product_id, uint16_t product_release, bool connect_blocking);
+
+protected:
+
+    /*
+    * 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
+    *
+    * @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 * buffer, uint32_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 readEP(uint8_t * buffer, uint32_t * size);
+
+    /*
+    * 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 readEP_NB(uint8_t * buffer, uint32_t * size);
+
+    /*
+    * Called by USBCallback_requestCompleted when CDC line coding is changed
+    * Warning: Called in ISR
+    *
+    * @param baud The baud rate
+    * @param bits The number of bits in a word (5-8)
+    * @param parity The parity
+    * @param stop The number of stop bits (1 or 2)
+    */
+    virtual void lineCodingChanged(int baud, int bits, int parity, int stop) {};
+
+protected:
+    virtual bool USBCallback_request();
+    virtual void USBCallback_requestCompleted(uint8_t *buf, uint32_t length);
+    virtual bool USBCallback_setConfiguration(uint8_t configuration);
+    volatile bool terminal_connected;
+
+};
+
+#endif
--- a/USBSerial/USBSerial.cpp	Tue May 03 00:16:32 2016 +0100
+++ b/USBSerial/USBSerial.cpp	Fri Apr 28 11:26:51 2017 +0100
@@ -1,67 +1,68 @@
-/* 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"
-
-int USBSerial::_putc(int c) {
-    if (!terminal_connected)
-        return 0;
-    send((uint8_t *)&c, 1);
-    return 1;
-}
-
-int USBSerial::_getc() {
-    uint8_t c = 0;
-    while (buf.isEmpty());
-    buf.dequeue(&c);
-    return c;
-}
-
-
-bool USBSerial::writeBlock(uint8_t * buf, uint16_t size) {
-    if(size > MAX_PACKET_SIZE_EPBULK) {
-        return false;
-    }
-    if(!send(buf, size)) {
-        return false;
-    }
-    return true;
-}
-
-
-
-bool USBSerial::EPBULK_OUT_callback() {
-    uint8_t c[65];
-    uint32_t size = 0;
-
-    //we read the packet received and put it on the circular buffer
-    readEP(c, &size);
-    for (uint32_t i = 0; i < size; i++) {
-        buf.queue(c[i]);
-    }
-
-    //call a potential handler
-    rx.call();
-
-    return true;
-}
-
-uint8_t USBSerial::available() {
-    return buf.available();
-}
+/* 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"
+
+int USBSerial::_putc(int c) {
+    if (!terminal_connected)
+        return 0;
+    send((uint8_t *)&c, 1);
+    return 1;
+}
+
+int USBSerial::_getc() {
+    uint8_t c = 0;
+    while (buf.isEmpty());
+    buf.dequeue(&c);
+    return c;
+}
+
+
+bool USBSerial::writeBlock(uint8_t * buf, uint16_t size) {
+    if(size > MAX_PACKET_SIZE_EPBULK) {
+        return false;
+    }
+    if(!send(buf, size)) {
+        return false;
+    }
+    return true;
+}
+
+
+
+bool USBSerial::EPBULK_OUT_callback() {
+    uint8_t c[65];
+    uint32_t size = 0;
+
+    //we read the packet received and put it on the circular buffer
+    readEP(c, &size);
+    for (uint32_t i = 0; i < size; i++) {
+        buf.queue(c[i]);
+    }
+
+    //call a potential handlenr
+    if (rx)
+        rx.call();
+
+    return true;
+}
+
+uint8_t USBSerial::available() {
+    return buf.available();
+}
--- a/USBSerial/USBSerial.h	Tue May 03 00:16:32 2016 +0100
+++ b/USBSerial/USBSerial.h	Fri Apr 28 11:26:51 2017 +0100
@@ -1,161 +1,161 @@
-/* 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 "CircBuffer.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)
-    * @param connect_blocking define if the connection must be blocked if USB not plugged in
-    *
-    */
-    USBSerial(uint16_t vendor_id = 0x1f00, uint16_t product_id = 0x2012, uint16_t product_release = 0x0001, bool connect_blocking = true): USBCDC(vendor_id, product_id, product_release, connect_blocking){
-        settingsChangedCallback = 0;
-    };
-
-
-    /**
-    * 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();
-
-    /** Determine if there is a character available to read
-     *
-     *  @returns
-     *    1 if there is a character available to read,
-     *    0 otherwise
-     */
-    int readable() { return available() ? 1 : 0; }
-
-    /** Determine if there is space available to write a character
-     *
-     *  @returns
-     *    1 if there is space to write a character,
-     *    0 otherwise
-     */
-    int writeable() { return 1; } // always return 1, for write operation is blocking
-
-    /**
-    * Write a block of data.
-    *
-    * For more efficiency, a block of size 64 (maximum size of a bulk endpoint) has to be written.
-    *
-    * @param buf pointer on data which will be written
-    * @param size size of the buffer. The maximum size of a block is limited by the size of the endpoint (64 bytes)
-    *
-    * @returns true if successfull
-    */
-    bool writeBlock(uint8_t * buf, uint16_t size);
-
-    /**
-     *  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)) {
-            rx.attach(tptr, mptr);
-        }
-    }
-
-    /**
-     * Attach a callback called when a packet is received
-     *
-     * @param fptr function pointer
-     */
-    void attach(void (*fptr)(void)) {
-        if(fptr != NULL) {
-            rx.attach(fptr);
-        }
-    }
-
-    /**
-     * Attach a callback to call when serial's settings are changed.
-     *
-     * @param fptr function pointer
-     */
-    void attach(void (*fptr)(int baud, int bits, int parity, int stop)) {
-        settingsChangedCallback = fptr;
-    }
-
-protected:
-    virtual bool EPBULK_OUT_callback();
-    virtual void lineCodingChanged(int baud, int bits, int parity, int stop){
-        if (settingsChangedCallback) {
-            settingsChangedCallback(baud, bits, parity, stop);
-        }
-    }
-
-private:
-    FunctionPointer rx;
-    CircBuffer<uint8_t,128> buf;
-    void (*settingsChangedCallback)(int baud, int bits, int parity, int stop);
-};
-
-#endif
+/* 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 "CircBuffer.h"
+#include "Callback.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)
+    * @param connect_blocking define if the connection must be blocked if USB not plugged in
+    *
+    */
+    USBSerial(uint16_t vendor_id = 0x1f00, uint16_t product_id = 0x2012, uint16_t product_release = 0x0001, bool connect_blocking = true): USBCDC(vendor_id, product_id, product_release, connect_blocking){
+        settingsChangedCallback = 0;
+    };
+
+
+    /**
+    * 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();
+
+    /** Determine if there is a character available to read
+     *
+     *  @returns
+     *    1 if there is a character available to read,
+     *    0 otherwise
+     */
+    int readable() { return available() ? 1 : 0; }
+
+    /** Determine if there is space available to write a character
+     *
+     *  @returns
+     *    1 if there is space to write a character,
+     *    0 otherwise
+     */
+    int writeable() { return 1; } // always return 1, for write operation is blocking
+
+    /**
+    * Write a block of data.
+    *
+    * For more efficiency, a block of size 64 (maximum size of a bulk endpoint) has to be written.
+    *
+    * @param buf pointer on data which will be written
+    * @param size size of the buffer. The maximum size of a block is limited by the size of the endpoint (64 bytes)
+    *
+    * @returns true if successfull
+    */
+    bool writeBlock(uint8_t * buf, uint16_t size);
+
+    /**
+     *  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)) {
+            rx.attach(tptr, mptr);
+        }
+    }
+
+    /**
+     * Attach a callback called when a packet is received
+     *
+     * @param fptr function pointer
+     */
+    void attach(void (*fptr)(void)) {
+        if(fptr != NULL) {
+            rx.attach(fptr);
+        }
+    }
+
+    /**
+     * Attach a callback to call when serial's settings are changed.
+     *
+     * @param fptr function pointer
+     */
+    void attach(void (*fptr)(int baud, int bits, int parity, int stop)) {
+        settingsChangedCallback = fptr;
+    }
+
+protected:
+    virtual bool EPBULK_OUT_callback();
+    virtual void lineCodingChanged(int baud, int bits, int parity, int stop){
+        if (settingsChangedCallback) {
+            settingsChangedCallback(baud, bits, parity, stop);
+        }
+    }
+
+private:
+    Callback<void()> rx;
+    CircBuffer<uint8_t,128> buf;
+    void (*settingsChangedCallback)(int baud, int bits, int parity, int stop);
+};
+
+#endif