Monttory Base

Dependencies:   AUDIO_DISCO_F746NG BSP_DISCO_F746NG EEPROM_DISCO_F746NG LCD_DISCO_F746NG QSPI_DISCO_F746NG SD_DISCO_F746NG SDRAM_DISCO_F746NG TS_DISCO_F746NG FATFileSystem mbed-rtos mbed

Fork of DISCO-F746NG_Monttory_Base by Douglas Choi

Files at this revision

API Documentation at this revision

Comitter:
DouglasK
Date:
Sat Oct 21 03:18:01 2017 +0000
Parent:
12:426bb1c90d59
Commit message:
Monttory Base 01

Changed in this revision

DISCO_F746NG_USBDevice.lib Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/USBAudio/USBAudio.cpp Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/USBAudio/USBAudio.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/USBAudio/USBAudio_Types.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/USBDevice/USBDescriptor.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/USBDevice/USBDevice.cpp Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/USBDevice/USBDevice.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/USBDevice/USBDevice_Types.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/USBDevice/USBEndpoints.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/USBDevice/USBHAL.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/USBHID/USBHID.cpp Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/USBHID/USBHID.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/USBHID/USBHID_Types.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/USBHID/USBKeyboard.cpp Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/USBHID/USBKeyboard.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/USBHID/USBMouse.cpp Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/USBHID/USBMouse.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/USBHID/USBMouseKeyboard.cpp Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/USBHID/USBMouseKeyboard.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/USBMIDI/MIDIMessage.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/USBMIDI/USBMIDI.cpp Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/USBMIDI/USBMIDI.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/USBMSD/USBMSD.cpp Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/USBMSD/USBMSD.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/USBSerial/CircBuffer.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/USBSerial/USBCDC.cpp Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/USBSerial/USBCDC.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/USBSerial/USBSerial.cpp Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/USBSerial/USBSerial.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32F1/TARGET_NUCLEO_F103RB/USBHAL_STM32F103RB.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32F1/TARGET_NUCLEO_F103RB/USBHAL_STM_TARGET.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32F2/TARGET_NUCLEO_F207ZG/USBHAL_STM_TARGET.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xE/TARGET_NUCLEO_F303ZE/USBHAL_STM32F303ZE.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xE/TARGET_NUCLEO_F303ZE/USBHAL_STM_TARGET.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F401xE/TARGET_NUCLEO_F401RE/USBHAL_STM_TARGET.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F407xG/TARGET_DISCO_F407VG/USBHAL_STM_TARGET.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/TARGET_NUCLEO_F411RE/USBHAL_STM_TARGET.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/TARGET_NUCLEO_F412ZG/USBHAL_STM_TARGET.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/TARGET_NUCLEO_F429ZI/USBHAL_STM_TARGET.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/TARGET_NUCLEO_F439ZI/USBHAL_STM_TARGET.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/TARGET_NUCLEO_F446RE/USBHAL_STM_TARGET.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/TARGET_NUCLEO_F446ZE/USBHAL_STM_TARGET.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/TARGET_NUCLEO_F746ZG/USBHAL_STM_TARGET.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F756xG/TARGET_NUCLEO_F756ZG/USBHAL_STM_TARGET.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/TARGET_NUCLEO_F767ZI/USBHAL_STM_TARGET.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/TARGET_DISCO_F769NI/USBHAL_STM32F769NI.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/TARGET_DISCO_F769NI/USBHAL_STM_TARGET.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L053C8/USBHAL_STM32L053C8.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L053C8/USBHAL_STM_TARGET.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L072CZ_LRWAN1/USBHAL_STM32L072CZ.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L072CZ_LRWAN1/USBHAL_STM_TARGET.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/TARGET_DISCO_L475VG_IOT01A/USBHAL_STM32L475VG.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/TARGET_DISCO_L475VG_IOT01A/USBHAL_STM_TARGET.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_DISCO_L476VG/USBHAL_STM32L476VG.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_DISCO_L476VG/USBHAL_STM_TARGET.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/targets/TARGET_STM/USBEndpoint_STM.cpp Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/targets/TARGET_STM/USBEndpoints_STM32.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/targets/TARGET_STM/USBEndpoints_STM32F4.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/targets/TARGET_STM/USBHAL_STM32.cpp Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/targets/TARGET_STM/USBHAL_STM32F4.cpp Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/targets/TARGET_STM/USBHAL_STM_144_64pins.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/targets/TARGET_STM/USBHAL_STM_TARGET.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBDevice/targets/TARGET_STM/USBRegs_STM32.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost.lib Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/USBHost/IUSBEnumerator.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/USBHost/USBDeviceConnected.cpp Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/USBHost/USBDeviceConnected.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/USBHost/USBEndpoint.cpp Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/USBHost/USBEndpoint.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/USBHost/USBHALHost.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/USBHost/USBHost.cpp Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/USBHost/USBHost.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/USBHost/USBHostConf.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/USBHost/USBHostTypes.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/USBHost/dbg.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/USBHost3GModule/IUSBHostSerial.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/USBHost3GModule/IUSBHostSerialListener.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/USBHost3GModule/WANDongle.cpp Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/USBHost3GModule/WANDongle.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/USBHost3GModule/WANDongleInitializer.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/USBHost3GModule/WANDongleSerialPort.cpp Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/USBHost3GModule/WANDongleSerialPort.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/USBHostHID/USBHostKeyboard.cpp Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/USBHostHID/USBHostKeyboard.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/USBHostHID/USBHostMouse.cpp Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/USBHostHID/USBHostMouse.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/USBHostHub/USBHostHub.cpp Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/USBHostHub/USBHostHub.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/USBHostMIDI/USBHostMIDI.cpp Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/USBHostMIDI/USBHostMIDI.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/USBHostMSD/USBHostMSD.cpp Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/USBHostMSD/USBHostMSD.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/USBHostSerial/MtxCircBuffer.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/USBHostSerial/USBHostSerial.cpp Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/USBHostSerial/USBHostSerial.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/targets/TARGET_STM/TARGET_STM32F2/TARGET_NUCLEO_F207ZG/USBHALHost_STM_TARGET.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F401xE/TARGET_NUCLEO_F401RE/USBHALHost_STM_TARGET.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/TARGET_NUCLEO_F411RE/USBHALHost_STM_TARGET.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/TARGET_NUCLEO_F412ZG/USBHALHost_STM_TARGET.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/TARGET_DISCO_F429ZI/USBHALHost_DISCOF429ZI.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/TARGET_DISCO_F429ZI/USBHALHost_STM_TARGET.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/TARGET_NUCLEO_F429ZI/USBHALHost_STM_TARGET.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/TARGET_NUCLEO_F439ZI/USBHALHost_STM_TARGET.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/TARGET_NUCLEO_F446RE/USBHALHost_STM_TARGET.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/TARGET_NUCLEO_F446ZE/USBHALHost_STM_TARGET.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/TARGET_NUCLEO_F746ZG/USBHALHost_STM_TARGET.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F756xG/TARGET_NUCLEO_F756ZG/USBHALHost_STM_TARGET.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/TARGET_NUCLEO_F767ZI/USBHALHost_STM_TARGET.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/TARGET_DISCO_L475VG_IOT01A/USBHALHost_DISCO_L475VG_IOT01A.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/TARGET_DISCO_L475VG_IOT01A/USBHALHost_STM_TARGET.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_DISCO_L476VG/USBHALHost_DISCOL476VG.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_DISCO_L476VG/USBHALHost_STM_TARGET.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_NUCLEO_L476RG/USBHALHost_STM_TARGET.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L486xG/TARGET_NUCLEO_L486RG/USBHALHost_STM_TARGET.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/targets/TARGET_STM/USBEndpoint_STM.cpp Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/targets/TARGET_STM/USBHALHost_STM.cpp Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/targets/TARGET_STM/USBHALHost_STM_144_64pins.h Show annotated file Show diff for this revision Revisions of this file
DISCO_F746NG_USBHost/targets/TARGET_STM/USBHALHost_STM_TARGET.h Show annotated file Show diff for this revision Revisions of this file
--- a/DISCO_F746NG_USBDevice.lib	Sat Oct 21 02:55:07 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-https://os.mbed.com/users/DouglasK/code/DISCO_F746NG_USBDevice/#28d1e1e7f7d1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/USBAudio/USBAudio.cpp	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,641 @@
+/* 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, AudioSampleCorrectType jitter_nb)
+{
+    if ((jitter_nb != RemoveOneSample) && (jitter_nb != AddOneSample)) {
+        jitter_nb = NoCorrection;
+    }
+    /* each sample is 2 bytes */
+    USBDevice::writeNB(EPISO_IN, buf, PACKET_SIZE_ISO_OUT + jitter_nb *(this->channel_nb_out*2), PACKET_SIZE_ISO_OUT+this->channel_nb_out*2);
+}
+
+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+this->channel_nb_out*2, 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+channel_nb_out*2)),                   // wMaxPacketSize
+        (uint8_t)(MSB(PACKET_SIZE_ISO_OUT+channel_nb_out*2)),                   // 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;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/USBAudio/USBAudio.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,337 @@
+/* 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);
+
+    /** Audio Jitter value*/
+    enum AudioSampleCorrectType {
+        RemoveOneSample = -1,
+        NoCorrection = 0,
+        AddOneSample = 1
+    };
+    /**
+     * Write packet in endpoint fifo. assuming tx fifo is empty
+     * @param buf pointer on the audio packet which will be sent
+     * @param jitter_nb : AudioSampleCorrecttype 
+	 **/
+    void writeSync(uint8_t *buf, AudioSampleCorrectType jitter_nb = NoCorrection );
+
+    /**
+    * 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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/USBAudio/USBAudio_Types.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/USBDevice/USBDescriptor.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,74 @@
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+/* Standard descriptor types */
+#define DEVICE_DESCRIPTOR        (1)
+#define CONFIGURATION_DESCRIPTOR (2)
+#define STRING_DESCRIPTOR        (3)
+#define INTERFACE_DESCRIPTOR     (4)
+#define ENDPOINT_DESCRIPTOR      (5)
+#define QUALIFIER_DESCRIPTOR     (6)
+
+/* Standard descriptor lengths */
+#define DEVICE_DESCRIPTOR_LENGTH        (0x12)
+#define CONFIGURATION_DESCRIPTOR_LENGTH (0x09)
+#define INTERFACE_DESCRIPTOR_LENGTH     (0x09)
+#define ENDPOINT_DESCRIPTOR_LENGTH      (0x07)
+
+
+/*string offset*/
+#define STRING_OFFSET_LANGID            (0)
+#define STRING_OFFSET_IMANUFACTURER     (1)
+#define STRING_OFFSET_IPRODUCT          (2)
+#define STRING_OFFSET_ISERIAL           (3)
+#define STRING_OFFSET_ICONFIGURATION    (4)
+#define STRING_OFFSET_IINTERFACE        (5)
+
+/* USB Specification Release Number */
+#define USB_VERSION_2_0 (0x0200)
+
+/* Least/Most significant byte of short integer */
+#define LSB(n)  ((n)&0xff)
+#define MSB(n)  (((n)&0xff00)>>8)
+
+/* Convert physical endpoint number to descriptor endpoint number */
+#define PHY_TO_DESC(endpoint) (((endpoint)>>1) | (((endpoint) & 1) ? 0x80:0))
+
+/* bmAttributes in configuration descriptor */
+/* C_RESERVED must always be set */
+#define C_RESERVED      (1U<<7)
+#define C_SELF_POWERED  (1U<<6)
+#define C_REMOTE_WAKEUP (1U<<5)
+
+/* bMaxPower in configuration descriptor */
+#define C_POWER(mA)     ((mA)/2)
+
+/* bmAttributes in endpoint descriptor */
+#define E_CONTROL       (0x00)
+#define E_ISOCHRONOUS   (0x01)
+#define E_BULK          (0x02)
+#define E_INTERRUPT     (0x03)
+
+/* For isochronous endpoints only: */
+#define E_NO_SYNCHRONIZATION    (0x00)
+#define E_ASYNCHRONOUS          (0x04)
+#define E_ADAPTIVE              (0x08)
+#define E_SYNCHRONOUS           (0x0C)
+#define E_DATA                  (0x00)
+#define E_FEEDBACK              (0x10)
+#define E_IMPLICIT_FEEDBACK     (0x20)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/USBDevice/USBDevice.cpp	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +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;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/USBDevice/USBDevice.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/USBDevice/USBDevice_Types.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,83 @@
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef USBDEVICE_TYPES_H
+#define USBDEVICE_TYPES_H
+
+/* Standard requests */
+#define GET_STATUS        (0)
+#define CLEAR_FEATURE     (1)
+#define SET_FEATURE       (3)
+#define SET_ADDRESS       (5)
+#define GET_DESCRIPTOR    (6)
+#define SET_DESCRIPTOR    (7)
+#define GET_CONFIGURATION (8)
+#define SET_CONFIGURATION (9)
+#define GET_INTERFACE     (10)
+#define SET_INTERFACE     (11)
+
+/* bmRequestType.dataTransferDirection */
+#define HOST_TO_DEVICE (0)
+#define DEVICE_TO_HOST (1)
+
+/* bmRequestType.Type*/
+#define STANDARD_TYPE  (0)
+#define CLASS_TYPE     (1)
+#define VENDOR_TYPE    (2)
+#define RESERVED_TYPE  (3)
+
+/* bmRequestType.Recipient */
+#define DEVICE_RECIPIENT    (0)
+#define INTERFACE_RECIPIENT (1)
+#define ENDPOINT_RECIPIENT  (2)
+#define OTHER_RECIPIENT     (3)
+
+/* Descriptors */
+#define DESCRIPTOR_TYPE(wValue)  (wValue >> 8)
+#define DESCRIPTOR_INDEX(wValue) (wValue & 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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/USBDevice/USBEndpoints.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +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(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_STM32L0) || 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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/USBDevice/USBHAL.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +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 "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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/USBHID/USBHID.cpp	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +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[] = {
+        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;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/USBHID/USBHID.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/USBHID/USBHID_Types.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +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_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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/USBHID/USBKeyboard.cpp	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +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),                         // 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;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/USBHID/USBKeyboard.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,188 @@
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef USBKEYBOARD_H
+#define USBKEYBOARD_H
+
+#include "USBHID.h"
+#include "Stream.h"
+
+/* Modifiers, left keys then right keys. */
+enum MODIFIER_KEY {
+    KEY_CTRL = 0x01,
+    KEY_SHIFT = 0x02,
+    KEY_ALT = 0x04,
+    KEY_LOGO = 0x08,
+    KEY_RCTRL = 0x10,
+    KEY_RSHIFT = 0x20,
+    KEY_RALT = 0x40,
+    KEY_RLOGO = 0x80,
+};
+
+
+enum MEDIA_KEY {
+    KEY_NEXT_TRACK,     /*!< next Track Button */
+    KEY_PREVIOUS_TRACK, /*!< Previous track Button */
+    KEY_STOP,           /*!< Stop Button */
+    KEY_PLAY_PAUSE,     /*!< Play/Pause Button */
+    KEY_MUTE,           /*!< Mute Button */
+    KEY_VOLUME_UP,      /*!< Volume Up Button */
+    KEY_VOLUME_DOWN,    /*!< Volume Down Button */
+};
+
+enum FUNCTION_KEY {
+    KEY_F1 = 128,   /* F1 key */
+    KEY_F2,         /* F2 key */
+    KEY_F3,         /* F3 key */
+    KEY_F4,         /* F4 key */
+    KEY_F5,         /* F5 key */
+    KEY_F6,         /* F6 key */
+    KEY_F7,         /* F7 key */
+    KEY_F8,         /* F8 key */
+    KEY_F9,         /* F9 key */
+    KEY_F10,        /* F10 key */
+    KEY_F11,        /* F11 key */
+    KEY_F12,        /* F12 key */
+
+    KEY_PRINT_SCREEN,   /* Print Screen key */
+    KEY_SCROLL_LOCK,    /* Scroll lock */
+    KEY_CAPS_LOCK,      /* caps lock */
+    KEY_NUM_LOCK,       /* num lock */
+    KEY_INSERT,         /* Insert key */
+    KEY_HOME,           /* Home key */
+    KEY_PAGE_UP,        /* Page Up key */
+    KEY_PAGE_DOWN,      /* Page Down key */
+
+    RIGHT_ARROW,        /* Right arrow */
+    LEFT_ARROW,         /* Left arrow */
+    DOWN_ARROW,         /* Down arrow */
+    UP_ARROW,           /* Up arrow */
+};
+
+/**
+ * USBKeyboard example
+ * @code
+ *
+ * #include "mbed.h"
+ * #include "USBKeyboard.h"
+ *
+ * USBKeyboard key;
+ *
+ * int main(void)
+ * {
+ *   while (1)
+ *   {
+ *       key.printf("Hello World\r\n");
+ *       wait(1);
+ *   }
+ * }
+ *
+ * @endcode
+ */
+class USBKeyboard: public USBHID, public Stream {
+public:
+
+    /**
+    *   Constructor
+    *
+    *
+    * @param leds Leds bus: first: NUM_LOCK, second: CAPS_LOCK, third: SCROLL_LOCK
+    * @param vendor_id Your vendor_id (default: 0x1235)
+    * @param product_id Your product_id (default: 0x0050)
+    * @param product_release Your preoduct_release (default: 0x0001)
+    *
+    */
+    USBKeyboard(uint16_t vendor_id = 0x1235, uint16_t product_id = 0x0050, uint16_t product_release = 0x0001):
+            USBHID(0, 0, vendor_id, product_id, product_release, false) {
+        lock_status = 0;
+        connect();
+    };
+
+    /**
+    * To send a character defined by a modifier(CTRL, SHIFT, ALT) and the key
+    *
+    * @code
+    * //To send CTRL + s (save)
+    *  keyboard.keyCode('s', KEY_CTRL);
+    * @endcode
+    *
+    * @param modifier bit 0: KEY_CTRL, bit 1: KEY_SHIFT, bit 2: KEY_ALT (default: 0)
+    * @param key character to send
+    * @returns true if there is no error, false otherwise
+    */
+    bool keyCode(uint8_t key, uint8_t modifier = 0);
+
+    /**
+    * Send a character
+    *
+    * @param c character to be sent
+    * @returns true if there is no error, false otherwise
+    */
+    virtual int _putc(int c);
+
+    /**
+    * Control media keys
+    *
+    * @param key media key pressed (KEY_NEXT_TRACK, KEY_PREVIOUS_TRACK, KEY_STOP, KEY_PLAY_PAUSE, KEY_MUTE, KEY_VOLUME_UP, KEY_VOLUME_DOWN)
+    * @returns true if there is no error, false otherwise
+    */
+    bool mediaControl(MEDIA_KEY key);
+
+    /*
+    * To define the report descriptor. Warning: this method has to store the length of the report descriptor in reportLength.
+    *
+    * @returns pointer to the report descriptor
+    */
+    virtual uint8_t * reportDesc();
+
+    /*
+    * Called when a data is received on the OUT endpoint. Useful to switch on LED of LOCK keys
+    *
+    * @returns if handle by subclass, return true
+    */
+    virtual bool EPINT_OUT_callback();
+
+    /**
+    * Read status of lock keys. Useful to switch-on/off leds according to key pressed. Only the first three bits of the result is important:
+    *   - First bit: NUM_LOCK
+    *   - Second bit: CAPS_LOCK
+    *   - Third bit: SCROLL_LOCK
+    *
+    * @returns status of lock keys
+    */
+    uint8_t lockStatus();
+
+protected:
+    /*
+    * Get configuration descriptor
+    *
+    * @returns pointer to the configuration descriptor
+    */
+    virtual uint8_t * configurationDesc();
+
+private:
+    //dummy otherwise it doesn,t compile (we must define all methods of an abstract class)
+    virtual int _getc() {
+        return -1;
+    };
+
+    uint8_t lock_status;
+
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/USBHID/USBMouse.cpp	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +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),                         // 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;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/USBHID/USBMouse.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/USBHID/USBMouseKeyboard.cpp	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +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);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/USBHID/USBMouseKeyboard.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,220 @@
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef USBMOUSEKEYBOARD_H
+#define USBMOUSEKEYBOARD_H
+
+#define REPORT_ID_KEYBOARD 1
+#define REPORT_ID_MOUSE 2
+#define REPORT_ID_VOLUME 3
+
+#include "USBMouse.h"
+#include "USBKeyboard.h"
+#include "Stream.h"
+#include "USBHID.h"
+
+/**
+ * USBMouseKeyboard example
+ * @code
+ *
+ * #include "mbed.h"
+ * #include "USBMouseKeyboard.h"
+ *
+ * USBMouseKeyboard key_mouse;
+ *
+ * int main(void)
+ * {
+ *   while(1)
+ *   {
+ *       key_mouse.move(20, 0);
+ *       key_mouse.printf("Hello From MBED\r\n");
+ *       wait(1);
+ *   }
+ * }
+ * @endcode
+ *
+ *
+ * @code
+ *
+ * #include "mbed.h"
+ * #include "USBMouseKeyboard.h"
+ *
+ * USBMouseKeyboard key_mouse(ABS_MOUSE);
+ *
+ * int main(void)
+ * {
+ *   while(1)
+ *   {
+ *       key_mouse.move(X_MAX_ABS/2, Y_MAX_ABS/2);
+ *       key_mouse.printf("Hello from MBED\r\n");
+ *       wait(1);
+ *   }
+ * }
+ * @endcode
+ */
+class USBMouseKeyboard: public USBHID, public Stream
+{
+    public:
+
+        /**
+        *   Constructor
+        *
+        * @param mouse_type Mouse type: ABS_MOUSE (absolute mouse) or REL_MOUSE (relative mouse) (default: REL_MOUSE)
+        * @param leds Leds bus: first: NUM_LOCK, second: CAPS_LOCK, third: SCROLL_LOCK
+        * @param vendor_id Your vendor_id (default: 0x1234)
+        * @param product_id Your product_id (default: 0x0001)
+        * @param product_release Your preoduct_release (default: 0x0001)
+        *
+        */
+        USBMouseKeyboard(MOUSE_TYPE mouse_type = REL_MOUSE, uint16_t vendor_id = 0x0021, uint16_t product_id = 0x0011, uint16_t product_release = 0x0001):
+            USBHID(0, 0, vendor_id, product_id, product_release, false)
+            {
+                lock_status = 0;
+                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 x-axis position
+        * @param y y-axis position
+        * @returns true if there is no error, false otherwise
+        */
+        bool move(int16_t x, int16_t y);
+
+        /**
+        * Press one or several buttons
+        *
+        * @param button button state (ex: press(MOUSE_LEFT))
+        * @returns true if there is no error, false otherwise
+        */
+        bool press(uint8_t button);
+
+        /**
+        * Release one or several buttons
+        *
+        * @param button button state (ex: release(MOUSE_LEFT))
+        * @returns true if there is no error, false otherwise
+        */
+        bool release(uint8_t button);
+
+        /**
+        * Double click (MOUSE_LEFT)
+        *
+        * @returns true if there is no error, false otherwise
+        */
+        bool doubleClick();
+
+        /**
+        * Click
+        *
+        * @param button state of the buttons ( ex: clic(MOUSE_LEFT))
+        * @returns true if there is no error, false otherwise
+        */
+        bool click(uint8_t button);
+
+        /**
+        * Scrolling
+        *
+        * @param z value of the wheel (>0 to go down, <0 to go up)
+        * @returns true if there is no error, false otherwise
+        */
+        bool scroll(int8_t z);
+
+        /**
+        * To send a character defined by a modifier(CTRL, SHIFT, ALT) and the key
+        *
+        * @code
+        * //To send CTRL + s (save)
+        *  keyboard.keyCode('s', KEY_CTRL);
+        * @endcode
+        *
+        * @param modifier bit 0: KEY_CTRL, bit 1: KEY_SHIFT, bit 2: KEY_ALT (default: 0)
+        * @param key character to send
+        * @returns true if there is no error, false otherwise
+        */
+        bool keyCode(uint8_t key, uint8_t modifier = 0);
+
+        /**
+        * Send a character
+        *
+        * @param c character to be sent
+        * @returns true if there is no error, false otherwise
+        */
+        virtual int _putc(int c);
+
+        /**
+        * Control media keys
+        *
+        * @param key media key pressed (KEY_NEXT_TRACK, KEY_PREVIOUS_TRACK, KEY_STOP, KEY_PLAY_PAUSE, KEY_MUTE, KEY_VOLUME_UP, KEY_VOLUME_DOWN)
+        * @returns true if there is no error, false otherwise
+        */
+        bool mediaControl(MEDIA_KEY key);
+
+        /**
+        * Read status of lock keys. Useful to switch-on/off leds according to key pressed. Only the first three bits of the result is important:
+        *   - First bit: NUM_LOCK
+        *   - Second bit: CAPS_LOCK
+        *   - Third bit: SCROLL_LOCK
+        *
+        * @returns status of lock keys
+        */
+        uint8_t lockStatus();
+
+        /*
+        * To define the report descriptor. Warning: this method has to store the length of the report descriptor in reportLength.
+        *
+        * @returns pointer to the report descriptor
+        */
+        virtual uint8_t * reportDesc();
+
+        /*
+        * Called when a data is received on the OUT endpoint. Useful to switch on LED of LOCK keys
+        *
+        * @returns if handle by subclass, return true
+        */
+        virtual bool EPINT_OUT_callback();
+
+
+    private:
+        bool mouseWrite(int8_t x, int8_t y, uint8_t buttons, int8_t z);
+        MOUSE_TYPE mouse_type;
+        uint8_t button;
+        bool mouseSend(int8_t x, int8_t y, uint8_t buttons, int8_t z);
+
+        uint8_t lock_status;
+
+        //dummy otherwise it doesn't compile (we must define all methods of an abstract class)
+        virtual int _getc() { return -1;}
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/USBMIDI/MIDIMessage.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/USBMIDI/USBMIDI.cpp	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +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;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/USBMIDI/USBMIDI.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,112 @@
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef USBMIDI_H
+#define USBMIDI_H
+
+/* These headers are included for child class. */
+#include "USBEndpoints.h"
+#include "USBDescriptor.h"
+#include "USBDevice_Types.h"
+
+#include "USBDevice.h"
+#include "MIDIMessage.h"
+
+#define DEFAULT_CONFIGURATION (1)
+
+/**
+* USBMIDI example
+*
+* @code
+* #include "mbed.h"
+* #include "USBMIDI.h"
+*
+* USBMIDI midi;
+*
+* int main() {
+*    while (1) {
+*        for(int i=48; i<83; i++) {     // send some messages!
+*            midi.write(MIDIMessage::NoteOn(i));
+*            wait(0.25);
+*            midi.write(MIDIMessage::NoteOff(i));
+*            wait(0.5);
+*        }
+*    }
+* }
+* @endcode
+*/
+class USBMIDI: public USBDevice {
+public:
+
+    /**
+    * Constructor
+    *
+    * @param vendor_id Your vendor_id
+    * @param product_id Your product_id
+    * @param product_release Your preoduct_release
+    */
+    USBMIDI(uint16_t vendor_id = 0x0700, uint16_t product_id = 0x0101, uint16_t product_release = 0x0001);
+
+    /**
+     * Send a MIDIMessage
+     *
+     * @param m The MIDIMessage to send
+     */
+    void write(MIDIMessage m);
+
+    /**
+     * Attach a callback for when a MIDIEvent is received
+     *
+     * @param fptr function pointer
+     */
+    void attach(void (*fptr)(MIDIMessage));
+
+
+protected:
+    virtual bool EPBULK_OUT_callback();
+    virtual bool USBCallback_setConfiguration(uint8_t configuration);
+    /*
+    * Get string product descriptor
+    *
+    * @returns pointer to the string product descriptor
+    */
+    virtual uint8_t * stringIproductDesc();
+
+    /*
+    * Get string interface descriptor
+    *
+    * @returns pointer to the string interface descriptor
+    */
+    virtual uint8_t * stringIinterfaceDesc();
+
+    /*
+    * Get configuration descriptor
+    *
+    * @returns pointer to the configuration descriptor
+    */
+    virtual uint8_t * configurationDesc();
+
+private:
+    uint8_t data[MAX_MIDI_MESSAGE_SIZE+1];
+    uint8_t cur_data;
+    bool data_end;
+    
+    void (*midi_evt)(MIDIMessage);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/USBMSD/USBMSD.cpp	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +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;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/USBMSD/USBMSD.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/USBSerial/CircBuffer.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,63 @@
+/* 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 CIRCBUFFER_H
+#define CIRCBUFFER_H
+
+template <class T, int Size>
+class CircBuffer {
+public:
+    CircBuffer():write(0), read(0){}
+    bool isFull() {
+        return ((write + 1) % size == read);
+    };
+
+    bool isEmpty() {
+        return (read == write);
+    };
+
+    void queue(T k) {
+        if (isFull()) {
+            read++;
+            read %= size;
+        }
+        buf[write++] = k;
+        write %= size;
+    }
+
+    uint16_t available() {
+        return (write >= read) ? write - read : size - read + write;
+    };
+
+    bool dequeue(T * c) {
+        bool empty = isEmpty();
+        if (!empty) {
+            *c = buf[read++];
+            read %= size;
+        }
+        return(!empty);
+    };
+
+private:
+    volatile uint16_t write;
+    volatile uint16_t read;
+    static const int size = Size+1;  //a modern optimizer should be able to remove this so it uses no ram.
+    T buf[Size+1];
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/USBSerial/USBCDC.cpp	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,290 @@
+/* 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);
+}
+
+void USBCDC::USBCallback_busReset(void) {
+    terminal_connected = false;
+};
+
+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;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/USBSerial/USBCDC.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,124 @@
+/* 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);
+    virtual void USBCallback_busReset(void);
+    volatile bool terminal_connected;
+
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/USBSerial/USBSerial.cpp	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,72 @@
+/* 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();
+}
+
+bool USBSerial::connected() {
+    return terminal_connected;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/USBSerial/USBSerial.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,168 @@
+/* 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();
+
+     /**
+    * Check if the terminal is connected.
+    *
+    * @returns connection status
+    */
+    bool connected();
+
+    /** 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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32F1/TARGET_NUCLEO_F103RB/USBHAL_STM32F103RB.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,147 @@
+/* Copyright (c) 2016 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 USBHAL_STM32F103RB
+#define USBHAL_STM32F103RB
+
+#define USBHAL_IRQn  USB_LP_CAN1_RX0_IRQn
+
+
+#define NB_ENDPOINT  8
+/*  must be multiple of 4 bytes */
+#define MAXTRANSFER_SIZE  0x200
+#define FIFO_USB_RAM_SIZE (MAXTRANSFER_SIZE+MAX_PACKET_SIZE_EP0+MAX_PACKET_SIZE_EP1+MAX_PACKET_SIZE_EP2+MAX_PACKET_SIZE_EP3)
+#if (FIFO_USB_RAM_SIZE > 0x500)
+#error "FIFO dimensioning incorrect"
+#endif
+
+typedef struct
+{
+    USBHAL *inst;
+    void (USBHAL::*bus_reset)(void);
+    void (USBHAL::*sof)(int frame);
+    void (USBHAL::*connect_change)(unsigned int  connected);
+    void (USBHAL::*suspend_change)(unsigned int suspended);
+    void (USBHAL::*ep0_setup)(void);
+    void (USBHAL::*ep0_in)(void);
+    void (USBHAL::*ep0_out)(void);
+    void (USBHAL::*ep0_read)(void);
+    bool (USBHAL::*ep_realise)(uint8_t endpoint, uint32_t maxPacket, uint32_t flags);
+    bool (USBHAL::*epCallback[2*NB_ENDPOINT-2])(void);
+    uint8_t epComplete[8];
+    /*  memorize dummy buffer used for reception */
+    uint32_t pBufRx[MAXTRANSFER_SIZE>>2];
+    uint32_t pBufRx0[MAX_PACKET_SIZE_EP0>>2];
+    gpio_t usb_switch;
+}USBHAL_Private_t;
+
+void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state)
+{
+    USBHAL_Private_t *priv=((USBHAL_Private_t *)(hpcd->pData));
+    gpio_write(&(priv->usb_switch),!state);
+}
+
+uint32_t HAL_PCDEx_GetTxFiFo(PCD_HandleTypeDef *hpcd, uint8_t fifo)
+{
+    return 1024;
+}
+void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
+{
+    USBHAL_Private_t *priv=((USBHAL_Private_t *)(hpcd->pData));
+    USBHAL *obj= priv->inst;
+    uint32_t sofnum = (hpcd->Instance->FNR) & USB_FNR_FN;
+    void (USBHAL::*func)(int frame) = priv->sof;
+    (obj->*func)(sofnum);
+}
+
+USBHAL * USBHAL::instance;
+
+USBHAL::USBHAL(void)
+{
+    /*  init parameter  */
+    USBHAL_Private_t *HALPriv = new(USBHAL_Private_t);
+    /*  initialized all field of init including 0 field  */
+    /*  constructor does not fill with zero */
+    hpcd.Instance = USB;
+    /*  initialized all field of init including 0 field  */
+    /*  constructor does not fill with zero */
+    memset(&hpcd.Init, 0, sizeof(hpcd.Init));
+    hpcd.Init.dev_endpoints = NB_ENDPOINT;
+    hpcd.Init.ep0_mps =   MAX_PACKET_SIZE_EP0;
+    hpcd.Init.phy_itface = PCD_PHY_EMBEDDED;
+    hpcd.Init.Sof_enable = 1;
+    hpcd.Init.speed = PCD_SPEED_FULL;
+    /*  pass instance for usage inside call back */
+    HALPriv->inst = this;
+    HALPriv->bus_reset = &USBHAL::busReset;
+    HALPriv->suspend_change = &USBHAL::suspendStateChanged;
+    HALPriv->connect_change = &USBHAL::connectStateChanged;
+    HALPriv->sof = &USBHAL::SOF;
+    HALPriv->ep0_setup = &USBHAL::EP0setupCallback;
+    HALPriv->ep_realise = &USBHAL::realiseEndpoint;
+    HALPriv->ep0_in = &USBHAL::EP0in;
+    HALPriv->ep0_out = &USBHAL::EP0out;
+    HALPriv->ep0_read = &USBHAL::EP0read;
+    hpcd.pData = (void*)HALPriv;
+    HALPriv->epCallback[0] = &USBHAL::EP1_OUT_callback;
+    HALPriv->epCallback[1] = &USBHAL::EP1_IN_callback;
+    HALPriv->epCallback[2] = &USBHAL::EP2_OUT_callback;
+    HALPriv->epCallback[3] = &USBHAL::EP2_IN_callback;
+    HALPriv->epCallback[4] = &USBHAL::EP3_OUT_callback;
+    HALPriv->epCallback[5] = &USBHAL::EP3_IN_callback;
+    instance = this;
+
+
+    /* Configure USB VBUS GPIO */
+    gpio_init_out(&HALPriv->usb_switch,PB_14);
+    gpio_mode(&HALPriv->usb_switch,OpenDrain);
+    /* Configure USB FS GPIOs */
+
+    /* Configure DM DP Pins
+     *   - USB-DP (D+ of the USB connector) <======> PA12 (Nucleo board)
+     *   Make sure to connect a 1.5KOhm pull up to USB-DP PA12 pin
+     *   (permanent pull-up)
+     - USB-DM (D- of the USB connector) <======> PA11 (Nucleo board)
+     */
+
+    pin_function(PA_11, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_MODE_AF_INPUT));
+    pin_function(PA_12, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_MODE_AF_INPUT));
+
+    __HAL_RCC_USB_CLK_ENABLE();
+
+    hpcd.State = HAL_PCD_STATE_RESET;
+
+    HAL_PCD_Init(&hpcd);
+    /* hardcoded size of FIFO according definition*/
+    HAL_PCDEx_PMAConfig(&hpcd , 0x00 , PCD_SNG_BUF, 0x30);
+    HAL_PCDEx_PMAConfig(&hpcd , 0x80 , PCD_SNG_BUF, 0x70);
+    HAL_PCDEx_PMAConfig(&hpcd , 0x01 , PCD_SNG_BUF, 0x90);
+    HAL_PCDEx_PMAConfig(&hpcd , 0x81 , PCD_SNG_BUF, 0xb0);
+#if 0
+    HAL_PCDEx_PMAConfig(&hpcd , 0x2, PCD_DBL_BUF, 0x018000b0);
+#else
+    HAL_PCDEx_PMAConfig(&hpcd , 0x2, PCD_SNG_BUF, 0x100);
+#endif
+    HAL_PCDEx_PMAConfig(&hpcd , 0x82, PCD_SNG_BUF, 0x120);
+
+    NVIC_SetVector(USBHAL_IRQn,(uint32_t)&_usbisr);
+    NVIC_SetPriority( USBHAL_IRQn, 1);
+
+    HAL_PCD_Start(&hpcd);
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32F1/TARGET_NUCLEO_F103RB/USBHAL_STM_TARGET.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,19 @@
+/* Copyright (c) 2016 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 "USBHAL_STM32F103RB.h"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32F2/TARGET_NUCLEO_F207ZG/USBHAL_STM_TARGET.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,19 @@
+/* Copyright (c) 2016 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 "USBHAL_STM_144_64pins.h"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xE/TARGET_NUCLEO_F303ZE/USBHAL_STM32F303ZE.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,127 @@
+/* Copyright (c) 2016 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 USBHAL_STM32F303ZE_H
+#define USBHAL_STM32F303ZE_H
+#define USBHAL_IRQn  USB_LP_CAN_RX0_IRQn
+/*  must be multiple of 4 bytes */
+#define NB_ENDPOINT 8
+#define MAXTRANSFER_SIZE  0x200
+#define FIFO_USB_RAM_SIZE (MAXTRANSFER_SIZE+MAX_PACKET_SIZE_EP0+MAX_PACKET_SIZE_EP1+MAX_PACKET_SIZE_EP2+MAX_PACKET_SIZE_EP3)
+#if (FIFO_USB_RAM_SIZE > 0x500)
+#error "FIFO dimensioning incorrect"
+#endif
+
+typedef struct
+{
+	USBHAL *inst;
+	void (USBHAL::*bus_reset)(void);
+	void (USBHAL::*sof)(int frame);
+	void (USBHAL::*connect_change)(unsigned int  connected);
+	void (USBHAL::*suspend_change)(unsigned int suspended);
+	void (USBHAL::*ep0_setup)(void);
+	void (USBHAL::*ep0_in)(void);
+	void (USBHAL::*ep0_out)(void);
+	void (USBHAL::*ep0_read)(void);
+	bool (USBHAL::*ep_realise)(uint8_t endpoint, uint32_t maxPacket, uint32_t flags);
+	bool (USBHAL::*epCallback[6])(void);
+	uint8_t epComplete[2*NB_ENDPOINT];
+	/*  memorize dummy buffer used for reception */
+	uint32_t pBufRx[MAXTRANSFER_SIZE>>2];
+	uint32_t pBufRx0[MAX_PACKET_SIZE_EP0>>2];
+    gpio_t usb_switch;
+}USBHAL_Private_t;
+
+uint32_t HAL_PCDEx_GetTxFiFo(PCD_HandleTypeDef *hpcd, uint8_t fifo)
+{
+        return 1024;
+}
+
+void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state){
+    USBHAL_Private_t *priv=((USBHAL_Private_t *)(hpcd->pData));
+    gpio_write(&(priv->usb_switch),state);
+}
+
+void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) {
+    USBHAL_Private_t *priv=((USBHAL_Private_t *)(hpcd->pData));
+    USBHAL *obj= priv->inst;
+    uint32_t sofnum = (hpcd->Instance->FNR) & USB_FNR_FN;
+    void (USBHAL::*func)(int frame) = priv->sof;
+    (obj->*func)(sofnum);
+}
+
+USBHAL * USBHAL::instance;
+
+USBHAL::USBHAL(void) {
+    /*  init parameter  */
+    USBHAL_Private_t *HALPriv = new(USBHAL_Private_t);
+    hpcd.Instance = USB;
+    /*  initialized Init to zero (constructor does not zero initialized the
+     *  area */
+    /*  initialized all field of init including 0 field  */
+    /*  constructor does not fill with zero */
+    memset(&hpcd.Init, 0, sizeof(hpcd.Init));
+    hpcd.Init.dev_endpoints = NB_ENDPOINT;
+    hpcd.Init.ep0_mps =   MAX_PACKET_SIZE_EP0;
+    hpcd.Init.phy_itface = PCD_PHY_EMBEDDED;
+    hpcd.Init.Sof_enable = 1;
+    hpcd.Init.speed = PCD_SPEED_FULL;
+    /*  pass instance for usage inside call back */
+    HALPriv->inst = this;
+    HALPriv->bus_reset = &USBHAL::busReset;
+    HALPriv->suspend_change = &USBHAL::suspendStateChanged;
+    HALPriv->connect_change = &USBHAL::connectStateChanged;
+    HALPriv->sof = &USBHAL::SOF;
+    HALPriv->ep0_setup = &USBHAL::EP0setupCallback;
+    HALPriv->ep_realise = &USBHAL::realiseEndpoint;
+    HALPriv->ep0_in = &USBHAL::EP0in;
+    HALPriv->ep0_out = &USBHAL::EP0out;
+    HALPriv->ep0_read = &USBHAL::EP0read;
+    hpcd.pData = (void*)HALPriv;
+    HALPriv->epCallback[0] = &USBHAL::EP1_OUT_callback;
+    HALPriv->epCallback[1] = &USBHAL::EP1_IN_callback;
+    HALPriv->epCallback[2] = &USBHAL::EP2_OUT_callback;
+    HALPriv->epCallback[3] = &USBHAL::EP2_IN_callback;
+    HALPriv->epCallback[4] = &USBHAL::EP3_OUT_callback;
+    HALPriv->epCallback[5] = &USBHAL::EP3_IN_callback;
+    instance = this;
+    __HAL_RCC_GPIOA_CLK_ENABLE();
+    /* Configure USB DM pin. This is optional, and maintained only for user guidance. */
+    pin_function(PA_11, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF14_USB));
+    pin_function(PA_12, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF14_USB));
+    __HAL_RCC_GPIOG_CLK_ENABLE();
+    gpio_init_out(&HALPriv->usb_switch,PG_6);
+    /* Enable USB Clock */
+    __HAL_RCC_USB_CLK_ENABLE();
+    /* Enable SYSCFG Clock */
+    __HAL_RCC_SYSCFG_CLK_ENABLE();
+    hpcd.State = HAL_PCD_STATE_RESET;
+    HAL_PCD_Init(&hpcd);
+    /* hardcoded size of FIFO according definition*/
+    HAL_PCDEx_PMAConfig(&hpcd , 0x00 , PCD_SNG_BUF, 0x30);
+    HAL_PCDEx_PMAConfig(&hpcd , 0x80 , PCD_SNG_BUF, 0x70);
+#if 1
+    HAL_PCDEx_PMAConfig(&hpcd , 0x3, PCD_DBL_BUF, 0x018000b0);
+#else
+    HAL_PCDEx_PMAConfig(&hpcd , 0x3, PCD_SNG_BUF, 0x180);
+#endif
+    HAL_PCDEx_PMAConfig(&hpcd , 0x83, PCD_SNG_BUF, 0xb0);
+    NVIC_SetVector(USBHAL_IRQn,(uint32_t)&_usbisr);
+    NVIC_SetPriority(USBHAL_IRQn, 1);
+    HAL_PCD_Start(&hpcd);
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xE/TARGET_NUCLEO_F303ZE/USBHAL_STM_TARGET.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,18 @@
+/* Copyright (c) 2016 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 "USBHAL_STM32F303ZE.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F401xE/TARGET_NUCLEO_F401RE/USBHAL_STM_TARGET.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,18 @@
+/* Copyright (c) 2016 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 "USBHAL_STM_144_64pins.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F407xG/TARGET_DISCO_F407VG/USBHAL_STM_TARGET.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,18 @@
+/* Copyright (c) 2016 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 "USBHAL_STM_144_64pins.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/TARGET_NUCLEO_F411RE/USBHAL_STM_TARGET.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,19 @@
+/* Copyright (c) 2016 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 "USBHAL_STM_144_64pins.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/TARGET_NUCLEO_F412ZG/USBHAL_STM_TARGET.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,18 @@
+/* Copyright (c) 2016 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 "USBHAL_STM_144_64pins.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/TARGET_NUCLEO_F429ZI/USBHAL_STM_TARGET.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,18 @@
+/* Copyright (c) 2016 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 "USBHAL_STM_144_64pins.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/TARGET_NUCLEO_F439ZI/USBHAL_STM_TARGET.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,18 @@
+/* Copyright (c) 2016 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 "USBHAL_STM_144_64pins.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/TARGET_NUCLEO_F446RE/USBHAL_STM_TARGET.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,18 @@
+/* Copyright (c) 2016 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 "USBHAL_STM_144_64pins.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/TARGET_NUCLEO_F446ZE/USBHAL_STM_TARGET.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,18 @@
+/* Copyright (c) 2016 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 "USBHAL_STM_144_64pins.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/TARGET_NUCLEO_F746ZG/USBHAL_STM_TARGET.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,19 @@
+/* Copyright (c) 2016 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 "USBHAL_STM_144_64pins.h"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F756xG/TARGET_NUCLEO_F756ZG/USBHAL_STM_TARGET.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,19 @@
+/* Copyright (c) 2016 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 "USBHAL_STM_144_64pins.h"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/TARGET_NUCLEO_F767ZI/USBHAL_STM_TARGET.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,18 @@
+/* Copyright (c) 2016 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 "USBHAL_STM_144_64pins.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/TARGET_DISCO_F769NI/USBHAL_STM32F769NI.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,147 @@
+/* Copyright (c) 2016 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 USBHAL_STM32F769NI_H
+#define USBHAL_STM32F769NI_H
+#define USBHAL_IRQn  OTG_HS_IRQn
+/*  must be multiple of 4 bytes */
+#define NB_ENDPOINT 4
+#define MAXTRANSFER_SIZE  0x200
+#define FIFO_USB_RAM_SIZE (MAXTRANSFER_SIZE+MAX_PACKET_SIZE_EP0+MAX_PACKET_SIZE_EP1+MAX_PACKET_SIZE_EP2+MAX_PACKET_SIZE_EP3)
+#if (FIFO_USB_RAM_SIZE > 0x500)
+#error "FIFO dimensioning incorrect"
+#endif
+
+typedef struct
+{
+    USBHAL *inst;
+    void (USBHAL::*bus_reset)(void);
+    void (USBHAL::*sof)(int frame);
+    void (USBHAL::*connect_change)(unsigned int  connected);
+    void (USBHAL::*suspend_change)(unsigned int suspended);
+    void (USBHAL::*ep0_setup)(void);
+    void (USBHAL::*ep0_in)(void);
+    void (USBHAL::*ep0_out)(void);
+    void (USBHAL::*ep0_read)(void);
+    bool (USBHAL::*ep_realise)(uint8_t endpoint, uint32_t maxPacket, uint32_t flags);
+    bool (USBHAL::*epCallback[2*NB_ENDPOINT-2])(void);
+    /*  memorize dummy buffer used for reception */
+    uint32_t pBufRx[MAXTRANSFER_SIZE>>2];
+    uint32_t pBufRx0[MAX_PACKET_SIZE_EP0>>2];
+    uint8_t epComplete[2*NB_ENDPOINT];
+}USBHAL_Private_t;
+
+uint32_t HAL_PCDEx_GetTxFiFo(PCD_HandleTypeDef *hpcd, uint8_t fifo)
+{
+    uint32_t len;
+    if (fifo == 0) len = hpcd->Instance->DIEPTXF0_HNPTXFSIZ>>16;
+    else
+        len =  hpcd->Instance->DIEPTXF[fifo - 1] >> 16;
+    return len*4;
+}
+void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) 
+{
+    USBHAL_Private_t *priv=((USBHAL_Private_t *)(hpcd->pData));
+    USBHAL *obj= priv->inst;
+    USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
+    uint32_t sofnum = (USBx_DEVICE->DSTS & USB_OTG_DSTS_FNSOF) >> 8;
+    void (USBHAL::*func)(int frame) = priv->sof;
+    /* fix me  call with same frame number */
+    (obj->*func)(sofnum);
+}
+
+
+USBHAL * USBHAL::instance;
+
+USBHAL::USBHAL(void) {
+    /*  init parameter  */
+    USBHAL_Private_t *HALPriv = new(USBHAL_Private_t);
+    hpcd.Instance = USB_OTG_HS;
+    memset(&hpcd.Init, 0, sizeof(hpcd.Init));
+    hpcd.Init.dev_endpoints = NB_ENDPOINT;
+    hpcd.Init.ep0_mps =   MAX_PACKET_SIZE_EP0;
+    hpcd.Init.phy_itface = PCD_PHY_ULPI;
+    hpcd.Init.Sof_enable = 0;
+
+    hpcd.Init.speed = PCD_SPEED_HIGH;
+    //hpcd.Init.vbus_sensing_enable = 0;
+    //hpcd.Init.lpm_enable = 0;
+    /*  pass instance for usage inside call back */
+    HALPriv->inst = this;
+    HALPriv->bus_reset = &USBHAL::busReset;
+    HALPriv->suspend_change = &USBHAL::suspendStateChanged;
+    HALPriv->connect_change = &USBHAL::connectStateChanged;
+    HALPriv->sof = &USBHAL::SOF;
+    HALPriv->ep0_setup = &USBHAL::EP0setupCallback;
+    HALPriv->ep_realise = &USBHAL::realiseEndpoint;
+    HALPriv->ep0_in = &USBHAL::EP0in;
+    HALPriv->ep0_out = &USBHAL::EP0out;
+    HALPriv->ep0_read = &USBHAL::EP0read;
+    hpcd.pData = (void*)HALPriv;
+    HALPriv->epCallback[0] = &USBHAL::EP1_OUT_callback;
+    HALPriv->epCallback[1] = &USBHAL::EP1_IN_callback;
+    HALPriv->epCallback[2] = &USBHAL::EP2_OUT_callback;
+    HALPriv->epCallback[3] = &USBHAL::EP2_IN_callback;
+    HALPriv->epCallback[4] = &USBHAL::EP3_OUT_callback;
+    HALPriv->epCallback[5] = &USBHAL::EP3_IN_callback;
+    instance = this;
+    /* Enable power and clocking */
+    __HAL_RCC_GPIOA_CLK_ENABLE();
+    __HAL_RCC_GPIOB_CLK_ENABLE();
+    __HAL_RCC_GPIOC_CLK_ENABLE();
+    __HAL_RCC_GPIOH_CLK_ENABLE();
+    __HAL_RCC_GPIOI_CLK_ENABLE();
+
+    pin_function(PA_5, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF10_OTG_HS)); // CLK
+    pin_function(PA_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF10_OTG_HS)); // D0
+
+    pin_function(PB_0, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF10_OTG_HS)); // D1
+    pin_function(PB_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF10_OTG_HS)); // D2
+    pin_function(PB_5, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF10_OTG_HS)); // D3
+    pin_function(PB_10, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF10_OTG_HS)); // D4
+    pin_function(PB_11, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF10_OTG_HS)); // D5
+    pin_function(PB_12, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF10_OTG_HS)); // D6
+    pin_function(PB_13, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF10_OTG_HS)); // D7
+
+    pin_function(PC_0, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF10_OTG_HS)); // STP
+    pin_function(PH_4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF10_OTG_HS)); // NXT
+    pin_function(PI_11, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF10_OTG_HS)); // DIR
+
+    __HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE();
+    __HAL_RCC_USB_OTG_HS_CLK_ENABLE();
+
+    __HAL_RCC_SYSCFG_CLK_ENABLE();
+    hpcd.State = HAL_PCD_STATE_RESET;
+    HAL_PCD_Init(&hpcd);
+    /* 1.25kbytes */
+    /* min value 16 (= 16 x 4 bytes) */
+    /*  max value 256 (= 1K bytes ) */
+    /*  maximum sum is 0x140 */
+    HAL_PCDEx_SetRxFiFo(&hpcd, (MAXTRANSFER_SIZE/4));
+    /*  bulk/int 64 bytes in FS  */
+    HAL_PCDEx_SetTxFiFo(&hpcd, 0, (MAX_PACKET_SIZE_EP0/4)+1);
+    /*  bulk/int bytes in FS */
+    HAL_PCDEx_SetTxFiFo(&hpcd, 1, (MAX_PACKET_SIZE_EP1/4)+1);
+    HAL_PCDEx_SetTxFiFo(&hpcd, 2, (MAX_PACKET_SIZE_EP2/4));
+    /* ISOchronous */
+    HAL_PCDEx_SetTxFiFo(&hpcd, 3, (MAX_PACKET_SIZE_EP3/4));
+    NVIC_SetVector(USBHAL_IRQn, (uint32_t)&_usbisr);
+    NVIC_SetPriority(USBHAL_IRQn, 1);
+    HAL_PCD_Start(&hpcd);
+}
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/TARGET_DISCO_F769NI/USBHAL_STM_TARGET.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,19 @@
+/* Copyright (c) 2016 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 "USBHAL_STM32F769NI.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L053C8/USBHAL_STM32L053C8.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,134 @@
+/* Copyright (c) 2016 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 USBHAL_STM32L053C8_H
+#define USBHAL_STM32L053C8_H
+
+#define USBHAL_IRQn  USB_IRQn
+
+/*  must be multiple of 4 bytes */
+#define NB_ENDPOINT 8
+#define MAXTRANSFER_SIZE  0x200
+#define FIFO_USB_RAM_SIZE (MAXTRANSFER_SIZE+MAX_PACKET_SIZE_EP0+MAX_PACKET_SIZE_EP1+MAX_PACKET_SIZE_EP2+MAX_PACKET_SIZE_EP3)
+#if (FIFO_USB_RAM_SIZE > 0x500)
+#error "FIFO dimensioning incorrect"
+#endif
+
+typedef struct
+{
+	USBHAL *inst;
+	void (USBHAL::*bus_reset)(void);
+	void (USBHAL::*sof)(int frame);
+	void (USBHAL::*connect_change)(unsigned int  connected);
+	void (USBHAL::*suspend_change)(unsigned int suspended);
+	void (USBHAL::*ep0_setup)(void);
+	void (USBHAL::*ep0_in)(void);
+	void (USBHAL::*ep0_out)(void);
+	void (USBHAL::*ep0_read)(void);
+	bool (USBHAL::*ep_realise)(uint8_t endpoint, uint32_t maxPacket, uint32_t flags);
+	bool (USBHAL::*epCallback[6])(void);
+	uint8_t epComplete[2*NB_ENDPOINT];
+	/*  memorize dummy buffer used for reception */
+	uint32_t pBufRx[MAXTRANSFER_SIZE>>2];
+	uint32_t pBufRx0[MAX_PACKET_SIZE_EP0>>2];
+    gpio_t usb_switch;
+}USBHAL_Private_t;
+
+uint32_t HAL_PCDEx_GetTxFiFo(PCD_HandleTypeDef *hpcd, uint8_t fifo)
+{
+        return 1024;
+}
+
+void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state)
+{
+    USBHAL_Private_t *priv=((USBHAL_Private_t *)(hpcd->pData));
+    gpio_write(&(priv->usb_switch),state);
+}
+
+void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
+{
+    USBHAL_Private_t *priv=((USBHAL_Private_t *)(hpcd->pData));
+    USBHAL *obj= priv->inst;
+    uint32_t sofnum = (hpcd->Instance->FNR) & USB_FNR_FN;
+    void (USBHAL::*func)(int frame) = priv->sof;
+    (obj->*func)(sofnum);
+}
+
+USBHAL * USBHAL::instance;
+
+USBHAL::USBHAL(void)
+{
+    /*  init parameter  */
+    USBHAL_Private_t *HALPriv = new(USBHAL_Private_t);
+    hpcd.Instance = USB;
+    /*  initialized Init to zero (constructor does not zero initialized the
+     *  area */
+    /*  initialized all field of init including 0 field  */
+    /*  constructor does not fill with zero */
+    memset(&hpcd.Init, 0, sizeof(hpcd.Init));
+    hpcd.Init.dev_endpoints = NB_ENDPOINT;
+    hpcd.Init.ep0_mps =   MAX_PACKET_SIZE_EP0;
+    hpcd.Init.phy_itface = PCD_PHY_EMBEDDED;
+    hpcd.Init.Sof_enable = 1;
+    hpcd.Init.speed = PCD_SPEED_FULL;
+    /*  pass instance for usage inside call back */
+    HALPriv->inst = this;
+    HALPriv->bus_reset = &USBHAL::busReset;
+    HALPriv->suspend_change = &USBHAL::suspendStateChanged;
+    HALPriv->connect_change = &USBHAL::connectStateChanged;
+    HALPriv->sof = &USBHAL::SOF;
+    HALPriv->ep0_setup = &USBHAL::EP0setupCallback;
+    HALPriv->ep_realise = &USBHAL::realiseEndpoint;
+    HALPriv->ep0_in = &USBHAL::EP0in;
+    HALPriv->ep0_out = &USBHAL::EP0out;
+    HALPriv->ep0_read = &USBHAL::EP0read;
+    hpcd.pData = (void*)HALPriv;
+    HALPriv->epCallback[0] = &USBHAL::EP1_OUT_callback;
+    HALPriv->epCallback[1] = &USBHAL::EP1_IN_callback;
+    HALPriv->epCallback[2] = &USBHAL::EP2_OUT_callback;
+    HALPriv->epCallback[3] = &USBHAL::EP2_IN_callback;
+    HALPriv->epCallback[4] = &USBHAL::EP3_OUT_callback;
+    HALPriv->epCallback[5] = &USBHAL::EP3_IN_callback;
+    instance = this;
+    
+    /* Configure USB DM pin. This is optional, and maintained only for user guidance. */
+    __HAL_RCC_GPIOA_CLK_ENABLE();
+    pin_function(PA_11, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF2_USB));
+    pin_function(PA_12, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF2_USB));
+    
+    /* Enable USB Clock */
+    __HAL_RCC_USB_CLK_ENABLE();
+    
+    /* Enable SYSCFG Clock */
+    __HAL_RCC_SYSCFG_CLK_ENABLE();
+    hpcd.State = HAL_PCD_STATE_RESET;
+    HAL_PCD_Init(&hpcd);
+    
+    /* hardcoded size of FIFO according definition*/
+    HAL_PCDEx_PMAConfig(&hpcd , 0x00 , PCD_SNG_BUF, 0x30);
+    HAL_PCDEx_PMAConfig(&hpcd , 0x80 , PCD_SNG_BUF, 0x70);
+#if 1
+    HAL_PCDEx_PMAConfig(&hpcd , 0x3, PCD_DBL_BUF, 0x018000b0);
+#else
+    HAL_PCDEx_PMAConfig(&hpcd , 0x3, PCD_SNG_BUF, 0x180);
+#endif
+    HAL_PCDEx_PMAConfig(&hpcd , 0x83, PCD_SNG_BUF, 0xb0);
+    NVIC_SetVector(USBHAL_IRQn,(uint32_t)&_usbisr);
+    NVIC_SetPriority(USBHAL_IRQn, 1);
+    HAL_PCD_Start(&hpcd);
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L053C8/USBHAL_STM_TARGET.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,18 @@
+/* Copyright (c) 2016 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 "USBHAL_STM32L053C8.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L072CZ_LRWAN1/USBHAL_STM32L072CZ.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,131 @@
+/* Copyright (c) 2016 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 USBHAL_STM32L072CZ_H
+#define USBHAL_STM32L072CZ_H
+
+#define USBHAL_IRQn  USB_IRQn
+
+/*  must be multiple of 4 bytes */
+#define NB_ENDPOINT 8
+#define MAXTRANSFER_SIZE  0x200
+#define FIFO_USB_RAM_SIZE (MAXTRANSFER_SIZE+MAX_PACKET_SIZE_EP0+MAX_PACKET_SIZE_EP1+MAX_PACKET_SIZE_EP2+MAX_PACKET_SIZE_EP3)
+#if (FIFO_USB_RAM_SIZE > 0x500)
+#error "FIFO dimensioning incorrect"
+#endif
+
+typedef struct
+{
+	USBHAL *inst;
+	void (USBHAL::*bus_reset)(void);
+	void (USBHAL::*sof)(int frame);
+	void (USBHAL::*connect_change)(unsigned int  connected);
+	void (USBHAL::*suspend_change)(unsigned int suspended);
+	void (USBHAL::*ep0_setup)(void);
+	void (USBHAL::*ep0_in)(void);
+	void (USBHAL::*ep0_out)(void);
+	void (USBHAL::*ep0_read)(void);
+	bool (USBHAL::*ep_realise)(uint8_t endpoint, uint32_t maxPacket, uint32_t flags);
+	bool (USBHAL::*epCallback[6])(void);
+	uint8_t epComplete[2*NB_ENDPOINT];
+	/*  memorize dummy buffer used for reception */
+	uint32_t pBufRx[MAXTRANSFER_SIZE>>2];
+	uint32_t pBufRx0[MAX_PACKET_SIZE_EP0>>2];
+    gpio_t usb_switch;
+}USBHAL_Private_t;
+
+uint32_t HAL_PCDEx_GetTxFiFo(PCD_HandleTypeDef *hpcd, uint8_t fifo)
+{
+        return 1024;
+}
+
+void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state)
+{
+    USBHAL_Private_t *priv=((USBHAL_Private_t *)(hpcd->pData));
+    gpio_write(&(priv->usb_switch),state);
+}
+
+void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
+{
+    USBHAL_Private_t *priv=((USBHAL_Private_t *)(hpcd->pData));
+    USBHAL *obj= priv->inst;
+    uint32_t sofnum = (hpcd->Instance->FNR) & USB_FNR_FN;
+    void (USBHAL::*func)(int frame) = priv->sof;
+    (obj->*func)(sofnum);
+}
+
+USBHAL * USBHAL::instance;
+
+USBHAL::USBHAL(void)
+{
+    /*  init parameter  */
+    USBHAL_Private_t *HALPriv = new(USBHAL_Private_t);
+    hpcd.Instance = USB;
+    /*  initialized Init to zero (constructor does not zero initialized the
+     *  area */
+    /*  initialized all field of init including 0 field  */
+    /*  constructor does not fill with zero */
+    memset(&hpcd.Init, 0, sizeof(hpcd.Init));
+    hpcd.Init.dev_endpoints = NB_ENDPOINT;
+    hpcd.Init.ep0_mps =   MAX_PACKET_SIZE_EP0;
+    hpcd.Init.phy_itface = PCD_PHY_EMBEDDED;
+    hpcd.Init.Sof_enable = 1;
+    hpcd.Init.speed = PCD_SPEED_FULL;
+    /*  pass instance for usage inside call back */
+    HALPriv->inst = this;
+    HALPriv->bus_reset = &USBHAL::busReset;
+    HALPriv->suspend_change = &USBHAL::suspendStateChanged;
+    HALPriv->connect_change = &USBHAL::connectStateChanged;
+    HALPriv->sof = &USBHAL::SOF;
+    HALPriv->ep0_setup = &USBHAL::EP0setupCallback;
+    HALPriv->ep_realise = &USBHAL::realiseEndpoint;
+    HALPriv->ep0_in = &USBHAL::EP0in;
+    HALPriv->ep0_out = &USBHAL::EP0out;
+    HALPriv->ep0_read = &USBHAL::EP0read;
+    hpcd.pData = (void*)HALPriv;
+    HALPriv->epCallback[0] = &USBHAL::EP1_OUT_callback;
+    HALPriv->epCallback[1] = &USBHAL::EP1_IN_callback;
+    HALPriv->epCallback[2] = &USBHAL::EP2_OUT_callback;
+    HALPriv->epCallback[3] = &USBHAL::EP2_IN_callback;
+    HALPriv->epCallback[4] = &USBHAL::EP3_OUT_callback;
+    HALPriv->epCallback[5] = &USBHAL::EP3_IN_callback;
+    instance = this;
+    
+    /* Configure USB DM pin. This is optional, and maintained only for user guidance. */
+    __HAL_RCC_GPIOA_CLK_ENABLE();
+    pin_function(PA_11, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF2_USB));
+    pin_function(PA_12, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF2_USB));
+    
+    /* Enable USB Clock */
+    __HAL_RCC_USB_CLK_ENABLE();
+    
+    /* Enable SYSCFG Clock */
+    __HAL_RCC_SYSCFG_CLK_ENABLE();
+    hpcd.State = HAL_PCD_STATE_RESET;
+    HAL_PCD_Init(&hpcd);
+    
+    /* hardcoded size of FIFO according definition*/
+    HAL_PCDEx_PMAConfig(&hpcd , 0x00 , PCD_SNG_BUF, 0x30);
+    HAL_PCDEx_PMAConfig(&hpcd , 0x80 , PCD_SNG_BUF, 0x70);
+    HAL_PCDEx_PMAConfig(&hpcd , 0x3, PCD_DBL_BUF, 0x018000b0);
+    HAL_PCDEx_PMAConfig(&hpcd , 0x83, PCD_SNG_BUF, 0xb0);
+
+    NVIC_SetVector(USBHAL_IRQn,(uint32_t)&_usbisr);
+    NVIC_SetPriority(USBHAL_IRQn, 1);
+    HAL_PCD_Start(&hpcd);
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L072CZ_LRWAN1/USBHAL_STM_TARGET.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,18 @@
+/* Copyright (c) 2016 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 "USBHAL_STM32L072CZ.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/TARGET_DISCO_L475VG_IOT01A/USBHAL_STM32L475VG.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,145 @@
+/* Copyright (c) 2016 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 USBHAL_STM32L475VG
+#define USBHAL_STM32L475VG
+
+#define USBHAL_IRQn  OTG_FS_IRQn
+
+
+#define NB_ENDPOINT  4
+/*  must be multiple of 4 bytes */
+#define MAXTRANSFER_SIZE  0x200
+#define FIFO_USB_RAM_SIZE (MAXTRANSFER_SIZE+MAX_PACKET_SIZE_EP0+MAX_PACKET_SIZE_EP1+MAX_PACKET_SIZE_EP2+MAX_PACKET_SIZE_EP3)
+#if (FIFO_USB_RAM_SIZE > 0x500)
+#error "FIFO dimensioning incorrect"
+#endif
+
+typedef struct
+{
+    USBHAL *inst;
+    void (USBHAL::*bus_reset)(void);
+    void (USBHAL::*sof)(int frame);
+    void (USBHAL::*connect_change)(unsigned int  connected);
+    void (USBHAL::*suspend_change)(unsigned int suspended);
+    void (USBHAL::*ep0_setup)(void);
+    void (USBHAL::*ep0_in)(void);
+    void (USBHAL::*ep0_out)(void);
+    void (USBHAL::*ep0_read)(void);
+    bool (USBHAL::*ep_realise)(uint8_t endpoint, uint32_t maxPacket, uint32_t flags);
+    bool (USBHAL::*epCallback[2*NB_ENDPOINT-2])(void);
+    uint8_t epComplete[8];
+    /*  memorize dummy buffer used for reception */
+    uint32_t pBufRx[MAXTRANSFER_SIZE>>2];
+    uint32_t pBufRx0[MAX_PACKET_SIZE_EP0>>2];
+}USBHAL_Private_t;
+
+uint32_t HAL_PCDEx_GetTxFiFo(PCD_HandleTypeDef *hpcd, uint8_t fifo)
+{
+    uint32_t len;
+    if (fifo == 0) len = hpcd->Instance->DIEPTXF0_HNPTXFSIZ>>16;
+    else
+        len =  hpcd->Instance->DIEPTXF[fifo - 1] >> 16;
+    return len*4;
+}
+void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) {
+    USBHAL_Private_t *priv=((USBHAL_Private_t *)(hpcd->pData));
+    USBHAL *obj= priv->inst;
+    USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
+    uint32_t sofnum = (USBx_DEVICE->DSTS & USB_OTG_DSTS_FNSOF) >> 8;
+    void (USBHAL::*func)(int frame) = priv->sof;
+    /* fix me  call with same frame number */
+    (obj->*func)(sofnum);
+}
+
+USBHAL * USBHAL::instance;
+
+USBHAL::USBHAL(void) {
+    /*  init parameter  */
+    USBHAL_Private_t *HALPriv = new(USBHAL_Private_t);
+    /*  initialized all field of init including 0 field  */
+    /*  constructor does not fill with zero */
+    hpcd.Instance = USB_OTG_FS;
+    /*  initialized all field of init including 0 field  */
+    /*  constructor does not fill with zero */
+    memset(&hpcd.Init, 0, sizeof(hpcd.Init));
+    hpcd.Init.dev_endpoints = NB_ENDPOINT;
+    hpcd.Init.ep0_mps =   MAX_PACKET_SIZE_EP0;
+    hpcd.Init.phy_itface = PCD_PHY_EMBEDDED;
+    hpcd.Init.Sof_enable = 1;
+    hpcd.Init.speed = PCD_SPEED_FULL;
+    /*  pass instance for usage inside call back */
+    HALPriv->inst = this;
+    HALPriv->bus_reset = &USBHAL::busReset;
+    HALPriv->suspend_change = &USBHAL::suspendStateChanged;
+    HALPriv->connect_change = &USBHAL::connectStateChanged;
+    HALPriv->sof = &USBHAL::SOF;
+    HALPriv->ep0_setup = &USBHAL::EP0setupCallback;
+    HALPriv->ep_realise = &USBHAL::realiseEndpoint;
+    HALPriv->ep0_in = &USBHAL::EP0in;
+    HALPriv->ep0_out = &USBHAL::EP0out;
+    HALPriv->ep0_read = &USBHAL::EP0read;
+    hpcd.pData = (void*)HALPriv;
+    HALPriv->epCallback[0] = &USBHAL::EP1_OUT_callback;
+    HALPriv->epCallback[1] = &USBHAL::EP1_IN_callback;
+    HALPriv->epCallback[2] = &USBHAL::EP2_OUT_callback;
+    HALPriv->epCallback[3] = &USBHAL::EP2_IN_callback;
+    HALPriv->epCallback[4] = &USBHAL::EP3_OUT_callback;
+    HALPriv->epCallback[5] = &USBHAL::EP3_IN_callback;
+    instance = this;
+
+    __HAL_RCC_PWR_CLK_ENABLE();
+
+    HAL_PWREx_EnableVddUSB(); 
+    /* Configure USB VBUS GPIO */
+    __HAL_RCC_GPIOC_CLK_ENABLE();
+
+    /* Configure USB FS GPIOs */
+    __HAL_RCC_GPIOA_CLK_ENABLE();
+
+    /* Configure DM DP Pins */
+    pin_function(PA_11, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF10_OTG_FS));
+    pin_function(PA_12, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF10_OTG_FS));
+
+    /* Configure VBUS Pin */
+    pin_function(PC_11, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF10_OTG_FS));
+
+    __HAL_RCC_USB_OTG_FS_CLK_ENABLE();
+
+    hpcd.State = HAL_PCD_STATE_RESET;
+
+    HAL_PCD_Init(&hpcd);
+    /* 1.25kbytes */
+    /* min value 16 (= 16 x 4 bytes) */
+    /*  max value 256 (= 1K bytes ) */
+    /*  maximum sum is 0x140 */
+    HAL_PCDEx_SetRxFiFo(&hpcd, (MAXTRANSFER_SIZE/4));
+    /*  bulk/int 64 bytes in FS  */
+    HAL_PCDEx_SetTxFiFo(&hpcd, 0, (MAX_PACKET_SIZE_EP0/4)+1);
+    /*  bulk/int bytes in FS */
+    HAL_PCDEx_SetTxFiFo(&hpcd, 1, (MAX_PACKET_SIZE_EP1/4)+1);
+    HAL_PCDEx_SetTxFiFo(&hpcd, 2, (MAX_PACKET_SIZE_EP2/4));
+    /* ISOchronous */
+    HAL_PCDEx_SetTxFiFo(&hpcd, 3, (MAX_PACKET_SIZE_EP3/4));
+
+    NVIC_SetVector(USBHAL_IRQn,(uint32_t)&_usbisr);
+    NVIC_SetPriority( USBHAL_IRQn, 1);
+
+    HAL_PCD_Start(&hpcd);
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/TARGET_DISCO_L475VG_IOT01A/USBHAL_STM_TARGET.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,18 @@
+/* Copyright (c) 2016 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 "USBHAL_STM32L475VG.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_DISCO_L476VG/USBHAL_STM32L476VG.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,145 @@
+/* Copyright (c) 2016 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 USBHAL_STM32L476VG
+#define USBHAL_STM32L476VG
+
+#define USBHAL_IRQn  OTG_FS_IRQn
+
+
+#define NB_ENDPOINT  4
+/*  must be multiple of 4 bytes */
+#define MAXTRANSFER_SIZE  0x200
+#define FIFO_USB_RAM_SIZE (MAXTRANSFER_SIZE+MAX_PACKET_SIZE_EP0+MAX_PACKET_SIZE_EP1+MAX_PACKET_SIZE_EP2+MAX_PACKET_SIZE_EP3)
+#if (FIFO_USB_RAM_SIZE > 0x500)
+#error "FIFO dimensioning incorrect"
+#endif
+
+typedef struct
+{
+    USBHAL *inst;
+    void (USBHAL::*bus_reset)(void);
+    void (USBHAL::*sof)(int frame);
+    void (USBHAL::*connect_change)(unsigned int  connected);
+    void (USBHAL::*suspend_change)(unsigned int suspended);
+    void (USBHAL::*ep0_setup)(void);
+    void (USBHAL::*ep0_in)(void);
+    void (USBHAL::*ep0_out)(void);
+    void (USBHAL::*ep0_read)(void);
+    bool (USBHAL::*ep_realise)(uint8_t endpoint, uint32_t maxPacket, uint32_t flags);
+    bool (USBHAL::*epCallback[2*NB_ENDPOINT-2])(void);
+    uint8_t epComplete[8];
+    /*  memorize dummy buffer used for reception */
+    uint32_t pBufRx[MAXTRANSFER_SIZE>>2];
+    uint32_t pBufRx0[MAX_PACKET_SIZE_EP0>>2];
+}USBHAL_Private_t;
+
+uint32_t HAL_PCDEx_GetTxFiFo(PCD_HandleTypeDef *hpcd, uint8_t fifo)
+{
+    uint32_t len;
+    if (fifo == 0) len = hpcd->Instance->DIEPTXF0_HNPTXFSIZ>>16;
+    else
+        len =  hpcd->Instance->DIEPTXF[fifo - 1] >> 16;
+    return len*4;
+}
+void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) {
+    USBHAL_Private_t *priv=((USBHAL_Private_t *)(hpcd->pData));
+    USBHAL *obj= priv->inst;
+    USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
+    uint32_t sofnum = (USBx_DEVICE->DSTS & USB_OTG_DSTS_FNSOF) >> 8;
+    void (USBHAL::*func)(int frame) = priv->sof;
+    /* fix me  call with same frame number */
+    (obj->*func)(sofnum);
+}
+
+USBHAL * USBHAL::instance;
+
+USBHAL::USBHAL(void) {
+    /*  init parameter  */
+    USBHAL_Private_t *HALPriv = new(USBHAL_Private_t);
+    /*  initialized all field of init including 0 field  */
+    /*  constructor does not fill with zero */
+    hpcd.Instance = USB_OTG_FS;
+    /*  initialized all field of init including 0 field  */
+    /*  constructor does not fill with zero */
+    memset(&hpcd.Init, 0, sizeof(hpcd.Init));
+    hpcd.Init.dev_endpoints = NB_ENDPOINT;
+    hpcd.Init.ep0_mps =   MAX_PACKET_SIZE_EP0;
+    hpcd.Init.phy_itface = PCD_PHY_EMBEDDED;
+    hpcd.Init.Sof_enable = 1;
+    hpcd.Init.speed = PCD_SPEED_FULL;
+    /*  pass instance for usage inside call back */
+    HALPriv->inst = this;
+    HALPriv->bus_reset = &USBHAL::busReset;
+    HALPriv->suspend_change = &USBHAL::suspendStateChanged;
+    HALPriv->connect_change = &USBHAL::connectStateChanged;
+    HALPriv->sof = &USBHAL::SOF;
+    HALPriv->ep0_setup = &USBHAL::EP0setupCallback;
+    HALPriv->ep_realise = &USBHAL::realiseEndpoint;
+    HALPriv->ep0_in = &USBHAL::EP0in;
+    HALPriv->ep0_out = &USBHAL::EP0out;
+    HALPriv->ep0_read = &USBHAL::EP0read;
+    hpcd.pData = (void*)HALPriv;
+    HALPriv->epCallback[0] = &USBHAL::EP1_OUT_callback;
+    HALPriv->epCallback[1] = &USBHAL::EP1_IN_callback;
+    HALPriv->epCallback[2] = &USBHAL::EP2_OUT_callback;
+    HALPriv->epCallback[3] = &USBHAL::EP2_IN_callback;
+    HALPriv->epCallback[4] = &USBHAL::EP3_OUT_callback;
+    HALPriv->epCallback[5] = &USBHAL::EP3_IN_callback;
+    instance = this;
+
+    __HAL_RCC_PWR_CLK_ENABLE();
+
+    HAL_PWREx_EnableVddUSB(); 
+    /* Configure USB VBUS GPIO */
+    __HAL_RCC_GPIOC_CLK_ENABLE();
+
+    /* Configure USB FS GPIOs */
+    __HAL_RCC_GPIOA_CLK_ENABLE();
+
+    /* Configure DM DP Pins */
+    pin_function(PA_11, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF10_OTG_FS));
+    pin_function(PA_12, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF10_OTG_FS));
+
+    /* Configure VBUS Pin */
+    pin_function(PC_11, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF10_OTG_FS));
+
+    __HAL_RCC_USB_OTG_FS_CLK_ENABLE();
+
+    hpcd.State = HAL_PCD_STATE_RESET;
+
+    HAL_PCD_Init(&hpcd);
+    /* 1.25kbytes */
+    /* min value 16 (= 16 x 4 bytes) */
+    /*  max value 256 (= 1K bytes ) */
+    /*  maximum sum is 0x140 */
+    HAL_PCDEx_SetRxFiFo(&hpcd, (MAXTRANSFER_SIZE/4));
+    /*  bulk/int 64 bytes in FS  */
+    HAL_PCDEx_SetTxFiFo(&hpcd, 0, (MAX_PACKET_SIZE_EP0/4)+1);
+    /*  bulk/int bytes in FS */
+    HAL_PCDEx_SetTxFiFo(&hpcd, 1, (MAX_PACKET_SIZE_EP1/4)+1);
+    HAL_PCDEx_SetTxFiFo(&hpcd, 2, (MAX_PACKET_SIZE_EP2/4));
+    /* ISOchronous */
+    HAL_PCDEx_SetTxFiFo(&hpcd, 3, (MAX_PACKET_SIZE_EP3/4));
+
+    NVIC_SetVector(USBHAL_IRQn,(uint32_t)&_usbisr);
+    NVIC_SetPriority( USBHAL_IRQn, 1);
+
+    HAL_PCD_Start(&hpcd);
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_DISCO_L476VG/USBHAL_STM_TARGET.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,18 @@
+/* Copyright (c) 2016 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 "USBHAL_STM32L476VG.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/targets/TARGET_STM/USBEndpoint_STM.cpp	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,183 @@
+/* mbed USBHost Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * 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_STM) && defined(USBHOST_OTHER)
+
+#include "dbg.h"
+#include "USBEndpoint.h"
+extern uint32_t HAL_HCD_HC_GetMaxPacket(HCD_HandleTypeDef *hhcd, uint8_t chn_num);
+extern uint32_t HAL_HCD_HC_GetType(HCD_HandleTypeDef *hhcd, uint8_t chn_num);
+extern void HAL_HCD_DisableInt(HCD_HandleTypeDef* hhcd, uint8_t chn_num);
+extern void HAL_HCD_EnableInt(HCD_HandleTypeDef* hhcd, uint8_t chn_num);
+
+
+
+
+void USBEndpoint::init(HCED * hced_, ENDPOINT_TYPE type_, ENDPOINT_DIRECTION dir_, uint32_t size, uint8_t ep_number, HCTD* td_list_[2])
+{
+    HCD_HandleTypeDef *hhcd;
+    uint32_t *addr;
+
+    hced = hced_;
+    type = type_;
+    dir = dir_;
+    setup = (type == CONTROL_ENDPOINT) ? true : false;
+
+    //TDs have been allocated by the host
+    memcpy((HCTD**)td_list, td_list_, sizeof(HCTD*)*2); //TODO: Maybe should add a param for td_list size... at least a define
+    memset(td_list_[0], 0, sizeof(HCTD));
+    memset(td_list_[1], 0, sizeof(HCTD));
+
+    td_list[0]->ep = this;
+    td_list[1]->ep = this;
+
+    address = (ep_number & 0x7F) | ((dir - 1) << 7);
+    this->size = size;
+    this->ep_number = ep_number;
+    transfer_len = 0;
+    transferred = 0;
+    buf_start = 0;
+    nextEp = NULL;
+
+    td_current = td_list[0];
+    td_next = td_list[1];
+    /*  remove potential post pending from previous endpoint */
+    ep_queue.get(0);
+    intf_nb = 0;
+    hhcd = (HCD_HandleTypeDef*)hced->hhcd;
+    addr = &((uint32_t *)hhcd->pData)[hced->ch_num];
+    *addr = 0;
+    state = USB_TYPE_IDLE;
+    speed =false;
+}
+void USBEndpoint::setSize(uint32_t size)
+{
+    this->size = size;
+}
+
+
+void USBEndpoint::setDeviceAddress(uint8_t addr)
+{
+    HCD_HandleTypeDef *hhcd;
+    uint8_t hcd_speed = HCD_SPEED_FULL;
+    /* fix me : small speed device with hub not supported
+    if (this->speed) hcd_speed = HCD_SPEED_LOW; */
+    if (this->speed) {
+        USB_WARN("small speed device on hub not supported");
+    }
+    MBED_ASSERT(HAL_HCD_HC_Init((HCD_HandleTypeDef*)hced->hhcd,hced->ch_num, address, addr, hcd_speed,  type, size)!=HAL_BUSY);
+    this->device_address = addr;
+
+}
+
+void USBEndpoint::setSpeed(uint8_t speed)
+{
+    this->speed = speed;
+}
+
+
+
+void USBEndpoint::setState(USB_TYPE st)
+{
+    /*  modify this state is possible only with a plug   */
+    if (state == USB_TYPE_FREE) {
+        return;
+    }
+
+    state = st;
+    if (st == USB_TYPE_FREE) {
+        HCD_HandleTypeDef *hhcd = (HCD_HandleTypeDef*)hced->hhcd;
+        uint32_t *addr = &((uint32_t *)hhcd->pData)[hced->ch_num];
+        if ((*addr) && (type != INTERRUPT_ENDPOINT)) {
+            this->ep_queue.put((uint8_t*)1);
+        }
+        MBED_ASSERT(HAL_HCD_HC_Halt((HCD_HandleTypeDef*)hced->hhcd, hced->ch_num)!=HAL_BUSY);
+        HAL_HCD_DisableInt((HCD_HandleTypeDef*)hced->hhcd, hced->ch_num);
+        *addr = 0;
+
+    }
+    if (st == USB_TYPE_ERROR) {
+        MBED_ASSERT(HAL_HCD_HC_Halt((HCD_HandleTypeDef*)hced->hhcd, hced->ch_num)!=HAL_BUSY);
+        HAL_HCD_DisableInt((HCD_HandleTypeDef*)hced->hhcd, hced->ch_num);
+
+    }
+    if (st == USB_TYPE_ERROR) {
+        uint8_t hcd_speed = HCD_SPEED_FULL;
+        /* small speed device with hub not supported
+           if (this->speed) hcd_speed = HCD_SPEED_LOW;*/
+        MBED_ASSERT(HAL_HCD_HC_Init((HCD_HandleTypeDef*)hced->hhcd,hced->ch_num, address, 0, hcd_speed,  type, size)!=HAL_BUSY);
+    }
+}
+
+
+extern uint32_t HAL_HCD_HC_GetMaxPacket(HCD_HandleTypeDef *hhcd, uint8_t chn_num);
+extern uint32_t HAL_HCD_HC_GetType(HCD_HandleTypeDef *hhcd, uint8_t chn_num);
+
+
+USB_TYPE USBEndpoint::queueTransfer()
+{
+    HCD_HandleTypeDef *hhcd = (HCD_HandleTypeDef*)hced->hhcd;
+    uint32_t *addr = &((uint32_t *)hhcd->pData)[hced->ch_num];
+    uint32_t type = HAL_HCD_HC_GetType(hhcd, hced->ch_num);
+    uint32_t max_size =  HAL_HCD_HC_GetMaxPacket(hhcd, hced->ch_num);
+    /*  if a packet is queue on disconnected ; no solution for now */
+    if (state == USB_TYPE_FREE)  {
+        td_current->state =  USB_TYPE_FREE;
+        return USB_TYPE_FREE;
+    }
+    ep_queue.get(0);
+    MBED_ASSERT(*addr ==0);
+    transfer_len =   td_current->size <= max_size ? td_current->size : max_size;
+    buf_start = (uint8_t *)td_current->currBufPtr;
+
+    //Now add this free TD at this end of the queue
+    state = USB_TYPE_PROCESSING;
+    /*  one request */
+    td_current->nextTD = (hcTd*)0;
+#if defined(MAX_NYET_RETRY)
+    td_current->retry = 0;
+#endif
+    td_current->setup = setup;
+    *addr = (uint32_t)td_current;
+    /*  dir /setup is inverted for ST */
+    /* token is useful only ctrl endpoint */
+    /*  last parameter is ping ? */
+    MBED_ASSERT(HAL_HCD_HC_SubmitRequest((HCD_HandleTypeDef*)hced->hhcd, hced->ch_num, dir-1, type,!setup,(uint8_t*) td_current->currBufPtr, transfer_len, 0)==HAL_OK);
+    HAL_HCD_EnableInt((HCD_HandleTypeDef*)hced->hhcd, hced->ch_num);
+
+    return USB_TYPE_PROCESSING;
+}
+
+void USBEndpoint::unqueueTransfer(volatile HCTD * td)
+{
+    if (state==USB_TYPE_FREE) {
+        return;
+    }
+    uint32_t *addr = &((uint32_t *)((HCD_HandleTypeDef*)hced->hhcd)->pData)[hced->ch_num];
+    td->state=0;
+    td->currBufPtr=0;
+    td->size=0;
+    td->nextTD=0;
+    *addr = 0;
+    td_current = td_next;
+    td_next = td;
+}
+
+void USBEndpoint::queueEndpoint(USBEndpoint * ed)
+{
+    nextEp = ed;
+}
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/targets/TARGET_STM/USBEndpoints_STM32.h	Sat Oct 21 03:18:01 2017 +0000
@@ -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)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/targets/TARGET_STM/USBEndpoints_STM32F4.h	Sat Oct 21 03:18:01 2017 +0000
@@ -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_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_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)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/targets/TARGET_STM/USBHAL_STM32.cpp	Sat Oct 21 03:18:01 2017 +0000
@@ -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
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/targets/TARGET_STM/USBHAL_STM32F4.cpp	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,416 @@
+/* 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_STM32F4) && !defined(USB_STM_HAL)
+
+#include "USBHAL.h"
+#include "USBRegs_STM32.h"
+#include "pinmap.h"
+
+USBHAL * USBHAL::instance;
+
+static volatile int epComplete = 0;
+
+static uint32_t bufferEnd = 0;
+static const uint32_t rxFifoSize = 512;
+static uint32_t rxFifoCount = 0;
+
+static uint32_t setupBuffer[MAX_PACKET_SIZE_EP0 >> 2];
+
+uint32_t USBHAL::endpointReadcore(uint8_t endpoint, uint8_t *buffer) {
+    return 0;
+}
+
+USBHAL::USBHAL(void) {
+    NVIC_DisableIRQ(OTG_FS_IRQn);
+    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;
+
+    // Enable power and clocking
+    RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
+
+#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));
+    pin_function(PA_11, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF10_OTG_FS));
+    pin_function(PA_12, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF10_OTG_FS));
+#else
+    pin_function(PA_8, STM_PIN_DATA(2, 10));
+    pin_function(PA_9, STM_PIN_DATA(0, 0));
+    pin_function(PA_10, STM_PIN_DATA(2, 10));
+    pin_function(PA_11, STM_PIN_DATA(2, 10));
+    pin_function(PA_12, STM_PIN_DATA(2, 10));
+
+    // Set ID pin to open drain with pull-up resistor
+    pin_mode(PA_10, OpenDrain);
+    GPIOA->PUPDR &= ~(0x3 << 20);
+    GPIOA->PUPDR |= 1 << 20;
+
+    // Set VBUS pin to open drain
+    pin_mode(PA_9, OpenDrain);
+#endif
+
+    RCC->AHB2ENR |= RCC_AHB2ENR_OTGFSEN;
+
+    // Enable interrupts
+    OTG_FS->GREGS.GAHBCFG |= (1 << 0);
+
+    // Turnaround time to maximum value - too small causes packet loss
+    OTG_FS->GREGS.GUSBCFG |= (0xF << 10);
+
+    // Unmask global interrupts
+    OTG_FS->GREGS.GINTMSK |= (1 << 3) | // SOF
+                             (1 << 4) | // RX FIFO not empty
+                             (1 << 12); // USB reset
+
+    OTG_FS->DREGS.DCFG |= (0x3 << 0) | // Full speed
+                          (1 << 2); // Non-zero-length status OUT handshake
+
+    OTG_FS->GREGS.GCCFG |= (1 << 19) | // Enable VBUS sensing
+                           (1 << 16); // Power Up
+
+    instance = this;
+    NVIC_SetVector(OTG_FS_IRQn, (uint32_t)&_usbisr);
+    NVIC_SetPriority(OTG_FS_IRQn, 1);
+}
+
+USBHAL::~USBHAL(void) {
+}
+
+void USBHAL::connect(void) {
+    NVIC_EnableIRQ(OTG_FS_IRQn);
+}
+
+void USBHAL::disconnect(void) {
+    NVIC_DisableIRQ(OTG_FS_IRQn);
+}
+
+void USBHAL::configureDevice(void) {
+    // Not needed
+}
+
+void USBHAL::unconfigureDevice(void) {
+    // Not needed
+}
+
+void USBHAL::setAddress(uint8_t address) {
+    OTG_FS->DREGS.DCFG |= (address << 4);
+    EP0write(0, 0);
+}
+
+bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket,
+                             uint32_t flags) {
+    uint32_t epIndex = endpoint >> 1;
+
+    uint32_t type;
+    switch (endpoint) {
+        case EP0IN:
+        case EP0OUT:
+            type = 0;
+            break;
+        case EPISO_IN:
+        case EPISO_OUT:
+            type = 1;
+        case EPBULK_IN:
+        case EPBULK_OUT:
+            type = 2;
+            break;
+        case EPINT_IN:
+        case EPINT_OUT:
+            type = 3;
+            break;
+    }
+
+    // Generic in or out EP controls
+    uint32_t control = (maxPacket << 0) | // Packet size
+                       (1 << 15) | // Active endpoint
+                       (type << 18); // Endpoint type
+
+    if (endpoint & 0x1) { // In Endpoint
+        // Set up the Tx FIFO
+        if (endpoint == EP0IN) {
+            OTG_FS->GREGS.DIEPTXF0_HNPTXFSIZ = ((maxPacket >> 2) << 16) |
+                                               (bufferEnd << 0);
+        }
+        else {
+            OTG_FS->GREGS.DIEPTXF[epIndex - 1] = ((maxPacket >> 2) << 16) |
+                                                 (bufferEnd << 0);
+        }
+        bufferEnd += maxPacket >> 2;
+
+        // Set the In EP specific control settings
+        if (endpoint != EP0IN) {
+            control |= (1 << 28); // SD0PID
+        }
+
+        control |= (epIndex << 22) | // TxFIFO index
+                   (1 << 27); // SNAK
+        OTG_FS->INEP_REGS[epIndex].DIEPCTL = control;
+
+        // Unmask the interrupt
+        OTG_FS->DREGS.DAINTMSK |= (1 << epIndex);
+    }
+    else { // Out endpoint
+        // Set the out EP specific control settings
+        control |= (1 << 26); // CNAK
+        OTG_FS->OUTEP_REGS[epIndex].DOEPCTL = control;
+
+        // Unmask the interrupt
+        OTG_FS->DREGS.DAINTMSK |= (1 << (epIndex + 16));
+    }
+    return true;
+}
+
+// read setup packet
+void USBHAL::EP0setup(uint8_t *buffer) {
+    memcpy(buffer, setupBuffer, MAX_PACKET_SIZE_EP0);
+}
+
+void USBHAL::EP0readStage(void) {
+}
+
+void USBHAL::EP0read(void) {
+}
+
+uint32_t USBHAL::EP0getReadResult(uint8_t *buffer) {
+    uint32_t* buffer32 = (uint32_t *) buffer;
+    uint32_t length = rxFifoCount;
+    for (uint32_t i = 0; i < length; i += 4) {
+        buffer32[i >> 2] = OTG_FS->FIFO[0][0];
+    }
+
+    rxFifoCount = 0;
+    return length;
+}
+
+void USBHAL::EP0write(uint8_t *buffer, uint32_t size) {
+    endpointWrite(0, buffer, size);
+}
+
+void USBHAL::EP0getWriteResult(void) {
+}
+
+void USBHAL::EP0stall(void) {
+    // If we stall the out endpoint here then we have problems transferring
+    // and setup requests after the (stalled) get device qualifier requests.
+    // TODO: Find out if this is correct behavior, or whether we are doing
+    // something else wrong
+    stallEndpoint(EP0IN);
+//    stallEndpoint(EP0OUT);
+}
+
+EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize) {
+    uint32_t epIndex = endpoint >> 1;
+    uint32_t size = (1 << 19) | // 1 packet
+                    (maximumSize << 0); // Packet size
+//    if (endpoint == EP0OUT) {
+        size |= (1 << 29); // 1 setup packet
+//    }
+    OTG_FS->OUTEP_REGS[epIndex].DOEPTSIZ = size;
+    OTG_FS->OUTEP_REGS[epIndex].DOEPCTL |= (1 << 31) | // Enable endpoint
+                                           (1 << 26); // Clear NAK
+
+    epComplete &= ~(1 << endpoint);
+    return EP_PENDING;
+}
+
+EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t * buffer, uint32_t *bytesRead) {
+    if (!(epComplete & (1 << endpoint))) {
+        return EP_PENDING;
+    }
+
+    uint32_t* buffer32 = (uint32_t *) buffer;
+    uint32_t length = rxFifoCount;
+    for (uint32_t i = 0; i < length; i += 4) {
+        buffer32[i >> 2] = OTG_FS->FIFO[endpoint >> 1][0];
+    }
+    rxFifoCount = 0;
+    *bytesRead = length;
+    return EP_COMPLETED;
+}
+
+EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size) {
+    uint32_t epIndex = endpoint >> 1;
+    OTG_FS->INEP_REGS[epIndex].DIEPTSIZ = (1 << 19) | // 1 packet
+                                          (size << 0); // Size of packet
+    OTG_FS->INEP_REGS[epIndex].DIEPCTL |= (1 << 31) | // Enable endpoint
+                                          (1 << 26); // CNAK
+    OTG_FS->DREGS.DIEPEMPMSK = (1 << epIndex);
+
+    while ((OTG_FS->INEP_REGS[epIndex].DTXFSTS & 0XFFFF) < ((size + 3) >> 2));
+
+    for (uint32_t i=0; i<(size + 3) >> 2; i++, data+=4) {
+        OTG_FS->FIFO[epIndex][0] = *(uint32_t *)data;
+    }
+
+    epComplete &= ~(1 << endpoint);
+
+    return EP_PENDING;
+}
+
+EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint) {
+    if (epComplete & (1 << endpoint)) {
+        epComplete &= ~(1 << endpoint);
+        return EP_COMPLETED;
+    }
+
+    return EP_PENDING;
+}
+
+void USBHAL::stallEndpoint(uint8_t endpoint) {
+    if (endpoint & 0x1) { // In EP
+        OTG_FS->INEP_REGS[endpoint >> 1].DIEPCTL |= (1 << 30) | // Disable
+                                                    (1 << 21); // Stall
+    }
+    else {  // Out EP
+        OTG_FS->DREGS.DCTL |= (1 << 9); // Set global out NAK
+        OTG_FS->OUTEP_REGS[endpoint >> 1].DOEPCTL |= (1 << 30) | // Disable
+                                                     (1 << 21); // Stall
+    }
+}
+
+void USBHAL::unstallEndpoint(uint8_t endpoint) {
+
+}
+
+bool USBHAL::getEndpointStallState(uint8_t endpoint) {
+    return false;
+}
+
+void USBHAL::remoteWakeup(void) {
+}
+
+
+void USBHAL::_usbisr(void) {
+    instance->usbisr();
+}
+
+
+void USBHAL::usbisr(void) {
+    if (OTG_FS->GREGS.GINTSTS & (1 << 11)) { // USB Suspend
+        suspendStateChanged(1);
+    };
+
+    if (OTG_FS->GREGS.GINTSTS & (1 << 12)) { // USB Reset
+        suspendStateChanged(0);
+
+        // Set SNAK bits
+        OTG_FS->OUTEP_REGS[0].DOEPCTL |= (1 << 27);
+        OTG_FS->OUTEP_REGS[1].DOEPCTL |= (1 << 27);
+        OTG_FS->OUTEP_REGS[2].DOEPCTL |= (1 << 27);
+        OTG_FS->OUTEP_REGS[3].DOEPCTL |= (1 << 27);
+
+        OTG_FS->DREGS.DIEPMSK = (1 << 0);
+
+        bufferEnd = 0;
+
+        // Set the receive FIFO size
+        OTG_FS->GREGS.GRXFSIZ = rxFifoSize >> 2;
+        bufferEnd += rxFifoSize >> 2;
+
+        // Create the endpoints, and wait for setup packets on out EP0
+        realiseEndpoint(EP0IN, MAX_PACKET_SIZE_EP0, 0);
+        realiseEndpoint(EP0OUT, MAX_PACKET_SIZE_EP0, 0);
+        endpointRead(EP0OUT, MAX_PACKET_SIZE_EP0);
+
+        OTG_FS->GREGS.GINTSTS = (1 << 12);
+    }
+
+    if (OTG_FS->GREGS.GINTSTS & (1 << 4)) { // RX FIFO not empty
+        uint32_t status = OTG_FS->GREGS.GRXSTSP;
+
+        uint32_t endpoint = (status & 0xF) << 1;
+        uint32_t length = (status >> 4) & 0x7FF;
+        uint32_t type = (status >> 17) & 0xF;
+
+        rxFifoCount = length;
+
+        if (type == 0x6) {
+            // Setup packet
+            for (uint32_t i=0; i<length; i+=4) {
+                setupBuffer[i >> 2] = OTG_FS->FIFO[0][i >> 2];
+            }
+            rxFifoCount = 0;
+        }
+
+        if (type == 0x4) {
+            // Setup complete
+            EP0setupCallback();
+            endpointRead(EP0OUT, MAX_PACKET_SIZE_EP0);
+        }
+
+        if (type == 0x2) {
+            // Out packet
+            if (endpoint == EP0OUT) {
+                EP0out();
+            }
+            else {
+                epComplete |= (1 << endpoint);
+                if ((instance->*(epCallback[endpoint - 2]))()) {
+                    epComplete &= ~(1 << endpoint);
+                }
+            }
+        }
+
+        for (uint32_t i=0; i<rxFifoCount; i+=4) {
+            (void) OTG_FS->FIFO[0][0];
+        }
+        OTG_FS->GREGS.GINTSTS = (1 << 4);
+    }
+
+    if (OTG_FS->GREGS.GINTSTS & (1 << 18)) { // In endpoint interrupt
+        // Loop through the in endpoints
+        for (uint32_t i=0; i<4; i++) {
+            if (OTG_FS->DREGS.DAINT & (1 << i)) { // Interrupt is on endpoint
+
+                if (OTG_FS->INEP_REGS[i].DIEPINT & (1 << 7)) {// Tx FIFO empty
+                    // If the Tx FIFO is empty on EP0 we need to send a further
+                    // packet, so call EP0in()
+                    if (i == 0) {
+                        EP0in();
+                    }
+                    // Clear the interrupt
+                    OTG_FS->INEP_REGS[i].DIEPINT = (1 << 7);
+                    // Stop firing Tx empty interrupts
+                    // Will get turned on again if another write is called
+                    OTG_FS->DREGS.DIEPEMPMSK &= ~(1 << i);
+                }
+
+                // If the transfer is complete
+                if (OTG_FS->INEP_REGS[i].DIEPINT & (1 << 0)) { // Tx Complete
+                    epComplete |= (1 << (1 + (i << 1)));
+                    OTG_FS->INEP_REGS[i].DIEPINT = (1 << 0);
+                }
+            }
+        }
+        OTG_FS->GREGS.GINTSTS = (1 << 18);
+    }
+
+    if (OTG_FS->GREGS.GINTSTS & (1 << 3)) { // Start of frame
+        SOF((OTG_FS->GREGS.GRXSTSR >> 17) & 0xF);
+        OTG_FS->GREGS.GINTSTS = (1 << 3);
+    }
+}
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/targets/TARGET_STM/USBHAL_STM_144_64pins.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,132 @@
+/* Copyright (c) 2016 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 USBHAL_STM32_144_64
+#define USBHAL_STM32_144_64
+
+#define USBHAL_IRQn  OTG_FS_IRQn
+/*  must be multiple of 4 bytes */
+#define NB_ENDPOINT 4
+#define MAXTRANSFER_SIZE  0x200
+#define FIFO_USB_RAM_SIZE (MAXTRANSFER_SIZE+MAX_PACKET_SIZE_EP0+MAX_PACKET_SIZE_EP1+MAX_PACKET_SIZE_EP2+MAX_PACKET_SIZE_EP3)
+#if (FIFO_USB_RAM_SIZE > 0x500)
+#error "FIFO dimensioning incorrect"
+#endif
+
+typedef struct
+{
+    USBHAL *inst;
+    void (USBHAL::*bus_reset)(void);
+    void (USBHAL::*sof)(int frame);
+    void (USBHAL::*connect_change)(unsigned int  connected);
+    void (USBHAL::*suspend_change)(unsigned int suspended);
+    void (USBHAL::*ep0_setup)(void);
+    void (USBHAL::*ep0_in)(void);
+    void (USBHAL::*ep0_out)(void);
+    void (USBHAL::*ep0_read)(void);
+    bool (USBHAL::*ep_realise)(uint8_t endpoint, uint32_t maxPacket, uint32_t flags);
+    bool (USBHAL::*epCallback[2*NB_ENDPOINT-2])(void);
+    /*  memorize dummy buffer used for reception */
+    uint32_t pBufRx[MAXTRANSFER_SIZE>>2];
+    uint32_t pBufRx0[MAX_PACKET_SIZE_EP0>>2];
+    uint8_t epComplete[2*NB_ENDPOINT];
+}USBHAL_Private_t;
+
+uint32_t HAL_PCDEx_GetTxFiFo(PCD_HandleTypeDef *hpcd, uint8_t fifo)
+{
+    uint32_t len;
+    if (fifo == 0) len = hpcd->Instance->DIEPTXF0_HNPTXFSIZ>>16;
+    else
+        len =  hpcd->Instance->DIEPTXF[fifo - 1] >> 16;
+    return len*4;
+}
+void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) 
+{
+    USBHAL_Private_t *priv=((USBHAL_Private_t *)(hpcd->pData));
+    USBHAL *obj= priv->inst;
+    USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
+    uint32_t sofnum = (USBx_DEVICE->DSTS & USB_OTG_DSTS_FNSOF) >> 8;
+    void (USBHAL::*func)(int frame) = priv->sof;
+    (obj->*func)(sofnum);
+}
+
+
+USBHAL * USBHAL::instance;
+
+USBHAL::USBHAL(void) {
+    /*  init parameter  */
+    USBHAL_Private_t *HALPriv = new(USBHAL_Private_t);
+    hpcd.Instance = USB_OTG_FS;
+    memset(&hpcd.Init, 0, sizeof(hpcd.Init));
+    hpcd.Init.dev_endpoints = NB_ENDPOINT;
+    hpcd.Init.ep0_mps =   MAX_PACKET_SIZE_EP0;
+    hpcd.Init.phy_itface = PCD_PHY_EMBEDDED;
+    hpcd.Init.Sof_enable = 1;
+
+    hpcd.Init.speed = PCD_SPEED_FULL;
+    //hpcd.Init.vbus_sensing_enable = 0;
+    //hpcd.Init.lpm_enable = 0;
+    /*  pass instance for usage inside call back */
+    HALPriv->inst = this;
+    HALPriv->bus_reset = &USBHAL::busReset;
+    HALPriv->suspend_change = &USBHAL::suspendStateChanged;
+    HALPriv->connect_change = &USBHAL::connectStateChanged;
+    HALPriv->sof = &USBHAL::SOF;
+    HALPriv->ep0_setup = &USBHAL::EP0setupCallback;
+    HALPriv->ep_realise = &USBHAL::realiseEndpoint;
+    HALPriv->ep0_in = &USBHAL::EP0in;
+    HALPriv->ep0_out = &USBHAL::EP0out;
+    HALPriv->ep0_read = &USBHAL::EP0read;
+    hpcd.pData = (void*)HALPriv;
+    HALPriv->epCallback[0] = &USBHAL::EP1_OUT_callback;
+    HALPriv->epCallback[1] = &USBHAL::EP1_IN_callback;
+    HALPriv->epCallback[2] = &USBHAL::EP2_OUT_callback;
+    HALPriv->epCallback[3] = &USBHAL::EP2_IN_callback;
+    HALPriv->epCallback[4] = &USBHAL::EP3_OUT_callback;
+    HALPriv->epCallback[5] = &USBHAL::EP3_IN_callback;
+    instance = this;
+    // Enable power and clocking
+    /*  board 144 pin all similar  */
+    __HAL_RCC_GPIOA_CLK_ENABLE();
+    pin_function(PA_8, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF10_OTG_FS));  /* OTG_FS_SOF */
+    pin_function(PA_9, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, GPIO_AF10_OTG_FS));  /* OTG_FS_VBUS */
+    pin_function(PA_10, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_PULLUP, GPIO_AF10_OTG_FS)); /* OTG_FS_ID */
+    pin_function(PA_11, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF10_OTG_FS)); /* OTG_FS_DM */
+    pin_function(PA_12, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF10_OTG_FS)); /* OTG_FS_DP */
+
+    __HAL_RCC_USB_OTG_FS_CLK_ENABLE();
+    __HAL_RCC_SYSCFG_CLK_ENABLE();
+    hpcd.State = HAL_PCD_STATE_RESET;
+    HAL_PCD_Init(&hpcd);
+    /* 1.25kbytes */
+    /* min value 16 (= 16 x 4 bytes) */
+    /*  max value 256 (= 1K bytes ) */
+    /*  maximum sum is 0x140 */
+    HAL_PCDEx_SetRxFiFo(&hpcd, (MAXTRANSFER_SIZE/4));
+    /*  bulk/int 64 bytes in FS  */
+    HAL_PCDEx_SetTxFiFo(&hpcd, 0, (MAX_PACKET_SIZE_EP0/4)+1);
+    /*  bulk/int bytes in FS */
+    HAL_PCDEx_SetTxFiFo(&hpcd, 1, (MAX_PACKET_SIZE_EP1/4)+1);
+    HAL_PCDEx_SetTxFiFo(&hpcd, 2, (MAX_PACKET_SIZE_EP2/4));
+    /* ISOchronous */
+    HAL_PCDEx_SetTxFiFo(&hpcd, 3, (MAX_PACKET_SIZE_EP3/4));
+    NVIC_SetVector(USBHAL_IRQn, (uint32_t)&_usbisr);
+    NVIC_SetPriority(USBHAL_IRQn, 1);
+    HAL_PCD_Start(&hpcd);
+}
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/targets/TARGET_STM/USBHAL_STM_TARGET.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,19 @@
+/* Copyright (c) 2016 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 "USBHAL_STM_144_64pins.h"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBDevice/targets/TARGET_STM/USBRegs_STM32.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,149 @@
+/**
+  ******************************************************************************
+  * @file    usb_regs.h
+  * @author  MCD Application Team
+  * @version V2.1.0
+  * @date    19-March-2012
+  * @brief   hardware registers
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
+  *
+  * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
+  *
+  * 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.
+  *
+  ******************************************************************************
+  */
+
+#ifndef __USB_OTG_REGS_H__
+#define __USB_OTG_REGS_H__
+
+typedef struct //000h
+{
+  __IO uint32_t GOTGCTL;      /* USB_OTG Control and Status Register    000h*/
+  __IO uint32_t GOTGINT;      /* USB_OTG Interrupt Register             004h*/
+  __IO uint32_t GAHBCFG;      /* Core AHB Configuration Register    008h*/
+  __IO uint32_t GUSBCFG;      /* Core USB Configuration Register    00Ch*/
+  __IO uint32_t GRSTCTL;      /* Core Reset Register                010h*/
+  __IO uint32_t GINTSTS;      /* Core Interrupt Register            014h*/
+  __IO uint32_t GINTMSK;      /* Core Interrupt Mask Register       018h*/
+  __IO uint32_t GRXSTSR;      /* Receive Sts Q Read Register        01Ch*/
+  __IO uint32_t GRXSTSP;      /* Receive Sts Q Read & POP Register  020h*/
+  __IO uint32_t GRXFSIZ;      /* Receive FIFO Size Register         024h*/
+  __IO uint32_t DIEPTXF0_HNPTXFSIZ;   /* EP0 / Non Periodic Tx FIFO Size Register 028h*/
+  __IO uint32_t HNPTXSTS;     /* Non Periodic Tx FIFO/Queue Sts reg 02Ch*/
+  uint32_t Reserved30[2];     /* Reserved                           030h*/
+  __IO uint32_t GCCFG;        /* General Purpose IO Register        038h*/
+  __IO uint32_t CID;          /* User ID Register                   03Ch*/
+  uint32_t  Reserved40[48];   /* Reserved                      040h-0FFh*/
+  __IO uint32_t HPTXFSIZ; /* Host Periodic Tx FIFO Size Reg     100h*/
+  __IO uint32_t DIEPTXF[3];/* dev Periodic Transmit FIFO */
+}
+USB_OTG_GREGS;
+
+typedef struct // 800h
+{
+  __IO uint32_t DCFG;         /* dev Configuration Register   800h*/
+  __IO uint32_t DCTL;         /* dev Control Register         804h*/
+  __IO uint32_t DSTS;         /* dev Status Register (RO)     808h*/
+  uint32_t Reserved0C;           /* Reserved                     80Ch*/
+  __IO uint32_t DIEPMSK;   /* dev IN Endpoint Mask         810h*/
+  __IO uint32_t DOEPMSK;  /* dev OUT Endpoint Mask        814h*/
+  __IO uint32_t DAINT;     /* dev All Endpoints Itr Reg    818h*/
+  __IO uint32_t DAINTMSK; /* dev All Endpoints Itr Mask   81Ch*/
+  uint32_t  Reserved20;          /* Reserved                     820h*/
+  uint32_t Reserved9;       /* Reserved                     824h*/
+  __IO uint32_t DVBUSDIS;    /* dev VBUS discharge Register  828h*/
+  __IO uint32_t DVBUSPULSE;  /* dev VBUS Pulse Register      82Ch*/
+  __IO uint32_t DTHRCTL;     /* dev thr                      830h*/
+  __IO uint32_t DIEPEMPMSK; /* dev empty msk             834h*/
+}
+USB_OTG_DREGS;
+
+typedef struct
+{
+  __IO uint32_t DIEPCTL; /* dev IN Endpoint Control Reg 900h + (ep_num * 20h) + 00h*/
+  uint32_t Reserved04;             /* Reserved                       900h + (ep_num * 20h) + 04h*/
+  __IO uint32_t DIEPINT; /* dev IN Endpoint Itr Reg     900h + (ep_num * 20h) + 08h*/
+  uint32_t Reserved0C;             /* Reserved                       900h + (ep_num * 20h) + 0Ch*/
+  __IO uint32_t DIEPTSIZ; /* IN Endpoint Txfer Size   900h + (ep_num * 20h) + 10h*/
+  uint32_t Reserved14;
+  __IO uint32_t DTXFSTS;/*IN Endpoint Tx FIFO Status Reg 900h + (ep_num * 20h) + 18h*/
+  uint32_t Reserved1C;             /* Reserved  900h+(ep_num*20h)+1Ch-900h+ (ep_num * 20h) + 1Ch*/
+}
+USB_OTG_INEPREGS;
+
+typedef struct
+{
+  __IO uint32_t DOEPCTL;       /* dev OUT Endpoint Control Reg  B00h + (ep_num * 20h) + 00h*/
+  uint32_t Reserved04;         /* Reserved                      B00h + (ep_num * 20h) + 04h*/
+  __IO uint32_t DOEPINT;       /* dev OUT Endpoint Itr Reg      B00h + (ep_num * 20h) + 08h*/
+  uint32_t Reserved0C;         /* Reserved                      B00h + (ep_num * 20h) + 0Ch*/
+  __IO uint32_t DOEPTSIZ;      /* dev OUT Endpoint Txfer Size   B00h + (ep_num * 20h) + 10h*/
+  uint32_t Reserved14[3];
+}
+USB_OTG_OUTEPREGS;
+
+typedef struct
+{
+  __IO uint32_t HCFG;             /* Host Configuration Register    400h*/
+  __IO uint32_t HFIR;      /* Host Frame Interval Register   404h*/
+  __IO uint32_t HFNUM;         /* Host Frame Nbr/Frame Remaining 408h*/
+  uint32_t Reserved40C;                   /* Reserved                       40Ch*/
+  __IO uint32_t HPTXSTS;   /* Host Periodic Tx FIFO/ Queue Status 410h*/
+  __IO uint32_t HAINT;   /* Host All Channels Interrupt Register 414h*/
+  __IO uint32_t HAINTMSK;   /* Host All Channels Interrupt Mask 418h*/
+}
+USB_OTG_HREGS;
+
+typedef struct
+{
+  __IO uint32_t HCCHAR;
+  __IO uint32_t HCSPLT;
+  __IO uint32_t HCINT;
+  __IO uint32_t HCINTMSK;
+  __IO uint32_t HCTSIZ;
+  uint32_t Reserved[3];
+}
+USB_OTG_HC_REGS;
+
+typedef struct
+{
+    USB_OTG_GREGS         GREGS;
+    uint32_t RESERVED0[188];
+    USB_OTG_HREGS         HREGS;
+    uint32_t RESERVED1[9];
+    __IO uint32_t         HPRT;
+    uint32_t RESERVED2[47];
+    USB_OTG_HC_REGS       HC_REGS[8];
+    uint32_t RESERVED3[128];
+    USB_OTG_DREGS         DREGS;
+    uint32_t RESERVED4[50];
+    USB_OTG_INEPREGS      INEP_REGS[4];
+    uint32_t RESERVED5[96];
+    USB_OTG_OUTEPREGS     OUTEP_REGS[4];
+    uint32_t RESERVED6[160];
+    __IO uint32_t         PCGCCTL;
+    uint32_t RESERVED7[127];
+    __IO uint32_t         FIFO[4][1024];
+}
+USB_OTG_CORE_REGS;
+
+
+#define OTG_FS_BASE (AHB2PERIPH_BASE + 0x0000)
+#define OTG_FS ((USB_OTG_CORE_REGS *) OTG_FS_BASE)
+
+#endif //__USB_OTG_REGS_H__
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- a/DISCO_F746NG_USBHost.lib	Sat Oct 21 02:55:07 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://os.mbed.com/users/mbed_official/code/USBHost/#ae44a48f3811
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/USBHost/IUSBEnumerator.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,36 @@
+/* mbed USBHost Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * 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.
+ */
+
+#ifndef IUSBENUMERATOR_H_
+#define IUSBENUMERATOR_H_
+
+#include "stdint.h"
+#include "USBEndpoint.h"
+
+/*
+Generic interface to implement for "smart" USB enumeration
+*/
+
+class IUSBEnumerator
+{
+public:
+    virtual void setVidPid(uint16_t vid, uint16_t pid) = 0;
+    virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) = 0; //Must return true if the interface should be parsed
+    virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) = 0; //Must return true if the endpoint will be used
+};
+
+#endif /*IUSBENUMERATOR_H_*/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/USBHost/USBDeviceConnected.cpp	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,124 @@
+/* mbed USBHost Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * 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.
+ */
+
+#include "USBDeviceConnected.h"
+#include "dbg.h"
+
+USBDeviceConnected::USBDeviceConnected() {
+    init();
+}
+
+void USBDeviceConnected::init() {
+    hub_nb = 0;
+    port = 0;
+    vid = 0;
+    pid = 0;
+    nb_interf = 0;
+    enumerated = false;
+    activeAddr = false;
+    sizeControlEndpoint = 8;
+    device_class = 0;
+    device_subclass = 0;
+    proto = 0;
+    speed = false;
+    for (int i = 0; i < MAX_INTF; i++) {
+        memset((void *)&intf[i], 0, sizeof(INTERFACE));
+        intf[i].in_use = false;
+        for (int j = 0; j < MAX_ENDPOINT_PER_INTERFACE; j++) {
+            intf[i].ep[j] = NULL;
+            strcpy(intf[i].name, "Unknown");
+        }
+    }
+    hub_parent = NULL;
+    hub = NULL;
+    nb_interf = 0;
+}
+
+INTERFACE * USBDeviceConnected::getInterface(uint8_t index) {
+    if (index >= MAX_INTF)
+        return NULL;
+
+    if (intf[index].in_use)
+        return &intf[index];
+
+    return NULL;
+}
+
+bool USBDeviceConnected::addInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) {
+    if ((intf_nb >= MAX_INTF) || (intf[intf_nb].in_use)) {
+        return false;
+    }
+    intf[intf_nb].in_use = true;
+    intf[intf_nb].intf_class = intf_class;
+    intf[intf_nb].intf_subclass = intf_subclass;
+    intf[intf_nb].intf_protocol = intf_protocol;
+    intf[intf_nb].nb_endpoint = 0;
+    return true;
+}
+
+bool USBDeviceConnected::addEndpoint(uint8_t intf_nb, USBEndpoint * ept) {
+    if ((intf_nb >= MAX_INTF) || (intf[intf_nb].in_use == false) || (intf[intf_nb].nb_endpoint >= MAX_ENDPOINT_PER_INTERFACE)) {
+        return false;
+    }
+    intf[intf_nb].nb_endpoint++;
+
+    for (int i = 0; i < MAX_ENDPOINT_PER_INTERFACE; i++) {
+        if (intf[intf_nb].ep[i] == NULL) {
+            intf[intf_nb].ep[i] = ept;
+            return true;
+        }
+    }
+    return false;
+}
+
+void USBDeviceConnected::init(uint8_t hub_, uint8_t port_, bool lowSpeed_) {
+    USB_DBG("init dev: %p", this);
+    init();
+    hub_nb = hub_;
+    port = port_;
+    speed = lowSpeed_;
+}
+
+void USBDeviceConnected::disconnect() {
+    for(int i = 0; i < MAX_INTF; i++) {
+        if (intf[i].detach) intf[i].detach.call();
+    }
+    init();
+}
+
+
+USBEndpoint * USBDeviceConnected::getEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir, uint8_t index) {
+    if (intf_nb >= MAX_INTF) {
+        return NULL;
+    }
+    for (int i = 0; i < MAX_ENDPOINT_PER_INTERFACE; i++) {
+        if ((intf[intf_nb].ep[i]->getType() == type) && (intf[intf_nb].ep[i]->getDir() == dir)) {
+            if(index) {
+                index--;
+            } else {
+                return intf[intf_nb].ep[i];
+            }
+        }
+    }
+    return NULL;
+}
+
+USBEndpoint * USBDeviceConnected::getEndpoint(uint8_t intf_nb, uint8_t index) {
+    if ((intf_nb >= MAX_INTF) || (index >= MAX_ENDPOINT_PER_INTERFACE)) {
+        return NULL;
+    }
+    return intf[intf_nb].ep[index];
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/USBHost/USBDeviceConnected.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,186 @@
+/* mbed USBHost Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * 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.
+ */
+
+#ifndef USBDEVICECONNECTED_H
+#define USBDEVICECONNECTED_H
+
+#include "stdint.h"
+#include "USBEndpoint.h"
+#include "USBHostConf.h"
+#include "rtos.h"
+#include "Callback.h"
+
+class USBHostHub;
+
+typedef struct {
+    bool in_use;
+    uint8_t nb_endpoint;
+    uint8_t intf_class;
+    uint8_t intf_subclass;
+    uint8_t intf_protocol;
+    USBEndpoint * ep[MAX_ENDPOINT_PER_INTERFACE];
+    Callback<void()> detach;
+    char name[10];
+} INTERFACE;
+
+/**
+* USBDeviceConnected class
+*/
+class USBDeviceConnected
+{
+public:
+
+    /**
+    * Constructor
+    */
+    USBDeviceConnected();
+
+    /**
+    * Attach an USBEndpoint to this device
+    *
+    * @param intf_nb interface number
+    * @param ep pointeur on the USBEndpoint which will be attached
+    * @returns true if successful, false otherwise
+    */
+    bool addEndpoint(uint8_t intf_nb, USBEndpoint * ep);
+
+    /**
+    * Retrieve an USBEndpoint by its TYPE and DIRECTION
+    *
+    * @param intf_nb the interface on which to lookup the USBEndpoint
+    * @param type type of the USBEndpoint looked for
+    * @param dir direction of the USBEndpoint looked for
+    * @param index the index of the USBEndpoint whitin the interface
+    * @returns pointer on the USBEndpoint if found, NULL otherwise
+    */
+    USBEndpoint * getEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir, uint8_t index = 0);
+
+    /**
+    * Retrieve an USBEndpoint by its index
+    *
+    * @param intf_nb interface number
+    * @param index index of the USBEndpoint
+    * @returns pointer on the USBEndpoint if found, NULL otherwise
+    */
+    USBEndpoint * getEndpoint(uint8_t intf_nb, uint8_t index);
+
+    /**
+    * Add a new interface to this device
+    *
+    * @param intf_nb interface number
+    * @param intf_class interface class
+    * @param intf_subclass interface subclass
+    * @param intf_protocol interface protocol
+    * @returns true if successful, false otherwise
+    */
+    bool addInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol);
+
+    /**
+    * Get a specific interface
+    *
+    * @param index index of the interface to be fetched
+    * @returns interface
+    */
+    INTERFACE * getInterface(uint8_t index);
+
+    /**
+     *  Attach a member function to call when a the device has been disconnected
+     *
+     *  @param intf_nb interface number
+     *  @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>
+    inline void onDisconnect(uint8_t intf_nb, T* tptr, void (T::*mptr)(void)) {
+        if ((mptr != NULL) && (tptr != NULL)) {
+            intf[intf_nb].detach.attach(tptr, mptr);
+        }
+    }
+
+    /**
+     * Attach a callback called when the device has been disconnected
+     *
+     *  @param intf_nb interface number
+     *  @param fn function pointer
+     */
+    inline void onDisconnect(uint8_t intf_nb, void (*fn)(void)) {
+        if (fn != NULL) {
+            intf[intf_nb].detach.attach(fn);
+        }
+    }
+
+    /**
+    * Disconnect the device by calling a callback function registered by a driver
+    */
+    void disconnect();
+
+    // setters
+    void init(uint8_t hub, uint8_t port, bool lowSpeed);
+    inline void setAddress(uint8_t addr_) { addr = addr_; };
+    inline void setVid(uint16_t vid_) { vid = vid_; };
+    inline void setPid(uint16_t pid_) { pid = pid_; };
+    inline void setClass(uint8_t device_class_) { device_class = device_class_; };
+    inline void setSubClass(uint8_t device_subclass_) { device_subclass = device_subclass_; };
+    inline void setProtocol(uint8_t pr) { proto = pr; };
+    inline void setSizeControlEndpoint(uint32_t size) { sizeControlEndpoint = size; };
+    inline void activeAddress(bool active) { activeAddr = active; };
+    inline void setEnumerated() { enumerated = true; };
+    inline void setNbIntf(uint8_t nb_intf) {nb_interf = nb_intf; };
+    inline void setHubParent(USBHostHub * hub) { hub_parent = hub; };
+    inline void setName(const char * name_, uint8_t intf_nb) { strcpy(intf[intf_nb].name, name_); };
+
+    //getters
+    inline uint8_t     getPort() { return port; };
+    inline uint8_t     getHub() { return hub_nb; };
+    inline uint8_t     getAddress() { return addr; };
+    inline uint16_t    getVid() { return vid; };
+    inline uint16_t    getPid() { return pid; };
+    inline uint8_t     getClass() { return device_class; };
+    inline uint8_t     getSubClass() { return device_subclass; };
+    inline uint8_t     getProtocol() { return proto; };
+    inline bool        getSpeed() { return speed; };
+    inline uint32_t    getSizeControlEndpoint() { return sizeControlEndpoint; };
+    inline bool        isActiveAddress() { return activeAddr; };
+    inline bool        isEnumerated() { return enumerated; };
+    inline USBHostHub * getHubParent() { return hub_parent; };
+    inline uint8_t      getNbIntf() { return nb_interf; };
+    inline const char * getName(uint8_t intf_nb) { return intf[intf_nb].name; };
+
+    // in case this device is a hub
+    USBHostHub * hub;
+
+private:
+    USBHostHub * hub_parent;
+
+    INTERFACE intf[MAX_INTF];
+    uint32_t sizeControlEndpoint;
+    uint8_t hub_nb;
+    uint8_t port;
+    uint16_t vid;
+    uint16_t pid;
+    uint8_t addr;
+    uint8_t device_class;
+    uint8_t device_subclass;
+    uint8_t proto;
+    bool speed;
+    volatile bool activeAddr;
+    volatile bool enumerated;
+    uint8_t nb_interf;
+
+    void init();
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/USBHost/USBEndpoint.cpp	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,163 @@
+/* mbed USBHost Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * 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.
+ */
+
+
+#include "dbg.h"
+#include "USBEndpoint.h"
+#if !defined(USBHOST_OTHER)
+void USBEndpoint::init(HCED * hced_, ENDPOINT_TYPE type_, ENDPOINT_DIRECTION dir_, uint32_t size, uint8_t ep_number, HCTD* td_list_[2])
+{
+    hced = hced_;
+    type = type_;
+    dir = dir_;
+    setup = (type == CONTROL_ENDPOINT) ? true : false;
+
+    //TDs have been allocated by the host
+    memcpy((HCTD**)td_list, td_list_, sizeof(HCTD*)*2); //TODO: Maybe should add a param for td_list size... at least a define
+    memset(td_list_[0], 0, sizeof(HCTD));
+    memset(td_list_[1], 0, sizeof(HCTD));
+
+    td_list[0]->ep = this;
+    td_list[1]->ep = this;
+
+    hced->control = 0;
+    //Empty queue
+    hced->tailTD = td_list[0];
+    hced->headTD = td_list[0];
+    hced->nextED = 0;
+
+    address = (ep_number & 0x7F) | ((dir - 1) << 7);
+
+    hced->control = ((ep_number & 0x7F) << 7)                         // Endpoint address
+                    | (type != CONTROL_ENDPOINT ? ( dir << 11) : 0 )  // direction : Out = 1, 2 = In
+                    | ((size & 0x3ff) << 16);                         // MaxPkt Size
+
+    transfer_len = 0;
+    transferred = 0;
+    buf_start = 0;
+    nextEp = NULL;
+
+    td_current = td_list[0];
+    td_next = td_list[1];
+
+    intf_nb = 0;
+
+    state = USB_TYPE_IDLE;
+}
+
+void USBEndpoint::setSize(uint32_t size)
+{
+    hced->control &= ~(0x3ff << 16);
+    hced->control |= (size << 16);
+}
+
+
+void USBEndpoint::setDeviceAddress(uint8_t addr)
+{
+    hced->control &= ~(0x7f);
+    hced->control |= (addr & 0x7F);
+}
+
+void USBEndpoint::setSpeed(uint8_t speed)
+{
+    hced->control &= ~(1 << 13);
+    hced->control |= (speed << 13);
+}
+#endif
+
+//Only for control Eps
+void USBEndpoint::setNextToken(uint32_t token)
+{
+    switch (token) {
+        case TD_SETUP:
+            dir = OUT;
+            setup = true;
+            break;
+        case TD_IN:
+            dir = IN;
+            setup = false;
+            break;
+        case TD_OUT:
+            dir = OUT;
+            setup = false;
+            break;
+    }
+}
+struct {
+    USB_TYPE type;
+    const char * str;
+} static type_string[] = {
+/*0*/   {USB_TYPE_OK, "USB_TYPE_OK"},
+        {USB_TYPE_CRC_ERROR, "USB_TYPE_CRC_ERROR"},
+        {USB_TYPE_BIT_STUFFING_ERROR, "USB_TYPE_BIT_STUFFING_ERROR"},
+        {USB_TYPE_DATA_TOGGLE_MISMATCH_ERROR, "USB_TYPE_DATA_TOGGLE_MISMATCH_ERROR"},
+        {USB_TYPE_STALL_ERROR, "USB_TYPE_STALL_ERROR"},
+/*5*/   {USB_TYPE_DEVICE_NOT_RESPONDING_ERROR, "USB_TYPE_DEVICE_NOT_RESPONDING_ERROR"},
+        {USB_TYPE_PID_CHECK_FAILURE_ERROR, "USB_TYPE_PID_CHECK_FAILURE_ERROR"},
+        {USB_TYPE_UNEXPECTED_PID_ERROR, "USB_TYPE_UNEXPECTED_PID_ERROR"},
+        {USB_TYPE_DATA_OVERRUN_ERROR, "USB_TYPE_DATA_OVERRUN_ERROR"},
+        {USB_TYPE_DATA_UNDERRUN_ERROR, "USB_TYPE_DATA_UNDERRUN_ERROR"},
+/*10*/  {USB_TYPE_ERROR, "USB_TYPE_ERROR"},
+        {USB_TYPE_ERROR, "USB_TYPE_ERROR"},
+        {USB_TYPE_BUFFER_OVERRUN_ERROR, "USB_TYPE_BUFFER_OVERRUN_ERROR"},
+        {USB_TYPE_BUFFER_UNDERRUN_ERROR, "USB_TYPE_BUFFER_UNDERRUN_ERROR"},
+        {USB_TYPE_DISCONNECTED, "USB_TYPE_DISCONNECTED"},
+/*15*/  {USB_TYPE_FREE, "USB_TYPE_FREE"},
+        {USB_TYPE_IDLE, "USB_TYPE_IDLE"},
+        {USB_TYPE_PROCESSING, "USB_TYPE_PROCESSING"},
+        {USB_TYPE_ERROR, "USB_TYPE_ERROR"}
+};
+const char * USBEndpoint::getStateString() {
+    return type_string[state].str;
+}
+
+#if !defined(USBHOST_OTHER)
+void USBEndpoint::setState(uint8_t st) {
+    if (st > 18)
+        return;
+    state = type_string[st].type;
+}
+
+USB_TYPE USBEndpoint::queueTransfer()
+{
+    transfer_len = (uint32_t)td_current->bufEnd - (uint32_t)td_current->currBufPtr + 1;
+    transferred = transfer_len;
+    buf_start = (uint8_t *)td_current->currBufPtr;
+
+    //Now add this free TD at this end of the queue
+    state = USB_TYPE_PROCESSING;
+    td_current->nextTD = (hcTd*)td_next;
+    hced->tailTD = td_next;
+    return USB_TYPE_PROCESSING;
+}
+
+void USBEndpoint::unqueueTransfer(volatile HCTD * td)
+{
+    td->control=0;
+    td->currBufPtr=0;
+    td->bufEnd=0;
+    td->nextTD=0;
+    hced->headTD = (HCTD *)((uint32_t)hced->tailTD | ((uint32_t)hced->headTD & 0x2)); //Carry bit
+    td_current = td_next;
+    td_next = td;
+}
+
+void USBEndpoint::queueEndpoint(USBEndpoint * ed)
+{
+    nextEp = ed;
+    hced->nextED = (ed == NULL) ? 0 : (hcEd*)(ed->getHCED());
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/USBHost/USBEndpoint.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,191 @@
+/* mbed USBHost Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * 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.
+ */
+
+#ifndef USBENDPOINT_H
+#define USBENDPOINT_H
+
+#include "Callback.h"
+#include "USBHostTypes.h"
+#include "rtos.h"
+
+class USBDeviceConnected;
+
+/**
+* USBEndpoint class
+*/
+class USBEndpoint
+{
+public:
+    /**
+    * Constructor
+    */
+    USBEndpoint() {
+#ifdef USBHOST_OTHER
+        speed = false;
+#endif
+        state = USB_TYPE_FREE;
+        nextEp = NULL;
+    };
+
+    /**
+    * Initialize an endpoint
+    *
+    * @param hced hced associated to the endpoint
+    * @param type endpoint type
+    * @param dir endpoint direction
+    * @param size endpoint size
+    * @param ep_number endpoint number
+    * @param td_list array of two allocated transfer descriptors
+    */
+
+    void init(HCED * hced, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir, uint32_t size, uint8_t ep_number, HCTD* td_list[2]);
+
+    /**
+    * Set next token. Warning: only useful for the control endpoint
+    *
+    * @param token IN, OUT or SETUP token
+    */
+    void setNextToken(uint32_t token);
+
+    /**
+    * Queue an endpoint
+    *
+    * @param endpoint endpoint which will be queued in the linked list
+    */
+    void queueEndpoint(USBEndpoint * endpoint);
+
+
+    /**
+    * Queue a transfer on the endpoint
+    */
+    USB_TYPE queueTransfer();
+
+    /**
+    * Unqueue a transfer from the endpoint
+    *
+    * @param td hctd which will be unqueued
+    */
+    void unqueueTransfer(volatile HCTD * td);
+
+    /**
+     *  Attach a member function to call when a transfer is finished
+     *
+     *  @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>
+    inline void attach(T* tptr, void (T::*mptr)(void)) {
+        if((mptr != NULL) && (tptr != NULL)) {
+            rx.attach(tptr, mptr);
+        }
+    }
+
+    /**
+     * Attach a callback called when a transfer is finished
+     *
+     * @param fptr function pointer
+     */
+    inline void attach(void (*fptr)(void)) {
+        if(fptr != NULL) {
+            rx.attach(fptr);
+        }
+    }
+
+    /**
+    * Call the handler associted to the end of a transfer
+    */
+    inline void call() {
+        if (rx)
+            rx.call();
+    };
+
+
+    // setters
+#ifdef USBHOST_OTHER
+    void setState(USB_TYPE st);
+#else
+    inline void setState(USB_TYPE st) { state = st; }
+#endif
+    void setState(uint8_t st);
+    void setDeviceAddress(uint8_t addr);
+    inline void setLengthTransferred(int len) { transferred = len; };
+    void setSpeed(uint8_t speed);
+    void setSize(uint32_t size);
+    inline void setDir(ENDPOINT_DIRECTION d) { dir = d; }
+    inline void setIntfNb(uint8_t intf_nb_) { intf_nb = intf_nb_; };
+
+    // getters
+    const char *                getStateString();
+    inline USB_TYPE             getState() { return state; }
+    inline ENDPOINT_TYPE        getType() { return type; };
+#ifdef  USBHOST_OTHER
+    inline uint8_t              getDeviceAddress() { return  device_address; };
+    inline uint32_t             getSize() { return size; };
+#else
+    inline uint8_t              getDeviceAddress() { return hced->control & 0x7f; };
+	inline uint32_t             getSize() { return (hced->control >> 16) & 0x3ff; };
+    inline volatile HCTD *      getHeadTD() { return (volatile HCTD*) ((uint32_t)hced->headTD & ~0xF); };
+#endif
+    inline int                  getLengthTransferred() { return transferred; }
+    inline uint8_t *            getBufStart() { return buf_start; }
+    inline uint8_t              getAddress(){ return address; };
+    inline volatile HCTD**      getTDList() { return td_list; };
+    inline volatile HCED *      getHCED() { return hced; };
+    inline ENDPOINT_DIRECTION   getDir() { return dir; }
+    inline volatile HCTD *      getProcessedTD() { return td_current; };
+    inline volatile HCTD*       getNextTD() { return td_current; };
+    inline bool                 isSetup() { return setup; }
+    inline USBEndpoint *        nextEndpoint() { return (USBEndpoint*)nextEp; };
+    inline uint8_t              getIntfNb() { return intf_nb; };
+
+    USBDeviceConnected * dev;
+
+    Queue<uint8_t, 1> ep_queue;
+
+private:
+    ENDPOINT_TYPE type;
+    volatile USB_TYPE state;
+    ENDPOINT_DIRECTION dir;
+#ifdef USBHOST_OTHER 
+	uint32_t size;
+	uint32_t ep_number;
+	uint32_t speed;
+    uint8_t device_address;
+#endif
+    bool setup;
+
+    uint8_t address;
+
+    int transfer_len;
+    int transferred;
+    uint8_t * buf_start;
+
+    Callback<void()> rx;
+
+    USBEndpoint* nextEp;
+
+    // USBEndpoint descriptor
+    volatile HCED * hced;
+
+    volatile HCTD * td_list[2];
+    volatile HCTD * td_current;
+    volatile HCTD * td_next;
+
+    uint8_t intf_nb;
+
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/USBHost/USBHALHost.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,173 @@
+/* mbed USBHost Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * 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.
+ */
+
+#ifndef USBHALHOST_H
+#define USBHALHOST_H
+
+#include "USBHostTypes.h"
+#include "USBHostConf.h"
+
+class USBHostHub;
+
+/**
+* USBHALHost class
+*/
+class USBHALHost {
+protected:
+
+    /**
+    * Constructor
+    * init variables and memory where will be stored HCCA, ED and TD
+    */
+    USBHALHost();
+
+    /**
+    * Initialize host controller. Enable USB interrupts. This part is not in the constructor because,
+    * this function calls a virtual method if a device is already connected
+    */
+    void init();
+
+    /**
+    * reset the root hub
+    */
+    void resetRootHub();
+
+    /**
+    * return the value contained in the control HEAD ED register
+    *
+    * @returns address of the control Head ED
+    */
+    uint32_t controlHeadED();
+
+    /**
+    * return the value contained in the bulk HEAD ED register
+    *
+    * @returns address of the bulk head ED
+    */
+    uint32_t bulkHeadED();
+
+    /**
+    * return the value of the head interrupt ED contained in the HCCA
+    *
+    * @returns address of the head interrupt ED contained in the HCCA
+    */
+    uint32_t interruptHeadED();
+
+    /**
+    * Update the head ED for control transfers
+    */
+    void updateControlHeadED(uint32_t addr);
+
+    /**
+    * Update the head ED for bulk transfers
+    */
+    void updateBulkHeadED(uint32_t addr);
+
+    /**
+    * Update the head ED for interrupt transfers
+    */
+    void updateInterruptHeadED(uint32_t addr);
+
+    /**
+    * Enable List for the specified endpoint type
+    *
+    * @param type enable the list of ENDPOINT_TYPE type
+    */
+    void enableList(ENDPOINT_TYPE type);
+
+    /**
+    * Disable List for the specified endpoint type
+    *
+    * @param type disable the list of ENDPOINT_TYPE type
+    */
+    bool disableList(ENDPOINT_TYPE type);
+
+    /**
+    * Virtual method called when a device has been connected
+    *
+    * @param hub hub number of the device
+    * @param port port number of the device
+    * @param lowSpeed 1 if low speed, 0 otherwise
+    * @param hub_parent reference to the hub where the device is connected (NULL if the hub parent is the root hub)
+    */
+    virtual void deviceConnected(int hub, int port, bool lowSpeed, USBHostHub * hub_parent = NULL) = 0;
+
+    /**
+    * Virtual method called when a device has been disconnected
+    *
+    * @param hub hub number of the device
+    * @param port port number of the device
+    * @param hub_parent reference to the hub where the device is connected (NULL if the hub parent is the root hub)
+    * @param addr list of the TDs which have been completed to dequeue freed TDs
+    */
+    virtual void deviceDisconnected(int hub, int port, USBHostHub * hub_parent, volatile uint32_t addr) = 0;
+
+    /**
+    * Virtual method called when a transfer has been completed
+    *
+    * @param addr list of the TDs which have been completed
+    */
+    virtual void transferCompleted(volatile uint32_t addr) = 0;
+
+    /**
+    * Find a memory section for a new ED
+    *
+    * @returns the address of the new ED
+    */
+    volatile uint8_t * getED();
+
+    /**
+    * Find a memory section for a new TD
+    *
+    * @returns the address of the new TD
+    */
+    volatile uint8_t * getTD();
+
+    /**
+    * Release a previous memory section reserved for an ED
+    *
+    * @param ed address of the ED
+    */
+    void freeED(volatile uint8_t * ed);
+
+    /**
+    * Release a previous memory section reserved for an TD
+    *
+    * @param td address of the TD
+    */
+    void freeTD(volatile uint8_t * td);
+
+private:
+    static void _usbisr(void);
+    void UsbIrqhandler();
+
+    void memInit();
+
+    HCCA volatile * usb_hcca;           //256 bytes aligned
+    uint8_t volatile  * usb_edBuf;      //4 bytes aligned
+    uint8_t volatile  * usb_tdBuf;      //4 bytes aligned
+
+    static USBHALHost * instHost;
+
+    bool volatile  edBufAlloc[MAX_ENDPOINT];
+    bool volatile tdBufAlloc[MAX_TD];
+#ifdef USBHOST_OTHER
+    int control_disable;
+#endif
+
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/USBHost/USBHost.cpp	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,1295 @@
+/* mbed USBHost Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * 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.
+ */
+
+
+#include "USBHost.h"
+#include "USBHostHub.h"
+
+USBHost * USBHost::instHost = NULL;
+
+#define DEVICE_CONNECTED_EVENT      (1 << 0)
+#define DEVICE_DISCONNECTED_EVENT   (1 << 1)
+#define TD_PROCESSED_EVENT          (1 << 2)
+
+#define MAX_TRY_ENUMERATE_HUB       3
+
+#define MIN(a, b) ((a > b) ? b : a)
+
+/**
+* How interrupts are processed:
+*    - new device connected:
+*       - a message is queued in queue_usb_event with the id DEVICE_CONNECTED_EVENT
+*       - when the usb_thread receives the event, it:
+*           - resets the device
+*           - reads the device descriptor
+*           - sets the address of the device
+*           - if it is a hub, enumerates it
+*   - device disconnected:
+*       - a message is queued in queue_usb_event with the id DEVICE_DISCONNECTED_EVENT
+*       - when the usb_thread receives the event, it:
+*           - free the device and all its children (hub)
+*   - td processed
+*       - a message is queued in queue_usb_event with the id TD_PROCESSED_EVENT
+*       - when the usb_thread receives the event, it:
+*           - call the callback attached to the endpoint where the td is attached
+*/
+void USBHost::usb_process()
+{
+
+    bool controlListState;
+    bool bulkListState;
+    bool interruptListState;
+    USBEndpoint * ep;
+    uint8_t i, j, res, timeout_set_addr = 10;
+    uint8_t buf[8];
+    bool too_many_hub;
+    int idx;
+
+#if DEBUG_TRANSFER
+    uint8_t * buf_transfer;
+#endif
+
+#if MAX_HUB_NB
+    uint8_t k;
+#endif
+
+    while(1) {
+        osEvent evt = mail_usb_event.get();
+
+        if (evt.status == osEventMail) {
+
+            message_t * usb_msg = (message_t*)evt.value.p;
+
+            switch (usb_msg->event_id) {
+
+                // a new device has been connected
+                case DEVICE_CONNECTED_EVENT:
+                    too_many_hub = false;
+                    buf[4] = 0;
+
+                    do {
+                        Lock lock(this);
+                        bool hub_unplugged = true;
+
+                        int idx = findDevice(usb_msg->hub, usb_msg->port, (USBHostHub *)(usb_msg->hub_parent));
+                        /*  check that hub is connected to root port  */
+                        if (usb_msg->hub_parent) {
+                            /*  a hub device must be present */
+                            for (k = 0; k < MAX_HUB_NB; k++) {
+                                if ((&hubs[k] == usb_msg->hub_parent) && (hub_in_use[k])) {
+                                    hub_unplugged=false;
+                                }
+                            }
+                        } else {
+                            hub_unplugged = false;
+                        }
+
+                        if (((idx!=-1) && deviceInUse[idx] ) || ((idx == -1) && hub_unplugged)) {
+                            break;
+                        }
+
+                        for (i =0 ; i < MAX_DEVICE_CONNECTED; i++) {
+                            if (!deviceInUse[i]) {
+                                USB_DBG_EVENT("new device connected: %p\r\n", &devices[i]);
+                                devices[i].init(usb_msg->hub, usb_msg->port, usb_msg->lowSpeed);
+                                deviceReset[i] = false;
+                                deviceInited[i] = true;
+                                break;
+                            }
+                        }
+
+                        if (i == MAX_DEVICE_CONNECTED) {
+                            USB_ERR("Too many device connected!!\r\n");
+                            continue;
+                        }
+
+                        if (!controlEndpointAllocated) {
+                            control = newEndpoint(CONTROL_ENDPOINT, OUT, 0x08, 0x00);
+                            addEndpoint(NULL, 0, (USBEndpoint*)control);
+                            controlEndpointAllocated = true;
+                        }
+
+#if MAX_HUB_NB
+                        if (usb_msg->hub_parent) {
+                            devices[i].setHubParent((USBHostHub *)(usb_msg->hub_parent));
+                        }
+#endif
+
+                        for (j = 0; j < timeout_set_addr; j++) {
+
+                            resetDevice(&devices[i]);
+
+                            // set size of control endpoint
+                            devices[i].setSizeControlEndpoint(8);
+
+                            devices[i].activeAddress(false);
+
+                            // get first 8 bit of device descriptor
+                            // and check if we deal with a hub
+                            USB_DBG("usb_thread read device descriptor on dev: %p\r\n", &devices[i]);
+                            res = getDeviceDescriptor(&devices[i], buf, 8);
+
+                            if (res != USB_TYPE_OK) {
+                                USB_ERR("usb_thread could not read dev descr");
+                                continue;
+                            }
+
+                            // set size of control endpoint
+                            devices[i].setSizeControlEndpoint(buf[7]);
+
+                            // second step: set an address to the device
+                            res = setAddress(&devices[i], devices[i].getAddress());
+
+                            if (res != USB_TYPE_OK) {
+                                USB_ERR("SET ADDR FAILED");
+                                continue;
+                            }
+                            devices[i].activeAddress(true);
+                            USB_DBG("Address of %p: %d", &devices[i], devices[i].getAddress());
+
+                            // try to read again the device descriptor to check if the device
+                            // answers to its new address
+                            res = getDeviceDescriptor(&devices[i], buf, 8);
+
+                            if (res == USB_TYPE_OK) {
+                                break;
+                            }
+
+                            Thread::wait(100);
+                        }
+
+                        USB_INFO("New device connected: %p [hub: %d - port: %d]", &devices[i], usb_msg->hub, usb_msg->port);
+
+#if MAX_HUB_NB
+                        if (buf[4] == HUB_CLASS) {
+                            for (k = 0; k < MAX_HUB_NB; k++) {
+                                if (hub_in_use[k] == false) {
+                                    for (uint8_t j = 0; j < MAX_TRY_ENUMERATE_HUB; j++) {
+                                        if (hubs[k].connect(&devices[i])) {
+                                            devices[i].hub = &hubs[k];
+                                            hub_in_use[k] = true;
+                                            break;
+                                        }
+                                    }
+                                    if (hub_in_use[k] == true) {
+                                        break;
+                                    }
+                                }
+                            }
+
+                            if (k == MAX_HUB_NB) {
+                                USB_ERR("Too many hubs connected!!\r\n");
+                                too_many_hub = true;
+                            }
+                        }
+
+                        if (usb_msg->hub_parent) {
+                            ((USBHostHub *)(usb_msg->hub_parent))->deviceConnected(&devices[i]);
+                        }
+#endif
+
+                        if ((i < MAX_DEVICE_CONNECTED) && !too_many_hub) {
+                            deviceInUse[i] = true;
+                        }
+
+                    } while(0);
+
+                    break;
+
+                // a device has been disconnected
+                case DEVICE_DISCONNECTED_EVENT:
+
+                    do {
+                        Lock lock(this);
+
+                        controlListState = disableList(CONTROL_ENDPOINT);
+                        bulkListState = disableList(BULK_ENDPOINT);
+                        interruptListState = disableList(INTERRUPT_ENDPOINT);
+
+                        idx = findDevice(usb_msg->hub, usb_msg->port, (USBHostHub *)(usb_msg->hub_parent));
+                        if (idx != -1) {
+                            freeDevice((USBDeviceConnected*)&devices[idx]);
+                            deviceInited[idx]=false;
+                        }
+
+                        if (controlListState) {
+                            enableList(CONTROL_ENDPOINT);
+                        }
+                        if (bulkListState) {
+                            enableList(BULK_ENDPOINT);
+                        }
+                        if (interruptListState) {
+                            enableList(INTERRUPT_ENDPOINT);
+                        }
+
+                    } while(0);
+
+                    break;
+
+                // a td has been processed
+                // call callback on the ed associated to the td
+                // we are not in ISR -> users can use printf in their callback method
+                case TD_PROCESSED_EVENT:
+                    ep = (USBEndpoint *) ((HCTD *)usb_msg->td_addr)->ep;
+                    if (usb_msg->td_state == USB_TYPE_IDLE) {
+                        USB_DBG_EVENT("call callback on td %p [ep: %p state: %s - dev: %p - %s]", usb_msg->td_addr, ep, ep->getStateString(), ep->dev, ep->dev->getName(ep->getIntfNb()));
+
+#if DEBUG_TRANSFER
+                        if (ep->getDir() == IN) {
+                            buf_transfer = ep->getBufStart();
+                            printf("READ SUCCESS [%d bytes transferred - td: 0x%08X] on ep: [%p - addr: %02X]: ",  ep->getLengthTransferred(), usb_msg->td_addr, ep, ep->getAddress());
+                            for (int i = 0; i < ep->getLengthTransferred(); i++) {
+                                printf("%02X ", buf_transfer[i]);
+                            }
+                            printf("\r\n\r\n");
+                        }
+#endif
+                        ep->call();
+                    } else {
+                        idx = findDevice(ep->dev);
+                        if (idx != -1) {
+                            if (deviceInUse[idx]) {
+                                USB_WARN("td %p processed but not in idle state: %s [ep: %p - dev: %p - %s]", usb_msg->td_addr, ep->getStateString(), ep, ep->dev, ep->dev->getName(ep->getIntfNb()));
+                                ep->setState(USB_TYPE_IDLE);
+                                /* as error, on interrupt endpoint can be
+                                 * reported, call the call back registered ,
+                                 * if  device still in use, this call back
+                                 * shall ask again an interrupt request.
+                                 */
+                                ep->call();
+                            }
+                        }
+                    }
+                    break;
+            }
+
+            mail_usb_event.free(usb_msg);
+        }
+    }
+}
+
+USBHost::USBHost() : usbThread(osPriorityNormal, USB_THREAD_STACK)
+{
+#ifndef USBHOST_OTHER
+    headControlEndpoint = NULL;
+    headBulkEndpoint = NULL;
+    headInterruptEndpoint = NULL;
+    tailControlEndpoint = NULL;
+    tailBulkEndpoint = NULL;
+    tailInterruptEndpoint = NULL;
+#endif
+    lenReportDescr = 0;
+
+    controlEndpointAllocated = false;
+
+    for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
+        deviceInUse[i] = false;
+        devices[i].setAddress(i + 1);
+        deviceReset[i] = false;
+        deviceInited[i] = false;
+        for (uint8_t j = 0; j < MAX_INTF; j++) {
+            deviceAttachedDriver[i][j] = false;
+        }
+    }
+
+#if MAX_HUB_NB
+    for (uint8_t i = 0; i < MAX_HUB_NB; i++) {
+        hubs[i].setHost(this);
+        hub_in_use[i] = false;
+    }
+#endif
+
+    usbThread.start(this, &USBHost::usb_process);
+}
+
+USBHost::Lock::Lock(USBHost* pHost) : m_pHost(pHost)
+{
+    m_pHost->usb_mutex.lock();
+}
+
+USBHost::Lock::~Lock()
+{
+    m_pHost->usb_mutex.unlock();
+}
+
+void USBHost::transferCompleted(volatile uint32_t addr)
+{
+    uint8_t state;
+
+    if(addr == 0) {
+        return;
+    }
+
+    volatile HCTD* tdList = NULL;
+
+    //First we must reverse the list order and dequeue each TD
+    do {
+        volatile HCTD* td = (volatile HCTD*)addr;
+        addr = (uint32_t)td->nextTD; //Dequeue from physical list
+        td->nextTD = (hcTd*)tdList; //Enqueue into reversed list
+        tdList = td;
+    } while(addr);
+
+    while(tdList != NULL) {
+        volatile HCTD* td = tdList;
+        tdList = (volatile HCTD*)td->nextTD; //Dequeue element now as it could be modified below
+        if (td->ep != NULL) {
+            USBEndpoint * ep = (USBEndpoint *)(td->ep);
+
+#ifdef USBHOST_OTHER
+            state =  ((HCTD *)td)->state;
+            if (state == USB_TYPE_IDLE) {
+                ep->setLengthTransferred((uint32_t)td->currBufPtr - (uint32_t)ep->getBufStart());
+            }
+
+#else
+            if (((HCTD *)td)->control >> 28) {
+                state = ((HCTD *)td)->control >> 28;
+            } else {
+                if (td->currBufPtr) {
+                    ep->setLengthTransferred((uint32_t)td->currBufPtr - (uint32_t)ep->getBufStart());
+                }
+                state = 16 /*USB_TYPE_IDLE*/;
+            }
+#endif
+            if (state == USB_TYPE_IDLE) {
+                ep->setLengthTransferred((uint32_t)td->currBufPtr - (uint32_t)ep->getBufStart());
+            }
+
+            ep->unqueueTransfer(td);
+
+            if (ep->getType() != CONTROL_ENDPOINT) {
+                // callback on the processed td will be called from the usb_thread (not in ISR)
+                message_t * usb_msg = mail_usb_event.alloc();
+                usb_msg->event_id = TD_PROCESSED_EVENT;
+                usb_msg->td_addr = (void *)td;
+                usb_msg->td_state = state;
+                mail_usb_event.put(usb_msg);
+            }
+            ep->setState((USB_TYPE)state);
+            ep->ep_queue.put((uint8_t*)1);
+        }
+    }
+}
+
+USBHost * USBHost::getHostInst()
+{
+    if (instHost == NULL) {
+        instHost = new USBHost();
+        instHost->init();
+    }
+    return instHost;
+}
+
+
+/*
+ * Called when a device has been connected
+ * Called in ISR!!!! (no printf)
+ */
+/* virtual */ void USBHost::deviceConnected(int hub, int port, bool lowSpeed, USBHostHub * hub_parent)
+{
+    // be sure that the new device connected is not already connected...
+    int idx = findDevice(hub, port, hub_parent);
+    if (idx != -1) {
+        if (deviceInited[idx]) {
+            return;
+        }
+    }
+
+    message_t * usb_msg = mail_usb_event.alloc();
+    usb_msg->event_id = DEVICE_CONNECTED_EVENT;
+    usb_msg->hub = hub;
+    usb_msg->port = port;
+    usb_msg->lowSpeed = lowSpeed;
+    usb_msg->hub_parent = hub_parent;
+    mail_usb_event.put(usb_msg);
+}
+
+/*
+ * Called when a device has been disconnected
+ * Called in ISR!!!! (no printf)
+ */
+/* virtual */ void USBHost::deviceDisconnected(int hub, int port, USBHostHub * hub_parent, volatile uint32_t addr)
+{
+    // be sure that the device disconnected is connected...
+    int idx = findDevice(hub, port, hub_parent);
+    if (idx != -1) {
+        if (!deviceInUse[idx]) {
+            return;
+        }
+    } else {
+        return;
+    }
+
+    message_t * usb_msg = mail_usb_event.alloc();
+    usb_msg->event_id = DEVICE_DISCONNECTED_EVENT;
+    usb_msg->hub = hub;
+    usb_msg->port = port;
+    usb_msg->hub_parent = hub_parent;
+    mail_usb_event.put(usb_msg);
+}
+
+void USBHost::freeDevice(USBDeviceConnected * dev)
+{
+    USBEndpoint * ep = NULL;
+    HCED * ed = NULL;
+
+#if MAX_HUB_NB
+    if (dev->getClass() == HUB_CLASS) {
+        if (dev->hub == NULL) {
+            USB_ERR("HUB NULL!!!!!\r\n");
+        } else {
+            dev->hub->hubDisconnected();
+            for (uint8_t i = 0; i < MAX_HUB_NB; i++) {
+                if (dev->hub == &hubs[i]) {
+                    hub_in_use[i] = false;
+                    break;
+                }
+            }
+        }
+    }
+
+    // notify hub parent that this device has been disconnected
+    if (dev->getHubParent()) {
+        dev->getHubParent()->deviceDisconnected(dev);
+    }
+
+#endif
+
+    int idx = findDevice(dev);
+    if (idx != -1) {
+        deviceInUse[idx] = false;
+        deviceReset[idx] = false;
+
+        for (uint8_t j = 0; j < MAX_INTF; j++) {
+            deviceAttachedDriver[idx][j] = false;
+            if (dev->getInterface(j) != NULL) {
+                USB_DBG("FREE INTF %d on dev: %p, %p, nb_endpot: %d, %s", j, (void *)dev->getInterface(j), dev, dev->getInterface(j)->nb_endpoint, dev->getName(j));
+                for (int i = 0; i < dev->getInterface(j)->nb_endpoint; i++) {
+                    if ((ep = dev->getEndpoint(j, i)) != NULL) {
+#ifndef USBHOST_OTHER
+                        ed = (HCED *)ep->getHCED();
+                        ed->control |= (1 << 14); //sKip bit
+#endif
+                        unqueueEndpoint(ep);
+
+                        freeTD((volatile uint8_t*)ep->getTDList()[0]);
+                        freeTD((volatile uint8_t*)ep->getTDList()[1]);
+
+                        freeED((uint8_t *)ep->getHCED());
+                    }
+                    printList(BULK_ENDPOINT);
+                    printList(INTERRUPT_ENDPOINT);
+                }
+                USB_INFO("Device disconnected [%p - %s - hub: %d - port: %d]", dev, dev->getName(j), dev->getHub(), dev->getPort());
+            }
+        }
+        dev->disconnect();
+    }
+}
+
+
+void USBHost::unqueueEndpoint(USBEndpoint * ep)
+{
+#ifdef USBHOST_OTHER
+    ep->setState(USB_TYPE_FREE);
+#else
+    USBEndpoint * prec = NULL;
+    USBEndpoint * current = NULL;
+
+    for (int i = 0; i < 2; i++) {
+        current = (i == 0) ? (USBEndpoint*)headBulkEndpoint : (USBEndpoint*)headInterruptEndpoint;
+        prec = current;
+        while (current != NULL) {
+            if (current == ep) {
+                if (current->nextEndpoint() != NULL) {
+                    prec->queueEndpoint(current->nextEndpoint());
+                    if (current == headBulkEndpoint) {
+                        updateBulkHeadED((uint32_t)current->nextEndpoint()->getHCED());
+                        headBulkEndpoint = current->nextEndpoint();
+                    } else if (current == headInterruptEndpoint) {
+                        updateInterruptHeadED((uint32_t)current->nextEndpoint()->getHCED());
+                        headInterruptEndpoint = current->nextEndpoint();
+                    }
+                }
+                // here we are dequeuing the queue of ed
+                // we need to update the tail pointer
+                else {
+                    prec->queueEndpoint(NULL);
+                    if (current == headBulkEndpoint) {
+                        updateBulkHeadED(0);
+                        headBulkEndpoint = current->nextEndpoint();
+                    } else if (current == headInterruptEndpoint) {
+                        updateInterruptHeadED(0);
+                        headInterruptEndpoint = current->nextEndpoint();
+                    }
+
+                    // modify tail
+                    switch (current->getType()) {
+                        case BULK_ENDPOINT:
+                            tailBulkEndpoint = prec;
+                            break;
+                        case INTERRUPT_ENDPOINT:
+                            tailInterruptEndpoint = prec;
+                            break;
+                        default:
+                            break;
+                    }
+                }
+                current->setState(USB_TYPE_FREE);
+                return;
+            }
+            prec = current;
+            current = current->nextEndpoint();
+        }
+    }
+#endif
+}
+
+
+USBDeviceConnected * USBHost::getDevice(uint8_t index)
+{
+    if ((index >= MAX_DEVICE_CONNECTED) || (!deviceInUse[index])) {
+        return NULL;
+    }
+    return (USBDeviceConnected*)&devices[index];
+}
+
+// create an USBEndpoint descriptor. the USBEndpoint is not linked
+USBEndpoint * USBHost::newEndpoint(ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir, uint32_t size, uint8_t addr)
+{
+    int i = 0;
+    HCED * ed = (HCED *)getED();
+    HCTD* td_list[2] = { (HCTD*)getTD(), (HCTD*)getTD() };
+
+    memset((void *)td_list[0], 0x00, sizeof(HCTD));
+    memset((void *)td_list[1], 0x00, sizeof(HCTD));
+
+    // search a free USBEndpoint
+    for (i = 0; i < MAX_ENDPOINT; i++) {
+        if (endpoints[i].getState() == USB_TYPE_FREE) {
+            endpoints[i].init(ed, type, dir, size, addr, td_list);
+            USB_DBG("USBEndpoint created (%p): type: %d, dir: %d, size: %d, addr: %d, state: %s", &endpoints[i], type, dir, size, addr, endpoints[i].getStateString());
+            return &endpoints[i];
+        }
+    }
+    USB_ERR("could not allocate more endpoints!!!!");
+    return NULL;
+}
+
+
+USB_TYPE USBHost::resetDevice(USBDeviceConnected * dev)
+{
+    int index = findDevice(dev);
+    if (index != -1) {
+        USB_DBG("Resetting hub %d, port %d\n", dev->getHub(), dev->getPort());
+        Thread::wait(100);
+        if (dev->getHub() == 0) {
+            resetRootHub();
+        }
+#if MAX_HUB_NB
+        else {
+            dev->getHubParent()->portReset(dev->getPort());
+        }
+#endif
+        Thread::wait(100);
+        deviceReset[index] = true;
+        return USB_TYPE_OK;
+    }
+
+    return USB_TYPE_ERROR;
+}
+
+// link the USBEndpoint to the linked list and attach an USBEndpoint to a device
+bool USBHost::addEndpoint(USBDeviceConnected * dev, uint8_t intf_nb, USBEndpoint * ep)
+{
+
+    if (ep == NULL) {
+        return false;
+    }
+
+#ifndef USBHOST_OTHER
+    HCED * prevEd;
+
+#endif
+    // set device address in the USBEndpoint descriptor
+    if (dev == NULL) {
+        ep->setDeviceAddress(0);
+    } else {
+        ep->setDeviceAddress(dev->getAddress());
+    }
+
+    if ((dev != NULL) && dev->getSpeed()) {
+        ep->setSpeed(dev->getSpeed());
+    }
+
+    ep->setIntfNb(intf_nb);
+
+#ifndef USBHOST_OTHER
+    // queue the new USBEndpoint on the ED list
+    switch (ep->getType()) {
+
+        case CONTROL_ENDPOINT:
+            prevEd = ( HCED*) controlHeadED();
+            if (!prevEd) {
+                updateControlHeadED((uint32_t) ep->getHCED());
+                USB_DBG_TRANSFER("First control USBEndpoint: %08X", (uint32_t) ep->getHCED());
+                headControlEndpoint = ep;
+                tailControlEndpoint = ep;
+                return true;
+            }
+            tailControlEndpoint->queueEndpoint(ep);
+            tailControlEndpoint = ep;
+            return true;
+
+        case BULK_ENDPOINT:
+            prevEd = ( HCED*) bulkHeadED();
+            if (!prevEd) {
+                updateBulkHeadED((uint32_t) ep->getHCED());
+                USB_DBG_TRANSFER("First bulk USBEndpoint: %08X\r\n", (uint32_t) ep->getHCED());
+                headBulkEndpoint = ep;
+                tailBulkEndpoint = ep;
+                break;
+            }
+            USB_DBG_TRANSFER("Queue BULK Ed %p after %p\r\n",ep->getHCED(), prevEd);
+            tailBulkEndpoint->queueEndpoint(ep);
+            tailBulkEndpoint = ep;
+            break;
+
+        case INTERRUPT_ENDPOINT:
+            prevEd = ( HCED*) interruptHeadED();
+            if (!prevEd) {
+                updateInterruptHeadED((uint32_t) ep->getHCED());
+                USB_DBG_TRANSFER("First interrupt USBEndpoint: %08X\r\n", (uint32_t) ep->getHCED());
+                headInterruptEndpoint = ep;
+                tailInterruptEndpoint = ep;
+                break;
+            }
+            USB_DBG_TRANSFER("Queue INTERRUPT Ed %p after %p\r\n",ep->getHCED(), prevEd);
+            tailInterruptEndpoint->queueEndpoint(ep);
+            tailInterruptEndpoint = ep;
+            break;
+        default:
+            return false;
+    }
+
+#endif
+    ep->dev = dev;
+    dev->addEndpoint(intf_nb, ep);
+
+    return true;
+}
+
+
+int USBHost::findDevice(USBDeviceConnected * dev)
+{
+    for (int i = 0; i < MAX_DEVICE_CONNECTED; i++) {
+        if (dev == &devices[i]) {
+            return i;
+        }
+    }
+    return -1;
+}
+
+int USBHost::findDevice(uint8_t hub, uint8_t port, USBHostHub * hub_parent)
+{
+    for (int i = 0; i < MAX_DEVICE_CONNECTED; i++) {
+        if (devices[i].getHub() == hub && devices[i].getPort() == port) {
+            if (hub_parent != NULL) {
+                if (hub_parent == devices[i].getHubParent()) {
+                    return i;
+                }
+            } else {
+                return i;
+            }
+        }
+    }
+    return -1;
+}
+
+void USBHost::printList(ENDPOINT_TYPE type)
+{
+#if defined(DEBUG_EP_STATE) && !defined(USBHOST_OTHER)
+    volatile HCED * hced;
+    switch(type) {
+        case CONTROL_ENDPOINT:
+            hced = (HCED *)controlHeadED();
+            break;
+        case BULK_ENDPOINT:
+            hced = (HCED *)bulkHeadED();
+            break;
+        case INTERRUPT_ENDPOINT:
+            hced = (HCED *)interruptHeadED();
+            break;
+    }
+    volatile HCTD * hctd = NULL;
+    const char * type_str = (type == BULK_ENDPOINT) ? "BULK" :
+                            ((type == INTERRUPT_ENDPOINT) ? "INTERRUPT" :
+                             ((type == CONTROL_ENDPOINT) ? "CONTROL" : "ISOCHRONOUS"));
+    printf("State of %s:\r\n", type_str);
+    while (hced != NULL) {
+        uint8_t dir = ((hced->control & (3 << 11)) >> 11);
+        printf("hced: %p [ADDR: %d, DIR: %s, EP_NB: 0x%X]\r\n", hced,
+               hced->control & 0x7f,
+               (dir == 1) ? "OUT" : ((dir == 0) ? "FROM_TD":"IN"),
+               (hced->control & (0xf << 7)) >> 7);
+        hctd = (HCTD *)((uint32_t)(hced->headTD) & ~(0xf));
+        while (hctd != hced->tailTD) {
+            printf("\thctd: %p [DIR: %s]\r\n", hctd, ((hctd->control & (3 << 19)) >> 19) == 1 ? "OUT" : "IN");
+            hctd = hctd->nextTD;
+        }
+        printf("\thctd: %p\r\n", hctd);
+        hced = hced->nextED;
+    }
+    printf("\r\n\r\n");
+#endif
+}
+
+
+// add a transfer on the TD linked list
+USB_TYPE USBHost::addTransfer(USBEndpoint * ed, uint8_t * buf, uint32_t len)
+{
+    USB_TYPE ret=USB_TYPE_PROCESSING;
+    td_mutex.lock();
+
+    // allocate a TD which will be freed in TDcompletion
+    volatile HCTD * td = ed->getNextTD();
+    if (td == NULL) {
+        return USB_TYPE_ERROR;
+    }
+
+#ifndef USBHOST_OTHER
+    uint32_t token = (ed->isSetup() ? TD_SETUP : ( (ed->getDir() == IN) ? TD_IN : TD_OUT ));
+
+    uint32_t td_toggle;
+
+    if (ed->getType() == CONTROL_ENDPOINT) {
+        if (ed->isSetup()) {
+            td_toggle = TD_TOGGLE_0;
+        } else {
+            td_toggle = TD_TOGGLE_1;
+        }
+    } else {
+        td_toggle = 0;
+    }
+
+    td->control      = (TD_ROUNDING | token | TD_DELAY_INT(0) | td_toggle | TD_CC);
+    td->currBufPtr   = buf;
+    td->bufEnd       = (buf + (len - 1));
+
+    ENDPOINT_TYPE type = ed->getType();
+
+    disableList(type);
+    ed->queueTransfer();
+    printList(type);
+    enableList(type);
+#else
+    /*  call method specific for endpoint  */
+    td->currBufPtr   = buf;
+    td->size = len;
+    ret = ed->queueTransfer();
+#endif
+
+    td_mutex.unlock();
+
+    return ret;
+}
+
+
+
+USB_TYPE USBHost::getDeviceDescriptor(USBDeviceConnected * dev, uint8_t * buf, uint16_t max_len_buf, uint16_t * len_dev_descr)
+{
+    USB_TYPE t = controlRead(  dev,
+                               USB_DEVICE_TO_HOST | USB_RECIPIENT_DEVICE,
+                               GET_DESCRIPTOR,
+                               (DEVICE_DESCRIPTOR << 8) | (0),
+                               0, buf, MIN(DEVICE_DESCRIPTOR_LENGTH, max_len_buf));
+    if (len_dev_descr) {
+        *len_dev_descr = MIN(DEVICE_DESCRIPTOR_LENGTH, max_len_buf);
+    }
+
+    return t;
+}
+
+USB_TYPE USBHost::getConfigurationDescriptor(USBDeviceConnected * dev, uint8_t * buf, uint16_t max_len_buf, uint16_t * len_conf_descr)
+{
+    USB_TYPE res;
+    uint16_t total_conf_descr_length = 0;
+
+    // fourth step: get the beginning of the configuration descriptor to have the total length of the conf descr
+    res = controlRead(  dev,
+                        USB_DEVICE_TO_HOST | USB_RECIPIENT_DEVICE,
+                        GET_DESCRIPTOR,
+                        (CONFIGURATION_DESCRIPTOR << 8) | (0),
+                        0, buf, CONFIGURATION_DESCRIPTOR_LENGTH);
+
+    if (res != USB_TYPE_OK) {
+        USB_ERR("GET CONF 1 DESCR FAILED");
+        return res;
+    }
+    total_conf_descr_length = buf[2] | (buf[3] << 8);
+    total_conf_descr_length = MIN(max_len_buf, total_conf_descr_length);
+
+    if (len_conf_descr) {
+        *len_conf_descr = total_conf_descr_length;
+    }
+
+    USB_DBG("TOTAL_LENGTH: %d \t NUM_INTERF: %d", total_conf_descr_length, buf[4]);
+
+    return controlRead(  dev,
+                         USB_DEVICE_TO_HOST | USB_RECIPIENT_DEVICE,
+                         GET_DESCRIPTOR,
+                         (CONFIGURATION_DESCRIPTOR << 8) | (0),
+                         0, buf, total_conf_descr_length);
+}
+
+
+USB_TYPE USBHost::setAddress(USBDeviceConnected * dev, uint8_t address)
+{
+    return controlWrite(    dev,
+                            USB_HOST_TO_DEVICE | USB_RECIPIENT_DEVICE,
+                            SET_ADDRESS,
+                            address,
+                            0, NULL, 0);
+
+}
+
+USB_TYPE USBHost::setConfiguration(USBDeviceConnected * dev, uint8_t conf)
+{
+    return controlWrite( dev,
+                         USB_HOST_TO_DEVICE | USB_RECIPIENT_DEVICE,
+                         SET_CONFIGURATION,
+                         conf,
+                         0, NULL, 0);
+}
+
+uint8_t USBHost::numberDriverAttached(USBDeviceConnected * dev)
+{
+    int index = findDevice(dev);
+    uint8_t cnt = 0;
+    if (index == -1) {
+        return 0;
+    }
+    for (uint8_t i = 0; i < MAX_INTF; i++) {
+        if (deviceAttachedDriver[index][i]) {
+            cnt++;
+        }
+    }
+    return cnt;
+}
+
+// enumerate a device with the control USBEndpoint
+USB_TYPE USBHost::enumerate(USBDeviceConnected * dev, IUSBEnumerator* pEnumerator)
+{
+    uint16_t total_conf_descr_length = 0;
+    USB_TYPE res;
+
+    do {
+        Lock lock(this);
+
+        // don't enumerate a device which all interfaces are registered to a specific driver
+        int index = findDevice(dev);
+
+        if (index == -1) {
+            return USB_TYPE_ERROR;
+        }
+
+        uint8_t nb_intf_attached = numberDriverAttached(dev);
+        USB_DBG("dev: %p nb_intf: %d", dev, dev->getNbIntf());
+        USB_DBG("dev: %p nb_intf_attached: %d", dev, nb_intf_attached);
+        if ((nb_intf_attached != 0) && (dev->getNbIntf() == nb_intf_attached)) {
+            USB_DBG("Don't enumerate dev: %p because all intf are registered with a driver", dev);
+            return USB_TYPE_OK;
+        }
+
+        USB_DBG("Enumerate dev: %p", dev);
+
+        // third step: get the whole device descriptor to see vid, pid
+        res = getDeviceDescriptor(dev, data, DEVICE_DESCRIPTOR_LENGTH);
+
+        if (res != USB_TYPE_OK) {
+            USB_DBG("GET DEV DESCR FAILED");
+            return res;
+        }
+
+        dev->setClass(data[4]);
+        dev->setSubClass(data[5]);
+        dev->setProtocol(data[6]);
+        dev->setVid(data[8] | (data[9] << 8));
+        dev->setPid(data[10] | (data[11] << 8));
+        USB_DBG("CLASS: %02X \t VID: %04X \t PID: %04X", data[4], data[8] | (data[9] << 8), data[10] | (data[11] << 8));
+
+        pEnumerator->setVidPid( data[8] | (data[9] << 8), data[10] | (data[11] << 8) );
+
+        res = getConfigurationDescriptor(dev, data, sizeof(data), &total_conf_descr_length);
+        if (res != USB_TYPE_OK) {
+            return res;
+        }
+
+#if (DEBUG > 3)
+        USB_DBG("CONFIGURATION DESCRIPTOR:\r\n");
+        for (int i = 0; i < total_conf_descr_length; i++) {
+            printf("%02X ", data[i]);
+        }
+        printf("\r\n\r\n");
+#endif
+
+        // Parse the configuration descriptor
+        parseConfDescr(dev, data, total_conf_descr_length, pEnumerator);
+
+        // only set configuration if not enumerated before
+        if (!dev->isEnumerated()) {
+
+            USB_DBG("Set configuration 1 on dev: %p", dev);
+            // sixth step: set configuration (only 1 supported)
+            res = setConfiguration(dev, 1);
+
+            if (res != USB_TYPE_OK) {
+                USB_DBG("SET CONF FAILED");
+                return res;
+            }
+        }
+
+        dev->setEnumerated();
+
+        // Now the device is enumerated!
+        USB_DBG("dev %p is enumerated\r\n", dev);
+
+    } while(0);
+
+    // Some devices may require this delay
+    Thread::wait(100);
+
+    return USB_TYPE_OK;
+}
+// this method fills the USBDeviceConnected object: class,.... . It also add endpoints found in the descriptor.
+void USBHost::parseConfDescr(USBDeviceConnected * dev, uint8_t * conf_descr, uint32_t len, IUSBEnumerator* pEnumerator)
+{
+    uint32_t index = 0;
+    uint32_t len_desc = 0;
+    uint8_t id = 0;
+    int nb_endpoints_used = 0;
+    USBEndpoint * ep = NULL;
+    uint8_t intf_nb = 0;
+    bool parsing_intf = false;
+    uint8_t current_intf = 0;
+
+    while (index < len) {
+        len_desc = conf_descr[index];
+        id = conf_descr[index+1];
+        switch (id) {
+            case CONFIGURATION_DESCRIPTOR:
+                USB_DBG("dev: %p has %d intf", dev, conf_descr[4]);
+                dev->setNbIntf(conf_descr[4]);
+                break;
+            case INTERFACE_DESCRIPTOR:
+                if(pEnumerator->parseInterface(conf_descr[index + 2], conf_descr[index + 5], conf_descr[index + 6], conf_descr[index + 7])) {
+                    if (intf_nb++ <= MAX_INTF) {
+                        current_intf = conf_descr[index + 2];
+                        dev->addInterface(current_intf, conf_descr[index + 5], conf_descr[index + 6], conf_descr[index + 7]);
+                        nb_endpoints_used = 0;
+                        USB_DBG("ADD INTF %d on device %p: class: %d, subclass: %d, proto: %d", current_intf, dev, conf_descr[index + 5],conf_descr[index + 6],conf_descr[index + 7]);
+                    } else {
+                        USB_DBG("Drop intf...");
+                    }
+                    parsing_intf = true;
+                } else {
+                    parsing_intf = false;
+                }
+                break;
+            case ENDPOINT_DESCRIPTOR:
+                if (parsing_intf && (intf_nb <= MAX_INTF) ) {
+                    if (nb_endpoints_used < MAX_ENDPOINT_PER_INTERFACE) {
+                        if( pEnumerator->useEndpoint(current_intf, (ENDPOINT_TYPE)(conf_descr[index + 3] & 0x03), (ENDPOINT_DIRECTION)((conf_descr[index + 2] >> 7) + 1)) ) {
+                            // if the USBEndpoint is isochronous -> skip it (TODO: fix this)
+                            if ((conf_descr[index + 3] & 0x03) != ISOCHRONOUS_ENDPOINT) {
+                                ep = newEndpoint((ENDPOINT_TYPE)(conf_descr[index+3] & 0x03),
+                                                 (ENDPOINT_DIRECTION)((conf_descr[index + 2] >> 7) + 1),
+                                                 conf_descr[index + 4] | (conf_descr[index + 5] << 8),
+                                                 conf_descr[index + 2] & 0x0f);
+                                USB_DBG("ADD USBEndpoint %p, on interf %d on device %p", ep, current_intf, dev);
+                                if (ep != NULL && dev != NULL) {
+                                    addEndpoint(dev, current_intf, ep);
+                                } else {
+                                    USB_DBG("EP NULL");
+                                }
+                                nb_endpoints_used++;
+                            } else {
+                                USB_DBG("ISO USBEndpoint NOT SUPPORTED");
+                            }
+                        }
+                    }
+                }
+                break;
+            case HID_DESCRIPTOR:
+                lenReportDescr = conf_descr[index + 7] | (conf_descr[index + 8] << 8);
+                break;
+            default:
+                break;
+        }
+        index += len_desc;
+    }
+}
+
+
+USB_TYPE USBHost::bulkWrite(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking)
+{
+    return generalTransfer(dev, ep, buf, len, blocking, BULK_ENDPOINT, true);
+}
+
+USB_TYPE USBHost::bulkRead(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking)
+{
+    return generalTransfer(dev, ep, buf, len, blocking, BULK_ENDPOINT, false);
+}
+
+USB_TYPE USBHost::interruptWrite(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking)
+{
+    return generalTransfer(dev, ep, buf, len, blocking, INTERRUPT_ENDPOINT, true);
+}
+
+USB_TYPE USBHost::interruptRead(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking)
+{
+    return generalTransfer(dev, ep, buf, len, blocking, INTERRUPT_ENDPOINT, false);
+}
+
+USB_TYPE USBHost::generalTransfer(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking, ENDPOINT_TYPE type, bool write)
+{
+
+#if DEBUG_TRANSFER
+    const char * type_str = (type == BULK_ENDPOINT) ? "BULK" : ((type == INTERRUPT_ENDPOINT) ? "INTERRUPT" : "ISOCHRONOUS");
+    USB_DBG_TRANSFER("----- %s %s [dev: %p - %s - hub: %d - port: %d - addr: %d - ep: %02X]------", type_str, (write) ? "WRITE" : "READ", dev, dev->getName(ep->getIntfNb()), dev->getHub(), dev->getPort(), dev->getAddress(), ep->getAddress());
+#endif
+
+    Lock lock(this);
+
+    USB_TYPE res;
+    ENDPOINT_DIRECTION dir = (write) ? OUT : IN;
+
+    if (dev == NULL) {
+        USB_ERR("dev NULL");
+        return USB_TYPE_ERROR;
+    }
+
+    if (ep == NULL) {
+        USB_ERR("ep NULL");
+        return USB_TYPE_ERROR;
+    }
+
+    if (ep->getState() != USB_TYPE_IDLE) {
+        USB_WARN("[ep: %p - dev: %p - %s] NOT IDLE: %s", ep, ep->dev, ep->dev->getName(ep->getIntfNb()), ep->getStateString());
+        return ep->getState();
+    }
+
+    if ((ep->getDir() != dir) || (ep->getType() != type)) {
+        USB_ERR("[ep: %p - dev: %p] wrong dir or bad USBEndpoint type", ep, ep->dev);
+        return USB_TYPE_ERROR;
+    }
+
+    if (dev->getAddress() != ep->getDeviceAddress()) {
+        USB_ERR("[ep: %p - dev: %p] USBEndpoint addr and device addr don't match", ep, ep->dev);
+        return USB_TYPE_ERROR;
+    }
+
+#if DEBUG_TRANSFER
+    if (write) {
+        USB_DBG_TRANSFER("%s WRITE buffer", type_str);
+        for (int i = 0; i < ep->getLengthTransferred(); i++) {
+            printf("%02X ", buf[i]);
+        }
+        printf("\r\n\r\n");
+    }
+#endif
+    res = addTransfer(ep, buf, len);
+
+    if ((blocking)&& (res == USB_TYPE_PROCESSING)) {
+#ifdef USBHOST_OTHER
+        osEvent  event = ep->ep_queue.get(TD_TIMEOUT);
+        if (event.status == osEventTimeout) {
+            /*  control endpoint is confusing for merge on b */
+            disableList(CONTROL_ENDPOINT);
+            ep->setState(USB_TYPE_ERROR);
+            ep->ep_queue.get(0);
+            ep->unqueueTransfer(ep->getProcessedTD());
+            enableList(CONTROL_ENDPOINT);
+        }
+#else
+        ep->ep_queue.get();
+#endif
+        res = ep->getState();
+
+        USB_DBG_TRANSFER("%s TRANSFER res: %s on ep: %p\r\n", type_str, ep->getStateString(), ep);
+
+        if (res != USB_TYPE_IDLE) {
+            return res;
+        }
+
+        return USB_TYPE_OK;
+    }
+
+    return res;
+
+}
+
+
+USB_TYPE USBHost::controlRead(USBDeviceConnected * dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len)
+{
+    return controlTransfer(dev, requestType, request, value, index, buf, len, false);
+}
+
+USB_TYPE USBHost::controlWrite(USBDeviceConnected * dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len)
+{
+    return controlTransfer(dev, requestType, request, value, index, buf, len, true);
+}
+
+USB_TYPE USBHost::controlTransfer(USBDeviceConnected * dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len, bool write)
+{
+    Lock lock(this);
+    USB_DBG_TRANSFER("----- CONTROL %s [dev: %p - hub: %d - port: %d] ------", (write) ? "WRITE" : "READ", dev, dev->getHub(), dev->getPort());
+
+    int length_transfer = len;
+    USB_TYPE res;
+    uint32_t token;
+
+    control->setSpeed(dev->getSpeed());
+    control->setSize(dev->getSizeControlEndpoint());
+    if (dev->isActiveAddress()) {
+        control->setDeviceAddress(dev->getAddress());
+    } else {
+        control->setDeviceAddress(0);
+    }
+
+    USB_DBG_TRANSFER("Control transfer on device: %d\r\n", control->getDeviceAddress());
+    fillControlBuf(requestType, request, value, index, len);
+
+#if DEBUG_TRANSFER
+    USB_DBG_TRANSFER("SETUP PACKET: ");
+    for (int i = 0; i < 8; i++) {
+        printf("%01X ", setupPacket[i]);
+    }
+    printf("\r\n");
+#endif
+
+    control->setNextToken(TD_SETUP);
+    res = addTransfer(control, (uint8_t*)setupPacket, 8);
+
+    if (res == USB_TYPE_PROCESSING)
+#ifdef USBHOST_OTHER
+    {
+        osEvent  event = control->ep_queue.get(TD_TIMEOUT_CTRL);
+        if (event.status == osEventTimeout) {
+            disableList(CONTROL_ENDPOINT);
+            control->setState(USB_TYPE_ERROR);
+            control->ep_queue.get(0);
+            control->unqueueTransfer(control->getProcessedTD());
+            enableList(CONTROL_ENDPOINT);
+        }
+    }
+#else
+        control->ep_queue.get();
+#endif
+    res = control->getState();
+
+    USB_DBG_TRANSFER("CONTROL setup stage %s", control->getStateString());
+
+    if (res != USB_TYPE_IDLE) {
+        return res;
+    }
+
+    if (length_transfer) {
+        token = (write) ? TD_OUT : TD_IN;
+        control->setNextToken(token);
+        res = addTransfer(control, (uint8_t *)buf, length_transfer);
+
+        if (res == USB_TYPE_PROCESSING)
+#ifdef USBHOST_OTHER
+        {
+            osEvent  event = control->ep_queue.get(TD_TIMEOUT_CTRL);
+            if (event.status == osEventTimeout) {
+                disableList(CONTROL_ENDPOINT);
+                control->setState(USB_TYPE_ERROR);
+                control->ep_queue.get(0);
+                control->unqueueTransfer(control->getProcessedTD());
+                enableList(CONTROL_ENDPOINT);
+            }
+        }
+#else
+            control->ep_queue.get();
+#endif
+        res = control->getState();
+
+#if DEBUG_TRANSFER
+        USB_DBG_TRANSFER("CONTROL %s stage %s", (write) ? "WRITE" : "READ", control->getStateString());
+        if (write) {
+            USB_DBG_TRANSFER("CONTROL WRITE buffer");
+            for (int i = 0; i < control->getLengthTransferred(); i++) {
+                printf("%02X ", buf[i]);
+            }
+            printf("\r\n\r\n");
+        } else {
+            USB_DBG_TRANSFER("CONTROL READ SUCCESS [%d bytes transferred]", control->getLengthTransferred());
+            for (int i = 0; i < control->getLengthTransferred(); i++) {
+                printf("%02X ", buf[i]);
+            }
+            printf("\r\n\r\n");
+        }
+#endif
+
+        if (res != USB_TYPE_IDLE) {
+            return res;
+        }
+    }
+
+    token = (write) ? TD_IN : TD_OUT;
+    control->setNextToken(token);
+    res = addTransfer(control, NULL, 0);
+    if (res == USB_TYPE_PROCESSING)
+#ifdef USBHOST_OTHER
+    {
+        osEvent  event = control->ep_queue.get(TD_TIMEOUT_CTRL);
+        if (event.status == osEventTimeout) {
+            disableList(CONTROL_ENDPOINT);
+            control->setState(USB_TYPE_ERROR);
+            control->ep_queue.get(0);
+            control->unqueueTransfer(control->getProcessedTD());
+            enableList(CONTROL_ENDPOINT);
+        }
+    }
+#else
+        control->ep_queue.get();
+#endif
+    res = control->getState();
+
+    USB_DBG_TRANSFER("CONTROL ack stage %s", control->getStateString());
+
+    if (res != USB_TYPE_IDLE) {
+        return res;
+    }
+
+    return USB_TYPE_OK;
+}
+
+
+void USBHost::fillControlBuf(uint8_t requestType, uint8_t request, uint16_t value, uint16_t index, int len)
+{
+    setupPacket[0] = requestType;
+    setupPacket[1] = request;
+    setupPacket[2] = (uint8_t) value;
+    setupPacket[3] = (uint8_t) (value >> 8);
+    setupPacket[4] = (uint8_t) index;
+    setupPacket[5] = (uint8_t) (index >> 8);
+    setupPacket[6] = (uint8_t) len;
+    setupPacket[7] = (uint8_t) (len >> 8);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/USBHost/USBHost.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,396 @@
+/* mbed USBHost Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * 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.
+ */
+
+#ifndef USBHOST_H
+#define USBHOST_H
+#ifdef TARGET_STM
+#include "mbed.h" 
+#endif
+#include "USBHALHost.h"
+#include "USBDeviceConnected.h"
+#include "IUSBEnumerator.h"
+#include "USBHostConf.h"
+#include "rtos.h"
+#include "dbg.h"
+#include "USBHostHub.h"
+
+/**
+* USBHost class
+*   This class is a singleton. All drivers have a reference on the static USBHost instance
+*/
+class USBHost : public USBHALHost {
+public:
+    /**
+    * Static method to create or retrieve the single USBHost instance
+    */
+    static USBHost * getHostInst();
+
+    /**
+    * Control read: setup stage, data stage and status stage
+    *
+    * @param dev the control read will be done for this device
+    * @param requestType request type
+    * @param request request
+    * @param value value
+    * @param index index
+    * @param buf pointer on a buffer where will be store the data received
+    * @param len length of the transfer
+    *
+    * @returns status of the control read
+    */
+    USB_TYPE controlRead(USBDeviceConnected * dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len);
+
+    /**
+    * Control write: setup stage, data stage and status stage
+    *
+    * @param dev the control write will be done for this device
+    * @param requestType request type
+    * @param request request
+    * @param value value
+    * @param index index
+    * @param buf pointer on a buffer which will be written
+    * @param len length of the transfer
+    *
+    * @returns status of the control write
+    */
+    USB_TYPE controlWrite(USBDeviceConnected * dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len);
+
+    /**
+    * Bulk read
+    *
+    * @param dev the bulk transfer will be done for this device
+    * @param ep USBEndpoint which will be used to read a packet
+    * @param buf pointer on a buffer where will be store the data received
+    * @param len length of the transfer
+    * @param blocking if true, the read is blocking (wait for completion)
+    *
+    * @returns status of the bulk read
+    */
+    USB_TYPE bulkRead(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking = true);
+
+    /**
+    * Bulk write
+    *
+    * @param dev the bulk transfer will be done for this device
+    * @param ep USBEndpoint which will be used to write a packet
+    * @param buf pointer on a buffer which will be written
+    * @param len length of the transfer
+    * @param blocking if true, the write is blocking (wait for completion)
+    *
+    * @returns status of the bulk write
+    */
+    USB_TYPE bulkWrite(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking = true);
+
+    /**
+    * Interrupt read
+    *
+    * @param dev the bulk transfer will be done for this device
+    * @param ep USBEndpoint which will be used to write a packet
+    * @param buf pointer on a buffer which will be written
+    * @param len length of the transfer
+    * @param blocking if true, the read is blocking (wait for completion)
+    *
+    * @returns status of the interrupt read
+    */
+    USB_TYPE interruptRead(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking = true);
+
+    /**
+    * Interrupt write
+    *
+    * @param dev the bulk transfer will be done for this device
+    * @param ep USBEndpoint which will be used to write a packet
+    * @param buf pointer on a buffer which will be written
+    * @param len length of the transfer
+    * @param blocking if true, the write is blocking (wait for completion)
+    *
+    * @returns status of the interrupt write
+    */
+    USB_TYPE interruptWrite(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking = true);
+
+    /**
+    * Enumerate a device.
+    *
+    * @param dev device which will be enumerated
+    *
+    * @returns status of the enumeration
+    */
+    USB_TYPE enumerate(USBDeviceConnected * dev, IUSBEnumerator* pEnumerator);
+
+    /**
+    * reset a specific device
+    *
+    * @param dev device which will be resetted
+    */
+    USB_TYPE resetDevice(USBDeviceConnected * dev);
+
+    /**
+    * Get a device
+    *
+    * @param index index of the device which will be returned
+    *
+    * @returns pointer on the "index" device
+    */
+    USBDeviceConnected * getDevice(uint8_t index);
+
+    /*
+    * If there is a HID device connected, the host stores the length of the report descriptor.
+    * This avoid to the driver to re-ask the configuration descriptor to request the report descriptor
+    *
+    * @returns length of the report descriptor
+    */
+    inline uint16_t getLengthReportDescr() {
+        return lenReportDescr;
+    };
+
+    /**
+     *  register a driver into the host associated with a callback function called when the device is disconnected
+     *
+     *  @param dev device
+     *  @param intf interface number
+     *  @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>
+    inline void registerDriver(USBDeviceConnected * dev, uint8_t intf, T* tptr, void (T::*mptr)(void)) {
+        int index = findDevice(dev);
+        if ((index != -1) && (mptr != NULL) && (tptr != NULL)) {
+            USB_DBG("register driver for dev: %p on intf: %d", dev, intf);
+            deviceAttachedDriver[index][intf] = true;
+            dev->onDisconnect(intf, tptr, mptr);
+        }
+    }
+
+    /**
+     * register a driver into the host associated with a callback function called when the device is disconnected
+     *
+     * @param dev device
+     * @param intf interface number
+     * @param fn callback called when the specified device has been disconnected
+     */
+    inline void registerDriver(USBDeviceConnected * dev, uint8_t intf, void (*fn)(void)) {
+        int index = findDevice(dev);
+        if ((index != -1) && (fn != NULL)) {
+            USB_DBG("register driver for dev: %p on intf: %d", dev, intf);
+            deviceAttachedDriver[index][intf] = true;
+            dev->onDisconnect(intf, fn);
+        }
+    }
+
+    /**
+     * Instantiate to protect USB thread from accessing shared objects (USBConnectedDevices and Interfaces)
+     */
+    class Lock
+    {
+    public:
+      Lock(USBHost* pHost);
+      ~Lock();
+    private:
+      USBHost* m_pHost;
+    };
+
+    friend class USBHostHub;
+
+protected:
+
+    /**
+    * Virtual method called when a transfer has been completed
+    *
+    * @param addr list of the TDs which have been completed
+    */
+    virtual void transferCompleted(volatile uint32_t addr);
+
+    /**
+    * Virtual method called when a device has been connected
+    *
+    * @param hub hub number of the device
+    * @param port port number of the device
+    * @param lowSpeed 1 if low speed, 0 otherwise
+    * @param hub_parent reference on the parent hub
+    */
+    virtual void deviceConnected(int hub, int port, bool lowSpeed, USBHostHub * hub_parent = NULL);
+
+    /**
+    * Virtuel method called when a device has been disconnected
+    *
+    * @param hub hub number of the device
+    * @param port port number of the device
+    * @param addr list of the TDs which have been completed to dequeue freed TDs
+    */
+    virtual void deviceDisconnected(int hub, int port, USBHostHub * hub_parent, volatile uint32_t addr);
+
+
+private:
+    // singleton class -> constructor is private
+    USBHost();
+    static USBHost * instHost;
+    uint16_t  lenReportDescr;
+
+    // endpoints
+    void unqueueEndpoint(USBEndpoint * ep) ;
+    USBEndpoint  endpoints[MAX_ENDPOINT];
+    USBEndpoint* volatile  control;
+
+    USBEndpoint* volatile  headControlEndpoint;
+    USBEndpoint* volatile  headBulkEndpoint;
+    USBEndpoint* volatile  headInterruptEndpoint;
+
+    USBEndpoint* volatile  tailControlEndpoint;
+    USBEndpoint* volatile  tailBulkEndpoint;
+    USBEndpoint* volatile  tailInterruptEndpoint;
+
+    bool controlEndpointAllocated;
+
+    // devices connected
+    USBDeviceConnected devices[MAX_DEVICE_CONNECTED];
+    bool  deviceInUse[MAX_DEVICE_CONNECTED];
+    bool  deviceAttachedDriver[MAX_DEVICE_CONNECTED][MAX_INTF];
+    bool  deviceReset[MAX_DEVICE_CONNECTED];
+    bool  deviceInited[MAX_DEVICE_CONNECTED];
+
+#if MAX_HUB_NB
+    USBHostHub hubs[MAX_HUB_NB];
+    bool hub_in_use[MAX_HUB_NB];
+#endif
+
+    // to store a setup packet
+    uint8_t  setupPacket[8];
+
+    typedef struct {
+        uint8_t event_id;
+        void * td_addr;
+        uint8_t hub;
+        uint8_t port;
+        uint8_t lowSpeed;
+        uint8_t td_state;
+        void * hub_parent;
+    } message_t;
+
+    Thread usbThread;
+    void usb_process();
+    Mail<message_t, 10> mail_usb_event;
+    Mutex usb_mutex;
+    Mutex td_mutex;
+
+    // buffer for conf descriptor
+    uint8_t data[415];
+
+    /**
+    * Add a transfer on the TD linked list associated to an ED
+    *
+    * @param ed the transfer is associated to this ed
+    * @param buf pointer on a buffer where will be read/write data to send or receive
+    * @param len transfer length
+    *
+    * @return status of the transfer
+    */
+    USB_TYPE addTransfer(USBEndpoint * ed, uint8_t * buf, uint32_t len) ;
+
+    /**
+    * Link the USBEndpoint to the linked list and attach an USBEndpoint this USBEndpoint to a device
+    *
+    * @param dev pointer on a USBDeviceConnected object
+    * @param ep pointer on the USBEndpoint which will be added
+    *
+    * return true if successful
+    */
+    bool addEndpoint(USBDeviceConnected * dev, uint8_t intf_nb, USBEndpoint * ep) ;
+
+    /**
+    * Create an USBEndpoint descriptor. Warning: the USBEndpoint is not linked.
+    *
+    * @param type USBEndpoint type (CONTROL_ENDPOINT, BULK_ENDPOINT, INTERRUPT_ENDPOINT)
+    * @param dir USBEndpoint direction (no meaning for CONTROL_ENDPOINT)
+    * @param size USBEndpoint max packet size
+    * @param addr USBEndpoint address
+    *
+    * @returns pointer on the USBEndpoint created
+    */
+    USBEndpoint * newEndpoint(ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir, uint32_t size, uint8_t addr) ;
+
+    /**
+    * Request the device descriptor
+    *
+    * @param dev request the device descriptor on this device
+    * @param buf buffer to store the device descriptor
+    * @param max_len_buf maximum size of buf
+    * @param len_dev_descr pointer to store the length of the packet transferred
+    */
+    USB_TYPE getDeviceDescriptor(USBDeviceConnected * dev, uint8_t * buf, uint16_t max_len_buf, uint16_t * len_dev_descr = NULL);
+
+    /**
+    * Request the configuration descriptor
+    *
+    * @param dev request the configuration descriptor on this device
+    * @param buf buffer to store the configuration descriptor
+    * @param max_len_buf maximum size of buf
+    * @param len_conf_descr pointer to store the length of the packet transferred
+    */
+    USB_TYPE getConfigurationDescriptor(USBDeviceConnected * dev, uint8_t * buf, uint16_t max_len_buf, uint16_t * len_conf_descr = NULL);
+
+    /**
+    * Set the address of a specific device
+    *
+    * @param dev device to set the address
+    * @param address address
+    */
+    USB_TYPE setAddress(USBDeviceConnected * dev, uint8_t address);
+
+    /**
+    * Set the configuration of a device
+    *
+    * @param dev device on which the specified configuration will be activated
+    * @param conf configuration number to activate (usually 1)
+    */
+    USB_TYPE setConfiguration(USBDeviceConnected * dev, uint8_t conf);
+
+    /**
+    * Free a specific device
+    *
+    * @param dev device to be freed
+    */
+    void freeDevice(USBDeviceConnected * dev);
+
+    USB_TYPE controlTransfer(   USBDeviceConnected * dev,
+                                uint8_t requestType,
+                                uint8_t request,
+                                uint32_t value,
+                                uint32_t index,
+                                uint8_t * buf,
+                                uint32_t len,
+                                bool write);
+
+    USB_TYPE generalTransfer(   USBDeviceConnected * dev,
+                                USBEndpoint * ep,
+                                uint8_t * buf,
+                                uint32_t len,
+                                bool blocking,
+                                ENDPOINT_TYPE type,
+                                bool write) ;
+
+    void fillControlBuf(uint8_t requestType, uint8_t request, uint16_t value, uint16_t index, int len) ;
+    void parseConfDescr(USBDeviceConnected * dev, uint8_t * conf_descr, uint32_t len, IUSBEnumerator* pEnumerator) ;
+    int findDevice(USBDeviceConnected * dev) ;
+    int findDevice(uint8_t hub, uint8_t port, USBHostHub * hub_parent = NULL) ;
+    uint8_t numberDriverAttached(USBDeviceConnected * dev);
+
+    /////////////////////////
+    /// FOR DEBUG
+    /////////////////////////
+    void printList(ENDPOINT_TYPE type);
+
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/USBHost/USBHostConf.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,154 @@
+/* mbed USBHost Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * 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.
+ */
+
+#ifndef USBHOST_CONF_H
+#define USBHOST_CONF_H
+#if defined(TARGET_STM)
+/*
+* Maximum number of devices that can be connected
+* to the usb host
+*/
+/*   hub + 2 devices */
+#define MAX_DEVICE_CONNECTED        5
+
+/*
+* Maximum of Hub connected to the usb host
+*/
+#define MAX_HUB_NB                  3
+
+/*
+* Maximum number of ports on a USB hub
+*/
+#define MAX_HUB_PORT                4
+
+/*
+* Enable USBHostMSD
+*/
+#define USBHOST_MSD                 1
+
+/*
+* Enable USBHostKeyboard
+*/
+#define USBHOST_KEYBOARD            1
+
+/*
+* Enable USBHostMouse
+*/
+#define USBHOST_MOUSE               1
+
+/*
+* Enable USBHostSerial or USBHostMultiSerial (if set > 1)
+*/
+#define USBHOST_SERIAL              1
+
+/*
+* Enable USB3Gmodule
+*/
+#define USBHOST_3GMODULE            1
+
+/*
+* Enable USB MIDI
+*/
+#define USBHOST_MIDI                1
+
+/*
+* Maximum number of interfaces of a usb device
+*/
+#define MAX_INTF                    2
+
+/*
+* Maximum number of endpoints on each interface
+*/
+#define MAX_ENDPOINT_PER_INTERFACE  2
+
+/*
+* Maximum number of endpoint descriptors that can be allocated
+*/
+#define MAX_ENDPOINT               11 /*  USB FS 11 channel */
+
+#else
+/*
+* Maximum number of devices that can be connected
+* to the usb host
+*/
+#define MAX_DEVICE_CONNECTED        5
+
+/*
+* Maximum of Hub connected to the usb host
+*/
+#define MAX_HUB_NB                  2
+
+/*
+* Maximum number of ports on a USB hub
+*/
+#define MAX_HUB_PORT                4
+
+/*
+* Enable USBHostMSD
+*/
+#define USBHOST_MSD                 1
+
+/*
+* Enable USBHostKeyboard
+*/
+#define USBHOST_KEYBOARD            1
+
+/*
+* Enable USBHostMouse
+*/
+#define USBHOST_MOUSE               1
+
+/*
+* Enable USBHostSerial or USBHostMultiSerial (if set > 1)
+*/
+#define USBHOST_SERIAL              1
+
+/*
+* Enable USB3Gmodule
+*/
+#define USBHOST_3GMODULE            1
+
+/*
+* Enable USB MIDI
+*/
+#define USBHOST_MIDI                1 
+
+/*
+* Maximum number of interfaces of a usb device
+*/
+#define MAX_INTF                    4
+
+/*
+* Maximum number of endpoints on each interface
+*/
+#define MAX_ENDPOINT_PER_INTERFACE  3
+
+/*
+* Maximum number of endpoint descriptors that can be allocated
+*/
+#define MAX_ENDPOINT                (MAX_DEVICE_CONNECTED * MAX_INTF * MAX_ENDPOINT_PER_INTERFACE)
+#endif
+/*
+* Maximum number of transfer descriptors that can be allocated
+*/
+#define MAX_TD                      (MAX_ENDPOINT*2)
+
+/*
+* usb_thread stack size
+*/
+#define USB_THREAD_STACK            (256*4 + 2*256*4)
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/USBHost/USBHostTypes.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,262 @@
+/* mbed USBHost Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * 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.
+ */
+
+#ifndef USB_INC_H
+#define USB_INC_H
+
+#include "mbed.h"
+#include "mbed_toolchain.h"
+
+enum USB_TYPE {
+    USB_TYPE_OK = 0,
+
+    // completion code
+    USB_TYPE_CRC_ERROR = 1,
+    USB_TYPE_BIT_STUFFING_ERROR = 2,
+    USB_TYPE_DATA_TOGGLE_MISMATCH_ERROR = 3,
+    USB_TYPE_STALL_ERROR = 4,
+    USB_TYPE_DEVICE_NOT_RESPONDING_ERROR = 5,
+    USB_TYPE_PID_CHECK_FAILURE_ERROR = 6,
+    USB_TYPE_UNEXPECTED_PID_ERROR = 7,
+    USB_TYPE_DATA_OVERRUN_ERROR = 8,
+    USB_TYPE_DATA_UNDERRUN_ERROR = 9,
+    USB_TYPE_RESERVED = 9,
+    USB_TYPE_RESERVED_ = 10,
+    USB_TYPE_BUFFER_OVERRUN_ERROR = 12,
+    USB_TYPE_BUFFER_UNDERRUN_ERROR = 13,
+
+    // general usb state
+    USB_TYPE_DISCONNECTED = 14,
+    USB_TYPE_FREE = 15,
+    USB_TYPE_IDLE = 16,
+    USB_TYPE_PROCESSING = 17,
+
+    USB_TYPE_ERROR = 18,
+};
+
+
+enum ENDPOINT_DIRECTION {
+    OUT = 1,
+    IN
+};
+
+enum ENDPOINT_TYPE {
+    CONTROL_ENDPOINT = 0,
+    ISOCHRONOUS_ENDPOINT,
+    BULK_ENDPOINT,
+    INTERRUPT_ENDPOINT
+};
+
+#define AUDIO_CLASS     0x01
+#define CDC_CLASS       0x02
+#define HID_CLASS       0x03
+#define MSD_CLASS       0x08
+#define HUB_CLASS       0x09
+#define SERIAL_CLASS    0x0A
+
+#if !defined(USBHOST_OTHER)
+// ------------------ HcControl Register ---------------------
+#define  OR_CONTROL_PLE                 0x00000004
+#define  OR_CONTROL_CLE                 0x00000010
+#define  OR_CONTROL_BLE                 0x00000020
+#define  OR_CONTROL_HCFS                0x000000C0
+#define  OR_CONTROL_HC_RSET             0x00000000
+#define  OR_CONTROL_HC_RES              0x00000040
+#define  OR_CONTROL_HC_OPER             0x00000080
+#define  OR_CONTROL_HC_SUSP             0x000000C0
+// ----------------- HcCommandStatus Register -----------------
+#define  OR_CMD_STATUS_HCR              0x00000001
+#define  OR_CMD_STATUS_CLF              0x00000002
+#define  OR_CMD_STATUS_BLF              0x00000004
+// --------------- HcInterruptStatus Register -----------------
+#define  OR_INTR_STATUS_WDH             0x00000002
+#define  OR_INTR_STATUS_RHSC            0x00000040
+#define  OR_INTR_STATUS_UE              0x00000010
+// --------------- HcInterruptEnable Register -----------------
+#define  OR_INTR_ENABLE_WDH             0x00000002
+#define  OR_INTR_ENABLE_RHSC            0x00000040
+#define  OR_INTR_ENABLE_MIE             0x80000000
+// ---------------- HcRhDescriptorA Register ------------------
+#define  OR_RH_STATUS_LPSC              0x00010000
+#define  OR_RH_STATUS_DRWE              0x00008000
+// -------------- HcRhPortStatus[1:NDP] Register --------------
+#define  OR_RH_PORT_CCS                 0x00000001
+#define  OR_RH_PORT_PRS                 0x00000010
+#define  OR_RH_PORT_CSC                 0x00010000
+#define  OR_RH_PORT_PRSC                0x00100000
+#define  OR_RH_PORT_LSDA                0x00000200
+#define  OR_RH_PORT_PESC                0x00020000
+#define  OR_RH_PORT_OCIC                0x00080000
+
+#define  FI                     0x2EDF           // 12000 bits per frame (-1)
+#define  DEFAULT_FMINTERVAL     ((((6 * (FI - 210)) / 7) << 16) | FI)
+
+#define  ED_SKIP            (uint32_t) (0x00001000)        // Skip this ep in queue
+
+#define  TD_ROUNDING        (uint32_t) (0x00040000)        // Buffer Rounding
+#define  TD_SETUP           (uint32_t)(0)                  // Direction of Setup Packet
+#define  TD_IN              (uint32_t)(0x00100000)         // Direction In
+#define  TD_OUT             (uint32_t)(0x00080000)         // Direction Out
+#define  TD_DELAY_INT(x)    (uint32_t)((x) << 21)          // Delay Interrupt
+#define  TD_TOGGLE_0        (uint32_t)(0x02000000)         // Toggle 0
+#define  TD_TOGGLE_1        (uint32_t)(0x03000000)         // Toggle 1
+#define  TD_CC              (uint32_t)(0xF0000000)         // Completion Code
+
+#else
+
+#define TD_TIMEOUT_CTRL  100
+#define TD_TIMEOUT  2000
+#define  TD_SETUP           (uint32_t)(0)                  // Direction of Setup Packet
+#define  TD_IN              (uint32_t)(0x00100000)         // Direction In
+#define  TD_OUT             (uint32_t)(0x00080000)         // Direction Out
+
+#endif
+#define  DEVICE_DESCRIPTOR                     (1)
+#define  CONFIGURATION_DESCRIPTOR              (2)
+#define  INTERFACE_DESCRIPTOR                  (4)
+#define  ENDPOINT_DESCRIPTOR                   (5)
+#define  HID_DESCRIPTOR                        (33)
+
+//  ----------- Control RequestType Fields  -----------
+#define  USB_DEVICE_TO_HOST         0x80
+#define  USB_HOST_TO_DEVICE         0x00
+#define  USB_REQUEST_TYPE_CLASS     0x20
+#define  USB_REQUEST_TYPE_STANDARD  0x00
+#define  USB_RECIPIENT_DEVICE       0x00
+#define  USB_RECIPIENT_INTERFACE    0x01
+#define  USB_RECIPIENT_ENDPOINT     0x02
+
+// -------------- USB Standard Requests  --------------
+#define  SET_ADDRESS                0x05
+#define  GET_DESCRIPTOR             0x06
+#define  SET_CONFIGURATION          0x09
+#define  SET_INTERFACE              0x0b
+#define  CLEAR_FEATURE              0x01
+
+// -------------- USB Descriptor Length  --------------
+#define DEVICE_DESCRIPTOR_LENGTH            0x12
+#define CONFIGURATION_DESCRIPTOR_LENGTH     0x09
+
+// ------------ HostController Transfer Descriptor ------------
+#if defined(USBHOST_OTHER)
+
+typedef struct hcTd {
+	__IO  uint32_t state;
+	__IO  uint8_t *  currBufPtr;    // Physical address of current buffer pointer
+	__IO  hcTd *     nextTD;         // Physical pointer to next Transfer Descriptor
+	__IO  uint32_t   size;        // size of buffer
+	void * ep;                      // ep address where a td is linked in
+	__IO  uint32_t retry;
+	__IO  uint32_t setup;
+} PACKED HCTD;
+// ----------- HostController EndPoint Descriptor -------------
+typedef struct hcEd {
+  uint8_t ch_num;
+  void *hhcd;
+} PACKED HCED;
+// ----------- Host Controller Communication Area ------------
+#define HCCA   void
+
+
+#else 
+// -------------OHCI register --------------------------------
+// ------------ HostController Transfer Descriptor ------------
+typedef struct hcTd {
+    __IO  uint32_t   control;        // Transfer descriptor control
+    __IO  uint8_t *  currBufPtr;    // Physical address of current buffer pointer
+    __IO  hcTd *     nextTD;         // Physical pointer to next Transfer Descriptor
+    __IO  uint8_t *  bufEnd;        // Physical address of end of buffer
+    void * ep;                      // ep address where a td is linked in
+    uint32_t dummy[3];              // padding
+} PACKED HCTD;
+// ----------- HostController EndPoint Descriptor -------------
+typedef struct hcEd {
+    __IO  uint32_t  control;        // Endpoint descriptor control
+    __IO  HCTD *  tailTD;           // Physical address of tail in Transfer descriptor list
+    __IO  HCTD *  headTD;           // Physcial address of head in Transfer descriptor list
+    __IO  hcEd *  nextED;         // Physical address of next Endpoint descriptor
+} PACKED HCED;
+// ----------- Host Controller Communication Area ------------
+typedef struct hcca {
+    __IO  uint32_t  IntTable[32];   // Interrupt Table
+    __IO  uint32_t  FrameNumber;    // Frame Number
+    __IO  uint32_t  DoneHead;       // Done Head
+    volatile  uint8_t   Reserved[116];  // Reserved for future use
+    volatile  uint8_t   Unknown[4];     // Unused
+} PACKED HCCA;
+#endif
+
+typedef struct {
+    uint8_t bLength;
+    uint8_t bDescriptorType;
+    uint16_t bcdUSB;
+    uint8_t bDeviceClass;
+    uint8_t bDeviceSubClass;
+    uint8_t bDeviceProtocol;
+    uint8_t bMaxPacketSize;
+    uint16_t idVendor;
+    uint16_t idProduct;
+    uint16_t bcdDevice;
+    uint8_t iManufacturer;
+    uint8_t iProduct;
+    uint8_t iSerialNumber;
+    uint8_t bNumConfigurations;
+} PACKED DeviceDescriptor;
+
+typedef struct {
+    uint8_t bLength;
+    uint8_t bDescriptorType;
+    uint16_t wTotalLength;
+    uint8_t bNumInterfaces;
+    uint8_t bConfigurationValue;
+    uint8_t iConfiguration;
+    uint8_t bmAttributes;
+    uint8_t bMaxPower;
+} PACKED ConfigurationDescriptor;
+
+typedef struct {
+    uint8_t bLength;
+    uint8_t bDescriptorType;
+    uint8_t bInterfaceNumber;
+    uint8_t bAlternateSetting;
+    uint8_t bNumEndpoints;
+    uint8_t bInterfaceClass;
+    uint8_t bInterfaceSubClass;
+    uint8_t bInterfaceProtocol;
+    uint8_t iInterface;
+} InterfaceDescriptor;
+
+typedef struct {
+    uint8_t bLength;
+    uint8_t bDescriptorType;
+    uint8_t bEndpointAddress;
+    uint8_t bmAttributes;
+    uint16_t wMaxPacketSize;
+    uint8_t bInterval;
+} EndpointDescriptor;
+
+typedef struct {
+    uint8_t bDescLength;
+    uint8_t bDescriptorType;
+    uint8_t bNbrPorts;
+    uint16_t wHubCharacteristics;
+    uint8_t bPwrOn2PwrGood;
+    uint8_t bHubContrCurrent;
+    uint8_t DeviceRemovable;
+    uint8_t PortPweCtrlMak;
+} HubDescriptor;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/USBHost/dbg.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,66 @@
+/* mbed USBHost Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * 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.
+ */
+
+#ifndef USB_DEBUG_H
+#define USB_DEBUG_H
+
+//Debug is disabled by default
+#define DEBUG 3 /*INFO,ERR,WARN*/
+#define DEBUG_TRANSFER 0
+#define DEBUG_EP_STATE 0
+#define DEBUG_EVENT 0
+
+#if (DEBUG > 3)
+#define USB_DBG(x, ...) std::printf("[USB_DBG: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__);
+#else
+#define USB_DBG(x, ...)
+#endif
+
+#if (DEBUG > 2)
+#define USB_INFO(x, ...) std::printf("[USB_INFO: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__);
+#else
+#define USB_INFO(x, ...)
+#endif
+
+#if (DEBUG > 1)
+#define USB_WARN(x, ...) std::printf("[USB_WARNING: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__);
+#else
+#define USB_WARN(x, ...)
+#endif
+
+#if (DEBUG > 0)
+#define USB_ERR(x, ...) std::printf("[USB_ERR: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__);
+#else
+#define USB_ERR(x, ...)
+#endif
+
+#if (DEBUG_TRANSFER)
+#define USB_DBG_TRANSFER(x, ...) std::printf("[USB_TRANSFER: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__);
+#else
+#define USB_DBG_TRANSFER(x, ...)
+#endif
+
+#if (DEBUG_EVENT)
+#define USB_DBG_EVENT(x, ...) std::printf("[USB_EVENT: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__);
+#else
+#define USB_DBG_EVENT(x, ...)
+#endif
+
+
+#endif
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/USBHost3GModule/IUSBHostSerial.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,95 @@
+/* IUSBHostSerial.h */
+/* Copyright (c) 2010-2012 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 IUSBHOSTSERIAL_H_
+#define IUSBHOSTSERIAL_H_
+
+/**
+ * Generic interface to abstract 3G dongles' impl
+ */
+
+#include "USBHostConf.h"
+
+#ifdef USBHOST_3GMODULE
+
+#include "IUSBHostSerialListener.h"
+
+// This is needed by some versions of GCC
+#undef putc
+#undef getc
+
+class IUSBHostSerial {
+public:
+
+    enum IrqType {
+        RxIrq,
+        TxIrq
+    };
+
+    /*
+    * Get a char from the dongle's serial interface
+    */
+    virtual int getc() = 0;
+
+    /*
+    * Put a char to the dongle's serial interface
+    */
+    virtual int putc(int c) = 0;
+
+    /*
+     *  Read a packet from the dongle's serial interface, to be called after multiple getc() calls
+     */
+    virtual int readPacket() = 0;
+
+    /*
+     *  Write a packet to the dongle's serial interface, to be called after multiple putc() calls
+     */
+    virtual int writePacket() = 0;
+
+    /**
+    * Check the number of bytes available.
+    *
+    * @returns the number of bytes available
+    */
+    virtual int readable() = 0;
+
+    /**
+    * Check the free space in output.
+    *
+    * @returns the number of bytes available
+    */
+    virtual int writeable() = 0;
+
+    /**
+     *  Attach a handler to call when a packet is received / when a packet has been transmitted.
+     *
+     *  @param pListener instance of the listener deriving from the IUSBHostSerialListener
+     */
+    virtual void attach(IUSBHostSerialListener* pListener) = 0;
+
+    /**
+     * Enable or disable readable/writeable callbacks
+     */
+    virtual void setupIrq(bool en, IrqType irq = RxIrq) = 0;
+
+};
+
+#endif /* USBHOST_3GMODULE */
+
+#endif /* IUSBHOSTSERIAL_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/USBHost3GModule/IUSBHostSerialListener.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,37 @@
+/* IUSBHostSerialListener.h */
+/* Copyright (c) 2010-2012 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 IUSBHOSTSERIALLISTENER_H_
+#define IUSBHOSTSERIALLISTENER_H_
+
+#include "USBHostConf.h"
+
+#ifdef USBHOST_3GMODULE
+
+class IUSBHostSerialListener
+{
+public:
+  virtual void readable() = 0; //Called when new data is available
+  virtual void writeable() = 0; //Called when new space is available
+};
+
+#endif /* USBHOST_3GMODULE */
+
+#endif /* IUSBHOSTSERIALLISTENER_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/USBHost3GModule/WANDongle.cpp	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,235 @@
+/* Copyright (c) 2010-2012 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 "USBHostConf.h"
+
+#ifdef USBHOST_3GMODULE
+
+#include "dbg.h"
+#include <stdint.h>
+#include "rtos.h"
+
+#include "WANDongle.h"
+#include "WANDongleInitializer.h"
+
+WANDongle::WANDongle() : m_pInitializer(NULL), m_serialCount(0), m_totalInitializers(0)
+{
+    host = USBHost::getHostInst();
+    init();
+}
+
+
+bool WANDongle::connected() {
+  return dev_connected;
+}
+
+bool WANDongle::tryConnect()
+{
+  //FIXME should run on USB thread
+
+  USB_DBG("Trying to connect device");
+
+  if (dev_connected) {
+      USB_DBG("Device is already connected!");
+      return true;
+  }
+
+  m_pInitializer = NULL;
+
+  //Protect from concurrent access from USB thread
+  USBHost::Lock lock(host);
+
+  for (int i = 0; i < MAX_DEVICE_CONNECTED; i++)
+  {
+      if ((dev = host->getDevice(i)) != NULL)
+      {
+          m_pInitializer = NULL; //Will be set in setVidPid callback
+
+          USB_DBG("Enumerate");
+          int ret = host->enumerate(dev, this);
+          if(ret)
+          {
+            return false;
+          }
+
+          USB_DBG("Device has VID:%04x PID:%04x", dev->getVid(), dev->getPid());
+
+          if(m_pInitializer) //If an initializer has been found
+          {
+            USB_DBG("m_pInitializer=%p", m_pInitializer);
+            USB_DBG("m_pInitializer->getSerialVid()=%04x", m_pInitializer->getSerialVid());
+            USB_DBG("m_pInitializer->getSerialPid()=%04x", m_pInitializer->getSerialPid());
+            if ((dev->getVid() == m_pInitializer->getSerialVid()) && (dev->getPid() == m_pInitializer->getSerialPid()))
+            {
+              USB_DBG("The dongle is in virtual serial mode");
+              host->registerDriver(dev, 0, this, &WANDongle::init);
+              m_serialCount = m_pInitializer->getSerialPortCount();
+              if( m_serialCount > WANDONGLE_MAX_SERIAL_PORTS )
+              {
+                m_serialCount = WANDONGLE_MAX_SERIAL_PORTS;
+              }
+              for(int j = 0; j < m_serialCount; j++)
+              {
+                USB_DBG("Connecting serial port #%d", j+1);
+                USB_DBG("Ep %p", m_pInitializer->getEp(dev, j, false));
+                USB_DBG("Ep %p", m_pInitializer->getEp(dev, j, true));
+                m_serial[j].connect( dev, m_pInitializer->getEp(dev, j, false), m_pInitializer->getEp(dev, j, true) );
+              }
+
+              USB_DBG("Device connected");
+
+              dev_connected = true;
+
+
+              return true;
+            }
+            else if ((dev->getVid() == m_pInitializer->getMSDVid()) && (dev->getPid() == m_pInitializer->getMSDPid()))
+            {
+              USB_DBG("Vodafone K3370 dongle detected in MSD mode");
+              //Try to switch
+              if( m_pInitializer->switchMode(dev) )
+              {
+                USB_DBG("Switched OK");
+                return false; //Will be connected on a next iteration
+              }
+              else
+              {
+                USB_ERR("Could not switch mode");
+                return false;
+              }
+            }
+          } //if()
+      } //if()
+  } //for()
+  return false;
+}
+
+bool WANDongle::disconnect()
+{
+  dev_connected = false;
+  for(int i = 0; i < WANDONGLE_MAX_SERIAL_PORTS; i++)
+  {
+    m_serial[i].disconnect();
+  }
+  return true;
+}
+
+int WANDongle::getDongleType()
+{
+  if( m_pInitializer != NULL )
+  {
+    return m_pInitializer->getType();
+  }
+  else
+  {
+    return WAN_DONGLE_TYPE_UNKNOWN;
+  }
+}
+
+IUSBHostSerial& WANDongle::getSerial(int index)
+{
+  return m_serial[index];
+}
+
+int WANDongle::getSerialCount()
+{
+  return m_serialCount;
+}
+
+//Private methods
+void WANDongle::init()
+{
+  m_pInitializer = NULL;
+  dev_connected = false;
+  for(int i = 0; i < WANDONGLE_MAX_SERIAL_PORTS; i++)
+  {
+    m_serial[i].init(host);
+  }
+}
+
+
+/*virtual*/ void WANDongle::setVidPid(uint16_t vid, uint16_t pid)
+{
+  WANDongleInitializer* initializer;
+
+  for(int i = 0; i < m_totalInitializers; i++)
+  {
+    initializer = m_Initializers[i];
+    USB_DBG("initializer=%p", initializer);
+    USB_DBG("initializer->getSerialVid()=%04x", initializer->getSerialVid());
+    USB_DBG("initializer->getSerialPid()=%04x", initializer->getSerialPid());
+    if ((dev->getVid() == initializer->getSerialVid()) && (dev->getPid() == initializer->getSerialPid()))
+    {
+      USB_DBG("The dongle is in virtual serial mode");
+      m_pInitializer = initializer;
+      break;
+    }
+    else if ((dev->getVid() == initializer->getMSDVid()) && (dev->getPid() == initializer->getMSDPid()))
+    {
+      USB_DBG("Dongle detected in MSD mode");
+      m_pInitializer = initializer;
+      break;
+    }
+    initializer++;
+  } //for
+  if(m_pInitializer)
+  {
+    m_pInitializer->setVidPid(vid, pid);
+  }
+}
+
+/*virtual*/ bool WANDongle::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed
+{
+  if(m_pInitializer)
+  {
+    return m_pInitializer->parseInterface(intf_nb, intf_class, intf_subclass, intf_protocol);
+  }
+  else
+  {
+    return false;
+  }
+}
+
+/*virtual*/ bool WANDongle::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
+{
+  if(m_pInitializer)
+  {
+    return m_pInitializer->useEndpoint(intf_nb, type, dir);
+  }
+  else
+  {
+    return false;
+  }
+}
+
+
+bool WANDongle::addInitializer(WANDongleInitializer* pInitializer)
+{
+  if (m_totalInitializers >= WANDONGLE_MAX_INITIALIZERS)
+    return false;
+  m_Initializers[m_totalInitializers++] = pInitializer;
+  return true;
+}
+
+WANDongle::~WANDongle()
+{
+  for(int i = 0; i < m_totalInitializers; i++)
+    delete m_Initializers[i];
+}
+
+#endif /* USBHOST_3GMODULE */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/USBHost3GModule/WANDongle.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,108 @@
+/* Copyright (c) 2010-2012 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 WANDONGLE_H
+#define WANDONGLE_H
+
+#include "USBHostConf.h"
+
+#ifdef USBHOST_3GMODULE
+
+#include "USBHost.h"
+#include "IUSBHostSerial.h"
+
+#include "rtos.h"
+
+#include "WANDongleSerialPort.h"
+#include "WANDongleInitializer.h"
+#include "IUSBEnumerator.h"
+
+#define WANDONGLE_MAX_OUTEP_SIZE 64
+#define WANDONGLE_MAX_INEP_SIZE 64
+
+/** A class to use a WAN (3G/LTE) access dongle
+ *
+ */
+class WANDongle : public IUSBEnumerator {
+public:
+    /*
+    * Constructor
+    *
+    * @param rootdir mount name
+    */
+    WANDongle();
+
+    /*
+    * Destructor
+    */
+    virtual ~WANDongle();
+
+    /*
+    * Check if a serial port device is connected
+    *
+    * @return true if a serial device is connected
+    */
+    bool connected();
+
+    /*
+     * Try to connect device
+     *
+     * * @return true if connection was successful
+     */
+    bool tryConnect();
+
+    /*
+     * Disconnect device
+     *
+     * * @return true if disconnection was successful
+     */
+    bool disconnect();
+
+    int getDongleType();
+
+    IUSBHostSerial& getSerial(int index);
+    int getSerialCount();
+    bool addInitializer(WANDongleInitializer* pInitializer);
+
+    //From IUSBEnumerator
+
+    virtual void setVidPid(uint16_t vid, uint16_t pid);
+
+    virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol); //Must return true if the interface should be parsed
+
+    virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir); //Must return true if the endpoint will be used
+
+protected:
+    USBHost * host;
+    USBDeviceConnected * dev;
+    bool dev_connected;
+
+    WANDongleInitializer* m_pInitializer;
+
+    void init();
+
+    WANDongleSerialPort m_serial[WANDONGLE_MAX_SERIAL_PORTS];
+    int m_serialCount;
+
+    int m_totalInitializers;
+    WANDongleInitializer* m_Initializers[WANDONGLE_MAX_INITIALIZERS];
+};
+
+#endif /* USBHOST_3GMODULE */
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/USBHost3GModule/WANDongleInitializer.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,73 @@
+/* Copyright (c) 2010-2012 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 WANDONGLEINITIALIZER_H
+#define WANDONGLEINITIALIZER_H
+
+#include "USBHostConf.h"
+
+#ifdef USBHOST_3GMODULE
+
+#include <stdint.h>
+
+#include "USBHost.h"
+#include "IUSBEnumerator.h"
+
+// [TODO] move these declarations to a proper place
+#define WANDONGLE_MAX_SERIAL_PORTS 2
+#define WANDONGLE_MAX_INITIALIZERS 6
+
+#define WAN_DONGLE_TYPE_UNKNOWN    (-1)
+
+class WANDongleInitializer : public IUSBEnumerator
+{
+protected:
+    WANDongleInitializer(USBHost* pHost) { m_pHost = pHost; }
+    USBHost* m_pHost;
+    uint8_t m_serialIntfMap[WANDONGLE_MAX_SERIAL_PORTS];
+
+public:
+    virtual ~WANDongleInitializer() {}
+    virtual uint16_t getMSDVid() = 0;
+    virtual uint16_t getMSDPid() = 0;
+
+    virtual uint16_t getSerialVid() = 0;
+    virtual uint16_t getSerialPid() = 0;
+
+    virtual bool switchMode(USBDeviceConnected* pDev) = 0;
+
+    virtual USBEndpoint* getEp(USBDeviceConnected* pDev, int serialPortNumber, bool tx) {
+        return pDev->getEndpoint(m_serialIntfMap[serialPortNumber], BULK_ENDPOINT, tx ? OUT : IN, 0);
+    }
+
+    virtual int getSerialPortCount() = 0;
+
+    virtual void setVidPid(uint16_t vid, uint16_t pid) = 0;
+
+    virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) = 0; //Must return true if the interface should be parsed
+
+    virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) = 0; //Must return true if the endpoint will be used
+
+    virtual int getType() = 0;
+
+    virtual uint8_t getSerialIntf(int index) { return m_serialIntfMap[index]; }
+};
+
+#endif /* USBHOST_3GMODULE */
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/USBHost3GModule/WANDongleSerialPort.cpp	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,340 @@
+/* Copyright (c) 2010-2012 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 "USBHostConf.h"
+
+#ifdef USBHOST_3GMODULE
+
+#define __DEBUG__ 0
+#ifndef __MODULE__
+#define __MODULE__ "WANDongleSerialPort.cpp"
+#endif
+
+#include "dbg.h"
+#include <stdint.h>
+#include "rtos.h"
+
+#include "WANDongleSerialPort.h"
+
+WANDongleSerialPort::WANDongleSerialPort() : cb_tx_en(false), cb_rx_en(false), listener(NULL)
+{
+  reset();
+}
+
+void WANDongleSerialPort::init(USBHost* pHost)
+{
+  host = pHost;
+}
+
+void WANDongleSerialPort::reset()
+{
+  tx_mtx.lock();
+  rx_mtx.lock();
+
+  bulk_in = NULL;
+  bulk_out = NULL;
+
+  buf_out_len = 0;
+  max_out_size = 0;
+  lock_tx = false;
+  cb_tx_pending = false;
+
+  buf_in_len = 0;
+  buf_in_read_pos = 0;
+  lock_rx = false;
+  cb_rx_pending = false;
+
+  tx_mtx.unlock();
+  rx_mtx.unlock();
+}
+
+int WANDongleSerialPort::readPacket()
+{
+  USB_DBG("Read packet on %p", this);
+  rx_mtx.lock();
+  if(lock_rx)
+  {
+    USB_ERR("Fail");
+    rx_mtx.unlock();
+    return -1;
+  }
+
+  if( bulk_in == NULL )
+  {
+    USB_WARN("Port is disconnected");
+    rx_mtx.unlock();
+    return -1;
+  }
+
+  lock_rx = true; //Receiving
+  rx_mtx.unlock();
+//  USB_DBG("readPacket");
+  //lock_rx.lock();
+  USB_TYPE res = host->bulkRead(dev, (USBEndpoint *)bulk_in, buf_in, ((USBEndpoint *)bulk_in)->getSize(), false); //Queue transfer
+  if(res != USB_TYPE_PROCESSING)
+  {
+    //lock_rx.unlock();
+    USB_ERR("host->bulkRead() returned %d", res);
+    Thread::wait(100);
+    return -1;
+  }
+  return 0;
+}
+
+int WANDongleSerialPort::writePacket()
+{
+  tx_mtx.lock();
+  if(lock_tx)
+  {
+    USB_ERR("Fail");
+    tx_mtx.unlock();
+    return -1;
+  }
+
+  if( bulk_out == NULL )
+  {
+    USB_WARN("Port is disconnected");
+    tx_mtx.unlock();
+    return -1;
+  }
+
+  lock_tx = true; //Transmitting
+  tx_mtx.unlock();
+//  USB_DBG("writePacket");
+
+  //lock_tx.lock();
+  USB_TYPE res = host->bulkWrite(dev, (USBEndpoint *)bulk_out, buf_out, buf_out_len, false); //Queue transfer
+  if(res != USB_TYPE_PROCESSING)
+  {
+    //lock_tx.unlock();
+    USB_ERR("host->bulkWrite() returned %d", res);
+    Thread::wait(100);
+    return -1;
+  }
+  return 0;
+}
+
+int WANDongleSerialPort::putc(int c)
+{
+  tx_mtx.lock();
+  if(!lock_tx)
+  {
+    if(buf_out_len < max_out_size)
+    {
+      buf_out[buf_out_len] = (uint8_t)c;
+      buf_out_len++;
+    }
+  }
+  else
+  {
+    USB_ERR("CAN'T WRITE!");
+  }
+  tx_mtx.unlock();
+  return c;
+}
+
+int WANDongleSerialPort::getc()
+{
+  rx_mtx.lock();
+  int c = 0;
+  if(!lock_rx)
+  {
+    if(buf_in_read_pos < buf_in_len)
+    {
+      c = (int)buf_in[buf_in_read_pos];
+      buf_in_read_pos++;
+    }
+  }
+  else
+  {
+    USB_ERR("CAN'T READ!");
+  }
+  rx_mtx.unlock();
+  return c;
+}
+
+int WANDongleSerialPort::readable()
+{
+  rx_mtx.lock();
+  if (lock_rx)
+  {
+    rx_mtx.unlock();
+    return 0;
+  }
+
+ /* if( !lock_rx.trylock() )
+  {
+    return 0;
+  }*/
+  int res = buf_in_len - buf_in_read_pos;
+  //lock_rx.unlock();
+  rx_mtx.unlock();
+  return res;
+}
+
+int WANDongleSerialPort::writeable()
+{
+  tx_mtx.lock();
+  if (lock_tx)
+  {
+    tx_mtx.unlock();
+    return 0;
+  }
+
+  /*if( !lock_tx.trylock() )
+  {
+    return 0;
+  }*/
+  int res = max_out_size - buf_out_len;
+  tx_mtx.unlock();
+ //lock_tx.unlock();
+  return res;
+}
+
+void WANDongleSerialPort::attach(IUSBHostSerialListener* pListener)
+{
+  if(pListener == NULL)
+  {
+    setupIrq(false, RxIrq);
+    setupIrq(false, TxIrq);
+  }
+  listener = pListener;
+  if(pListener != NULL)
+  {
+    setupIrq(true, RxIrq);
+    setupIrq(true, TxIrq);
+  }
+}
+
+void WANDongleSerialPort::setupIrq(bool en, IrqType irq /*= RxIrq*/)
+{
+  switch(irq)
+  {
+  case RxIrq:
+    rx_mtx.lock();
+    cb_rx_en = en;
+    if(en && cb_rx_pending)
+    {
+      cb_rx_pending = false;
+      rx_mtx.unlock();
+      listener->readable(); //Process the interrupt that was raised
+    }
+    else
+    {
+      rx_mtx.unlock();
+    }
+    break;
+  case TxIrq:
+    tx_mtx.lock();
+    cb_tx_en = en;
+    if(en && cb_tx_pending)
+    {
+      cb_tx_pending = false;
+      tx_mtx.unlock();
+      listener->writeable(); //Process the interrupt that was raised
+    }
+    else
+    {
+      tx_mtx.unlock();
+    }
+    break;
+  }
+}
+
+
+void WANDongleSerialPort::connect( USBDeviceConnected* pDev, USBEndpoint* pInEp, USBEndpoint* pOutEp )
+{
+  dev = pDev;
+  bulk_in = pInEp;
+  bulk_out = pOutEp;
+  max_out_size = bulk_out->getSize();
+  if( max_out_size > WANDONGLE_MAX_OUTEP_SIZE )
+  {
+    max_out_size = WANDONGLE_MAX_OUTEP_SIZE;
+  }
+  bulk_in->attach(this, &WANDongleSerialPort::rxHandler);
+  bulk_out->attach(this, &WANDongleSerialPort::txHandler);
+  readPacket(); //Start receiving data
+}
+
+void WANDongleSerialPort::disconnect( )
+{
+    reset();
+}
+
+//Private methods
+
+
+void WANDongleSerialPort::rxHandler()
+{
+  if (((USBEndpoint *) bulk_in)->getState() == USB_TYPE_IDLE) //Success
+  {
+    buf_in_read_pos = 0;
+    buf_in_len = ((USBEndpoint *) bulk_in)->getLengthTransferred(); //Update length
+    //lock_rx.unlock();
+    rx_mtx.lock();
+    lock_rx = false; //Transmission complete
+    if(cb_rx_en)
+    {
+      rx_mtx.unlock();
+      listener->readable(); //Call handler from the IRQ context
+      //readPacket() should be called by the handler subsequently once the buffer has been emptied
+    }
+    else
+    {
+      cb_rx_pending = true; //Queue the callback
+      rx_mtx.unlock();
+    }
+
+  }
+  else //Error, try reading again
+  {
+    //lock_rx.unlock();
+    USB_DBG("Trying again");
+    readPacket();
+  }
+}
+
+void WANDongleSerialPort::txHandler()
+{
+  if (((USBEndpoint *) bulk_out)->getState() == USB_TYPE_IDLE) //Success
+  {
+    tx_mtx.lock();
+    buf_out_len = 0; //Reset length
+    lock_tx = false; //Transmission complete
+    //lock_tx.unlock();
+    if(cb_tx_en)
+    {
+      tx_mtx.unlock();
+      listener->writeable(); //Call handler from the IRQ context
+      //writePacket() should be called by the handler subsequently once the buffer has been filled
+    }
+    else
+    {
+      cb_tx_pending = true; //Queue the callback
+      tx_mtx.unlock();
+    }
+  }
+  else //Error, try reading again
+  {
+    //lock_tx.unlock();
+    writePacket();
+  }
+}
+
+#endif /* USBHOST_3GMODULE */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/USBHost3GModule/WANDongleSerialPort.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,133 @@
+/* Copyright (c) 2010-2012 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 WANDONGLESERIALPORT_H
+#define WANDONGLESERIALPORT_H
+
+#include "USBHostConf.h"
+
+#ifdef USBHOST_3GMODULE
+
+#include "USBHost.h"
+#include "IUSBHostSerial.h"
+
+#include "rtos.h"
+
+
+#define WANDONGLE_MAX_OUTEP_SIZE 64
+#define WANDONGLE_MAX_INEP_SIZE 64
+
+/** A class to use a WAN (3G/LTE) access dongle
+ *
+ */
+class WANDongleSerialPort : public IUSBHostSerial {
+public:
+    /*
+    * Constructor
+    *
+    */
+    WANDongleSerialPort();
+
+    void init( USBHost* pHost );
+
+    void connect( USBDeviceConnected* pDev, USBEndpoint* pInEp, USBEndpoint* pOutEp );
+
+    void disconnect( );
+
+    /*
+    * Get a char from the dongle's serial interface
+    */
+    virtual int getc();
+
+    /*
+    * Put a char to the dongle's serial interface
+    */
+    virtual int putc(int c);
+
+    /*
+     *  Read a packet from the dongle's serial interface, to be called after multiple getc() calls
+     */
+    virtual int readPacket();
+
+    /*
+     *  Write a packet to the dongle's serial interface, to be called after multiple putc() calls
+     */
+    virtual int writePacket();
+
+    /**
+    * Check the number of bytes available.
+    *
+    * @returns the number of bytes available
+    */
+    virtual int readable();
+
+    /**
+    * Check the free space in output.
+    *
+    * @returns the number of bytes available
+    */
+    virtual int writeable();
+
+    /**
+     *  Attach a handler to call when a packet is received / when a packet has been transmitted.
+     *
+     *  @param pListener instance of the listener deriving from the IUSBHostSerialListener
+     */
+    virtual void attach(IUSBHostSerialListener* pListener);
+
+    /**
+     * Enable or disable readable/writeable callbacks
+     */
+    virtual void setupIrq(bool en, IrqType irq = RxIrq);
+
+
+protected:
+    USBEndpoint * bulk_in;
+    USBEndpoint * bulk_out;
+    USBHost * host;
+    USBDeviceConnected * dev;
+
+    uint8_t buf_out[WANDONGLE_MAX_OUTEP_SIZE];
+    volatile uint32_t buf_out_len;
+    uint32_t max_out_size;
+    volatile bool lock_tx;
+    volatile bool cb_tx_en;
+    volatile bool cb_tx_pending;
+    Mutex tx_mtx;
+
+    uint8_t buf_in[WANDONGLE_MAX_INEP_SIZE];
+    volatile uint32_t buf_in_len;
+    volatile uint32_t buf_in_read_pos;
+    volatile bool lock_rx;
+    volatile bool cb_rx_en;
+    volatile bool cb_rx_pending;
+    Mutex rx_mtx;
+
+    IUSBHostSerialListener* listener;
+
+    void reset();
+
+    void rxHandler();
+    void txHandler();
+
+};
+
+#endif /* USBHOST_3GMODULE */
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/USBHostHID/USBHostKeyboard.cpp	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,207 @@
+/* mbed USBHost Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * 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.
+ */
+
+#include "USBHostKeyboard.h"
+
+#if USBHOST_KEYBOARD
+
+static uint8_t keymap[4][0x39] = {
+    {
+        0, 0, 0, 0, 'a', 'b' /*0x05*/,
+        'c', 'd', 'e', 'f', 'g' /*0x0a*/,
+        'h', 'i', 'j', 'k', 'l'/*0x0f*/,
+        'm', 'n', 'o', 'p', 'q'/*0x14*/,
+        'r', 's', 't', 'u', 'v'/*0x19*/,
+        'w', 'x', 'y', 'z', '1'/*0x1E*/,
+        '2', '3', '4', '5', '6'/*0x23*/,
+        '7', '8', '9', '0', 0x0A /*enter*/, /*0x28*/
+        0x1B /*escape*/, 0x08 /*backspace*/, 0x09/*tab*/, 0x20/*space*/, '-', /*0x2d*/
+        '=', '[', ']', '\\', '#', /*0x32*/
+        ';', '\'', 0, ',', '.', /*0x37*/
+        '/'
+    },
+
+    /* CTRL MODIFIER */
+    {
+        0, 0, 0, 0, 0, 0 /*0x05*/,
+        0, 0, 0, 0, 0 /*0x0a*/,
+        0, 0, 0, 0, 0/*0x0f*/,
+        0, 0, 0, 0, 0/*0x14*/,
+        0, 0, 0, 0, 0/*0x19*/,
+        0, 0, 0, 0, 0/*0x1E*/,
+        0, 0, 0, 0, 0/*0x23*/,
+        0, 0, 0, 0, 0 /*enter*/, /*0x28*/
+        0, 0, 0, 0, 0, /*0x2d*/
+        0, 0, 0, 0, 0, /*0x32*/
+        0, 0, 0, 0, 0, /*0x37*/
+        0
+    },
+
+    /* SHIFT MODIFIER */
+    {
+        0, 0, 0, 0, 'A', 'B' /*0x05*/,
+        'C', 'D', 'E', 'F', 'G' /*0x0a*/,
+        'H', 'I', 'J', 'K', 'L'/*0x0f*/,
+        'M', 'N', 'O', 'P', 'Q'/*0x14*/,
+        'R', 'S', 'T', 'U', 'V'/*0x19*/,
+        'W', 'X', 'Y', 'Z', '!'/*0x1E*/,
+        '@', '#', '$', '%', '^'/*0x23*/,
+        '&', '*', '(', ')', 0, /*0x28*/
+        0, 0, 0, 0, 0, /*0x2d*/
+        '+', '{', '}', '|', '~', /*0x32*/
+        ':', '"', 0, '<', '>', /*0x37*/
+        '?'
+    },
+
+    /* ALT MODIFIER */
+    {
+        0, 0, 0, 0, 0, 0 /*0x05*/,
+        0, 0, 0, 0, 0 /*0x0a*/,
+        0, 0, 0, 0, 0/*0x0f*/,
+        0, 0, 0, 0, 0/*0x14*/,
+        0, 0, 0, 0, 0/*0x19*/,
+        0, 0, 0, 0, 0/*0x1E*/,
+        0, 0, 0, 0, 0/*0x23*/,
+        0, 0, 0, 0, 0 /*enter*/, /*0x28*/
+        0, 0, 0, 0, 0, /*0x2d*/
+        0, 0, 0, 0, 0, /*0x32*/
+        0, 0, 0, 0, 0, /*0x37*/
+        0
+    }
+
+};
+
+
+USBHostKeyboard::USBHostKeyboard()
+{
+    host = USBHost::getHostInst();
+    init();
+}
+
+
+void USBHostKeyboard::init()
+{
+    dev = NULL;
+    int_in = NULL;
+    report_id = 0;
+    onKey = NULL;
+    onKeyCode = NULL;
+    dev_connected = false;
+    keyboard_intf = -1;
+    keyboard_device_found = false;
+}
+
+bool USBHostKeyboard::connected()
+{
+    return dev_connected;
+}
+
+
+bool USBHostKeyboard::connect()
+{
+
+    if (dev_connected) {
+        return true;
+    }
+
+    for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
+        if ((dev = host->getDevice(i)) != NULL) {
+
+            if (host->enumerate(dev, this)) {
+                break;
+            }
+
+            if (keyboard_device_found) {
+                {
+                    /* As this is done in a specific thread
+                     * this lock is taken to avoid to process the device
+                     * disconnect in usb process during the device registering */
+                    USBHost::Lock  Lock(host);
+
+                    int_in = dev->getEndpoint(keyboard_intf, INTERRUPT_ENDPOINT, IN);
+
+                    if (!int_in) {
+                        break;
+                    }
+
+                    USB_INFO("New Keyboard device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, keyboard_intf);
+                    dev->setName("Keyboard", keyboard_intf);
+                    host->registerDriver(dev, keyboard_intf, this, &USBHostKeyboard::init);
+
+                    int_in->attach(this, &USBHostKeyboard::rxHandler);
+                }
+                host->interruptRead(dev, int_in, report, int_in->getSize(), false);
+
+                dev_connected = true;
+                return true;
+            }
+        }
+    }
+    init();
+    return false;
+}
+
+void USBHostKeyboard::rxHandler()
+{
+    int len = int_in->getLengthTransferred();
+    int index = (len == 9) ? 1 : 0;
+    int len_listen = int_in->getSize();
+    uint8_t key = 0;
+    if (len == 8 || len == 9) {
+        uint8_t modifier = (report[index] == 4) ? 3 : report[index];
+        len_listen = len;
+        key = keymap[modifier][report[index + 2]];
+        if (key && onKey) {
+            (*onKey)(key);
+        }
+        if ((report[index + 2] || modifier) && onKeyCode) {
+            (*onKeyCode)(report[index + 2], modifier);
+        }
+    }
+    if (dev && int_in) {
+        host->interruptRead(dev, int_in, report, len_listen, false);
+    }
+}
+
+/*virtual*/ void USBHostKeyboard::setVidPid(uint16_t vid, uint16_t pid)
+{
+    // we don't check VID/PID for keyboard driver
+}
+
+/*virtual*/ bool USBHostKeyboard::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed
+{
+    if ((keyboard_intf == -1) &&
+            (intf_class == HID_CLASS) &&
+            (intf_subclass == 0x01) &&
+            (intf_protocol == 0x01)) {
+        keyboard_intf = intf_nb;
+        return true;
+    }
+    return false;
+}
+
+/*virtual*/ bool USBHostKeyboard::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
+{
+    if (intf_nb == keyboard_intf) {
+        if (type == INTERRUPT_ENDPOINT && dir == IN) {
+            keyboard_device_found = true;
+            return true;
+        }
+    }
+    return false;
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/USBHostHID/USBHostKeyboard.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,105 @@
+/* mbed USBHost Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * 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.
+ */
+
+#ifndef USBHOSTKEYBOARD_H
+#define USBHOSTKEYBOARD_H
+
+#include "USBHostConf.h"
+
+#if USBHOST_KEYBOARD
+
+#include "USBHost.h"
+
+/**
+ * A class to communicate a USB keyboard
+ */
+class USBHostKeyboard : public IUSBEnumerator
+{
+public:
+
+    /**
+    * Constructor
+    */
+    USBHostKeyboard();
+
+    /**
+     * Try to connect a keyboard device
+     *
+     * @return true if connection was successful
+     */
+    bool connect();
+
+    /**
+    * Check if a keyboard is connected
+    *
+    * @returns true if a keyboard is connected
+    */
+    bool connected();
+
+    /**
+     * Attach a callback called when a keyboard event is received
+     *
+     * @param ptr function pointer
+     */
+    inline void attach(void (*ptr)(uint8_t key))
+    {
+        if (ptr != NULL) {
+            onKey = ptr;
+        }
+    }
+
+    /**
+     * Attach a callback called when a keyboard event is received
+     *
+     * @param ptr function pointer
+     */
+    inline void attach(void (*ptr)(uint8_t keyCode, uint8_t modifier))
+    {
+        if (ptr != NULL) {
+            onKeyCode = ptr;
+        }
+    }
+
+protected:
+    //From IUSBEnumerator
+    virtual void setVidPid(uint16_t vid, uint16_t pid);
+    virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol); //Must return true if the interface should be parsed
+    virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir); //Must return true if the endpoint will be used
+
+private:
+    USBHost * host;
+    USBDeviceConnected * dev;
+    USBEndpoint * int_in;
+    uint8_t report[9];
+    int keyboard_intf;
+    bool keyboard_device_found;
+
+    bool dev_connected;
+
+    void rxHandler();
+
+    void (*onKey)(uint8_t key);
+    void (*onKeyCode)(uint8_t key, uint8_t modifier);
+
+    int report_id;
+
+    void init();
+
+};
+
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/USBHostHID/USBHostMouse.cpp	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,174 @@
+/* mbed USBHost Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * 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.
+ */
+
+#include "USBHostMouse.h"
+
+#if USBHOST_MOUSE
+
+USBHostMouse::USBHostMouse()
+{
+    host = USBHost::getHostInst();
+    init();
+}
+
+void USBHostMouse::init()
+{
+    dev = NULL;
+    int_in = NULL;
+    onUpdate = NULL;
+    onButtonUpdate = NULL;
+    onXUpdate = NULL;
+    onYUpdate = NULL;
+    onZUpdate = NULL;
+    report_id = 0;
+    dev_connected = false;
+    mouse_device_found = false;
+    mouse_intf = -1;
+
+    buttons = 0;
+    x = 0;
+    y = 0;
+    z = 0;
+}
+
+bool USBHostMouse::connected()
+{
+    return dev_connected;
+}
+
+bool USBHostMouse::connect()
+{
+    int len_listen;
+
+    if (dev_connected) {
+        return true;
+    }
+
+    for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
+        if ((dev = host->getDevice(i)) != NULL) {
+
+            if(host->enumerate(dev, this)) {
+                break;
+            }
+            if (mouse_device_found) {
+                {
+                    /* As this is done in a specific thread
+                     * this lock is taken to avoid to process the device
+                     * disconnect in usb process during the device registering */
+                    USBHost::Lock  Lock(host);
+                    int_in = dev->getEndpoint(mouse_intf, INTERRUPT_ENDPOINT, IN);
+                    if (!int_in) {
+                        break;
+                    }
+
+                    USB_INFO("New Mouse device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, mouse_intf);
+                    dev->setName("Mouse", mouse_intf);
+                    host->registerDriver(dev, mouse_intf, this, &USBHostMouse::init);
+
+                    int_in->attach(this, &USBHostMouse::rxHandler);
+                    len_listen = int_in->getSize();
+                    if (len_listen > sizeof(report)) {
+                        len_listen = sizeof(report);
+                    }
+                }
+                int ret=host->interruptRead(dev, int_in, report, len_listen, false);
+                MBED_ASSERT((ret==USB_TYPE_OK) || (ret ==USB_TYPE_PROCESSING) || (ret == USB_TYPE_FREE));
+                if ((ret==USB_TYPE_OK) || (ret ==USB_TYPE_PROCESSING)) {
+                    dev_connected = true;
+                }
+                if (ret == USB_TYPE_FREE) {
+                    dev_connected = false;
+                }
+                return true;
+            }
+        }
+    }
+    init();
+    return false;
+}
+
+void USBHostMouse::rxHandler()
+{
+    int len_listen = int_in->getLengthTransferred();
+    if (len_listen !=0) {
+
+        if (onUpdate) {
+            (*onUpdate)(report[0] & 0x07, report[1], report[2], report[3]);
+        }
+
+        if (onButtonUpdate && (buttons != (report[0] & 0x07))) {
+            (*onButtonUpdate)(report[0] & 0x07);
+        }
+
+        if (onXUpdate && (x != report[1])) {
+            (*onXUpdate)(report[1]);
+        }
+
+        if (onYUpdate && (y != report[2])) {
+            (*onYUpdate)(report[2]);
+        }
+
+        if (onZUpdate && (z != report[3])) {
+            (*onZUpdate)(report[3]);
+        }
+
+        // update mouse state
+        buttons = report[0] & 0x07;
+        x = report[1];
+        y = report[2];
+        z = report[3];
+    }
+    /*  set again the maximum value */
+    len_listen = int_in->getSize();
+
+    if (len_listen > sizeof(report)) {
+        len_listen = sizeof(report);
+    }
+
+    if (dev) {
+        host->interruptRead(dev, int_in, report, len_listen, false);
+    }
+}
+
+/*virtual*/ void USBHostMouse::setVidPid(uint16_t vid, uint16_t pid)
+{
+    // we don't check VID/PID for mouse driver
+}
+
+/*virtual*/ bool USBHostMouse::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed
+{
+    if ((mouse_intf == -1) &&
+            (intf_class == HID_CLASS) &&
+            (intf_subclass == 0x01) &&
+            (intf_protocol == 0x02)) {
+        mouse_intf = intf_nb;
+        return true;
+    }
+    return false;
+}
+
+/*virtual*/ bool USBHostMouse::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
+{
+    if (intf_nb == mouse_intf) {
+        if (type == INTERRUPT_ENDPOINT && dir == IN) {
+            mouse_device_found = true;
+            return true;
+        }
+    }
+    return false;
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/USBHostHID/USBHostMouse.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,144 @@
+/* mbed USBHost Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * 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.
+ */
+
+#ifndef USBHOSTMOUSE_H
+#define USBHOSTMOUSE_H
+
+#include "USBHostConf.h"
+
+#if USBHOST_MOUSE
+
+#include "USBHost.h"
+
+/**
+ * A class to communicate a USB mouse
+ */
+class USBHostMouse : public IUSBEnumerator
+{
+public:
+
+    /**
+    * Constructor
+    */
+    USBHostMouse();
+
+    /**
+     * Try to connect a mouse device
+     *
+     * @return true if connection was successful
+     */
+    bool connect();
+
+    /**
+    * Check if a mouse is connected
+    *
+    * @returns true if a mouse is connected
+    */
+    bool connected();
+
+    /**
+     * Attach a callback called when a mouse event is received
+     *
+     * @param ptr function pointer
+     */
+    inline void attachEvent(void (*ptr)(uint8_t buttons, int8_t x, int8_t y, int8_t z))
+    {
+        if (ptr != NULL) {
+            onUpdate = ptr;
+        }
+    }
+
+    /**
+     * Attach a callback called when the button state changes
+     *
+     * @param ptr function pointer
+     */
+    inline void attachButtonEvent(void (*ptr)(uint8_t buttons))
+    {
+        if (ptr != NULL) {
+            onButtonUpdate = ptr;
+        }
+    }
+
+    /**
+     * Attach a callback called when the X axis value changes
+     *
+     * @param ptr function pointer
+     */
+    inline void attachXEvent(void (*ptr)(int8_t x))
+    {
+        if (ptr != NULL) {
+            onXUpdate = ptr;
+        }
+    }
+
+    /**
+     * Attach a callback called when the Y axis value changes
+     *
+     * @param ptr function pointer
+     */
+    inline void attachYEvent(void (*ptr)(int8_t y))
+    {
+        if (ptr != NULL) {
+            onYUpdate = ptr;
+        }
+    }
+
+    /**
+     * Attach a callback called when the Z axis value changes (scrolling)
+     *
+     * @param ptr function pointer
+     */
+    inline void attachZEvent(void (*ptr)(int8_t z))
+    {
+        if (ptr != NULL) {
+            onZUpdate = ptr;
+        }
+    }
+
+protected:
+    //From IUSBEnumerator
+    virtual void setVidPid(uint16_t vid, uint16_t pid);
+    virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol); //Must return true if the interface should be parsed
+    virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir); //Must return true if the endpoint will be used
+
+private:
+    USBHost * host;
+    USBDeviceConnected * dev;
+    USBEndpoint * int_in;
+    uint8_t report[64];
+    bool dev_connected;
+    bool mouse_device_found;
+    int mouse_intf;
+
+    uint8_t buttons;
+    int8_t x;
+    int8_t y;
+    int8_t z;
+
+    void rxHandler();
+    void (*onUpdate)(uint8_t buttons, int8_t x, int8_t y, int8_t z);
+    void (*onButtonUpdate)(uint8_t buttons);
+    void (*onXUpdate)(int8_t x);
+    void (*onYUpdate)(int8_t y);
+    void (*onZUpdate)(int8_t z);
+    int report_id;
+    void init();
+};
+
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/USBHostHub/USBHostHub.cpp	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,291 @@
+/* mbed USBHost Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * 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.
+ */
+
+#include "USBHostHub.h"
+
+#if MAX_HUB_NB
+
+#include "USBHost.h"
+#include "dbg.h"
+
+#define GET_STATUS 0x00
+#define CLEAR_FEATURE 0x01
+#define GET_STATE 0x02
+#define SET_FEATURE 0x03
+#define GET_DESCRIPTOR 0x06
+
+#define PORT_CONNECTION_FEATURE     (0x00)
+#define PORT_ENABLE_FEATURE         (0x01)
+#define PORT_RESET_FEATURE          (0x04)
+#define PORT_POWER_FEATURE          (0x08)
+
+#define C_PORT_CONNECTION_FEATURE     (16)
+#define C_PORT_ENABLE_FEATURE         (17)
+#define C_PORT_RESET_FEATURE          (20)
+
+#define PORT_CONNECTION   (1 << 0)
+#define PORT_ENABLE       (1 << 1)
+#define PORT_SUSPEND      (1 << 2)
+#define PORT_OVER_CURRENT (1 << 3)
+#define PORT_RESET        (1 << 4)
+#define PORT_POWER        (1 << 8)
+#define PORT_LOW_SPEED    (1 << 9)
+
+#define C_PORT_CONNECTION   (1 << 16)
+#define C_PORT_ENABLE       (1 << 17)
+#define C_PORT_SUSPEND      (1 << 18)
+#define C_PORT_OVER_CURRENT (1 << 19)
+#define C_PORT_RESET        (1 << 20)
+
+USBHostHub::USBHostHub()
+{
+    host = NULL;
+    init();
+}
+
+void USBHostHub::init()
+{
+    dev_connected = false;
+    dev = NULL;
+    int_in = NULL;
+    dev_connected = false;
+    hub_intf = -1;
+    hub_device_found = false;
+    nb_port = 0;
+    hub_characteristics = 0;
+
+    for (int i = 0; i < MAX_HUB_PORT; i++) {
+        device_children[i] = NULL;
+    }
+}
+
+void USBHostHub::setHost(USBHost * host_)
+{
+    host = host_;
+}
+
+bool USBHostHub::connected()
+{
+    return dev_connected;
+}
+
+bool USBHostHub::connect(USBDeviceConnected * dev)
+{
+    if (dev_connected) {
+        return true;
+    }
+
+    if(host->enumerate(dev, this)) {
+        init();
+        return false;
+    }
+
+    if (hub_device_found) {
+        this->dev = dev;
+
+        int_in = dev->getEndpoint(hub_intf, INTERRUPT_ENDPOINT, IN);
+
+        if (!int_in) {
+            init();
+            return false;
+        }
+
+        USB_INFO("New HUB: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, hub_intf);
+        dev->setName("Hub", hub_intf);
+        host->registerDriver(dev, hub_intf, this, &USBHostHub::disconnect);
+
+        int_in->attach(this, &USBHostHub::rxHandler);
+
+        // get HUB descriptor
+        host->controlRead(  dev,
+                            USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS,
+                            GET_DESCRIPTOR,
+                            0x29 << 8, 0, buf, sizeof(HubDescriptor));
+        nb_port = buf[2];
+        hub_characteristics = buf[3];
+
+        USB_DBG("Hub has %d port", nb_port);
+
+        for (uint8_t j = 1; j <= nb_port; j++) {
+            setPortFeature(PORT_POWER_FEATURE, j);
+        }
+        wait_ms(buf[5]*2);
+
+        host->interruptRead(dev, int_in, buf, 1, false);
+        dev_connected = true;
+        return true;
+    }
+
+    return false;
+}
+
+void USBHostHub::disconnect()
+{
+    init();
+}
+
+/*virtual*/ void USBHostHub::setVidPid(uint16_t vid, uint16_t pid)
+{
+    // we don't check VID/PID for MSD driver
+}
+
+/*virtual*/ bool USBHostHub::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed
+{
+    if ((hub_intf == -1) &&
+            (intf_class == HUB_CLASS) &&
+            (intf_subclass == 0) &&
+            (intf_protocol == 0)) {
+        hub_intf = intf_nb;
+        return true;
+    }
+    return false;
+}
+
+/*virtual*/ bool USBHostHub::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
+{
+    if (intf_nb == hub_intf) {
+        if ((type == INTERRUPT_ENDPOINT) && (dir == IN)) {
+            hub_device_found = true;
+            return true;
+        }
+    }
+    return false;
+}
+
+void USBHostHub::deviceConnected(USBDeviceConnected * dev)
+{
+    device_children[dev->getPort() - 1] = dev;
+}
+
+void USBHostHub::deviceDisconnected(USBDeviceConnected * dev)
+{
+    device_children[dev->getPort() - 1] = NULL;
+}
+
+void USBHostHub::hubDisconnected()
+{
+    for (uint8_t i = 0; i < MAX_HUB_PORT; i++) {
+        if (device_children[i] != NULL) {
+            host->freeDevice(device_children[i]);
+        }
+    }
+}
+
+void USBHostHub::rxHandler()
+{
+    uint32_t status;
+    if (int_in) {
+        if ((int_in->getLengthTransferred())&&(int_in->getState() == USB_TYPE_IDLE)) {
+            for (int port = 1; port <= nb_port; port++) {
+                status = getPortStatus(port);
+                USB_DBG("[hub handler hub: %d] status port %d [hub: %p]: 0x%X", dev->getHub(), port, dev, status);
+
+                // if connection status has changed
+                if (status & C_PORT_CONNECTION) {
+                    if (status & PORT_CONNECTION) {
+                        USB_DBG("[hub handler hub: %d - port: %d] new device connected", dev->getHub(), port);
+                        host->deviceConnected(dev->getHub() + 1, port, status & PORT_LOW_SPEED, this);
+                    } else {
+                        USB_DBG("[hub handler hub: %d - port: %d] device disconnected", dev->getHub(), port);
+                        host->deviceDisconnected(dev->getHub() + 1, port, this, 0);
+                    }
+
+                    clearPortFeature(C_PORT_CONNECTION_FEATURE, port);
+                }
+
+                if (status & C_PORT_RESET) {
+                    clearPortFeature(C_PORT_RESET_FEATURE, port);
+                }
+
+                if (status & C_PORT_ENABLE) {
+                    clearPortFeature(C_PORT_ENABLE_FEATURE, port);
+                }
+
+                if ((status & PORT_OVER_CURRENT)) {
+                    USB_ERR("OVER CURRENT DETECTED\r\n");
+                    clearPortFeature(PORT_OVER_CURRENT, port);
+                    host->deviceDisconnected(dev->getHub() + 1, port, this, 0);
+                }
+            }
+        }
+        host->interruptRead(dev, int_in, buf, 1, false);
+    }
+}
+
+void USBHostHub::portReset(uint8_t port)
+{
+    // reset port
+    uint32_t status;
+    USB_DBG("reset port %d on hub: %p [this: %p]", port, dev, this)
+    setPortFeature(PORT_RESET_FEATURE, port);
+#if defined(TARGET_RZ_A1H)
+    Thread::wait(50);   // Reset release waiting for Hi-Speed check.
+#endif
+    while(1) {
+        status = getPortStatus(port);
+        /*  disconnection since reset request */
+        if (!(status & PORT_CONNECTION)) {
+            break;
+        }
+        if (status & (PORT_ENABLE | PORT_RESET)) {
+            break;
+        }
+        if (status & PORT_OVER_CURRENT) {
+            USB_ERR("OVER CURRENT DETECTED\r\n");
+            clearPortFeature(PORT_OVER_CURRENT, port);
+            host->deviceDisconnected(dev->getHub() + 1, port, this, 0);
+            break;
+        }
+        Thread::wait(10);
+    }
+}
+
+void USBHostHub::setPortFeature(uint32_t feature, uint8_t port)
+{
+    host->controlWrite( dev,
+                        USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE | USB_RECIPIENT_ENDPOINT,
+                        SET_FEATURE,
+                        feature,
+                        port,
+                        NULL,
+                        0);
+}
+
+void USBHostHub::clearPortFeature(uint32_t feature, uint8_t port)
+{
+    host->controlWrite( dev,
+                        USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE | USB_RECIPIENT_ENDPOINT,
+                        CLEAR_FEATURE,
+                        feature,
+                        port,
+                        NULL,
+                        0);
+}
+
+uint32_t USBHostHub::getPortStatus(uint8_t port)
+{
+    uint32_t st;
+    host->controlRead(  dev,
+                        USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE | USB_RECIPIENT_ENDPOINT,
+                        GET_STATUS,
+                        0,
+                        port,
+                        (uint8_t *)&st,
+                        4);
+    return st;
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/USBHostHub/USBHostHub.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,126 @@
+/* mbed USBHost Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * 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.
+ */
+
+#ifndef USBHOSTHUB_H
+#define USBHOSTHUB_H
+
+#include "USBHostConf.h"
+
+#if MAX_HUB_NB
+
+#include "USBHostTypes.h"
+#include "IUSBEnumerator.h"
+
+class USBHost;
+class USBDeviceConnected;
+class USBEndpoint;
+
+/**
+ * A class to use a USB Hub
+ */
+class USBHostHub : public IUSBEnumerator
+{
+public:
+    /**
+    * Constructor
+    */
+    USBHostHub();
+
+    /**
+    * Check if a USB Hub is connected
+    *
+    * @return true if a serial device is connected
+    */
+    bool connected();
+
+    /**
+     * Try to connect device
+     *
+     * @param dev device to connect
+     * @return true if connection was successful
+     */
+    bool connect(USBDeviceConnected * dev);
+
+    /**
+    * Automatically called by USBHost when a device
+    * has been enumerated by usb_thread
+    *
+    * @param dev device connected
+    */
+    void deviceConnected(USBDeviceConnected * dev);
+
+    /**
+    * Automatically called by USBHost when a device
+    * has been disconnected from this hub
+    *
+    * @param dev device disconnected
+    */
+    void deviceDisconnected(USBDeviceConnected * dev);
+
+    /**
+    * Rest a specific port
+    *
+    * @param port port number
+    */
+    void portReset(uint8_t port);
+
+    /*
+    * Called by USBHost to set the instance of USBHost
+    *
+    * @param host host instance
+    */
+    void setHost(USBHost * host);
+
+    /**
+    * Called by USBhost when a hub has been disconnected
+    */
+    void hubDisconnected();
+
+protected:
+    //From IUSBEnumerator
+    virtual void setVidPid(uint16_t vid, uint16_t pid);
+    virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol); //Must return true if the interface should be parsed
+    virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir); //Must return true if the endpoint will be used
+
+private:
+    USBHost * host;
+    USBDeviceConnected * dev;
+    bool dev_connected;
+    USBEndpoint * int_in;
+    uint8_t nb_port;
+    uint8_t hub_characteristics;
+
+    void rxHandler();
+
+    uint8_t buf[sizeof(HubDescriptor)];
+
+    int hub_intf;
+    bool hub_device_found;
+
+    void setPortFeature(uint32_t feature, uint8_t port);
+    void clearPortFeature(uint32_t feature, uint8_t port);
+    uint32_t getPortStatus(uint8_t port);
+
+    USBDeviceConnected * device_children[MAX_HUB_PORT];
+
+    void init();
+    void disconnect();
+
+};
+
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/USBHostMIDI/USBHostMIDI.cpp	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,362 @@
+/* Copyright (c) 2014 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 "USBHostMIDI.h"
+
+#if USBHOST_MIDI
+
+#include "dbg.h"
+
+#define SET_LINE_CODING 0x20
+
+USBHostMIDI::USBHostMIDI() {
+    host = USBHost::getHostInst();
+    size_bulk_in = 0;
+    size_bulk_out = 0;
+    init();
+}
+
+void USBHostMIDI::init() {
+    dev = NULL;
+    bulk_in = NULL;
+    bulk_out = NULL;
+    dev_connected = false;
+    midi_intf = -1;
+    midi_device_found = false;
+    sysExBufferPos = 0;
+}
+
+bool USBHostMIDI::connected() {
+    return dev_connected;
+}
+
+bool USBHostMIDI::connect() {
+    if (dev_connected) {
+        return true;
+    }
+
+    for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
+        if ((dev = host->getDevice(i)) != NULL) {
+            
+            USB_DBG("Trying to connect MIDI device\r\n");
+
+            if (host->enumerate(dev, this)) {
+                break;
+            }
+            
+            if (midi_device_found) {
+                bulk_in = dev->getEndpoint(midi_intf, BULK_ENDPOINT, IN);
+                bulk_out = dev->getEndpoint(midi_intf, BULK_ENDPOINT, OUT);
+                
+                if (!bulk_in || !bulk_out) {
+                    break;
+                }
+                
+                USB_INFO("New MIDI device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, midi_intf);
+                dev->setName("MIDI", midi_intf);
+                host->registerDriver(dev, midi_intf, this, &USBHostMIDI::init);
+                
+                size_bulk_in = bulk_in->getSize();
+                size_bulk_out = bulk_out->getSize();
+                
+                bulk_in->attach(this, &USBHostMIDI::rxHandler);
+                
+                host->bulkRead(dev, bulk_in, buf, size_bulk_in, false);
+                dev_connected = true;
+                return true;
+            }
+        }
+    }
+
+    init();
+    return false;
+}
+
+void USBHostMIDI::rxHandler() {
+    uint8_t *midi;
+    if (bulk_in) {
+        int length = bulk_in->getLengthTransferred();
+        if (bulk_in->getState() == USB_TYPE_IDLE || bulk_in->getState() == USB_TYPE_FREE) {
+            // MIDI event handling
+            for (int i = 0; i < length; i += 4) {
+                if (i + 4 > length) {
+                    // length shortage, ignored.
+                    break;
+                }
+
+                // read each four bytes
+                midi = &buf[i];
+                // process MIDI message
+                // switch by code index number
+                switch (midi[0] & 0xf) {
+                    case 0: // miscellaneous function codes
+                        miscellaneousFunctionCode(midi[1], midi[2], midi[3]);
+                        break;
+                    case 1: // cable events
+                        cableEvent(midi[1], midi[2], midi[3]);
+                        break;
+                    case 2: // two bytes system common messages 
+                        systemCommonTwoBytes(midi[1], midi[2]);
+                        break;
+                    case 3: // three bytes system common messages 
+                        systemCommonThreeBytes(midi[1], midi[2], midi[3]);
+                        break;
+                    case 4: // SysEx starts or continues
+                        sysExBuffer[sysExBufferPos++] = midi[1];
+                        if (sysExBufferPos >= 64) {
+                            systemExclusive(sysExBuffer, sysExBufferPos, true);
+                            sysExBufferPos = 0;
+                        }
+                        sysExBuffer[sysExBufferPos++] = midi[2];
+                        if (sysExBufferPos >= 64) {
+                            systemExclusive(sysExBuffer, sysExBufferPos, true);
+                            sysExBufferPos = 0;
+                        }
+                        sysExBuffer[sysExBufferPos++] = midi[3];
+                        // SysEx continues. don't send
+                        break;
+                    case 5: // SysEx ends with single byte
+                        sysExBuffer[sysExBufferPos++] = midi[1];
+                        systemExclusive(sysExBuffer, sysExBufferPos, false);
+                        sysExBufferPos = 0;
+                        break;
+                    case 6: // SysEx ends with two bytes
+                        sysExBuffer[sysExBufferPos++] = midi[1];
+                        if (sysExBufferPos >= 64) {
+                            systemExclusive(sysExBuffer, sysExBufferPos, true);
+                            sysExBufferPos = 0;
+                        }
+                        sysExBuffer[sysExBufferPos++] = midi[2];
+                        systemExclusive(sysExBuffer, sysExBufferPos, false);
+                        sysExBufferPos = 0;
+                        break;
+                    case 7: // SysEx ends with three bytes
+                        sysExBuffer[sysExBufferPos++] = midi[1];
+                        if (sysExBufferPos >= 64) {
+                            systemExclusive(sysExBuffer, sysExBufferPos, true);
+                            sysExBufferPos = 0;
+                        }
+                        sysExBuffer[sysExBufferPos++] = midi[2];
+                        if (sysExBufferPos >= 64) {
+                            systemExclusive(sysExBuffer, sysExBufferPos, true);
+                            sysExBufferPos = 0;
+                        }
+                        sysExBuffer[sysExBufferPos++] = midi[3];
+                        systemExclusive(sysExBuffer, sysExBufferPos, false);
+                        sysExBufferPos = 0;
+                        break;
+                    case 8:
+                        noteOff(midi[1] & 0xf, midi[2], midi[3]);
+                        break;
+                    case 9:
+                        if (midi[3]) {
+                            noteOn(midi[1] & 0xf, midi[2], midi[3]);
+                        } else {
+                            noteOff(midi[1] & 0xf, midi[2], midi[3]);
+                        }
+                        break;
+                    case 10:
+                        polyKeyPress(midi[1] & 0xf, midi[2], midi[3]);
+                        break;
+                    case 11:
+                        controlChange(midi[1] & 0xf, midi[2], midi[3]);
+                        break;
+                    case 12:
+                        programChange(midi[1] & 0xf, midi[2]);
+                        break;
+                    case 13:
+                        channelPressure(midi[1] & 0xf, midi[2]);
+                        break;
+                    case 14:
+                        pitchBend(midi[1] & 0xf, midi[2] | (midi[3] << 7));
+                        break;
+                    case 15:
+                        singleByte(midi[1]);
+                        break;
+                }
+            }
+            
+            // read another message
+            host->bulkRead(dev, bulk_in, buf, size_bulk_in, false);
+        }
+    }
+}
+
+bool USBHostMIDI::sendMidiBuffer(uint8_t data0, uint8_t data1, uint8_t data2, uint8_t data3) {
+    if (bulk_out) {
+        uint8_t midi[4];
+
+        midi[0] = data0;
+        midi[1] = data1;
+        midi[2] = data2;
+        midi[3] = data3;
+        if (host->bulkWrite(dev, bulk_out, (uint8_t *)midi, 4) == USB_TYPE_OK) {
+            return true;
+        }
+    }
+    return false;
+}
+
+bool USBHostMIDI::sendMiscellaneousFunctionCode(uint8_t data1, uint8_t data2, uint8_t data3) {
+    return sendMidiBuffer(0, data1, data2, data3);
+}
+
+bool USBHostMIDI::sendCableEvent(uint8_t data1, uint8_t data2, uint8_t data3) {
+    return sendMidiBuffer(1, data1, data2, data3);
+}
+
+bool USBHostMIDI::sendSystemCommmonTwoBytes(uint8_t data1, uint8_t data2) {
+    return sendMidiBuffer(2, data1, data2, 0);
+}
+
+bool USBHostMIDI::sendSystemCommmonThreeBytes(uint8_t data1, uint8_t data2, uint8_t data3) {
+    return sendMidiBuffer(3, data1, data2, 0);
+}
+
+bool USBHostMIDI::sendSystemExclusive(uint8_t *buffer, int length) {
+    uint8_t midi[64];
+    int midiLength;
+    int midiPos;
+    if (bulk_out) {
+        for (int i = 0; i < length; i += 48) {
+            if (i + 48 >= length) {
+                // contains last data
+                midiLength = (((length - i) + 2) / 3) * 4;
+                for (int pos = i; pos < length; pos += 3) {
+                    midiPos = (pos + 2) / 3 * 4;
+                    if (pos + 3 >= length) {
+                        // last data
+                        switch (pos % 3) {
+                            case 0:
+                                midi[midiPos    ] = 7;
+                                midi[midiPos + 1] = buffer[pos    ];
+                                midi[midiPos + 2] = buffer[pos + 1];
+                                midi[midiPos + 3] = buffer[pos + 2];
+                                break;
+                            case 1:
+                                midi[midiPos    ] = 5;
+                                midi[midiPos + 1] = buffer[pos    ];
+                                midi[midiPos + 2] = 0;
+                                midi[midiPos + 3] = 0;
+                               break;
+                            case 2:
+                                midi[midiPos    ] = 6;
+                                midi[midiPos + 1] = buffer[pos    ];
+                                midi[midiPos + 2] = buffer[pos + 1];
+                                midi[midiPos + 3] = 0;
+                                break;
+                        }
+                    } else {
+                        // has more data
+                        midi[midiPos    ] = 4;
+                        midi[midiPos + 1] = buffer[pos    ];
+                        midi[midiPos + 2] = buffer[pos + 1];
+                        midi[midiPos + 3] = buffer[pos + 2];
+                    }
+                }
+            } else {
+                // has more data
+                midiLength = 64;
+                for (int pos = i; pos < length; pos += 3) {
+                    midiPos = (pos + 2) / 3 * 4;
+                    midi[midiPos    ] = 4;
+                    midi[midiPos + 1] = buffer[pos    ];
+                    midi[midiPos + 2] = buffer[pos + 1];
+                    midi[midiPos + 3] = buffer[pos + 2];
+                }
+            }
+
+            if (host->bulkWrite(dev, bulk_out, (uint8_t *)midi, midiLength) != USB_TYPE_OK) {
+                return false;
+            }
+        }
+        return true;
+    }
+    return false;
+}
+
+bool USBHostMIDI::sendNoteOff(uint8_t channel, uint8_t note, uint8_t velocity) {
+    return sendMidiBuffer(8, channel & 0xf | 0x80, note & 0x7f, velocity & 0x7f);
+}
+
+bool USBHostMIDI::sendNoteOn(uint8_t channel, uint8_t note, uint8_t velocity) {
+    return sendMidiBuffer(9, channel & 0xf | 0x90, note & 0x7f, velocity & 0x7f);
+}
+
+bool USBHostMIDI::sendPolyKeyPress(uint8_t channel, uint8_t note, uint8_t pressure) {
+    return sendMidiBuffer(10, channel & 0xf | 0xa0, note & 0x7f, pressure & 0x7f);
+}
+
+bool USBHostMIDI::sendControlChange(uint8_t channel, uint8_t key, uint8_t value) {
+    return sendMidiBuffer(11, channel & 0xf | 0xb0, key & 0x7f, value & 0x7f);
+}
+
+bool USBHostMIDI::sendProgramChange(uint8_t channel, uint8_t program) {
+    return sendMidiBuffer(12, channel & 0xf | 0xc0, program & 0x7f, 0);
+}
+
+bool USBHostMIDI::sendChannelPressure(uint8_t channel, uint8_t pressure) {
+    return sendMidiBuffer(13, channel & 0xf | 0xd0, pressure & 0x7f, 0);
+}
+
+bool USBHostMIDI::sendPitchBend(uint8_t channel, uint16_t value) {
+    return sendMidiBuffer(14, channel & 0xf | 0xe0, value & 0x7f, (value >> 7) & 0x7f);
+}
+
+bool USBHostMIDI::sendSingleByte(uint8_t data) {
+    return sendMidiBuffer(15, data, 0, 0);
+}
+
+/*virtual*/ void USBHostMIDI::setVidPid(uint16_t vid, uint16_t pid)
+{
+    // we don't check VID/PID for this driver
+}
+
+/*virtual*/ bool USBHostMIDI::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed
+{
+    // USB MIDI class/subclass
+    if ((midi_intf == -1) &&
+        (intf_class == AUDIO_CLASS) &&
+        (intf_subclass == 0x03)) {
+        midi_intf = intf_nb;
+        return true;
+    }
+    
+    // vendor specific device
+    if ((midi_intf == -1) &&
+        (intf_class == 0xff) &&
+        (intf_subclass == 0x03)) {
+        midi_intf = intf_nb;
+        return true;
+    }
+    
+    return false;
+}
+
+/*virtual*/ bool USBHostMIDI::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
+{
+    if (intf_nb == midi_intf) {
+        if (type == BULK_ENDPOINT) {
+            midi_device_found = true;
+            return true;
+        }
+    }
+    return false;
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/USBHostMIDI/USBHostMIDI.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,353 @@
+/* Copyright (c) 2014 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 USBHOSTMIDI_H
+#define USBHOSTMIDI_H
+
+#include "USBHostConf.h"
+
+#if USBHOST_MIDI
+
+#include "USBHost.h"
+
+/** 
+ * A class to communicate a USB MIDI device
+ */
+class USBHostMIDI : public IUSBEnumerator {
+public:
+    /**
+     * Constructor
+     */
+    USBHostMIDI();
+
+    /**
+     * Check if a USB MIDI device is connected
+     *
+     * @returns true if a midi device is connected
+     */
+    bool connected();
+    
+    /**
+     * Try to connect a midi device
+     *
+     * @return true if connection was successful
+     */
+    bool connect();
+    
+    /**
+     * Attach a callback called when miscellaneous function code is received
+     *
+     * @param ptr function pointer
+     *   prototype: void onMiscellaneousFunctionCode(uint8_t data1, uint8_t data2, uint8_t data3);
+     */
+    inline void attachMiscellaneousFunctionCode(void (*fn)(uint8_t, uint8_t, uint8_t)) {
+        miscellaneousFunctionCode = fn;
+    }
+
+    /**
+     * Attach a callback called when cable event is received
+     *
+     * @param ptr function pointer
+     *   prototype: void onCableEvent(uint8_t data1, uint8_t data2, uint8_t data3);
+     */
+    inline void attachCableEvent(void (*fn)(uint8_t, uint8_t, uint8_t)) {
+        cableEvent = fn;
+    }
+
+    /**
+     * Attach a callback called when system exclusive is received
+     *
+     * @param ptr function pointer
+     *   prototype: void onSystemCommonTwoBytes(uint8_t data1, uint8_t data2);
+     */
+    inline void attachSystemCommonTwoBytes(void (*fn)(uint8_t, uint8_t)) {
+        systemCommonTwoBytes = fn;
+    }
+    
+    /**
+     * Attach a callback called when system exclusive is received
+     *
+     * @param ptr function pointer
+     *   prototype: void onSystemCommonThreeBytes(uint8_t data1, uint8_t data2, uint8_t data3);
+     */
+    inline void attachSystemCommonThreeBytes(void (*fn)(uint8_t, uint8_t, uint8_t)) {
+        systemCommonThreeBytes = fn;
+    }
+    
+    /**
+     * Attach a callback called when system exclusive is received
+     *
+     * @param ptr function pointer
+     *   prototype: void onSystemExclusive(uint8_t *data, uint16_t length, bool hasNextData);
+     */
+    inline void attachSystemExclusive(void (*fn)(uint8_t *, uint16_t, bool)) {
+        systemExclusive = fn;
+    }
+
+    /**
+     * Attach a callback called when note on is received
+     *
+     * @param ptr function pointer
+     *   prototype: void onNoteOn(uint8_t channel, uint8_t note, uint8_t velocity);
+     */
+    inline void attachNoteOn(void (*fn)(uint8_t, uint8_t, uint8_t)) {
+        noteOn = fn;
+    }
+
+    /**
+     * Attach a callback called when note off is received
+     *
+     * @param ptr function pointer
+     *   prototype: void onNoteOff(uint8_t channel, uint8_t note, uint8_t velocity);
+     */
+    inline void attachNoteOff(void (*fn)(uint8_t, uint8_t, uint8_t)) {
+        noteOff = fn;
+    }
+
+    /**
+     * Attach a callback called when poly keypress is received
+     *
+     * @param ptr function pointer
+     *   prototype: void onPolyKeyPress(uint8_t channel, uint8_t note, uint8_t pressure);
+     */
+    inline void attachPolyKeyPress(void (*fn)(uint8_t, uint8_t, uint8_t)) {
+        polyKeyPress = fn;
+    }
+
+    /**
+     * Attach a callback called when control change is received
+     *
+     * @param ptr function pointer
+     *   prototype: void onControlChange(uint8_t channel, uint8_t key, uint8_t value);
+     */
+    inline void attachControlChange(void (*fn)(uint8_t, uint8_t, uint8_t)) {
+        controlChange = fn;
+    }
+
+    /**
+     * Attach a callback called when program change is received
+     *
+     * @param ptr function pointer
+     *   prototype: void onProgramChange(uint8_t channel, uint8_t program);
+     */
+    inline void attachProgramChange(void (*fn)(uint8_t, uint8_t)) {
+        programChange = fn;
+    }
+
+    /**
+     * Attach a callback called when channel pressure is received
+     *
+     * @param ptr function pointer
+     *   prototype: void onChannelPressure(uint8_t channel, uint8_t pressure);
+     */
+    inline void attachChannelPressure(void (*fn)(uint8_t, uint8_t)) {
+        channelPressure = fn;
+    }
+
+    /**
+     * Attach a callback called when pitch bend is received
+     *
+     * @param ptr function pointer
+     *   prototype: void onPitchBend(uint8_t channel, uint16_t value);
+     */
+    inline void attachPitchBend(void (*fn)(uint8_t, uint16_t)) {
+        pitchBend = fn;
+    }
+
+    /**
+     * Attach a callback called when single byte is received
+     *
+     * @param ptr function pointer
+     *   prototype: void onSingleByte(uint8_t value);
+     */
+    inline void attachSingleByte(void (*fn)(uint8_t)) {
+        singleByte = fn;
+    }
+
+    /**
+     * Send a cable event with 3 bytes event
+     *
+     * @param data1 0-255
+     * @param data2 0-255
+     * @param data3 0-255
+     * @return true if message sent successfully
+     */
+    bool sendMiscellaneousFunctionCode(uint8_t data1, uint8_t data2, uint8_t data3);
+
+    /**
+     * Send a cable event with 3 bytes event
+     *
+     * @param data1 0-255
+     * @param data2 0-255
+     * @param data3 0-255
+     * @return true if message sent successfully
+     */
+    bool sendCableEvent(uint8_t data1, uint8_t data2, uint8_t data3);
+
+    /**
+     * Send a system common message with 2 bytes event
+     *
+     * @param data1 0-255
+     * @param data2 0-255
+     * @return true if message sent successfully
+     */
+    bool sendSystemCommmonTwoBytes(uint8_t data1, uint8_t data2);
+
+    /**
+     * Send a system common message with 3 bytes event
+     *
+     * @param data1 0-255
+     * @param data2 0-255
+     * @param data3 0-255
+     * @return true if message sent successfully
+     */
+    bool sendSystemCommmonThreeBytes(uint8_t data1, uint8_t data2, uint8_t data3);
+
+    /**
+     * Send a system exclusive event
+     *
+     * @param buffer, starts with 0xF0, and end with 0xf7
+     * @param length
+     * @return true if message sent successfully
+     */
+    bool sendSystemExclusive(uint8_t *buffer, int length);
+
+    /**
+     * Send a note off event
+     *
+     * @param channel 0-15
+     * @param note 0-127
+     * @param velocity 0-127
+     * @return true if message sent successfully
+     */
+    bool sendNoteOff(uint8_t channel, uint8_t note, uint8_t velocity);
+
+    /**
+     * Send a note on event
+     *
+     * @param channel 0-15
+     * @param note 0-127
+     * @param velocity 0-127 (0 means note off)
+     * @return true if message sent successfully
+     */
+    bool sendNoteOn(uint8_t channel, uint8_t note, uint8_t velocity);
+
+    /**
+     * Send a poly keypress event
+     *
+     * @param channel 0-15
+     * @param note 0-127
+     * @param pressure 0-127
+     * @return true if message sent successfully
+     */
+    bool sendPolyKeyPress(uint8_t channel, uint8_t note, uint8_t pressure);
+
+    /**
+     * Send a control change event
+     *
+     * @param channel 0-15
+     * @param key 0-127
+     * @param value 0-127
+     * @return true if message sent successfully
+     */
+    bool sendControlChange(uint8_t channel, uint8_t key, uint8_t value);
+
+    /**
+     * Send a program change event
+     *
+     * @param channel 0-15
+     * @param program 0-127
+     * @return true if message sent successfully
+     */
+    bool sendProgramChange(uint8_t channel, uint8_t program);
+
+    /**
+     * Send a channel pressure event
+     *
+     * @param channel 0-15
+     * @param pressure 0-127
+     * @return true if message sent successfully
+     */
+    bool sendChannelPressure(uint8_t channel, uint8_t pressure);
+
+    /**
+     * Send a control change event
+     *
+     * @param channel 0-15
+     * @param key 0(lower)-8191(center)-16383(higher)
+     * @return true if message sent successfully
+     */
+    bool sendPitchBend(uint8_t channel, uint16_t value);
+
+    /**
+     * Send a single byte event
+     *
+     * @param data 0-255
+     * @return true if message sent successfully
+     */
+    bool sendSingleByte(uint8_t data);
+
+protected:
+    //From IUSBEnumerator
+    virtual void setVidPid(uint16_t vid, uint16_t pid);
+    virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol); //Must return true if the interface should be parsed
+    virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir); //Must return true if the endpoint will be used
+
+private:
+    USBHost * host;
+    USBDeviceConnected * dev;
+    USBEndpoint * bulk_in;
+    USBEndpoint * bulk_out;
+    uint32_t size_bulk_in;
+    uint32_t size_bulk_out;
+
+    bool dev_connected;
+
+    void init();
+
+    uint8_t buf[64];
+
+    void rxHandler();
+
+    uint16_t sysExBufferPos;
+    uint8_t sysExBuffer[64];
+
+    void (*miscellaneousFunctionCode)(uint8_t, uint8_t, uint8_t);
+    void (*cableEvent)(uint8_t, uint8_t, uint8_t);
+    void (*systemCommonTwoBytes)(uint8_t, uint8_t);
+    void (*systemCommonThreeBytes)(uint8_t, uint8_t, uint8_t);
+    void (*systemExclusive)(uint8_t *, uint16_t, bool);
+    void (*noteOff)(uint8_t, uint8_t, uint8_t);
+    void (*noteOn)(uint8_t, uint8_t, uint8_t);
+    void (*polyKeyPress)(uint8_t, uint8_t, uint8_t);
+    void (*controlChange)(uint8_t, uint8_t, uint8_t);
+    void (*programChange)(uint8_t, uint8_t);
+    void (*channelPressure)(uint8_t, uint8_t);
+    void (*pitchBend)(uint8_t, uint16_t);
+    void (*singleByte)(uint8_t);
+
+    bool sendMidiBuffer(uint8_t data0, uint8_t data1, uint8_t data2, uint8_t data3);
+
+    int midi_intf;
+    bool midi_device_found;
+
+};
+
+#endif /* USBHOST_MIDI */
+
+#endif /* USBHOSTMIDI_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/USBHostMSD/USBHostMSD.cpp	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,379 @@
+/* mbed USBHost Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * 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.
+ */
+
+#include "USBHostMSD.h"
+
+#if USBHOST_MSD
+
+#include "dbg.h"
+
+#define CBW_SIGNATURE   0x43425355
+#define CSW_SIGNATURE   0x53425355
+
+#define DEVICE_TO_HOST  0x80
+#define HOST_TO_DEVICE  0x00
+
+#define GET_MAX_LUN             (0xFE)
+#define BO_MASS_STORAGE_RESET   (0xFF)
+
+USBHostMSD::USBHostMSD(const char * rootdir) : FATFileSystem(rootdir)
+{
+    host = USBHost::getHostInst();
+    init();
+}
+
+void USBHostMSD::init() {
+    dev_connected = false;
+    dev = NULL;
+    bulk_in = NULL;
+    bulk_out = NULL;
+    dev_connected = false;
+    blockSize = 0;
+    blockCount = 0;
+    msd_intf = -1;
+    msd_device_found = false;
+    disk_init = false;
+    dev_connected = false;
+    nb_ep = 0;
+}
+
+
+bool USBHostMSD::connected()
+{
+    return dev_connected;
+}
+
+bool USBHostMSD::connect()
+{
+
+    if (dev_connected) {
+        return true;
+    }
+
+    for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
+        if ((dev = host->getDevice(i)) != NULL) {
+
+            USB_DBG("Trying to connect MSD device\r\n");
+
+            if(host->enumerate(dev, this))
+                break;
+
+            if (msd_device_found) {
+                /* As this is done in a specific thread
+                 * this lock is taken to avoid to process a disconnection in
+                 * usb process during the device registering */
+                USBHost::Lock  Lock(host);
+
+                bulk_in = dev->getEndpoint(msd_intf, BULK_ENDPOINT, IN);
+                bulk_out = dev->getEndpoint(msd_intf, BULK_ENDPOINT, OUT);
+
+                if (!bulk_in || !bulk_out)
+                    continue;
+
+                USB_INFO("New MSD device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, msd_intf);
+                dev->setName("MSD", msd_intf);
+                host->registerDriver(dev, msd_intf, this, &USBHostMSD::init);
+
+                dev_connected = true;
+                return true;
+            }
+        } //if()
+    } //for()
+    init();
+    return false;
+}
+
+/*virtual*/ void USBHostMSD::setVidPid(uint16_t vid, uint16_t pid)
+{
+    // we don't check VID/PID for MSD driver
+}
+
+/*virtual*/ bool USBHostMSD::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed
+{
+    if ((msd_intf == -1) &&
+        (intf_class == MSD_CLASS) &&
+        (intf_subclass == 0x06) &&
+        (intf_protocol == 0x50)) {
+        msd_intf = intf_nb;
+        return true;
+    }
+    return false;
+}
+
+/*virtual*/ bool USBHostMSD::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
+{
+    if (intf_nb == msd_intf) {
+        if (type == BULK_ENDPOINT) {
+            nb_ep++;
+            if (nb_ep == 2)
+                msd_device_found = true;
+            return true;
+        }
+    }
+    return false;
+}
+
+
+int USBHostMSD::testUnitReady()
+{
+    USB_DBG("Test unit ready");
+    return SCSITransfer(NULL, 6, DEVICE_TO_HOST, 0, 0);
+}
+
+
+int USBHostMSD::readCapacity()
+{
+    USB_DBG("Read capacity");
+    uint8_t cmd[10] = {0x25,0,0,0,0,0,0,0,0,0};
+    uint8_t result[8];
+    int status = SCSITransfer(cmd, 10, DEVICE_TO_HOST, result, 8);
+    if (status == 0) {
+        blockCount = (result[0] << 24) | (result[1] << 16) | (result[2] << 8) | result[3];
+        blockSize = (result[4] << 24) | (result[5] << 16) | (result[6] << 8) | result[7];
+        USB_INFO("MSD [dev: %p] - blockCount: %lld, blockSize: %d, Capacity: %lld\r\n", dev, blockCount, blockSize, blockCount*blockSize);
+    }
+    return status;
+}
+
+
+int USBHostMSD::SCSIRequestSense()
+{
+    USB_DBG("Request sense");
+    uint8_t cmd[6] = {0x03,0,0,0,18,0};
+    uint8_t result[18];
+    int status = SCSITransfer(cmd, 6, DEVICE_TO_HOST, result, 18);
+    return status;
+}
+
+
+int USBHostMSD::inquiry(uint8_t lun, uint8_t page_code)
+{
+    USB_DBG("Inquiry");
+    uint8_t evpd = (page_code == 0) ? 0 : 1;
+    uint8_t cmd[6] = {0x12, uint8_t((lun << 5) | evpd), page_code, 0, 36, 0};
+    uint8_t result[36];
+    int status = SCSITransfer(cmd, 6, DEVICE_TO_HOST, result, 36);
+    if (status == 0) {
+        char vid_pid[17];
+        memcpy(vid_pid, &result[8], 8);
+        vid_pid[8] = 0;
+        USB_INFO("MSD [dev: %p] - Vendor ID: %s", dev, vid_pid);
+
+        memcpy(vid_pid, &result[16], 16);
+        vid_pid[16] = 0;
+        USB_INFO("MSD [dev: %p] - Product ID: %s", dev, vid_pid);
+
+        memcpy(vid_pid, &result[32], 4);
+        vid_pid[4] = 0;
+        USB_INFO("MSD [dev: %p] - Product rev: %s", dev, vid_pid);
+    }
+    return status;
+}
+
+int USBHostMSD::checkResult(uint8_t res, USBEndpoint * ep)
+{
+    // if ep stalled: send clear feature
+    if (res == USB_TYPE_STALL_ERROR) {
+        res = host->controlWrite(   dev,
+                                    USB_RECIPIENT_ENDPOINT | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_STANDARD,
+                                    CLEAR_FEATURE,
+                                    0, ep->getAddress(), NULL, 0);
+        // set state to IDLE if clear feature successful
+        if (res == USB_TYPE_OK) {
+            ep->setState(USB_TYPE_IDLE);
+        }
+    }
+
+    if (res != USB_TYPE_OK)
+        return -1;
+
+    return 0;
+}
+
+
+int USBHostMSD::SCSITransfer(uint8_t * cmd, uint8_t cmd_len, int flags, uint8_t * data, uint32_t transfer_len)
+{
+
+    int res = 0;
+
+    cbw.Signature = CBW_SIGNATURE;
+    cbw.Tag = 0;
+    cbw.DataLength = transfer_len;
+    cbw.Flags = flags;
+    cbw.LUN = 0;
+    cbw.CBLength = cmd_len;
+    memset(cbw.CB,0,sizeof(cbw.CB));
+    if (cmd) {
+        memcpy(cbw.CB,cmd,cmd_len);
+    }
+
+    // send the cbw
+    USB_DBG("Send CBW");
+    res = host->bulkWrite(dev, bulk_out,(uint8_t *)&cbw, 31);
+    if (checkResult(res, bulk_out))
+        return -1;
+
+    // data stage if needed
+    if (data) {
+        USB_DBG("data stage");
+        if (flags == HOST_TO_DEVICE) {
+
+            res = host->bulkWrite(dev, bulk_out, data, transfer_len);
+            if (checkResult(res, bulk_out))
+                return -1;
+
+        } else if (flags == DEVICE_TO_HOST) {
+
+            res = host->bulkRead(dev, bulk_in, data, transfer_len);
+            if (checkResult(res, bulk_in))
+                return -1;
+        }
+    }
+
+    // status stage
+    csw.Signature = 0;
+    USB_DBG("Read CSW");
+    res = host->bulkRead(dev, bulk_in,(uint8_t *)&csw, 13);
+    if (checkResult(res, bulk_in))
+        return -1;
+
+    if (csw.Signature != CSW_SIGNATURE) {
+        return -1;
+    }
+
+    USB_DBG("recv csw: status: %d", csw.Status);
+
+    // ModeSense?
+    if ((csw.Status == 1) && (cmd[0] != 0x03)) {
+        USB_DBG("request mode sense");
+        return SCSIRequestSense();
+    }
+
+    // perform reset recovery
+    if ((csw.Status == 2) && (cmd[0] != 0x03)) {
+
+        // send Bulk-Only Mass Storage Reset request
+        res = host->controlWrite(   dev,
+                                    USB_RECIPIENT_INTERFACE | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS,
+                                    BO_MASS_STORAGE_RESET,
+                                    0, msd_intf, NULL, 0);
+
+        // unstall both endpoints
+        res = host->controlWrite(   dev,
+                                    USB_RECIPIENT_ENDPOINT | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_STANDARD,
+                                    CLEAR_FEATURE,
+                                    0, bulk_in->getAddress(), NULL, 0);
+
+        res = host->controlWrite(   dev,
+                                    USB_RECIPIENT_ENDPOINT | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_STANDARD,
+                                    CLEAR_FEATURE,
+                                    0, bulk_out->getAddress(), NULL, 0);
+
+    }
+
+    return csw.Status;
+}
+
+
+int USBHostMSD::dataTransfer(uint8_t * buf, uint32_t block, uint8_t nbBlock, int direction)
+{
+    uint8_t cmd[10];
+    memset(cmd,0,10);
+    cmd[0] = (direction == DEVICE_TO_HOST) ? 0x28 : 0x2A;
+
+    cmd[2] = (block >> 24) & 0xff;
+    cmd[3] = (block >> 16) & 0xff;
+    cmd[4] = (block >> 8) & 0xff;
+    cmd[5] =  block & 0xff;
+
+    cmd[7] = (nbBlock >> 8) & 0xff;
+    cmd[8] = nbBlock & 0xff;
+
+    return SCSITransfer(cmd, 10, direction, buf, blockSize*nbBlock);
+}
+
+int USBHostMSD::getMaxLun()
+{
+    uint8_t buf[1], res;
+    res = host->controlRead(    dev, USB_RECIPIENT_INTERFACE | USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS,
+                                0xfe, 0, msd_intf, buf, 1);
+    USB_DBG("max lun: %d", buf[0]);
+    return res;
+}
+
+int USBHostMSD::disk_initialize() {
+    USB_DBG("FILESYSTEM: init");
+    uint16_t i, timeout = 10;
+
+    getMaxLun();
+
+    for (i = 0; i < timeout; i++) {
+        Thread::wait(100);
+        if (!testUnitReady())
+            break;
+    }
+
+    if (i == timeout) {
+        disk_init = false;
+        return -1;
+    }
+
+    inquiry(0, 0);
+    disk_init = 1;
+    return readCapacity();
+}
+
+int USBHostMSD::disk_write(const uint8_t* buffer, uint32_t block_number, uint32_t count) {
+    USB_DBG("FILESYSTEM: write block: %lld, count: %d", block_number, count);
+    if (!disk_init) {
+        disk_initialize();
+    }
+    if (!disk_init)
+        return -1;
+    for (uint32_t b = block_number; b < block_number + count; b++) {
+        if (dataTransfer((uint8_t*)buffer, b, 1, HOST_TO_DEVICE))
+            return -1;
+        buffer += 512;
+    }
+    return 0;
+}
+
+int USBHostMSD::disk_read(uint8_t* buffer, uint32_t block_number, uint32_t count) {
+    USB_DBG("FILESYSTEM: read block: %lld, count: %d", block_number, count);
+    if (!disk_init) {
+        disk_initialize();
+    }
+    if (!disk_init)
+        return -1;
+    for (uint32_t b = block_number; b < block_number + count; b++) {
+        if (dataTransfer((uint8_t*)buffer, b, 1, DEVICE_TO_HOST))
+            return -1;
+        buffer += 512;
+    }
+    return 0;
+}
+
+uint32_t USBHostMSD::disk_sectors() {
+    USB_DBG("FILESYSTEM: sectors");
+    if (!disk_init) {
+        disk_initialize();
+    }
+    if (!disk_init)
+        return 0;
+    return blockCount;
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/USBHostMSD/USBHostMSD.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,119 @@
+/* mbed USBHost Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * 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.
+ */
+
+#ifndef USBHOSTMSD_H
+#define USBHOSTMSD_H
+
+#include "USBHostConf.h"
+
+#if USBHOST_MSD
+
+#include "USBHost.h"
+#include "FATFileSystem.h"
+
+/**
+ * A class to communicate a USB flash disk
+ */
+class USBHostMSD : public IUSBEnumerator, public FATFileSystem {
+public:
+    /**
+    * Constructor
+    *
+    * @param rootdir mount name
+    */
+    USBHostMSD(const char * rootdir);
+
+    /**
+    * Check if a MSD device is connected
+    *
+    * @return true if a MSD device is connected
+    */
+    bool connected();
+
+    /**
+     * Try to connect to a MSD device
+     *
+     * @return true if connection was successful
+     */
+    bool connect();
+
+protected:
+    //From IUSBEnumerator
+    virtual void setVidPid(uint16_t vid, uint16_t pid);
+    virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol); //Must return true if the interface should be parsed
+    virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir); //Must return true if the endpoint will be used
+
+    // From FATFileSystem
+    virtual int disk_initialize();
+    virtual int disk_status() {return 0;};
+    virtual int disk_read(uint8_t* buffer, uint32_t sector, uint32_t count);
+    virtual int disk_write(const uint8_t* buffer, uint32_t sector, uint32_t count);
+    virtual int disk_sync() {return 0;};
+    virtual uint32_t disk_sectors();
+
+private:
+    USBHost * host;
+    USBDeviceConnected * dev;
+    bool dev_connected;
+    USBEndpoint * bulk_in;
+    USBEndpoint * bulk_out;
+    uint8_t nb_ep;
+
+    // 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;
+
+    CBW cbw;
+    CSW csw;
+
+    int SCSITransfer(uint8_t * cmd, uint8_t cmd_len, int flags, uint8_t * data, uint32_t transfer_len);
+    int testUnitReady();
+    int readCapacity();
+    int inquiry(uint8_t lun, uint8_t page_code);
+    int SCSIRequestSense();
+    int dataTransfer(uint8_t * buf, uint32_t block, uint8_t nbBlock, int direction);
+    int checkResult(uint8_t res, USBEndpoint * ep);
+    int getMaxLun();
+
+    int blockSize;
+    uint32_t blockCount;
+
+    int msd_intf;
+    bool msd_device_found;
+    bool disk_init;
+
+    void init();
+
+};
+
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/USBHostSerial/MtxCircBuffer.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,89 @@
+/* mbed USBHost Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * 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.
+ */
+
+#ifndef MTXCIRCBUFFER_H
+#define MTXCIRCBUFFER_H
+
+#include "stdint.h"
+#include "rtos.h"
+
+//Mutex protected circular buffer
+template<typename T, int size>
+class MtxCircBuffer {
+public:
+
+    MtxCircBuffer() {
+        write = 0;
+        read = 0;
+    }
+
+    bool isFull() {
+        mtx.lock();
+        bool r = (((write + 1) % size) == read);
+        mtx.unlock();
+        return r;
+    }
+
+    bool isEmpty() {
+        mtx.lock();
+        bool r = (read == write);
+        mtx.unlock();
+        return r;
+    }
+
+    void flush() {
+        write = 0;
+        read = 0;
+    }
+
+    void queue(T k) {
+        mtx.lock();
+        while (((write + 1) % size) == read) {
+            mtx.unlock();
+            Thread::wait(10);
+            mtx.lock();
+        }
+        buf[write++] = k;
+        write %= size;
+        mtx.unlock();
+    }
+
+    uint16_t available() {
+        mtx.lock();
+        uint16_t a = (write >= read) ? (write - read) : (size - read + write);
+        mtx.unlock();
+        return a;
+    }
+
+    bool dequeue(T * c) {
+        mtx.lock();
+        bool empty = (read == write);
+        if (!empty) {
+            *c = buf[read++];
+            read %= size;
+        }
+        mtx.unlock();
+        return (!empty);
+    }
+
+private:
+    volatile uint16_t write;
+    volatile uint16_t read;
+    volatile T buf[size];
+    Mutex mtx;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/USBHostSerial/USBHostSerial.cpp	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,345 @@
+/* mbed USBHost Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * 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.
+ */
+
+#include "USBHostSerial.h"
+
+#if USBHOST_SERIAL
+
+#include "dbg.h"
+
+#define CHECK_INTERFACE(cls,subcls,proto) \
+        (((cls == 0xFF)         && (subcls == 0xFF) && (proto == 0xFF)) /* QUALCOM CDC */  || \
+         ((cls == SERIAL_CLASS) && (subcls == 0x00) && (proto == 0x00)) /* STANDARD CDC */ )
+
+#if (USBHOST_SERIAL <= 1)
+
+USBHostSerial::USBHostSerial()
+{
+    host = USBHost::getHostInst();
+    ports_found = 0;
+    dev_connected = false;
+}
+
+bool USBHostSerial::connected()
+{
+    return dev_connected;
+}
+
+void USBHostSerial::disconnect(void)
+{
+    ports_found = 0;
+    dev = NULL;
+}
+
+bool USBHostSerial::connect() {
+
+    if (dev)
+    {
+        for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++)
+        {
+            USBDeviceConnected* d = host->getDevice(i);
+            if (dev == d)
+                return true;
+        }
+        disconnect();
+    }
+    for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++)
+    {
+        USBDeviceConnected* d = host->getDevice(i);
+        if (d != NULL) {
+
+            USB_DBG("Trying to connect serial device \r\n");
+            if(host->enumerate(d, this))
+                break;
+
+            USBEndpoint* bulk_in  = d->getEndpoint(port_intf, BULK_ENDPOINT, IN);
+            USBEndpoint* bulk_out = d->getEndpoint(port_intf, BULK_ENDPOINT, OUT);
+            if (bulk_in && bulk_out)
+            {
+                USBHostSerialPort::connect(host,d,port_intf,bulk_in, bulk_out);
+                dev = d;
+                dev_connected = true;
+            }
+        }
+    }
+    return dev != NULL;
+}
+
+/*virtual*/ void USBHostSerial::setVidPid(uint16_t vid, uint16_t pid)
+{
+    // we don't check VID/PID for MSD driver
+}
+
+/*virtual*/ bool USBHostSerial::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed
+{
+    if (!ports_found &&
+        CHECK_INTERFACE(intf_class, intf_subclass, intf_protocol)) {
+        port_intf = intf_nb;
+        ports_found = true;
+        return true;
+    }
+    return false;
+}
+
+/*virtual*/ bool USBHostSerial::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
+{
+    if (ports_found && (intf_nb == port_intf)) {
+        if (type == BULK_ENDPOINT)
+            return true;
+    }
+    return false;
+}
+
+#else // (USBHOST_SERIAL > 1)
+
+//------------------------------------------------------------------------------
+
+USBHostMultiSerial::USBHostMultiSerial()
+{
+    host = USBHost::getHostInst();
+    dev = NULL;
+    memset(ports, NULL, sizeof(ports));
+    ports_found = 0;
+    dev_connected = false;
+}
+
+USBHostMultiSerial::~USBHostMultiSerial()
+{
+    disconnect();
+}
+
+bool USBHostMultiSerial::connected()
+{
+    return dev_connected;
+}
+
+void USBHostMultiSerial::disconnect(void)
+{
+    for (int port = 0; port < USBHOST_SERIAL; port ++)
+    {
+        if (ports[port])
+        {
+            delete ports[port];
+            ports[port] = NULL;
+        }
+    }
+    ports_found = 0;
+    dev = NULL;
+}
+
+bool USBHostMultiSerial::connect() {
+
+    if (dev)
+    {
+        for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++)
+        {
+            USBDeviceConnected* d = host->getDevice(i);
+            if (dev == d)
+                return true;
+        }
+        disconnect();
+    }
+    for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++)
+    {
+        USBDeviceConnected* d = host->getDevice(i);
+        if (d != NULL) {
+
+            USB_DBG("Trying to connect serial device \r\n");
+            if(host->enumerate(d, this))
+                break;
+
+            for (int port = 0; port < ports_found; port ++)
+            {
+                USBEndpoint* bulk_in  = d->getEndpoint(port_intf[port], BULK_ENDPOINT, IN);
+                USBEndpoint* bulk_out = d->getEndpoint(port_intf[port], BULK_ENDPOINT, OUT);
+                if (bulk_in && bulk_out)
+                {
+                    ports[port] = new USBHostSerialPort();
+                    if (ports[port])
+                    {
+                        ports[port]->connect(host,d,port_intf[port],bulk_in, bulk_out);
+                        dev = d;
+                        dev_connected = true;
+                    }
+                }
+            }
+        }
+    }
+    return dev != NULL;
+}
+
+/*virtual*/ void USBHostMultiSerial::setVidPid(uint16_t vid, uint16_t pid)
+{
+    // we don't check VID/PID for MSD driver
+}
+
+/*virtual*/ bool USBHostMultiSerial::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed
+{
+    if ((ports_found < USBHOST_SERIAL) &&
+        CHECK_INTERFACE(intf_class, intf_subclass, intf_protocol)) {
+        port_intf[ports_found++] = intf_nb;
+        return true;
+    }
+    return false;
+}
+
+/*virtual*/ bool USBHostMultiSerial::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
+{
+    if ((ports_found > 0) && (intf_nb == port_intf[ports_found-1])) {
+        if (type == BULK_ENDPOINT)
+            return true;
+    }
+    return false;
+}
+
+#endif
+
+//------------------------------------------------------------------------------
+
+#define SET_LINE_CODING 0x20
+
+USBHostSerialPort::USBHostSerialPort(): circ_buf()
+{
+    init();
+}
+
+void USBHostSerialPort::init(void)
+{
+    host = NULL;
+    dev = NULL;
+    serial_intf = NULL;
+    size_bulk_in = 0;
+    size_bulk_out = 0;
+    bulk_in = NULL;
+    bulk_out = NULL;
+    line_coding.baudrate = 9600;
+    line_coding.data_bits = 8;
+    line_coding.parity = None;
+    line_coding.stop_bits = 1;
+    circ_buf.flush();
+}
+
+void USBHostSerialPort::connect(USBHost* _host, USBDeviceConnected * _dev,
+        uint8_t _serial_intf, USBEndpoint* _bulk_in, USBEndpoint* _bulk_out)
+{
+    host = _host;
+    dev = _dev;
+    serial_intf = _serial_intf;
+    bulk_in = _bulk_in;
+    bulk_out = _bulk_out;
+
+    USB_INFO("New Serial device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, serial_intf);
+    dev->setName("Serial", serial_intf);
+    host->registerDriver(dev, serial_intf, this, &USBHostSerialPort::init);
+    baud(9600);
+    size_bulk_in = bulk_in->getSize();
+    size_bulk_out = bulk_out->getSize();
+    bulk_in->attach(this, &USBHostSerialPort::rxHandler);
+    bulk_out->attach(this, &USBHostSerialPort::txHandler);
+    host->bulkRead(dev, bulk_in, buf, size_bulk_in, false);
+}
+
+void USBHostSerialPort::rxHandler() {
+    if (bulk_in) {
+        int len = bulk_in->getLengthTransferred();
+        if (bulk_in->getState() == USB_TYPE_IDLE) {
+            for (int i = 0; i < len; i++) {
+                circ_buf.queue(buf[i]);
+            }
+            rx.call();
+            host->bulkRead(dev, bulk_in, buf, size_bulk_in, false);
+        }
+    }
+}
+
+void USBHostSerialPort::txHandler() {
+    if (bulk_out) {
+        if (bulk_out->getState() == USB_TYPE_IDLE) {
+            tx.call();
+        }
+    }
+}
+
+int USBHostSerialPort::_putc(int c) {
+    if (bulk_out) {
+        if (host->bulkWrite(dev, bulk_out, (uint8_t *)&c, 1) == USB_TYPE_OK) {
+            return 1;
+        }
+    }
+    return -1;
+}
+
+void USBHostSerialPort::baud(int baudrate) {
+    line_coding.baudrate = baudrate;
+    format(line_coding.data_bits, (Parity)line_coding.parity, line_coding.stop_bits);
+}
+
+void USBHostSerialPort::format(int bits, Parity parity, int stop_bits) {
+    line_coding.data_bits = bits;
+    line_coding.parity = parity;
+    line_coding.stop_bits = (stop_bits == 1) ? 0 : 2;
+
+    // set line coding
+    host->controlWrite( dev,
+                        USB_RECIPIENT_INTERFACE | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS,
+                        SET_LINE_CODING,
+                        0, serial_intf, (uint8_t *)&line_coding, 7);
+}
+
+int USBHostSerialPort::_getc() {
+    uint8_t c = 0;
+    if (bulk_in == NULL) {
+        init();
+        return -1;
+    }
+    while (circ_buf.isEmpty());
+    circ_buf.dequeue(&c);
+    return c;
+}
+
+int USBHostSerialPort::writeBuf(const char* b, int s)
+{
+    int c = 0;
+    if (bulk_out)
+    {
+        while (c < s)
+        {
+            int i = (s < size_bulk_out) ? s : size_bulk_out;
+            if (host->bulkWrite(dev, bulk_out, (uint8_t *)(b+c), i) == USB_TYPE_OK)
+                c += i;
+        }
+    }
+    return s;
+}
+
+int USBHostSerialPort::readBuf(char* b, int s)
+{
+    int i = 0;
+    if (bulk_in)
+    {
+        for (i = 0; i < s; )
+            b[i++] = getc();
+    }
+    return i;
+}
+
+uint8_t USBHostSerialPort::available() {
+    return circ_buf.available();
+}
+
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/USBHostSerial/USBHostSerial.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,232 @@
+/* mbed USBHost Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * 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.
+ */
+
+#ifndef USBHOSTSERIAL_H
+#define USBHOSTSERIAL_H
+
+#include "USBHostConf.h"
+
+#if USBHOST_SERIAL
+
+#include "USBHost.h"
+#include "Stream.h"
+#include "MtxCircBuffer.h"
+#include "Callback.h"
+
+/**
+ * A class to communicate a USB virtual serial port
+ */
+class USBHostSerialPort : public Stream {
+public:
+    /**
+    * Constructor
+    */
+    USBHostSerialPort();
+
+    enum IrqType {
+        RxIrq,
+        TxIrq
+    };
+
+    enum Parity {
+        None = 0,
+        Odd,
+        Even,
+        Mark,
+        Space
+    };
+
+    void connect(USBHost* _host, USBDeviceConnected * _dev,
+        uint8_t _serial_intf, USBEndpoint* _bulk_in, USBEndpoint* _bulk_out);
+
+    /**
+    * Check the number of bytes available.
+    *
+    * @returns the number of bytes available
+    */
+    uint8_t available();
+
+    /**
+     *  Attach a member function to call when a packet is received.
+     *
+     *  @param tptr pointer to the object to call the member function on
+     *  @param mptr pointer to the member function to be called
+     *  @param irq irq type
+     */
+    template<typename T>
+    inline void attach(T* tptr, void (T::*mptr)(void), IrqType irq = RxIrq) {
+        if ((mptr != NULL) && (tptr != NULL)) {
+            if (irq == RxIrq) {
+                rx.attach(tptr, mptr);
+            } else {
+                tx.attach(tptr, mptr);
+            }
+        }
+    }
+
+    /**
+     * Attach a callback called when a packet is received
+     *
+     * @param ptr function pointer
+     */
+    inline void attach(void (*fn)(void), IrqType irq = RxIrq) {
+        if (fn != NULL) {
+            if (irq == RxIrq) {
+                rx.attach(fn);
+            } else {
+                tx.attach(fn);
+            }
+        }
+    }
+
+    /** Set the baud rate of the serial port
+     *
+     *  @param baudrate The baudrate of the serial port (default = 9600).
+     */
+    void baud(int baudrate = 9600);
+
+    /** Set the transmission format used by the Serial port
+     *
+     *  @param bits The number of bits in a word (default = 8)
+     *  @param parity The parity used (USBHostSerialPort::None, USBHostSerialPort::Odd, USBHostSerialPort::Even, USBHostSerialPort::Mark, USBHostSerialPort::Space; default = USBHostSerialPort::None)
+     *  @param stop The number of stop bits (1 or 2; default = 1)
+     */
+    void format(int bits = 8, Parity parity = USBHostSerialPort::None, int stop_bits = 1);
+    virtual int writeBuf(const char* b, int s);
+    virtual int readBuf(char* b, int s);
+
+protected:
+    virtual int _getc();
+    virtual int _putc(int c);
+
+private:
+    USBHost * host;
+    USBDeviceConnected * dev;
+
+    USBEndpoint * bulk_in;
+    USBEndpoint * bulk_out;
+    uint32_t size_bulk_in;
+    uint32_t size_bulk_out;
+
+    void init();
+
+    MtxCircBuffer<uint8_t, 128> circ_buf;
+
+    uint8_t buf[64];
+
+    typedef struct {
+        uint32_t baudrate;
+        uint8_t stop_bits;
+        uint8_t parity;
+        uint8_t data_bits;
+    } PACKED LINE_CODING;
+
+    LINE_CODING line_coding;
+
+    void rxHandler();
+    void txHandler();
+    Callback<void()> rx;
+    Callback<void()> tx;
+
+    uint8_t serial_intf;
+};
+
+#if (USBHOST_SERIAL <= 1)
+
+class USBHostSerial : public IUSBEnumerator, public USBHostSerialPort
+{
+public:
+    USBHostSerial();
+
+    /**
+     * Try to connect a serial device
+     *
+     * @return true if connection was successful
+     */
+    bool connect();
+
+    void disconnect();
+
+    /**
+    * Check if a any serial port is connected
+    *
+    * @returns true if a serial device is connected
+    */
+    bool connected();
+
+protected:
+    USBHost* host;
+    USBDeviceConnected* dev;
+    uint8_t port_intf;
+    int ports_found;
+
+    //From IUSBEnumerator
+    virtual void setVidPid(uint16_t vid, uint16_t pid);
+    virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol); //Must return true if the interface should be parsed
+    virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir); //Must return true if the endpoint will be used
+
+private:
+    bool dev_connected;
+};
+
+#else // (USBHOST_SERIAL > 1)
+
+class USBHostMultiSerial : public IUSBEnumerator {
+public:
+    USBHostMultiSerial();
+    virtual ~USBHostMultiSerial();
+
+    USBHostSerialPort* getPort(int port)
+    {
+        return port < USBHOST_SERIAL ? ports[port] : NULL;
+    }
+
+    /**
+     * Try to connect a serial device
+     *
+     * @return true if connection was successful
+     */
+    bool connect();
+
+    void disconnect();
+
+    /**
+    * Check if a any serial port is connected
+    *
+    * @returns true if a serial device is connected
+    */
+    bool connected();
+
+protected:
+    USBHost* host;
+    USBDeviceConnected* dev;
+    USBHostSerialPort* ports[USBHOST_SERIAL];
+    uint8_t port_intf[USBHOST_SERIAL];
+    int ports_found;
+
+    //From IUSBEnumerator
+    virtual void setVidPid(uint16_t vid, uint16_t pid);
+    virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol); //Must return true if the interface should be parsed
+    virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir); //Must return true if the endpoint will be used
+
+private:
+    bool dev_connected;
+};
+#endif // (USBHOST_SERIAL <= 1)
+
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/targets/TARGET_STM/TARGET_STM32F2/TARGET_NUCLEO_F207ZG/USBHALHost_STM_TARGET.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,19 @@
+/* Copyright (c) 2016 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 "USBHALHost_STM_144_64pins.h"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F401xE/TARGET_NUCLEO_F401RE/USBHALHost_STM_TARGET.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,20 @@
+/* Copyright (c) 2016 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 USBHALHOST_64pins
+#include "USBHALHost_STM_144_64pins.h"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/TARGET_NUCLEO_F411RE/USBHALHost_STM_TARGET.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,40 @@
+/* Copyright (c) 2016 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.
+*/
+
+/*  144 pins boards */
+#if defined(TARGET_NUCLEO_F429ZI) || defined(TARGET_NUCLEO_F446ZE)  || defined(TARGET_NUCLEO_F207ZG) \
+|| defined(TARGET_NUCLEO_F767ZI) || defined(TARGET_NUCLEO_F746ZG) || defined(TARGET_NUCLEO_F412ZG) \
+|| defined(TARGET_DISCO_F413ZH)
+#include "USBHALHost_STM_144_64pins.h"
+#endif
+
+/*  64 pins boards */
+#if defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_L476RG) || defined(TARGET_NUCLEO_F411RE)
+#define USBHALHOST_64pins
+#include "USBHALHost_STM_144_64pins.h"
+#endif
+
+/*  DISCO board  */
+
+#ifdef TARGET_DISCO_F429ZI
+#include "USBHALHost_DISCOF429ZI.h"
+#endif
+
+#ifdef TARGET_DISCO_L476VG
+#include "USBHALHost_DISCOL476VG.h"
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/TARGET_NUCLEO_F412ZG/USBHALHost_STM_TARGET.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,19 @@
+/* Copyright (c) 2016 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 "USBHALHost_STM_144_64pins.h"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/TARGET_DISCO_F429ZI/USBHALHost_DISCOF429ZI.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,112 @@
+/* mbed USBHost Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * 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.
+ */
+#ifndef USBHALHOST_DISCOF429ZI
+#define USBHALHOST_DISCOF429ZI
+
+#define USBHAL_IRQn  OTG_HS_IRQn
+
+#define HCCA_SIZE sizeof(HCD_HandleTypeDef)
+#define ED_SIZE  sizeof(HCED)
+#define TD_SIZE  sizeof(HCTD)
+
+#define TOTAL_SIZE (HCCA_SIZE + (MAX_ENDPOINT*ED_SIZE) + (MAX_TD*TD_SIZE))
+/* STM device FS have 11 channels  (definition is for 60 channels) */
+static volatile  uint8_t usb_buf[TOTAL_SIZE];
+typedef struct
+{
+    /* store the request ongoing on each endpoit  */
+    /*  1st field of structure avoid  giving knowledge of all structure to
+     *  endpoint */
+    volatile uint32_t addr[MAX_ENDPOINT];
+    USBHALHost *inst;
+    void (USBHALHost::*deviceConnected)(int hub, int port, bool lowSpeed, USBHostHub * hub_parent);
+    void (USBHALHost::*deviceDisconnected)(int hub, int port, USBHostHub * hub_parent, volatile uint32_t addr);
+    void (USBHALHost::*transferCompleted)(volatile uint32_t addr);
+}USBHALHost_Private_t;
+/*  CONFIGURATION for USB_VBUS  
+ *  on 64 bits board PC_0 is used  (0  VBUS on,  1 VBUS off)
+ *  on 144 pins board PG_6 is used ( 1 VBUS on, 0 VBUS on)
+ */
+static gpio_t gpio_vbus;
+
+#define  VBUS_OFF 1
+#define  VBUS_ON 0
+#define USB_VBUS_CONFIG \
+    do {__HAL_RCC_GPIOC_CLK_ENABLE();\
+		gpio_init_out_ex(&gpio_vbus, PC_4, VBUS_OFF);\
+	}while(0);
+
+
+void  usb_vbus( uint8_t state)
+{
+    if(state == 0)
+    {
+        gpio_write(&gpio_vbus, VBUS_OFF);
+    }
+    else
+    {
+        gpio_write(&gpio_vbus, VBUS_ON);
+    }
+    wait(0.2);
+}
+
+
+USBHALHost::USBHALHost() {
+    gpio_t  pin_vbus;
+    instHost = this;
+    HCD_HandleTypeDef *hhcd;
+    USBHALHost_Private_t *HALPriv = new(USBHALHost_Private_t);
+    memset(HALPriv, 0, sizeof(USBHALHost_Private_t));
+    memInit();
+    memset((void*)usb_hcca, 0, HCCA_SIZE);
+    hhcd = (HCD_HandleTypeDef *)usb_hcca;
+    hhcd->Instance = USB_OTG_HS;
+    hhcd->pData = (void*)HALPriv;
+    hhcd->Init.Host_channels = 11;
+    /*   for now failed with dma */
+    hhcd->Init.dma_enable = 0;
+    hhcd->Init.speed = HCD_SPEED_HIGH;
+    hhcd->Init.phy_itface = HCD_PHY_EMBEDDED;
+    hhcd->Init.use_external_vbus = 1;
+    HALPriv->inst = this;
+    HALPriv->deviceConnected = &USBHALHost::deviceConnected;
+    HALPriv->deviceDisconnected = &USBHALHost::deviceDisconnected;
+    HALPriv->transferCompleted = &USBHALHost::transferCompleted;
+    for (int i = 0; i < MAX_ENDPOINT; i++) {
+        edBufAlloc[i] = false;
+        HALPriv->addr[i]=(uint32_t)-1;
+    }
+    for (int i = 0; i < MAX_TD; i++) {
+        tdBufAlloc[i] = false;
+    }
+    /* Configure USB HS GPIOs */
+    __HAL_RCC_GPIOB_CLK_ENABLE();
+
+    /*USB DM and DP */
+    pin_function(PB_14, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_OTG_HS_FS));
+    pin_function(PB_15, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_OTG_HS_FS));
+    /* Configure  VBUS Pin */
+    gpio_init_in(&pin_vbus, PB_13);
+    /* Configure POWER_SWITCH IO pin */
+    USB_VBUS_CONFIG;
+    /* Enable USB HS Clocks */
+    __HAL_RCC_USB_OTG_HS_CLK_ENABLE();
+
+    /* Set USBFS Interrupt priority */
+    HAL_NVIC_SetPriority(USBHAL_IRQn, 5, 0);
+    NVIC_SetVector(USBHAL_IRQn, (uint32_t)&_usbisr);
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/TARGET_DISCO_F429ZI/USBHALHost_STM_TARGET.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,18 @@
+/* Copyright (c) 2016 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 "USBHALHost_DISCOF429ZI.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/TARGET_NUCLEO_F429ZI/USBHALHost_STM_TARGET.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,18 @@
+/* Copyright (c) 2016 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 "USBHALHost_STM_144_64pins.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/TARGET_NUCLEO_F439ZI/USBHALHost_STM_TARGET.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,18 @@
+/* Copyright (c) 2016 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 "USBHALHost_STM_144_64pins.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/TARGET_NUCLEO_F446RE/USBHALHost_STM_TARGET.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,18 @@
+/* Copyright (c) 2016 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 "USBHALHost_STM_144_64pins.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/TARGET_NUCLEO_F446ZE/USBHALHost_STM_TARGET.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,19 @@
+/* Copyright (c) 2016 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 "USBHALHost_STM_144_64pins.h"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/TARGET_NUCLEO_F746ZG/USBHALHost_STM_TARGET.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,18 @@
+/* Copyright (c) 2016 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 "USBHALHost_STM_144_64pins.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F756xG/TARGET_NUCLEO_F756ZG/USBHALHost_STM_TARGET.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,18 @@
+/* Copyright (c) 2016 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 "USBHALHost_STM_144_64pins.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/TARGET_NUCLEO_F767ZI/USBHALHost_STM_TARGET.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,19 @@
+/* Copyright (c) 2016 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 "USBHALHost_STM_144_64pins.h"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/TARGET_DISCO_L475VG_IOT01A/USBHALHost_DISCO_L475VG_IOT01A.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,120 @@
+/* Copyright (c) 2017 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 USBHALHOST_DISCO_L475VG_IOT01A
+#define USBHALHOST_DISCO_L475VG_IOT01A
+
+#define USBHAL_IRQn  OTG_FS_IRQn
+
+#define HCCA_SIZE sizeof(HCD_HandleTypeDef)
+#define ED_SIZE  sizeof(HCED)
+#define TD_SIZE  sizeof(HCTD)
+
+#define TOTAL_SIZE (HCCA_SIZE + (MAX_ENDPOINT*ED_SIZE) + (MAX_TD*TD_SIZE))
+
+/* STM device FS have 11 channels (definition is for 60 channels) */
+static volatile  uint8_t usb_buf[TOTAL_SIZE];
+
+typedef struct {
+    /* store the request ongoing on each endpoit  */
+    /*  1st field of structure avoid  giving knowledge of all structure to
+     *  endpoint */
+    volatile uint32_t addr[MAX_ENDPOINT];
+    USBHALHost *inst;
+    void (USBHALHost::*deviceConnected)(int hub, int port, bool lowSpeed, USBHostHub * hub_parent);
+    void (USBHALHost::*deviceDisconnected)(int hub, int port, USBHostHub * hub_parent, volatile uint32_t addr);
+    void (USBHALHost::*transferCompleted)(volatile uint32_t addr);
+} USBHALHost_Private_t;
+
+static gpio_t gpio_powerpin;
+
+#define USB_POWER_OFF 1
+#define USB_POWER_ON  0
+#define USB_POWERPIN_CONFIG {gpio_init_out_ex(&gpio_powerpin, PD_12, USB_POWER_OFF);}
+
+
+void usb_vbus( uint8_t state)
+{
+    if (state == 0) {
+        gpio_write(&gpio_powerpin, USB_POWER_OFF);
+    } else {
+        gpio_write(&gpio_powerpin, USB_POWER_ON);
+    }
+    wait(0.2);
+}
+
+
+USBHALHost::USBHALHost()
+{
+    instHost = this;
+    HCD_HandleTypeDef *hhcd;
+    USBHALHost_Private_t *HALPriv = new(USBHALHost_Private_t);
+
+    memset(HALPriv, 0, sizeof(USBHALHost_Private_t));
+    memInit();
+    memset((void*)usb_hcca, 0, HCCA_SIZE);
+
+    hhcd = (HCD_HandleTypeDef *)usb_hcca;
+    hhcd->Instance = USB_OTG_FS;
+    hhcd->pData = (void*)HALPriv;
+    hhcd->Init.Host_channels = 11;
+
+    /* for now failed with dma */
+    hhcd->Init.dma_enable = 0;
+    hhcd->Init.speed =  HCD_SPEED_FULL;
+    hhcd->Init.phy_itface = HCD_PHY_EMBEDDED;
+    hhcd->Init.use_external_vbus = 1;
+
+    HALPriv->inst = this;
+    HALPriv->deviceConnected = &USBHALHost::deviceConnected;
+    HALPriv->deviceDisconnected = &USBHALHost::deviceDisconnected;
+    HALPriv->transferCompleted = &USBHALHost::transferCompleted;
+
+    for (int i = 0; i < MAX_ENDPOINT; i++) {
+        edBufAlloc[i] = false;
+        HALPriv->addr[i]=(uint32_t)-1;
+    }
+
+    for (int i = 0; i < MAX_TD; i++) {
+        tdBufAlloc[i] = false;
+    }
+
+    __HAL_RCC_PWR_CLK_ENABLE();
+
+#ifdef TARGET_STM32L4
+    HAL_PWREx_EnableVddUSB();
+#endif
+
+    /* Configure USB GPIOs */
+    __HAL_RCC_GPIOA_CLK_ENABLE();
+    pin_function(PA_11, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF10_OTG_FS)); // DM pin
+    pin_function(PA_12, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF10_OTG_FS)); // DP pin
+    pin_function(PA_9, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF10_OTG_FS)); // VBUS pin
+
+    /* Configure USB POWER pin */
+    USB_POWERPIN_CONFIG;
+
+    /* Enable USB FS Clocks */
+    __HAL_RCC_SYSCFG_CLK_ENABLE();
+    __HAL_RCC_USB_OTG_FS_CLK_ENABLE();
+
+    /* Set USBFS Interrupt priority */
+    HAL_NVIC_SetPriority(USBHAL_IRQn, 5, 0);
+    NVIC_SetVector(USBHAL_IRQn, (uint32_t)&_usbisr);
+}
+
+#endif // USBHALHOST_DISCO_L475VG_IOT01A
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/TARGET_DISCO_L475VG_IOT01A/USBHALHost_STM_TARGET.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,18 @@
+/* Copyright (c) 2016 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 "USBHALHost_DISCO_L475VG_IOT01A.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_DISCO_L476VG/USBHALHost_DISCOL476VG.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,118 @@
+/* Copyright (c) 2016 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 USBHALHOST_DISCOL476VG
+#define USBHALHOST_DISCOL476VG
+
+#define USBHAL_IRQn  OTG_FS_IRQn
+
+#define HCCA_SIZE sizeof(HCD_HandleTypeDef)
+#define ED_SIZE  sizeof(HCED)
+#define TD_SIZE  sizeof(HCTD)
+
+#define TOTAL_SIZE (HCCA_SIZE + (MAX_ENDPOINT*ED_SIZE) + (MAX_TD*TD_SIZE))
+/* STM device FS have 11 channels  (definition is for 60 channels) */
+static volatile  uint8_t usb_buf[TOTAL_SIZE];
+typedef struct
+{
+    /* store the request ongoing on each endpoit  */
+    /*  1st field of structure avoid  giving knowledge of all structure to
+     *  endpoint */
+    volatile uint32_t addr[MAX_ENDPOINT];
+    USBHALHost *inst;
+    void (USBHALHost::*deviceConnected)(int hub, int port, bool lowSpeed, USBHostHub * hub_parent);
+    void (USBHALHost::*deviceDisconnected)(int hub, int port, USBHostHub * hub_parent, volatile uint32_t addr);
+    void (USBHALHost::*transferCompleted)(volatile uint32_t addr);
+}USBHALHost_Private_t;
+
+static gpio_t gpio_vbus;
+
+#define  VBUS_OFF 1
+#define  VBUS_ON 0
+#define USB_VBUS_CONFIG \
+    do {\
+		gpio_init_out_ex(&gpio_vbus, PC_9, VBUS_OFF);\
+	}while(0);
+
+
+void  usb_vbus( uint8_t state)
+{
+    if(state == 0)
+    {
+        gpio_write(&gpio_vbus, VBUS_OFF);
+    }
+    else
+    {
+        gpio_write(&gpio_vbus, VBUS_ON);
+    }
+    wait(0.2);
+}
+
+
+USBHALHost::USBHALHost() {
+    instHost = this;
+    HCD_HandleTypeDef *hhcd;
+    USBHALHost_Private_t *HALPriv = new(USBHALHost_Private_t);
+    memset(HALPriv, 0, sizeof(USBHALHost_Private_t));
+    memInit();
+    memset((void*)usb_hcca, 0, HCCA_SIZE);
+    hhcd = (HCD_HandleTypeDef *)usb_hcca;
+    hhcd->Instance = USB_OTG_FS;
+    hhcd->pData = (void*)HALPriv;
+    hhcd->Init.Host_channels = 11;
+    /*   for now failed with dma */
+    hhcd->Init.dma_enable = 0;
+    hhcd->Init.speed =  HCD_SPEED_FULL;
+    hhcd->Init.phy_itface = HCD_PHY_EMBEDDED;
+    hhcd->Init.use_external_vbus = 1;
+    HALPriv->inst = this;
+    HALPriv->deviceConnected = &USBHALHost::deviceConnected;
+    HALPriv->deviceDisconnected = &USBHALHost::deviceDisconnected;
+    HALPriv->transferCompleted = &USBHALHost::transferCompleted;
+    for (int i = 0; i < MAX_ENDPOINT; i++) {
+        edBufAlloc[i] = false;
+        HALPriv->addr[i]=(uint32_t)-1;
+    }
+    for (int i = 0; i < MAX_TD; i++) {
+        tdBufAlloc[i] = false;
+    }
+    __HAL_RCC_PWR_CLK_ENABLE();
+#ifdef TARGET_STM32L4
+    HAL_PWREx_EnableVddUSB();
+#endif
+
+    /* Configure USB HS GPIOs */
+    __HAL_RCC_GPIOA_CLK_ENABLE();
+
+    /*USB DM and DP */
+    pin_function(PA_11, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF10_OTG_FS));
+    pin_function(PA_12, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF10_OTG_FS));
+
+    /* Configure  VBUS Pin */
+    __HAL_RCC_GPIOC_CLK_ENABLE();
+    pin_function(PC_11, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF10_OTG_FS));
+    /* Configure POWER_SWITCH IO pin */
+    USB_VBUS_CONFIG;
+    __HAL_RCC_SYSCFG_CLK_ENABLE();
+
+    /* Enable USB FS Clocks */
+    __HAL_RCC_USB_OTG_FS_CLK_ENABLE();
+    /* Set USBFS Interrupt priority */
+    HAL_NVIC_SetPriority(USBHAL_IRQn, 5, 0);
+    NVIC_SetVector(USBHAL_IRQn, (uint32_t)&_usbisr);
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_DISCO_L476VG/USBHALHost_STM_TARGET.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,18 @@
+/* Copyright (c) 2016 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 "USBHALHost_DISCOL476VG.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_NUCLEO_L476RG/USBHALHost_STM_TARGET.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,19 @@
+/* Copyright (c) 2016 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 USBHALHOST_64pins
+#include "USBHALHost_STM_144_64pins.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L486xG/TARGET_NUCLEO_L486RG/USBHALHost_STM_TARGET.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,19 @@
+/* Copyright (c) 2016 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 USBHALHOST_64pins
+#include "USBHALHost_STM_144_64pins.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/targets/TARGET_STM/USBEndpoint_STM.cpp	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,182 @@
+/* mbed USBHost Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * 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_STM) && defined(USBHOST_OTHER)
+
+#include "dbg.h"
+#include "USBEndpoint.h"
+extern uint32_t HAL_HCD_HC_GetMaxPacket(HCD_HandleTypeDef *hhcd, uint8_t chn_num);
+extern uint32_t HAL_HCD_HC_GetType(HCD_HandleTypeDef *hhcd, uint8_t chn_num);
+extern void HAL_HCD_DisableInt(HCD_HandleTypeDef* hhcd, uint8_t chn_num);
+extern void HAL_HCD_EnableInt(HCD_HandleTypeDef* hhcd, uint8_t chn_num);
+
+
+
+
+void USBEndpoint::init(HCED * hced_, ENDPOINT_TYPE type_, ENDPOINT_DIRECTION dir_, uint32_t size, uint8_t ep_number, HCTD* td_list_[2])
+{
+    HCD_HandleTypeDef *hhcd;
+    uint32_t *addr;
+
+    hced = hced_;
+    type = type_;
+    dir = dir_;
+    setup = (type == CONTROL_ENDPOINT) ? true : false;
+
+    //TDs have been allocated by the host
+    memcpy((HCTD**)td_list, td_list_, sizeof(HCTD*)*2); //TODO: Maybe should add a param for td_list size... at least a define
+    memset(td_list_[0], 0, sizeof(HCTD));
+    memset(td_list_[1], 0, sizeof(HCTD));
+
+    td_list[0]->ep = this;
+    td_list[1]->ep = this;
+
+    address = (ep_number & 0x7F) | ((dir - 1) << 7);
+    this->size = size;
+    this->ep_number = ep_number;
+    transfer_len = 0;
+    transferred = 0;
+    buf_start = 0;
+    nextEp = NULL;
+
+    td_current = td_list[0];
+    td_next = td_list[1];
+    /*  remove potential post pending from previous endpoint */
+    ep_queue.get(0);
+    intf_nb = 0;
+    hhcd = (HCD_HandleTypeDef*)hced->hhcd;
+    addr = &((uint32_t *)hhcd->pData)[hced->ch_num];
+    *addr = 0;
+    state = USB_TYPE_IDLE;
+    speed =false;
+}
+void USBEndpoint::setSize(uint32_t size)
+{
+    this->size = size;
+}
+
+
+void USBEndpoint::setDeviceAddress(uint8_t addr)
+{
+    HCD_HandleTypeDef *hhcd;
+    uint8_t hcd_speed = HCD_SPEED_FULL;
+    /* fix me : small speed device with hub not supported
+    if (this->speed) hcd_speed = HCD_SPEED_LOW; */
+    if (this->speed) {
+        USB_WARN("small speed device on hub not supported");
+    }
+    MBED_ASSERT(HAL_HCD_HC_Init((HCD_HandleTypeDef*)hced->hhcd,hced->ch_num, address, addr, hcd_speed,  type, size)!=HAL_BUSY);
+    this->device_address = addr;
+
+}
+
+void USBEndpoint::setSpeed(uint8_t speed)
+{
+    this->speed = speed;
+}
+
+
+
+void USBEndpoint::setState(USB_TYPE st)
+{
+    /*  modify this state is possible only with a plug   */
+    if (state == USB_TYPE_FREE) {
+        return;
+    }
+
+    state = st;
+    if (st == USB_TYPE_FREE) {
+        HCD_HandleTypeDef *hhcd = (HCD_HandleTypeDef*)hced->hhcd;
+        uint32_t *addr = &((uint32_t *)hhcd->pData)[hced->ch_num];
+        if ((*addr) && (type != INTERRUPT_ENDPOINT)) {
+            this->ep_queue.put((uint8_t*)1);
+        }
+        MBED_ASSERT(HAL_HCD_HC_Halt((HCD_HandleTypeDef*)hced->hhcd, hced->ch_num)!=HAL_BUSY);
+        HAL_HCD_DisableInt((HCD_HandleTypeDef*)hced->hhcd, hced->ch_num);
+        *addr = 0;
+
+    }
+    if (st == USB_TYPE_ERROR) {
+        MBED_ASSERT(HAL_HCD_HC_Halt((HCD_HandleTypeDef*)hced->hhcd, hced->ch_num)!=HAL_BUSY);
+        HAL_HCD_DisableInt((HCD_HandleTypeDef*)hced->hhcd, hced->ch_num);
+
+    }
+    if (st == USB_TYPE_ERROR) {
+        uint8_t hcd_speed = HCD_SPEED_FULL;
+        /* small speed device with hub not supported
+           if (this->speed) hcd_speed = HCD_SPEED_LOW;*/
+        MBED_ASSERT(HAL_HCD_HC_Init((HCD_HandleTypeDef*)hced->hhcd,hced->ch_num, address, 0, hcd_speed,  type, size)!=HAL_BUSY);
+    }
+}
+
+
+extern uint32_t HAL_HCD_HC_GetMaxPacket(HCD_HandleTypeDef *hhcd, uint8_t chn_num);
+extern uint32_t HAL_HCD_HC_GetType(HCD_HandleTypeDef *hhcd, uint8_t chn_num);
+
+
+USB_TYPE USBEndpoint::queueTransfer()
+{
+    HCD_HandleTypeDef *hhcd = (HCD_HandleTypeDef*)hced->hhcd;
+    uint32_t *addr = &((uint32_t *)hhcd->pData)[hced->ch_num];
+    uint32_t type = HAL_HCD_HC_GetType(hhcd, hced->ch_num);
+    uint32_t max_size =  HAL_HCD_HC_GetMaxPacket(hhcd, hced->ch_num);
+    /*  if a packet is queue on disconnected ; no solution for now */
+    if (state == USB_TYPE_FREE)  {
+        td_current->state =  USB_TYPE_FREE;
+        return USB_TYPE_FREE;
+    }
+    ep_queue.get(0);
+    MBED_ASSERT(*addr ==0);
+    transfer_len =   td_current->size <= max_size ? td_current->size : max_size;
+    buf_start = (uint8_t *)td_current->currBufPtr;
+
+    //Now add this free TD at this end of the queue
+    state = USB_TYPE_PROCESSING;
+    /*  one request */
+    td_current->nextTD = (hcTd*)0;
+#if defined(MAX_NYET_RETRY)
+    td_current->retry = 0;
+#endif
+    td_current->setup = setup;
+    *addr = (uint32_t)td_current;
+    /*  dir /setup is inverted for ST */
+    /* token is useful only ctrl endpoint */
+    /*  last parameter is ping ? */
+    MBED_ASSERT(HAL_HCD_HC_SubmitRequest((HCD_HandleTypeDef*)hced->hhcd, hced->ch_num, dir-1, type,!setup,(uint8_t*) td_current->currBufPtr, transfer_len, 0)==HAL_OK);
+    HAL_HCD_EnableInt((HCD_HandleTypeDef*)hced->hhcd, hced->ch_num);
+
+    return USB_TYPE_PROCESSING;
+}
+
+void USBEndpoint::unqueueTransfer(volatile HCTD * td)
+{
+    if (state==USB_TYPE_FREE) {
+        return;
+    }
+    uint32_t *addr = &((uint32_t *)((HCD_HandleTypeDef*)hced->hhcd)->pData)[hced->ch_num];
+    td->state=0;
+    td->currBufPtr=0;
+    td->size=0;
+    td->nextTD=0;
+    *addr = 0;
+    td_current = td_next;
+    td_next = td;
+}
+
+void USBEndpoint::queueEndpoint(USBEndpoint * ed)
+{
+    nextEp = ed;
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/targets/TARGET_STM/USBHALHost_STM.cpp	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,313 @@
+/* mbed USBHost Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * 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.
+ */
+
+#ifdef TARGET_STM
+#include "mbed.h"
+#include "USBHALHost.h"
+#include "dbg.h"
+#include "pinmap.h"
+
+#include "USBHALHost_STM_TARGET.h"
+
+void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd)
+{
+    USBHALHost_Private_t *priv=(USBHALHost_Private_t *)(hhcd->pData);
+    USBHALHost *obj= priv->inst;
+    void (USBHALHost::*func)(int hub, int port, bool lowSpeed, USBHostHub * hub_parent ) = priv->deviceConnected;
+    (obj->*func)(0,1,0,NULL);
+}
+void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd)
+{
+    USBHALHost_Private_t *priv=(USBHALHost_Private_t *)(hhcd->pData);
+    USBHALHost *obj= priv->inst;
+    void (USBHALHost::*func1)(int hub, int port, USBHostHub * hub_parent, volatile uint32_t addr)= priv->deviceDisconnected;
+    (obj->*func1)(0,1,(USBHostHub *)NULL,0);
+}
+int HAL_HCD_HC_GetDirection(HCD_HandleTypeDef *hhcd,uint8_t chnum)
+{
+    /*  useful for transmission */
+    return hhcd->hc[chnum].ep_is_in;
+}
+
+uint32_t HAL_HCD_HC_GetMaxPacket(HCD_HandleTypeDef *hhcd,uint8_t chnum)
+{
+    /*  useful for transmission */
+    return hhcd->hc[chnum].max_packet;
+}
+
+void  HAL_HCD_EnableInt(HCD_HandleTypeDef *hhcd,uint8_t chnum)
+{
+    USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
+    USBx_HOST->HAINTMSK |= (1 << chnum);
+}
+
+
+void  HAL_HCD_DisableInt(HCD_HandleTypeDef *hhcd,uint8_t chnum)
+{
+    USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
+    USBx_HOST->HAINTMSK &= ~(1 << chnum);
+}
+uint32_t HAL_HCD_HC_GetType(HCD_HandleTypeDef *hhcd,uint8_t chnum)
+{
+    /*  useful for transmission */
+    return hhcd->hc[chnum].ep_type;
+}
+
+void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd,uint8_t chnum, HCD_URBStateTypeDef urb_state)
+{
+    USBHALHost_Private_t *priv=(USBHALHost_Private_t *)(hhcd->pData);
+    USBHALHost *obj= priv->inst;
+    void (USBHALHost::*func)(volatile uint32_t addr)= priv->transferCompleted;
+
+    uint32_t addr = priv->addr[chnum];
+    uint32_t max_size = HAL_HCD_HC_GetMaxPacket(hhcd, chnum);
+    uint32_t type = HAL_HCD_HC_GetType(hhcd, chnum);
+    uint32_t dir = HAL_HCD_HC_GetDirection(hhcd,chnum);
+    uint32_t length;
+    if ( (addr!=0)) {
+        HCTD *td = (HCTD *)addr;
+
+        if ((type == EP_TYPE_BULK) || (type == EP_TYPE_CTRL )) {
+            switch (urb_state) {
+                case URB_DONE:
+#if defined(MAX_NYET_RETRY)
+                    td->retry = 0;
+#endif
+/* 20171020 MOFD */
+#ifdef USBHOST_OTHER
+                    if (td->size >  max_size) {
+                        /*  enqueue  another request */
+                        td->currBufPtr += max_size;
+                        td->size -= max_size;
+                        length = td->size <= max_size ? td->size : max_size;
+                        MBED_ASSERT(HAL_HCD_HC_SubmitRequest(hhcd, chnum, dir ,type , !td->setup,(uint8_t*) td->currBufPtr, length, 0)==HAL_OK);
+                        HAL_HCD_EnableInt(hhcd, chnum);
+                        return;
+                    }
+#endif
+                    break;
+                case  URB_NOTREADY:
+                    /*  try again  */
+                    /*  abritary limit , to avoid dead lock if other error than
+                     *  slow response is  */
+#if defined(MAX_NYET_RETRY)
+                    if (td->retry < MAX_NYET_RETRY) {
+                        /*  increment retry counter */
+                        td->retry++;
+#endif
+/* 20171020 MOFD */
+#ifdef USBHOST_OTHER
+                        length = td->size <= max_size ? td->size : max_size;
+                        MBED_ASSERT(HAL_HCD_HC_SubmitRequest(hhcd, chnum, dir ,type , !td->setup,(uint8_t*) td->currBufPtr, length, 0)==HAL_OK);
+                        HAL_HCD_EnableInt(hhcd, chnum);
+                        return;
+#endif
+#if defined(MAX_NYET_RETRY)
+                    } else {
+                        USB_ERR("urb_state != URB_NOTREADY");
+                    }
+#endif
+                    break;
+            }
+        }
+        if ((type == EP_TYPE_INTR) ) {
+            /*  reply a packet of length NULL, this will be analyse in call back
+             *  for mouse or hub */
+/* 20171020 MOFD */
+#ifdef USBHOST_OTHER
+            td->state =USB_TYPE_IDLE ;
+#endif
+            HAL_HCD_DisableInt(hhcd, chnum);
+
+        } else {
+/* 20171020 MOFD */
+#ifdef USBHOST_OTHER
+            td->state = (urb_state == URB_DONE) ?  USB_TYPE_IDLE : USB_TYPE_ERROR;
+#endif
+        }
+        td->currBufPtr +=HAL_HCD_HC_GetXferCount(hhcd, chnum);
+        (obj->*func)(addr);
+    } else {
+        if (urb_state !=0) {
+            USB_DBG_EVENT("spurious %d %d",chnum, urb_state);
+        }
+    }
+}
+
+USBHALHost * USBHALHost::instHost;
+
+
+void USBHALHost::init()
+{
+
+    NVIC_DisableIRQ(USBHAL_IRQn);
+    NVIC_SetVector(USBHAL_IRQn, (uint32_t)(_usbisr));
+    HAL_HCD_Init((HCD_HandleTypeDef *) usb_hcca);
+    NVIC_EnableIRQ(USBHAL_IRQn);
+/* 20171020 MOFD */
+#ifdef USBHOST_OTHER
+    control_disable = 0;
+#endif
+    HAL_HCD_Start((HCD_HandleTypeDef *) usb_hcca);
+    usb_vbus(1);
+}
+
+uint32_t USBHALHost::controlHeadED()
+{
+    return 0xffffffff;
+}
+
+uint32_t USBHALHost::bulkHeadED()
+{
+    return 0xffffffff;
+}
+
+uint32_t USBHALHost::interruptHeadED()
+{
+    return 0xffffffff;
+}
+
+void USBHALHost::updateBulkHeadED(uint32_t addr)
+{
+}
+
+
+void USBHALHost::updateControlHeadED(uint32_t addr)
+{
+}
+
+void USBHALHost::updateInterruptHeadED(uint32_t addr)
+{
+}
+
+
+void USBHALHost::enableList(ENDPOINT_TYPE type)
+{
+    /*  react when the 3 lists are requested to be disabled */
+    if (type == CONTROL_ENDPOINT) {
+/* 20171020 MOFD */
+#ifdef USBHOST_OTHER
+        control_disable--;
+
+        if (control_disable == 0) {
+            NVIC_EnableIRQ(USBHAL_IRQn);
+        } else {
+            printf("reent\n");
+        }
+#endif
+    }
+}
+
+
+bool USBHALHost::disableList(ENDPOINT_TYPE type)
+{
+    if (type == CONTROL_ENDPOINT) {
+        NVIC_DisableIRQ(USBHAL_IRQn);
+/* 20171020 MOFD */
+#ifdef USBHOST_OTHER
+        control_disable++;
+
+        if (control_disable > 1) {
+            printf("disable reentrance !!!\n");
+        }
+        return true;
+#endif
+    }
+    return false;
+}
+
+
+void USBHALHost::memInit()
+{
+/* 20171020 MOFD */
+#ifdef USBHOST_OTHER
+    usb_hcca =  (volatile HCD_HandleTypeDef *)usb_buf;
+#endif
+    usb_edBuf = usb_buf + HCCA_SIZE;
+    usb_tdBuf = usb_buf + HCCA_SIZE +(MAX_ENDPOINT*ED_SIZE);
+    /*  init channel  */
+    memset((void*)usb_buf,0, TOTAL_SIZE);
+    for (int i=0; i < MAX_ENDPOINT; i++) {
+        HCED	*hced = (HCED*)(usb_edBuf + i*ED_SIZE);
+/* 20171020 MOFD */
+#ifdef USBHOST_OTHER
+        hced->ch_num = i;
+        hced->hhcd = (HCCA *) usb_hcca;
+#endif
+    }
+}
+
+volatile uint8_t * USBHALHost::getED()
+{
+    for (int i = 0; i < MAX_ENDPOINT; i++) {
+        if ( !edBufAlloc[i] ) {
+            edBufAlloc[i] = true;
+            return (volatile uint8_t *)(usb_edBuf + i*ED_SIZE);
+        }
+    }
+    perror("Could not allocate ED\r\n");
+    return NULL; //Could not alloc ED
+}
+
+volatile uint8_t * USBHALHost::getTD()
+{
+    int i;
+    for (i = 0; i < MAX_TD; i++) {
+        if ( !tdBufAlloc[i] ) {
+            tdBufAlloc[i] = true;
+            return (volatile uint8_t *)(usb_tdBuf + i*TD_SIZE);
+        }
+    }
+    perror("Could not allocate TD\r\n");
+    return NULL; //Could not alloc TD
+}
+
+
+void USBHALHost::freeED(volatile uint8_t * ed)
+{
+    int i;
+    i = (ed - usb_edBuf) / ED_SIZE;
+    edBufAlloc[i] = false;
+}
+
+void USBHALHost::freeTD(volatile uint8_t * td)
+{
+    int i;
+    i = (td - usb_tdBuf) / TD_SIZE;
+    tdBufAlloc[i] = false;
+}
+
+
+void USBHALHost::resetRootHub()
+{
+    // Initiate port reset
+    wait(0.2);
+    HAL_HCD_ResetPort((HCD_HandleTypeDef *)usb_hcca);
+}
+
+
+void USBHALHost::_usbisr(void)
+{
+    if (instHost) {
+        instHost->UsbIrqhandler();
+    }
+}
+
+void USBHALHost::UsbIrqhandler()
+{
+    HAL_HCD_IRQHandler((HCD_HandleTypeDef *)usb_hcca);
+}
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/targets/TARGET_STM/USBHALHost_STM_144_64pins.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,121 @@
+/* mbed USBHost Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * 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.
+ */
+#ifndef USBHALHOST_STM32_144_64
+#define USBHALHOST_STM32_144_64
+
+#define USBHAL_IRQn  OTG_FS_IRQn
+
+#define HCCA_SIZE sizeof(HCD_HandleTypeDef)
+#define ED_SIZE  sizeof(HCED)
+#define TD_SIZE  sizeof(HCTD)
+
+#define TOTAL_SIZE (HCCA_SIZE + (MAX_ENDPOINT*ED_SIZE) + (MAX_TD*TD_SIZE))
+/* STM device FS have 11 channels  (definition is for 60 channels) */
+static volatile  uint8_t usb_buf[TOTAL_SIZE];
+typedef struct
+{
+	/* store the request ongoing on each endpoit  */
+	/*  1st field of structure avoid  giving knowledge of all structure to
+	 *  endpoint */
+	volatile uint32_t addr[MAX_ENDPOINT];
+	USBHALHost *inst;
+	void (USBHALHost::*deviceConnected)(int hub, int port, bool lowSpeed, USBHostHub * hub_parent);
+	void (USBHALHost::*deviceDisconnected)(int hub, int port, USBHostHub * hub_parent, volatile uint32_t addr);
+	void (USBHALHost::*transferCompleted)(volatile uint32_t addr);
+}USBHALHost_Private_t;
+
+/*  CONFIGURATION for USB_VBUS  
+ *  on 64 bits board PC_0 is used  (0  VBUS on,  1 VBUS off)
+ *  on 144 pins board PG_6 is used ( 1 VBUS on, 0 VBUS on)
+ */
+static gpio_t gpio_vbus;
+
+#if defined(USBHALHOST_64pins)
+#define  VBUS_OFF 1
+#define  VBUS_ON 0
+#define USB_VBUS_CONFIG \
+    do {__HAL_RCC_GPIOC_CLK_ENABLE();\
+		gpio_init_out_ex(&gpio_vbus, PC_0, VBUS_OFF);\
+	}while(0);
+#else
+#define  VBUS_OFF 0
+#define  VBUS_ON 1
+#define USB_VBUS_CONFIG \
+    do {__HAL_RCC_GPIOG_CLK_ENABLE();\
+		gpio_init_out_ex(&gpio_vbus, PG_6, VBUS_OFF);\
+	}while(0);
+#endif
+
+void  usb_vbus( uint8_t state)
+{
+    if(state == 0)
+    {
+        gpio_write(&gpio_vbus, VBUS_OFF);
+    }
+    else
+    {
+        gpio_write(&gpio_vbus, VBUS_ON);
+    }
+    wait(0.2);
+}
+
+USBHALHost::USBHALHost() {
+    instHost = this;
+    HCD_HandleTypeDef *hhcd;
+    USBHALHost_Private_t *HALPriv = new(USBHALHost_Private_t);
+    memset(HALPriv, 0, sizeof(USBHALHost_Private_t));
+    memInit();
+    memset((void*)usb_hcca, 0, HCCA_SIZE);
+    hhcd = (HCD_HandleTypeDef *)usb_hcca;
+    hhcd->Instance = USB_OTG_FS;
+    hhcd->pData = (void*)HALPriv;
+    hhcd->Init.Host_channels = 11;
+    hhcd->Init.speed = HCD_SPEED_FULL; 
+    hhcd->Init.phy_itface = HCD_PHY_EMBEDDED;
+    HALPriv->inst = this;
+    HALPriv->deviceConnected = &USBHALHost::deviceConnected;
+    HALPriv->deviceDisconnected = &USBHALHost::deviceDisconnected;
+    HALPriv->transferCompleted = &USBHALHost::transferCompleted;
+    for (int i = 0; i < MAX_ENDPOINT; i++) {
+        edBufAlloc[i] = false;
+        HALPriv->addr[i]=(uint32_t)-1;
+    }
+    for (int i = 0; i < MAX_TD; i++) {
+        tdBufAlloc[i] = false;
+    }
+    __HAL_RCC_PWR_CLK_ENABLE();
+#ifdef TARGET_STM32L4
+    HAL_PWREx_EnableVddUSB();
+#endif
+    /* Configure USB FS GPIOs */
+    __HAL_RCC_GPIOA_CLK_ENABLE();
+
+    /*USB DM and DP */
+    pin_function(PA_11, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF10_OTG_FS));
+    pin_function(PA_12, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF10_OTG_FS));
+    /*USB ID */
+    pin_function(PA_10, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_PULLUP, GPIO_AF10_OTG_FS));
+
+    __HAL_RCC_SYSCFG_CLK_ENABLE();
+    /* Configure POWER_SWITCH IO pin */
+    USB_VBUS_CONFIG;
+    /* Enable USB FS Clocks */
+    __HAL_RCC_USB_OTG_FS_CLK_ENABLE();
+
+    /* Set USBFS Interrupt priority */
+    HAL_NVIC_SetPriority(OTG_FS_IRQn, 6, 0);
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DISCO_F746NG_USBHost/targets/TARGET_STM/USBHALHost_STM_TARGET.h	Sat Oct 21 03:18:01 2017 +0000
@@ -0,0 +1,18 @@
+/* Copyright (c) 2016 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 "USBHALHost_STM_144_64pins.h"