USB CDC library for MBED on STM32

Dependents:   PushToGo-F429

Files at this revision

API Documentation at this revision

Comitter:
caoyuan9642
Date:
Sun Sep 09 19:03:18 2018 +0000
Commit message:
usb

Changed in this revision

IOQueue.h Show annotated file Show diff for this revision Revisions of this file
USBSerial.cpp Show annotated file Show diff for this revision Revisions of this file
USBSerial.h Show annotated file Show diff for this revision Revisions of this file
usbd_cdc.c Show annotated file Show diff for this revision Revisions of this file
usbd_cdc.h Show annotated file Show diff for this revision Revisions of this file
usbd_conf.c Show annotated file Show diff for this revision Revisions of this file
usbd_conf.h Show annotated file Show diff for this revision Revisions of this file
usbd_core.c Show annotated file Show diff for this revision Revisions of this file
usbd_core.h Show annotated file Show diff for this revision Revisions of this file
usbd_ctlreq.c Show annotated file Show diff for this revision Revisions of this file
usbd_ctlreq.h Show annotated file Show diff for this revision Revisions of this file
usbd_def.h Show annotated file Show diff for this revision Revisions of this file
usbd_desc.c Show annotated file Show diff for this revision Revisions of this file
usbd_desc.h Show annotated file Show diff for this revision Revisions of this file
usbd_ioreq.c Show annotated file Show diff for this revision Revisions of this file
usbd_ioreq.h Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 7cf972f622d3 IOQueue.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IOQueue.h	Sun Sep 09 19:03:18 2018 +0000
@@ -0,0 +1,387 @@
+/*
+ * DQueue.h
+ *
+ *  Created on: 2018Äê4ÔÂ15ÈÕ
+ *      Author: caoyuan9642
+ */
+
+#ifndef IOQUEUE_H_
+#define IOQUEUE_H_
+
+#include "mbed.h"
+
+#define SIGNAL_QUEUE 0x00000010
+#define MAX_THREAD_QUEUE 16
+
+struct ThreadQueue
+{
+	osThreadId_t threads[MAX_THREAD_QUEUE];
+	osThreadId_t *head, *tail;
+
+	ThreadQueue()
+	{
+		head = tail = threads;
+	}
+
+	bool empty()
+	{
+		return head == tail;
+	}
+
+	bool full()
+	{
+		return ((tail - head + 1) % MAX_THREAD_QUEUE) == 0;
+	}
+
+	osThreadId_t get()
+	{
+		if (empty())
+			return NULL;
+		osThreadId_t th = *head;
+		if (++head == threads + MAX_THREAD_QUEUE)
+			head = threads;
+		return th;
+	}
+
+	int put(osThreadId_t th)
+	{
+		if (full())
+		{
+			return -1;
+		}
+		*tail = th;
+		if (++tail == threads + MAX_THREAD_QUEUE)
+			tail = threads;
+		return 0;
+	}
+
+	/*
+	 * Wait on the current thread until awaken by other operations in the queue
+	 */
+	osStatus qwait(uint32_t wait)
+	{
+		if (wait == 0)
+		{
+			return osErrorTimeout;
+		}
+		core_util_critical_section_exit();
+
+		Thread::signal_clr(0x7FFFFFFF); // Clear all signals before adding to queue. Important!
+		if (put(Thread::gettid()) != 0)
+		{
+			// Queue full
+			printf("Queue full");
+			core_util_critical_section_enter();
+			return osErrorTimeout;
+		}
+		Thread::signal_wait(SIGNAL_QUEUE, wait);
+		core_util_critical_section_enter();
+		return osOK;
+	}
+};
+
+template<typename T, unsigned int N>
+class OutputQueue: private mbed::NonCopyable<OutputQueue<T, N> >
+{
+public:
+
+	typedef void (*notify_cb)(OutputQueue<T, N> *);
+
+	/** Create and initialize a message Queue.
+	 *
+	 * @note You cannot call this function from ISR context.
+	 */
+	OutputQueue()
+	{
+		memset(buf, 0, sizeof(buf));
+		ntf = NULL;
+		head = buf;
+		tail = buf;
+	}
+	/** Queue destructor
+	 *
+	 * @note You cannot call this function from ISR context.
+	 */
+	virtual ~OutputQueue()
+	{
+	}
+
+	/** Check if the queue is empty
+	 *
+	 * @return True if the queue is empty, false if not
+	 *
+	 * @note You may call this function from ISR context.
+	 */
+	bool empty() const
+	{
+		return head == tail;
+	}
+
+	/** Check if the queue is full
+	 *
+	 * @return True if the queue is full, false if not
+	 *
+	 * @note You may call this function from ISR context.
+	 */
+	bool full() const
+	{
+		return (tail - head == -1) || (tail - head == N - 1);
+	}
+
+	/** Check if the queue is full
+	 *
+	 * @return number of empty space
+	 *
+	 * @note You may call this function from ISR context.
+	 */
+	int capacity() const
+	{
+		return N - (tail - head + N) % N - 1;
+	}
+	/** Check if the queue is full
+	 *
+	 * @return number of empty space
+	 *
+	 * @note You may call this function from ISR context.
+	 */
+	int count() const
+	{
+		return (tail - head + N) % N;
+	}
+
+	/** Put a message in a Queue.
+	 @param   data      message pointer.
+	 @param   millisec  timeout value or 0 in case of no time-out. (default: osWaitForever)
+	 @return  status code that indicates the execution status of the function:
+	 @a osOK the message has been put into the queue.
+	 @a osErrorTimeout the message could not be put into the queue in the given time.
+
+	 @note You may call this function from ISR context if the millisec parameter is set to 0.
+	 */
+	osStatus put(const T &data, uint32_t wait = osWaitForever)
+	{
+		core_util_critical_section_enter();
+
+		// Wait for signal
+		while (full())
+		{
+			if (thq.qwait(wait) == osErrorTimeout)
+			{
+				core_util_critical_section_exit();
+				return osErrorTimeout;
+			}
+		}
+
+		*tail = data;
+		if (++tail == buf + N)
+			tail = buf;
+
+		if (ntf)
+		{
+			ntf(this);
+		}
+		core_util_critical_section_exit();
+
+		return osOK;
+	}
+
+	/** Get a message or Wait for a message from a Queue. Messages are retrieved in a descending priority order or
+	 first in first out when the priorities are the same.
+	 @param   pdata     pointer for return value
+	 @param   millisec  timeout value or 0 in case of no time-out. (default: osWaitForever).
+	 @return  status code that indicates the execution status of the function:
+	 @a osOK data retrieved in pdata
+	 @a osEventTimeout no message has arrived during the given timeout period.
+
+	 @note You may call this function from ISR context if the millisec parameter is set to 0.
+	 */
+	osStatus get(T *pdata)
+	{
+		if (empty())
+			return osErrorResource;
+
+		core_util_critical_section_enter();
+
+		*pdata = *head;
+		if (++head == buf + N)
+			head = buf;
+		if (!thq.empty())
+		{
+			osThreadId_t th = thq.get();
+			if (th)
+				osThreadFlagsSet(th, SIGNAL_QUEUE);
+		}
+
+		core_util_critical_section_exit();
+
+		return osOK;
+	}
+
+	void notify(notify_cb cb)
+	{
+		ntf = cb;
+	}
+
+protected:
+	notify_cb ntf;
+	T buf[N];
+	T* head;
+	T* tail;
+	ThreadQueue thq;
+
+};
+
+template<typename T, unsigned int N>
+class InputQueue: private mbed::NonCopyable<InputQueue<T, N> >
+{
+public:
+
+	typedef void (*notify_cb)(InputQueue<T, N> *);
+
+	/** Create and initialize a message Queue.
+	 *
+	 * @note You cannot call this function from ISR context.
+	 */
+	InputQueue()
+	{
+		memset(buf, 0, sizeof(buf));
+		ntf = NULL;
+		head = buf;
+		tail = buf;
+	}
+	/** Queue destructor
+	 *
+	 * @note You cannot call this function from ISR context.
+	 */
+	virtual ~InputQueue()
+	{
+	}
+
+	/** Check if the queue is empty
+	 *
+	 * @return True if the queue is empty, false if not
+	 *
+	 * @note You may call this function from ISR context.
+	 */
+	bool empty() const
+	{
+		return head == tail;
+	}
+
+	/** Check if the queue is full
+	 *
+	 * @return True if the queue is full, false if not
+	 *
+	 * @note You may call this function from ISR context.
+	 */
+	bool full() const
+	{
+		return (tail - head == -1) || (tail - head == N - 1);
+	}
+
+	/** Check if the queue is full
+	 *
+	 * @return number of empty space
+	 *
+	 * @note You may call this function from ISR context.
+	 */
+	int capacity() const
+	{
+		return N - (tail - head + N) % N - 1;
+	}
+	/** Check if the queue is full
+	 *
+	 * @return number of empty space
+	 *
+	 * @note You may call this function from ISR context.
+	 */
+	int count() const
+	{
+		return (tail - head + N) % N;
+	}
+
+	/** Put a message in a Queue.
+	 @param   data      message pointer.
+	 @param   millisec  timeout value or 0 in case of no time-out. (default: osWaitForever)
+	 @return  status code that indicates the execution status of the function:
+	 @a osOK the message has been put into the queue.
+	 @a osErrorTimeout the message could not be put into the queue in the given time.
+
+	 @note You may call this function from ISR context if the millisec parameter is set to 0.
+	 */
+	osStatus put(const T &data)
+	{
+		core_util_critical_section_enter();
+
+		*tail = data;
+		if (++tail == buf + N)
+			tail = buf;
+
+		if (!thq.empty())
+		{
+			osThreadId_t th = thq.get();
+			if (th)
+				osThreadFlagsSet(th, SIGNAL_QUEUE);
+		}
+
+		core_util_critical_section_exit();
+
+		return osOK;
+	}
+
+	/** Get a message or Wait for a message from a Queue. Messages are retrieved in a descending priority order or
+	 first in first out when the priorities are the same.
+	 @param   pdata     pointer for return value
+	 @param   millisec  timeout value or 0 in case of no time-out. (default: osWaitForever).
+	 @return  status code that indicates the execution status of the function:
+	 @a osOK data retrieved in pdata
+	 @a osEventTimeout no message has arrived during the given timeout period.
+
+	 @note You may call this function from ISR context if the millisec parameter is set to 0.
+	 */
+	osStatus get(T *pdata, uint32_t wait = osWaitForever)
+	{
+		core_util_critical_section_enter();
+
+		// Wait for non-empty
+		while (empty())
+		{
+			if (thq.qwait(wait) == osErrorTimeout)
+			{
+				core_util_critical_section_exit();
+				return osErrorTimeout;
+			}
+		}
+
+		*pdata = *head;
+		if (++head == buf + N)
+			head = buf;
+
+		if (ntf)
+		{
+			ntf(this);
+		}
+
+		core_util_critical_section_exit();
+
+		return osOK;
+	}
+
+	void notify(notify_cb cb)
+	{
+		ntf = cb;
+	}
+
+protected:
+	notify_cb ntf;
+	T buf[N];
+	T* head;
+	T* tail;
+	ThreadQueue thq;
+
+};
+/** @}*/
+/** @}*/
+
+#endif
+
diff -r 000000000000 -r 7cf972f622d3 USBSerial.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBSerial.cpp	Sun Sep 09 19:03:18 2018 +0000
@@ -0,0 +1,190 @@
+/*
+ * USBSerial.cpp
+ *
+ *  Created on: 2018Äê4ÔÂ15ÈÕ
+ *      Author: caoyuan9642
+ */
+
+#include "USBSerial.h"
+#include "usbd_def.h"
+
+InputQueue<char, USBSERIAL_QUEUE_SIZE> USBSerial::rxq;
+OutputQueue<char, USBSERIAL_QUEUE_SIZE> USBSerial::txq;
+USBD_HandleTypeDef USBSerial::hUSBDDevice;
+
+static unsigned char rxbuf[USBSERIAL_QUEUE_SIZE];
+static unsigned char txbuf[USBSERIAL_QUEUE_SIZE];
+
+USBSerial USBSerial::instance;
+
+USBD_CDC_LineCodingTypeDef linecoding =
+{ 115200, /* baud rate*/
+0x00, /* stop bits-1*/
+0x00, /* parity - none*/
+0x08 /* nb. of bits 8*/
+};
+
+int8_t USBSerial::CDC_Init(void)
+{
+	/*Start receiving*/
+	USBD_CDC_SetRxBuffer(&hUSBDDevice, rxbuf);
+	USBD_CDC_ReceivePacket(&hUSBDDevice);
+	return 0;
+}
+
+int8_t USBSerial::CDC_DeInit(void)
+{
+	return 0;
+}
+
+int8_t USBSerial::CDC_Control(uint8_t cmd, uint8_t* pbuf, uint16_t length)
+{
+	switch (cmd)
+	{
+	case CDC_SEND_ENCAPSULATED_COMMAND:
+		/* Add your code here */
+		break;
+
+	case CDC_GET_ENCAPSULATED_RESPONSE:
+		/* Add your code here */
+		break;
+
+	case CDC_SET_COMM_FEATURE:
+		/* Add your code here */
+		break;
+
+	case CDC_GET_COMM_FEATURE:
+		/* Add your code here */
+		break;
+
+	case CDC_CLEAR_COMM_FEATURE:
+		/* Add your code here */
+		break;
+
+	case CDC_SET_LINE_CODING:
+		linecoding.bitrate = (uint32_t) (pbuf[0] | (pbuf[1] << 8)
+				|\
+ (pbuf[2] << 16) | (pbuf[3] << 24));
+		linecoding.format = pbuf[4];
+		linecoding.paritytype = pbuf[5];
+		linecoding.datatype = pbuf[6];
+
+		/* Add your code here */
+		break;
+
+	case CDC_GET_LINE_CODING:
+		pbuf[0] = (uint8_t) (linecoding.bitrate);
+		pbuf[1] = (uint8_t) (linecoding.bitrate >> 8);
+		pbuf[2] = (uint8_t) (linecoding.bitrate >> 16);
+		pbuf[3] = (uint8_t) (linecoding.bitrate >> 24);
+		pbuf[4] = linecoding.format;
+		pbuf[5] = linecoding.paritytype;
+		pbuf[6] = linecoding.datatype;
+
+		/* Add your code here */
+		break;
+
+	case CDC_SET_CONTROL_LINE_STATE:
+		/* Add your code here */
+		break;
+
+	case CDC_SEND_BREAK:
+		/* Add your code here */
+		break;
+
+	default:
+		break;
+	}
+
+	return (0);
+}
+
+void USBSerial::onotify(OutputQueue<char, USBSERIAL_QUEUE_SIZE>* txq)
+{
+	// Data available in output queue
+	core_util_critical_section_enter();
+	USBD_CDC_HandleTypeDef *hcdc =
+			(USBD_CDC_HandleTypeDef*) hUSBDDevice.pClassData;
+	unsigned int len = txq->count();
+
+	if (hcdc->TxState == 0 && len > 0)
+	{
+		// No ongoing transmission
+		unsigned int i;
+		for (i = 0; i < len; i++)
+		{
+			txq->get((char*) &txbuf[i]);
+		}
+		USBD_CDC_SetTxBuffer(&hUSBDDevice, txbuf, i);
+		USBD_CDC_TransmitPacket(&hUSBDDevice);
+	}
+	core_util_critical_section_exit();
+}
+
+void USBSerial::inotify(InputQueue<char, USBSERIAL_QUEUE_SIZE>* rxq)
+{
+	// Space available in queue
+	core_util_critical_section_enter();
+	USBD_CDC_HandleTypeDef *hcdc =
+			(USBD_CDC_HandleTypeDef*) hUSBDDevice.pClassData;
+	unsigned int space = rxq->capacity();
+	if (hcdc->RxState == 0 && space >= CDC_DATA_FS_MAX_PACKET_SIZE)
+	{
+		// No ongoing transmission
+		USBD_CDC_SetRxBuffer(&hUSBDDevice, rxbuf);
+		USBD_CDC_ReceivePacket(&hUSBDDevice);
+	}
+	core_util_critical_section_exit();
+}
+
+int8_t USBSerial::CDC_Received(uint8_t* pbuf, uint32_t* Len)
+{
+	int len = *Len;
+	if (len > rxq.capacity())
+		len = rxq.capacity();
+	for (int i = 0; i < len; i++)
+	{
+		rxq.put(pbuf[i]);
+	}
+	// Prepare for next receive
+	inotify(&rxq);
+	return 0;
+}
+
+int8_t USBSerial::CDC_Transmitted(uint8_t* pbuf, uint32_t* Len)
+{
+	// Check if anything to send
+	onotify(&txq);
+	return 0;
+}
+
+ssize_t USBSerial::read(void* buffer, size_t size)
+{
+	char *p = (char*) buffer;
+	for (unsigned int i = 0; i < size; i++)
+	{
+		rxq.get(&p[i]);
+	}
+	return size;
+}
+
+ssize_t USBSerial::write(const void* buffer, size_t size)
+{
+	char *p = (char*) buffer;
+	for (unsigned int i = 0; i < size; i++)
+	{
+		txq.put(p[i]);
+	}
+	return size;
+}
+
+off_t USBSerial::seek(off_t offset, int whence)
+{
+	return 0;
+}
+
+int USBSerial::close()
+{
+	return 0;
+}
+
diff -r 000000000000 -r 7cf972f622d3 USBSerial.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBSerial.h	Sun Sep 09 19:03:18 2018 +0000
@@ -0,0 +1,134 @@
+/*
+ * USBSerial.h
+ *
+ *  Created on: 2018Äê4ÔÂ15ÈÕ
+ *      Author: caoyuan9642
+ */
+
+#ifndef USB_USBSERIAL_H_
+
+#define USB_USBSERIAL_H_
+
+#include "FileHandle.h"
+#include "usbd_core.h"
+#include "usbd_cdc.h"
+#include "IOQueue.h"
+
+#define USBSERIAL_QUEUE_SIZE (2 * CDC_DATA_FS_MAX_PACKET_SIZE)
+
+class USBSerial: public mbed::FileHandle
+{
+private:
+	static USBD_HandleTypeDef hUSBDDevice;
+	static USBSerial instance;
+	static int8_t CDC_Init(void);
+	static int8_t CDC_DeInit(void);
+	static int8_t CDC_Control(uint8_t cmd, uint8_t* pbuf, uint16_t length);
+	static int8_t CDC_Received(uint8_t* pbuf, uint32_t *Len);
+	static int8_t CDC_Transmitted(uint8_t* pbuf, uint32_t *Len);
+
+	static void onotify(OutputQueue<char, USBSERIAL_QUEUE_SIZE> *);
+	static void inotify(InputQueue<char, USBSERIAL_QUEUE_SIZE> *);
+
+	static InputQueue<char, USBSERIAL_QUEUE_SIZE> rxq;
+	static OutputQueue<char, USBSERIAL_QUEUE_SIZE> txq;
+
+	USBSerial()
+	{
+		USBD_Init(&hUSBDDevice, &USB_Desc, 0);
+		USBD_RegisterClass(&hUSBDDevice, USBD_CDC_CLASS);
+
+		static USBD_CDC_ItfTypeDef cdc_callbacks =
+		{ CDC_Init, CDC_DeInit, CDC_Control, CDC_Received, CDC_Transmitted };
+
+		USBD_CDC_RegisterInterface(&hUSBDDevice, &cdc_callbacks);
+		USBD_Start(&hUSBDDevice);
+		rxq.notify(inotify);
+		txq.notify(onotify);
+	}
+	virtual ~USBSerial()
+	{
+		USBD_Stop(&hUSBDDevice);
+		USBD_DeInit(&hUSBDDevice);
+	}
+public:
+
+	static USBSerial &getInstance()
+	{
+		return instance;
+	}
+
+	/** Read the contents of a file into a buffer
+	 *
+	 *  Devices acting as FileHandles should follow POSIX semantics:
+	 *
+	 *  * if no data is available, and non-blocking set return -EAGAIN
+	 *  * if no data is available, and blocking set, wait until some data is available
+	 *  * If any data is available, call returns immediately
+	 *
+	 *  @param buffer   The buffer to read in to
+	 *  @param size     The number of bytes to read
+	 *  @return         The number of bytes read, 0 at end of file, negative error on failure
+	 */
+	ssize_t read(void *buffer, size_t size);
+
+	/** Write the contents of a buffer to a file
+	 *
+	 *  Devices acting as FileHandles should follow POSIX semantics:
+	 *
+	 * * if blocking, block until all data is written
+	 * * if no data can be written, and non-blocking set, return -EAGAIN
+	 * * if some data can be written, and non-blocking set, write partial
+	 *
+	 *  @param buffer   The buffer to write from
+	 *  @param size     The number of bytes to write
+	 *  @return         The number of bytes written, negative error on failure
+	 */
+	ssize_t write(const void *buffer, size_t size);
+
+	/** Move the file position to a given offset from from a given location
+	 *
+	 *  @param offset   The offset from whence to move to
+	 *  @param whence   The start of where to seek
+	 *      SEEK_SET to start from beginning of file,
+	 *      SEEK_CUR to start from current position in file,
+	 *      SEEK_END to start from end of file
+	 *  @return         The new offset of the file, negative error code on failure
+	 */
+	off_t seek(off_t offset, int whence = SEEK_SET);
+
+	/** Close a file
+	 *
+	 *  @return         0 on success, negative error code on failure
+	 */
+	int close();
+	/** Check if the file in an interactive terminal device
+	 *
+	 *  @return         True if the file is a terminal
+	 *  @return         False if the file is not a terminal
+	 *  @return         Negative error code on failure
+	 */
+	int isatty()
+	{
+		return true;
+	}
+
+	/** Check for poll event flags
+	 * The input parameter can be used or ignored - the could always return all events,
+	 * or could check just the events listed in events.
+	 * Call is non-blocking - returns instantaneous state of events.
+	 * Whenever an event occurs, the derived class should call the sigio() callback).
+	 *
+	 * @param events        bitmask of poll events we're interested in - POLLIN/POLLOUT etc.
+	 *
+	 * @returns             bitmask of poll events that have occurred.
+	 */
+	short poll(short events) const
+	{
+		// Possible default for real files
+		return POLLIN | POLLOUT;
+	}
+};
+
+#endif /* USB_USBSERIAL_H_ */
+
diff -r 000000000000 -r 7cf972f622d3 usbd_cdc.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbd_cdc.c	Sun Sep 09 19:03:18 2018 +0000
@@ -0,0 +1,701 @@
+/**
+ ******************************************************************************
+ * @file    usbd_cdc.c
+ * @author  MCD Application Team
+ * @version V2.4.2
+ * @date    11-December-2015
+ * @brief   This file provides the high layer firmware functions to manage the
+ *          following functionalities of the USB CDC Class:
+ *           - Initialization and Configuration of high and low layer
+ *           - Enumeration as CDC Device (and enumeration for each implemented memory interface)
+ *           - OUT/IN data transfer
+ *           - Command IN transfer (class requests management)
+ *           - Error management
+ *
+ *  @verbatim
+ *
+ *          ===================================================================
+ *                                CDC Class Driver Description
+ *          ===================================================================
+ *           This driver manages the "Universal Serial Bus Class Definitions for Communications Devices
+ *           Revision 1.2 November 16, 2007" and the sub-protocol specification of "Universal Serial Bus
+ *           Communications Class Subclass Specification for PSTN Devices Revision 1.2 February 9, 2007"
+ *           This driver implements the following aspects of the specification:
+ *             - Device descriptor management
+ *             - Configuration descriptor management
+ *             - Enumeration as CDC device with 2 data endpoints (IN and OUT) and 1 command endpoint (IN)
+ *             - Requests management (as described in section 6.2 in specification)
+ *             - Abstract Control Model compliant
+ *             - Union Functional collection (using 1 IN endpoint for control)
+ *             - Data interface class
+ *
+ *           These aspects may be enriched or modified for a specific user application.
+ *
+ *            This driver doesn't implement the following aspects of the specification
+ *            (but it is possible to manage these features with some modifications on this driver):
+ *             - Any class-specific aspect relative to communication classes should be managed by user application.
+ *             - All communication classes other than PSTN are not managed
+ *
+ *  @endverbatim
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2015 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_cdc.h"
+#include "usbd_ctlreq.h"
+
+/** @addtogroup STM32_USB_DEVICE_LIBRARY
+ * @{
+ */
+
+/** @defgroup USBD_CDC 
+ * @brief usbd core module
+ * @{
+ */
+
+/** @defgroup USBD_CDC_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CDC_Private_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CDC_Private_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CDC_Private_FunctionPrototypes
+ * @{
+ */
+
+static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
+
+static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
+
+static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev,
+		USBD_SetupReqTypedef *req);
+
+static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
+
+static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
+
+static uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev);
+
+static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length);
+
+static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length);
+
+static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length);
+
+static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length);
+
+uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length);
+
+/* USB Standard Device Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_CDC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END
+		=
+		{
+		USB_LEN_DEV_QUALIFIER_DESC,
+		USB_DESC_TYPE_DEVICE_QUALIFIER, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
+				0x01, 0x00, };
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CDC_Private_Variables
+ * @{
+ */
+
+/* CDC interface class callbacks structure */
+USBD_ClassTypeDef USBD_CDC =
+{  USBD_CDC_Init, USBD_CDC_DeInit, USBD_CDC_Setup,
+NULL, /* EP0_TxSent, */
+USBD_CDC_EP0_RxReady, USBD_CDC_DataIn, USBD_CDC_DataOut,
+NULL,
+NULL,
+NULL, USBD_CDC_GetHSCfgDesc, USBD_CDC_GetFSCfgDesc,
+		USBD_CDC_GetOtherSpeedCfgDesc, USBD_CDC_GetDeviceQualifierDescriptor, };
+
+/* USB CDC device Configuration Descriptor */
+__ALIGN_BEGIN uint8_t USBD_CDC_CfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
+{
+
+//
+		/*Configuration Descriptor*/
+		0x09, /* bLength: Configuration Descriptor size */
+		USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
+		USB_CDC_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */
+		0x00, 0x02, /* bNumInterfaces: 2 interface */
+		0x01, /* bConfigurationValue: Configuration value */
+		0x00, /* iConfiguration: Index of string descriptor describing the configuration */
+		0xC0, /* bmAttributes: self powered */
+		0x32, /* MaxPower 0 mA */
+
+		/*---------------------------------------------------------------------------*/
+		// 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 */
+		0x09, /* bLength: Interface Descriptor size */
+		USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
+		/* Interface descriptor type */
+		0x00, /* bInterfaceNumber: Number of Interface */
+		0x00, /* bAlternateSetting: Alternate setting */
+		0x01, /* bNumEndpoints: One endpoints used */
+		0x02, /* bInterfaceClass: Communication Interface Class */
+		0x02, /* bInterfaceSubClass: Abstract Control Model */
+		0x01, /* bInterfaceProtocol: Common AT commands */
+		0x00, /* iInterface: */
+
+		/*Header Functional Descriptor*/
+		0x05, /* bLength: Endpoint Descriptor size */
+		0x24, /* bDescriptorType: CS_INTERFACE */
+		0x00, /* bDescriptorSubtype: Header Func Desc */
+		0x10, /* bcdCDC: spec release number */
+		0x01,
+
+		/*Call Management Functional Descriptor*/
+		0x05, /* bFunctionLength */
+		0x24, /* bDescriptorType: CS_INTERFACE */
+		0x01, /* bDescriptorSubtype: Call Management Func Desc */
+		0x03, /* bmCapabilities: D0+D1 */
+		0x01, /* bDataInterface: 1 */
+
+		/*ACM Functional Descriptor*/
+		0x04, /* bFunctionLength */
+		0x24, /* bDescriptorType: CS_INTERFACE */
+		0x02, /* bDescriptorSubtype: Abstract Control Management desc */
+		0x02, /* bmCapabilities */
+
+		/*Union Functional Descriptor*/
+		0x05, /* bFunctionLength */
+		0x24, /* bDescriptorType: CS_INTERFACE */
+		0x06, /* bDescriptorSubtype: Union func desc */
+		0x00, /* bMasterInterface: Communication class interface */
+		0x01, /* bSlaveInterface0: Data Class Interface */
+
+		/*Endpoint 2 Descriptor*/
+		0x07, /* bLength: Endpoint Descriptor size */
+		USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+		CDC_CMD_EP, /* bEndpointAddress */
+		0x03, /* bmAttributes: Interrupt */
+		LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */
+		HIBYTE(CDC_CMD_PACKET_SIZE), 0x10, /* bInterval: */
+		/*---------------------------------------------------------------------------*/
+
+		/*Data class interface descriptor*/
+		0x09, /* bLength: Endpoint Descriptor size */
+		USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
+		0x01, /* bInterfaceNumber: Number of Interface */
+		0x00, /* bAlternateSetting: Alternate setting */
+		0x02, /* bNumEndpoints: Two endpoints used */
+		0x0A, /* bInterfaceClass: CDC */
+		0x00, /* bInterfaceSubClass: */
+		0x00, /* bInterfaceProtocol: */
+		0x00, /* iInterface: */
+
+		/*Endpoint OUT Descriptor*/
+		0x07, /* bLength: Endpoint Descriptor size */
+		USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+		CDC_OUT_EP, /* bEndpointAddress */
+		0x02, /* bmAttributes: Bulk */
+		LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
+		HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), 0x00, /* bInterval: ignore for Bulk transfer */
+
+		/*Endpoint IN Descriptor*/
+		0x07, /* bLength: Endpoint Descriptor size */
+		USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+		CDC_IN_EP, /* bEndpointAddress */
+		0x02, /* bmAttributes: Bulk */
+		LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
+		HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), 0x00 /* bInterval: ignore for Bulk transfer */
+};
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CDC_Private_Functions
+ * @{
+ */
+
+static USBD_CDC_HandleTypeDef usbd_cdc;
+
+/**
+ * @brief  USBD_CDC_Init
+ *         Initialize the CDC interface
+ * @param  pdev: device instance
+ * @param  cfgidx: Configuration index
+ * @retval status
+ */
+static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
+{
+	uint8_t ret = 0;
+	USBD_CDC_HandleTypeDef *hcdc;
+
+	if (pdev->dev_speed == USBD_SPEED_HIGH)
+	{
+		/* Open EP IN */
+		USBD_LL_OpenEP(pdev,
+		CDC_IN_EP,
+		USBD_EP_TYPE_BULK,
+		CDC_DATA_HS_IN_PACKET_SIZE);
+
+		/* Open EP OUT */
+		USBD_LL_OpenEP(pdev,
+		CDC_OUT_EP,
+		USBD_EP_TYPE_BULK,
+		CDC_DATA_HS_OUT_PACKET_SIZE);
+
+	}
+	else
+	{
+		/* Open EP IN */
+		USBD_LL_OpenEP(pdev,
+		CDC_IN_EP,
+		USBD_EP_TYPE_BULK,
+		CDC_DATA_FS_IN_PACKET_SIZE);
+
+		/* Open EP OUT */
+		USBD_LL_OpenEP(pdev,
+		CDC_OUT_EP,
+		USBD_EP_TYPE_BULK,
+		CDC_DATA_FS_OUT_PACKET_SIZE);
+	}
+	/* Open Command IN EP */
+	USBD_LL_OpenEP(pdev,
+	CDC_CMD_EP,
+	USBD_EP_TYPE_INTR,
+	CDC_CMD_PACKET_SIZE);
+
+//  pdev->pClassData = USBD_malloc(sizeof (USBD_CDC_HandleTypeDef));
+	pdev->pClassData = &usbd_cdc;
+
+	if (pdev->pClassData == NULL)
+	{
+		ret = 1;
+	}
+	else
+	{
+		hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
+
+		/* Init  physical Interface components */
+		((USBD_CDC_ItfTypeDef *) pdev->pUserData)->Init();
+
+		/* Init Xfer states */
+		hcdc->TxState = 0;
+		hcdc->RxState = 0;
+
+		if (pdev->dev_speed == USBD_SPEED_HIGH)
+		{
+			/* Prepare Out endpoint to receive next packet */
+			USBD_LL_PrepareReceive(pdev,
+			CDC_OUT_EP, hcdc->RxBuffer,
+			CDC_DATA_HS_OUT_PACKET_SIZE);
+		}
+		else
+		{
+			/* Prepare Out endpoint to receive next packet */
+			USBD_LL_PrepareReceive(pdev,
+			CDC_OUT_EP, hcdc->RxBuffer,
+			CDC_DATA_FS_OUT_PACKET_SIZE);
+		}
+
+	}
+	return ret;
+}
+
+/**
+ * @brief  USBD_CDC_Init
+ *         DeInitialize the CDC layer
+ * @param  pdev: device instance
+ * @param  cfgidx: Configuration index
+ * @retval status
+ */
+static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
+{
+	uint8_t ret = 0;
+
+	/* Open EP IN */
+	USBD_LL_CloseEP(pdev,
+	CDC_IN_EP);
+
+	/* Open EP OUT */
+	USBD_LL_CloseEP(pdev,
+	CDC_OUT_EP);
+
+	/* Open Command IN EP */
+	USBD_LL_CloseEP(pdev,
+	CDC_CMD_EP);
+
+	/* DeInit  physical Interface components */
+	if (pdev->pClassData != NULL)
+	{
+		((USBD_CDC_ItfTypeDef *) pdev->pUserData)->DeInit();
+		//USBD_free(pdev->pClassData);
+		pdev->pClassData = NULL;
+	}
+
+	return ret;
+}
+
+/**
+ * @brief  USBD_CDC_Setup
+ *         Handle the CDC specific requests
+ * @param  pdev: instance
+ * @param  req: usb requests
+ * @retval status
+ */
+static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev,
+		USBD_SetupReqTypedef *req)
+{
+	USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
+	static uint8_t ifalt = 0;
+
+	switch (req->bmRequest & USB_REQ_TYPE_MASK)
+	{
+	case USB_REQ_TYPE_CLASS:
+		if (req->wLength)
+		{
+			if (req->bmRequest & 0x80)
+			{
+				((USBD_CDC_ItfTypeDef *) pdev->pUserData)->Control(
+						req->bRequest, (uint8_t *) hcdc->data, req->wLength);
+				USBD_CtlSendData(pdev, (uint8_t *) hcdc->data, req->wLength);
+			}
+			else
+			{
+				hcdc->CmdOpCode = req->bRequest;
+				hcdc->CmdLength = req->wLength;
+
+				USBD_CtlPrepareRx(pdev, (uint8_t *) hcdc->data, req->wLength);
+			}
+
+		}
+		else
+		{
+			((USBD_CDC_ItfTypeDef *) pdev->pUserData)->Control(req->bRequest,
+					(uint8_t*) req, 0);
+		}
+		break;
+
+	case USB_REQ_TYPE_STANDARD:
+		switch (req->bRequest)
+		{
+		case USB_REQ_GET_INTERFACE:
+			USBD_CtlSendData(pdev, &ifalt, 1);
+			break;
+
+		case USB_REQ_SET_INTERFACE:
+			break;
+		}
+		break;
+
+	default:
+		break;
+	}
+	return USBD_OK;
+}
+
+/**
+ * @brief  USBD_CDC_DataIn
+ *         Data sent on non-control IN endpoint
+ * @param  pdev: device instance
+ * @param  epnum: endpoint number
+ * @retval status
+ */
+static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
+{
+	USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
+
+	if (pdev->pClassData != NULL)
+	{
+
+		hcdc->TxState = 0;
+
+		((USBD_CDC_ItfTypeDef *) pdev->pUserData)->Transmitted(hcdc->TxBuffer,
+				hcdc->TxLength);
+
+		return USBD_OK;
+	}
+	else
+	{
+		return USBD_FAIL;
+	}
+}
+
+/**
+ * @brief  USBD_CDC_DataOut
+ *         Data received on non-control Out endpoint
+ * @param  pdev: device instance
+ * @param  epnum: endpoint number
+ * @retval status
+ */
+static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
+{
+	USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
+
+	/* Get the received data length */
+	hcdc->RxLength = USBD_LL_GetRxDataSize(pdev, epnum);
+	hcdc->RxState = 0;
+
+	/* USB data will be immediately processed, this allow next USB traffic being
+	 NAKed till the end of the application Xfer */
+	if (pdev->pClassData != NULL)
+	{
+		((USBD_CDC_ItfTypeDef *) pdev->pUserData)->Received(hcdc->RxBuffer,
+				&hcdc->RxLength);
+
+		return USBD_OK;
+	}
+	else
+	{
+		return USBD_FAIL;
+	}
+}
+
+/**
+ * @brief  USBD_CDC_DataOut
+ *         Data received on non-control Out endpoint
+ * @param  pdev: device instance
+ * @param  epnum: endpoint number
+ * @retval status
+ */
+static uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev)
+{
+	USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
+
+	if ((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFF))
+	{
+		((USBD_CDC_ItfTypeDef *) pdev->pUserData)->Control(hcdc->CmdOpCode,
+				(uint8_t *) hcdc->data, hcdc->CmdLength);
+		hcdc->CmdOpCode = 0xFF;
+
+	}
+	return USBD_OK;
+}
+
+/**
+ * @brief  USBD_CDC_GetFSCfgDesc
+ *         Return configuration descriptor
+ * @param  speed : current device speed
+ * @param  length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length)
+{
+	*length = USB_CDC_CONFIG_DESC_SIZ;
+	return USBD_CDC_CfgDesc;
+}
+
+/**
+ * @brief  USBD_CDC_GetHSCfgDesc
+ *         Return configuration descriptor
+ * @param  speed : current device speed
+ * @param  length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length)
+{
+	*length = USB_CDC_CONFIG_DESC_SIZ;
+	return USBD_CDC_CfgDesc;
+}
+
+/**
+ * @brief  USBD_CDC_GetCfgDesc
+ *         Return configuration descriptor
+ * @param  speed : current device speed
+ * @param  length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length)
+{
+	*length = USB_CDC_CONFIG_DESC_SIZ;
+	return USBD_CDC_CfgDesc;
+}
+
+/**
+ * @brief  DeviceQualifierDescriptor
+ *         return Device Qualifier descriptor
+ * @param  length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length)
+{
+	*length = sizeof(USBD_CDC_DeviceQualifierDesc);
+	return USBD_CDC_DeviceQualifierDesc;
+}
+
+/**
+ * @brief  USBD_CDC_RegisterInterface
+ * @param  pdev: device instance
+ * @param  fops: CD  Interface callback
+ * @retval status
+ */
+uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev,
+		USBD_CDC_ItfTypeDef *fops)
+{
+	uint8_t ret = USBD_FAIL;
+
+	if (fops != NULL)
+	{
+		pdev->pUserData = fops;
+		ret = USBD_OK;
+	}
+
+	return ret;
+}
+
+/**
+ * @brief  USBD_CDC_SetTxBuffer
+ * @param  pdev: device instance
+ * @param  pbuff: Tx Buffer
+ * @retval status
+ */
+uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff,
+		uint16_t length)
+{
+	USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
+
+	hcdc->TxBuffer = pbuff;
+	hcdc->TxLength = length;
+
+	return USBD_OK;
+}
+
+/**
+ * @brief  USBD_CDC_SetRxBuffer
+ * @param  pdev: device instance
+ * @param  pbuff: Rx Buffer
+ * @retval status
+ */
+uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff)
+{
+	USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
+
+	hcdc->RxBuffer = pbuff;
+
+	return USBD_OK;
+}
+
+/**
+ * @brief  USBD_CDC_DataOut
+ *         Data received on non-control Out endpoint
+ * @param  pdev: device instance
+ * @param  epnum: endpoint number
+ * @retval status
+ */
+uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev)
+{
+	USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
+
+	if (pdev->pClassData != NULL)
+	{
+		if (hcdc->TxState == 0)
+		{
+			/* Tx Transfer in progress */
+			hcdc->TxState = 1;
+
+			/* Transmit next packet */
+			USBD_LL_Transmit(pdev,
+			CDC_IN_EP, hcdc->TxBuffer, hcdc->TxLength);
+
+			return USBD_OK;
+		}
+		else
+		{
+			return USBD_BUSY;
+		}
+	}
+	else
+	{
+		return USBD_FAIL;
+	}
+}
+
+/**
+ * @brief  USBD_CDC_ReceivePacket
+ *         prepare OUT Endpoint for reception
+ * @param  pdev: device instance
+ * @retval status
+ */
+uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev)
+{
+	USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
+
+	/* Suspend or Resume USB Out process */
+	if (pdev->pClassData != NULL)
+	{
+		hcdc->RxState = 1;
+		if (pdev->dev_speed == USBD_SPEED_HIGH)
+		{
+			/* Prepare Out endpoint to receive next packet */
+			USBD_LL_PrepareReceive(pdev,
+			CDC_OUT_EP, hcdc->RxBuffer,
+			CDC_DATA_HS_OUT_PACKET_SIZE);
+		}
+		else
+		{
+			/* Prepare Out endpoint to receive next packet */
+			USBD_LL_PrepareReceive(pdev,
+			CDC_OUT_EP, hcdc->RxBuffer,
+			CDC_DATA_FS_OUT_PACKET_SIZE);
+		}
+		return USBD_OK;
+	}
+	else
+	{
+		return USBD_FAIL;
+	}
+}
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff -r 000000000000 -r 7cf972f622d3 usbd_cdc.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbd_cdc.h	Sun Sep 09 19:03:18 2018 +0000
@@ -0,0 +1,182 @@
+/**
+  ******************************************************************************
+  * @file    usbd_cdc.h
+  * @author  MCD Application Team
+  * @version V2.4.2
+  * @date    11-December-2015
+  * @brief   header file for the usbd_cdc.c file.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT 2015 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.
+  *
+  ******************************************************************************
+  */ 
+ 
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_CDC_H
+#define __USB_CDC_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include  "usbd_ioreq.h"
+#include "usbd_desc.h"
+
+/** @addtogroup STM32_USB_DEVICE_LIBRARY
+  * @{
+  */
+  
+/** @defgroup usbd_cdc
+  * @brief This file is the Header file for usbd_cdc.c
+  * @{
+  */ 
+
+
+/** @defgroup usbd_cdc_Exported_Defines
+  * @{
+  */ 
+#define CDC_IN_EP                                   0x81  /* EP1 for data IN */
+#define CDC_OUT_EP                                  0x01  /* EP1 for data OUT */
+#define CDC_CMD_EP                                  0x82  /* EP2 for CDC commands */
+
+/* CDC Endpoints parameters: you can fine tune these values depending on the needed baudrates and performance. */
+#define CDC_DATA_HS_MAX_PACKET_SIZE                 512  /* Endpoint IN & OUT Packet size */
+#define CDC_DATA_FS_MAX_PACKET_SIZE                 64  /* Endpoint IN & OUT Packet size */
+#define CDC_CMD_PACKET_SIZE                         8  /* Control Endpoint Packet size */ 
+
+#define USB_CDC_CONFIG_DESC_SIZ                     75
+#define CDC_DATA_HS_IN_PACKET_SIZE                  CDC_DATA_HS_MAX_PACKET_SIZE
+#define CDC_DATA_HS_OUT_PACKET_SIZE                 CDC_DATA_HS_MAX_PACKET_SIZE
+
+#define CDC_DATA_FS_IN_PACKET_SIZE                  CDC_DATA_FS_MAX_PACKET_SIZE
+#define CDC_DATA_FS_OUT_PACKET_SIZE                 CDC_DATA_FS_MAX_PACKET_SIZE
+
+/*---------------------------------------------------------------------*/
+/*  CDC definitions                                                    */
+/*---------------------------------------------------------------------*/
+#define CDC_SEND_ENCAPSULATED_COMMAND               0x00
+#define CDC_GET_ENCAPSULATED_RESPONSE               0x01
+#define CDC_SET_COMM_FEATURE                        0x02
+#define CDC_GET_COMM_FEATURE                        0x03
+#define CDC_CLEAR_COMM_FEATURE                      0x04
+#define CDC_SET_LINE_CODING                         0x20
+#define CDC_GET_LINE_CODING                         0x21
+#define CDC_SET_CONTROL_LINE_STATE                  0x22
+#define CDC_SEND_BREAK                              0x23
+
+/**
+  * @}
+  */ 
+
+
+/** @defgroup USBD_CORE_Exported_TypesDefinitions
+  * @{
+  */
+
+/**
+  * @}
+  */ 
+typedef struct
+{
+  uint32_t bitrate;
+  uint8_t  format;
+  uint8_t  paritytype;
+  uint8_t  datatype;
+}USBD_CDC_LineCodingTypeDef;
+
+typedef struct _USBD_CDC_Itf
+{
+  int8_t (* Init)          (void);
+  int8_t (* DeInit)        (void);
+  int8_t (* Control)       (uint8_t, uint8_t * , uint16_t);   
+  int8_t (* Received)      (uint8_t *, uint32_t *);
+  int8_t (* Transmitted)   (uint8_t *, uint32_t *);
+
+}USBD_CDC_ItfTypeDef;
+
+
+typedef struct
+{
+  uint32_t data[CDC_DATA_HS_MAX_PACKET_SIZE/4];      /* Force 32bits alignment */
+  uint8_t  CmdOpCode;
+  uint8_t  CmdLength;    
+  uint8_t  *RxBuffer;  
+  uint8_t  *TxBuffer;   
+  uint32_t RxLength;
+  uint32_t TxLength;    
+  
+  __IO uint32_t TxState;     
+  __IO uint32_t RxState;    
+}
+USBD_CDC_HandleTypeDef; 
+
+
+
+/** @defgroup USBD_CORE_Exported_Macros
+  * @{
+  */ 
+  
+/**
+  * @}
+  */ 
+
+/** @defgroup USBD_CORE_Exported_Variables
+  * @{
+  */ 
+
+extern USBD_ClassTypeDef  USBD_CDC;
+#define USBD_CDC_CLASS    &USBD_CDC
+/**
+  * @}
+  */ 
+
+/** @defgroup USB_CORE_Exported_Functions
+  * @{
+  */
+uint8_t  USBD_CDC_RegisterInterface  (USBD_HandleTypeDef   *pdev, 
+                                      USBD_CDC_ItfTypeDef *fops);
+
+uint8_t  USBD_CDC_SetTxBuffer        (USBD_HandleTypeDef   *pdev,
+                                      uint8_t  *pbuff,
+                                      uint16_t length);
+
+uint8_t  USBD_CDC_SetRxBuffer        (USBD_HandleTypeDef   *pdev,
+                                      uint8_t  *pbuff);
+  
+uint8_t  USBD_CDC_ReceivePacket      (USBD_HandleTypeDef *pdev);
+
+uint8_t  USBD_CDC_TransmitPacket     (USBD_HandleTypeDef *pdev);
+/**
+  * @}
+  */ 
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* __USB_CDC_H */
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+  
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff -r 000000000000 -r 7cf972f622d3 usbd_conf.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbd_conf.c	Sun Sep 09 19:03:18 2018 +0000
@@ -0,0 +1,423 @@
+/**
+ ******************************************************************************
+ * @file    usbd_conf_template.c
+ * @author  MCD Application Team
+ * @version V2.4.2
+ * @date    11-December-2015
+ * @brief   USB Device configuration and interface file
+ *          This template should be copied to the user folder, renamed and customized
+ *          following user needs.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2015 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_core.h"
+#include "stm32f4xx_hal.h"
+#include "pinmap.h"
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+PCD_HandleTypeDef hpcd;
+void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
+{
+	pin_function(PB_14,
+			STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_OTG_HS_FS)); // DM
+	pin_function(PB_15,
+			STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_OTG_HS_FS)); // DP
+	pin_function(PB_13,
+			STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, GPIO_AF12_OTG_HS_FS)); // VBUS
+	__HAL_RCC_USB_OTG_HS_CLK_ENABLE()
+	;
+
+	NVIC_SetPriority(OTG_HS_IRQn, 1);
+}
+
+/**
+ * @brief  DeInitializes the PCD MSP.
+ * @param  hpcd: PCD handle
+ * @retval None
+ */
+void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd)
+{
+	/* Disable USB FS Clocks */
+	__HAL_RCC_USB_OTG_HS_CLK_ENABLE()
+	;
+}
+
+/*******************************************************************************
+ LL Driver Callbacks (PCD -> USB Device Library)
+ *******************************************************************************/
+
+/**
+ * @brief  SOF callback.
+ * @param  hpcd: PCD handle
+ * @retval None
+ */
+void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
+{
+	USBD_LL_SetupStage(hpcd->pData, (uint8_t *) hpcd->Setup);
+}
+
+/**
+ * @brief  SOF callback.
+ * @param  hpcd: PCD handle
+ * @retval None
+ */
+void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
+{
+	USBD_LL_DataOutStage(hpcd->pData, epnum, hpcd->OUT_ep[epnum].xfer_buff);
+}
+
+/**
+ * @brief  SOF callback.
+ * @param  hpcd: PCD handle
+ * @retval None
+ */
+void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
+{
+	USBD_LL_DataInStage(hpcd->pData, epnum, hpcd->IN_ep[epnum].xfer_buff);
+}
+
+/**
+ * @brief  SOF callback.
+ * @param  hpcd: PCD handle
+ * @retval None
+ */
+void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
+{
+	USBD_LL_SOF(hpcd->pData);
+}
+
+/**
+ * @brief  SOF callback.
+ * @param  hpcd: PCD handle
+ * @retval None
+ */
+void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
+{
+	USBD_SpeedTypeDef speed = USBD_SPEED_FULL;
+
+	/*Set USB Current Speed*/
+	switch (hpcd->Init.speed)
+	{
+	case PCD_SPEED_HIGH:
+		speed = USBD_SPEED_HIGH;
+		break;
+
+	case PCD_SPEED_FULL:
+		speed = USBD_SPEED_FULL;
+		break;
+
+	default:
+		speed = USBD_SPEED_FULL;
+		break;
+	}
+	USBD_LL_SetSpeed(hpcd->pData, speed);
+
+	/*Reset Device*/
+	USBD_LL_Reset(hpcd->pData);
+}
+
+/**
+ * @brief  SOF callback.
+ * @param  hpcd: PCD handle
+ * @retval None
+ */
+void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
+{
+	USBD_LL_Suspend(hpcd->pData);
+}
+
+/**
+ * @brief  SOF callback.
+ * @param  hpcd: PCD handle
+ * @retval None
+ */
+void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
+{
+	USBD_LL_Resume(hpcd->pData);
+}
+
+/**
+ * @brief  SOF callback.
+ * @param  hpcd: PCD handle
+ * @retval None
+ */
+void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
+{
+	USBD_LL_IsoOUTIncomplete(hpcd->pData, epnum);
+}
+
+/**
+ * @brief  SOF callback.
+ * @param  hpcd: PCD handle
+ * @retval None
+ */
+void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
+{
+	USBD_LL_IsoINIncomplete(hpcd->pData, epnum);
+}
+
+/**
+ * @brief  SOF callback.
+ * @param  hpcd: PCD handle
+ * @retval None
+ */
+void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
+{
+	USBD_LL_DevConnected(hpcd->pData);
+}
+
+/**
+ * @brief  SOF callback.
+ * @param  hpcd: PCD handle
+ * @retval None
+ */
+void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
+{
+	USBD_LL_DevDisconnected(hpcd->pData);
+}
+
+/**
+ * @brief  Initializes the Low Level portion of the Device driver.
+ * @param  pdev: Device handle
+ * @retval USBD Status
+ */
+USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev)
+{
+	/*Set LL Driver parameters */
+	hpcd.Instance = USB_OTG_HS;
+	hpcd.Init.dev_endpoints = 4;
+	hpcd.Init.use_dedicated_ep1 = 0;
+	hpcd.Init.ep0_mps = 0x40;
+	hpcd.Init.dma_enable = 0;
+	hpcd.Init.low_power_enable = 0;
+	hpcd.Init.phy_itface = PCD_PHY_EMBEDDED;
+	hpcd.Init.Sof_enable = 0;
+	hpcd.Init.speed = PCD_SPEED_HIGH;
+	hpcd.Init.vbus_sensing_enable = 1;
+	/* Link The driver to the stack */
+	hpcd.pData = pdev;
+	pdev->pData = &hpcd;
+	/*Initialize LL Driver */
+	HAL_PCD_Init(&hpcd);
+
+	HAL_PCDEx_SetRxFiFo(&hpcd, 0x80);
+	HAL_PCDEx_SetTxFiFo(&hpcd, 0, 0x40);
+	HAL_PCDEx_SetTxFiFo(&hpcd, 1, 0x80);
+	HAL_PCDEx_SetTxFiFo(&hpcd, 2, 0x80);
+	HAL_PCDEx_SetTxFiFo(&hpcd, 3, 0x80);
+	return USBD_OK;
+}
+
+/**
+ * @brief  De-Initializes the Low Level portion of the Device driver.
+ * @param  pdev: Device handle
+ * @retval USBD Status
+ */
+USBD_StatusTypeDef USBD_LL_DeInit(USBD_HandleTypeDef *pdev)
+{
+	HAL_PCD_DeInit(pdev->pData);
+	return USBD_OK;
+}
+
+/**
+ * @brief  Starts the Low Level portion of the Device driver.
+ * @param  pdev: Device handle
+ * @retval USBD Status
+ */
+USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev)
+{
+	HAL_PCD_Start(pdev->pData);
+	NVIC_EnableIRQ(OTG_HS_IRQn);
+	return USBD_OK;
+}
+
+/**
+ * @brief  Stops the Low Level portion of the Device driver.
+ * @param  pdev: Device handle
+ * @retval USBD Status
+ */
+USBD_StatusTypeDef USBD_LL_Stop(USBD_HandleTypeDef *pdev)
+{
+	HAL_PCD_Stop(pdev->pData);
+	NVIC_DisableIRQ(OTG_HS_IRQn);
+	return USBD_OK;
+}
+
+/**
+ * @brief  Opens an endpoint of the Low Level Driver.
+ * @param  pdev: Device handle
+ * @param  ep_addr: Endpoint Number
+ * @param  ep_type: Endpoint Type
+ * @param  ep_mps: Endpoint Max Packet Size
+ * @retval USBD Status
+ */
+USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr,
+		uint8_t ep_type, uint16_t ep_mps)
+{
+	HAL_PCD_EP_Open(pdev->pData, ep_addr, ep_mps, ep_type);
+	return USBD_OK;
+}
+
+/**
+ * @brief  Closes an endpoint of the Low Level Driver.
+ * @param  pdev: Device handle
+ * @param  ep_addr: Endpoint Number
+ * @retval USBD Status
+ */
+USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
+{
+	HAL_PCD_EP_Close(pdev->pData, ep_addr);
+	return USBD_OK;
+}
+
+/**
+ * @brief  Flushes an endpoint of the Low Level Driver.
+ * @param  pdev: Device handle
+ * @param  ep_addr: Endpoint Number
+ * @retval USBD Status
+ */
+USBD_StatusTypeDef USBD_LL_FlushEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
+{
+	HAL_PCD_EP_Flush(pdev->pData, ep_addr);
+	return USBD_OK;
+}
+
+/**
+ * @brief  Sets a Stall condition on an endpoint of the Low Level Driver.
+ * @param  pdev: Device handle
+ * @param  ep_addr: Endpoint Number
+ * @retval USBD Status
+ */
+USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
+{
+	HAL_PCD_EP_SetStall(pdev->pData, ep_addr);
+	return USBD_OK;
+}
+
+/**
+ * @brief  Clears a Stall condition on an endpoint of the Low Level Driver.
+ * @param  pdev: Device handle
+ * @param  ep_addr: Endpoint Number
+ * @retval USBD Status
+ */
+USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef *pdev,
+		uint8_t ep_addr)
+{
+	HAL_PCD_EP_ClrStall(pdev->pData, ep_addr);
+	return USBD_OK;
+}
+
+/**
+ * @brief  Returns Stall condition.
+ * @param  pdev: Device handle
+ * @param  ep_addr: Endpoint Number
+ * @retval Stall (1: Yes, 0: No)
+ */
+uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
+{
+	PCD_HandleTypeDef *hpcd = pdev->pData;
+
+	if ((ep_addr & 0x80) == 0x80)
+	{
+		return hpcd->IN_ep[ep_addr & 0x7F].is_stall;
+	}
+	else
+	{
+		return hpcd->OUT_ep[ep_addr & 0x7F].is_stall;
+	}
+	return 0;
+}
+
+/**
+ * @brief  Assigns a USB address to the device.
+ * @param  pdev: Device handle
+ * @param  ep_addr: Endpoint Number
+ * @retval USBD Status
+ */
+USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev,
+		uint8_t dev_addr)
+{
+	HAL_PCD_SetAddress(pdev->pData, dev_addr);
+	return USBD_OK;
+}
+
+/**
+ * @brief  Transmits data over an endpoint.
+ * @param  pdev: Device handle
+ * @param  ep_addr: Endpoint Number
+ * @param  pbuf: Pointer to data to be sent
+ * @param  size: Data size
+ * @retval USBD Status
+ */
+USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, uint8_t ep_addr,
+		uint8_t *pbuf, uint16_t size)
+{
+	HAL_PCD_EP_Transmit(pdev->pData, ep_addr, pbuf, size);
+	return USBD_OK;
+}
+
+/**
+ * @brief  Prepares an endpoint for reception.
+ * @param  pdev: Device handle
+ * @param  ep_addr: Endpoint Number
+ * @param  pbuf: Pointer to data to be received
+ * @param  size: Data size
+ * @retval USBD Status
+ */
+USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev,
+		uint8_t ep_addr, uint8_t *pbuf, uint16_t size)
+{
+	HAL_PCD_EP_Receive(pdev->pData, ep_addr, pbuf, size);
+	return USBD_OK;
+}
+
+/**
+ * @brief  Returns the last transferred packet size.
+ * @param  pdev: Device handle
+ * @param  ep_addr: Endpoint Number
+ * @retval Recived Data Size
+ */
+uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
+{
+	return HAL_PCD_EP_GetRxCount(pdev->pData, ep_addr);
+}
+
+/**
+ * @brief  Delays routine for the USB Device Library.
+ * @param  Delay: Delay in ms
+ * @retval None
+ */
+void USBD_LL_Delay(uint32_t Delay)
+{
+	HAL_Delay(Delay);
+}
+
+void OTG_HS_IRQHandler(void)
+{
+	HAL_PCD_IRQHandler(&hpcd);
+}
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
+
diff -r 000000000000 -r 7cf972f622d3 usbd_conf.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbd_conf.h	Sun Sep 09 19:03:18 2018 +0000
@@ -0,0 +1,170 @@
+/**
+  ******************************************************************************
+  * @file    usbd_conf_template.h
+  * @author  MCD Application Team
+  * @version V2.4.2
+  * @date    11-December-2015
+  * @brief   Header file for the usbd_conf_template.c file
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT 2015 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.
+  *
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USBD_CONF_TEMPLATE_H
+#define __USBD_CONF_TEMPLATE_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx.h"  /* replace 'stm32xxx' with your HAL driver header filename, ex: stm32f4xx.h */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/** @addtogroup STM32_USB_DEVICE_LIBRARY
+  * @{
+  */
+  
+/** @defgroup USBD_CONF
+  * @brief USB device low level driver configuration file
+  * @{
+  */ 
+
+/** @defgroup USBD_CONF_Exported_Defines
+  * @{
+  */ 
+
+#define USBD_MAX_NUM_INTERFACES               1
+#define USBD_MAX_NUM_CONFIGURATION            1
+#define USBD_MAX_STR_DESC_SIZ                 0x100
+#define USBD_SUPPORT_USER_STRING              0 
+#define USBD_SELF_POWERED                     1
+#define USBD_DEBUG_LEVEL                      2
+
+/* MSC Class Config */
+#define MSC_MEDIA_PACKET                       8192   
+
+/* CDC Class Config */
+#define USBD_CDC_INTERVAL                      2000  
+
+ /* DFU Class Config */
+#define USBD_DFU_MAX_ITF_NUM                   1
+#define USBD_DFU_XFERS_IZE                     1024
+
+ /* AUDIO Class Config */
+#define USBD_AUDIO_FREQ                       22100 
+
+/** @defgroup USBD_Exported_Macros
+  * @{
+  */ 
+
+ /* Memory management macros */   
+#define USBD_malloc               malloc
+#define USBD_free                 free
+#define USBD_memset               memset
+#define USBD_memcpy               memcpy
+    
+ /* DEBUG macros */  
+
+  
+#if (USBD_DEBUG_LEVEL > 0)
+#define  USBD_UsrLog(...)   printf(__VA_ARGS__);\
+                            printf("\n");
+#else
+#define USBD_UsrLog(...)   
+#endif 
+                            
+                            
+#if (USBD_DEBUG_LEVEL > 1)
+
+#define  USBD_ErrLog(...)   printf("ERROR: ") ;\
+                            printf(__VA_ARGS__);\
+                            printf("\n");
+#else
+#define USBD_ErrLog(...)   
+#endif 
+                            
+                            
+#if (USBD_DEBUG_LEVEL > 2)                         
+#define  USBD_DbgLog(...)   printf("DEBUG : ") ;\
+                            printf(__VA_ARGS__);\
+                            printf("\n");
+#else
+#define USBD_DbgLog(...)                         
+#endif
+                            
+/**
+  * @}
+  */ 
+ 
+    
+    
+/**
+  * @}
+  */ 
+
+
+/** @defgroup USBD_CONF_Exported_Types
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+
+
+/** @defgroup USBD_CONF_Exported_Macros
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+
+/** @defgroup USBD_CONF_Exported_Variables
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+
+/** @defgroup USBD_CONF_Exported_FunctionsPrototype
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __USBD_CONF_TEMPLATE_H */
+
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
+
diff -r 000000000000 -r 7cf972f622d3 usbd_core.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbd_core.c	Sun Sep 09 19:03:18 2018 +0000
@@ -0,0 +1,566 @@
+/**
+  ******************************************************************************
+  * @file    usbd_core.c
+  * @author  MCD Application Team
+  * @version V2.4.2
+  * @date    11-December-2015
+  * @brief   This file provides all the USBD core functions.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT 2015 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.
+  *
+  ******************************************************************************
+  */ 
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_core.h"
+
+/** @addtogroup STM32_USBD_DEVICE_LIBRARY
+* @{
+*/
+
+
+/** @defgroup USBD_CORE 
+* @brief usbd core module
+* @{
+*/ 
+
+/** @defgroup USBD_CORE_Private_TypesDefinitions
+* @{
+*/ 
+/**
+* @}
+*/ 
+
+
+/** @defgroup USBD_CORE_Private_Defines
+* @{
+*/ 
+
+/**
+* @}
+*/ 
+
+
+/** @defgroup USBD_CORE_Private_Macros
+* @{
+*/ 
+/**
+* @}
+*/ 
+
+
+
+
+/** @defgroup USBD_CORE_Private_FunctionPrototypes
+* @{
+*/ 
+
+/**
+* @}
+*/ 
+
+/** @defgroup USBD_CORE_Private_Variables
+* @{
+*/ 
+
+/**
+* @}
+*/ 
+
+/** @defgroup USBD_CORE_Private_Functions
+* @{
+*/ 
+
+/**
+* @brief  USBD_Init
+*         Initializes the device stack and load the class driver
+* @param  pdev: device instance
+* @param  pdesc: Descriptor structure address
+* @param  id: Low level core index
+* @retval None
+*/
+USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, USBD_DescriptorsTypeDef *pdesc, uint8_t id)
+{
+  /* Check whether the USB Host handle is valid */
+  if(pdev == NULL)
+  {
+    USBD_ErrLog("Invalid Device handle");
+    return USBD_FAIL; 
+  }
+  
+  /* Unlink previous class*/
+  if(pdev->pClass != NULL)
+  {
+    pdev->pClass = NULL;
+  }
+  
+  /* Assign USBD Descriptors */
+  if(pdesc != NULL)
+  {
+    pdev->pDesc = pdesc;
+  }
+  
+  /* Set Device initial State */
+  pdev->dev_state  = USBD_STATE_DEFAULT;
+  pdev->id = id;
+  /* Initialize low level driver */
+  USBD_LL_Init(pdev);
+  
+  return USBD_OK; 
+}
+
+/**
+* @brief  USBD_DeInit 
+*         Re-Initialize th device library
+* @param  pdev: device instance
+* @retval status: status
+*/
+USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev)
+{
+  /* Set Default State */
+  pdev->dev_state  = USBD_STATE_DEFAULT;
+  
+  /* Free Class Resources */
+  pdev->pClass->DeInit(pdev, pdev->dev_config);  
+  
+    /* Stop the low level driver  */
+  USBD_LL_Stop(pdev); 
+  
+  /* Initialize low level driver */
+  USBD_LL_DeInit(pdev);
+  
+  return USBD_OK;
+}
+
+
+/**
+  * @brief  USBD_RegisterClass 
+  *         Link class driver to Device Core.
+  * @param  pDevice : Device Handle
+  * @param  pclass: Class handle
+  * @retval USBD Status
+  */
+USBD_StatusTypeDef  USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass)
+{
+  USBD_StatusTypeDef   status = USBD_OK;
+  if(pclass != 0)
+  {
+    /* link the class to the USB Device handle */
+    pdev->pClass = pclass;
+    status = USBD_OK;
+  }
+  else
+  {
+    USBD_ErrLog("Invalid Class handle");
+    status = USBD_FAIL; 
+  }
+  
+  return status;
+}
+
+/**
+  * @brief  USBD_Start 
+  *         Start the USB Device Core.
+  * @param  pdev: Device Handle
+  * @retval USBD Status
+  */
+USBD_StatusTypeDef  USBD_Start  (USBD_HandleTypeDef *pdev)
+{
+  
+  /* Start the low level driver  */
+  USBD_LL_Start(pdev); 
+  
+  return USBD_OK;  
+}
+
+/**
+  * @brief  USBD_Stop 
+  *         Stop the USB Device Core.
+  * @param  pdev: Device Handle
+  * @retval USBD Status
+  */
+USBD_StatusTypeDef  USBD_Stop   (USBD_HandleTypeDef *pdev)
+{
+  /* Free Class Resources */
+  pdev->pClass->DeInit(pdev, pdev->dev_config);  
+
+  /* Stop the low level driver  */
+  USBD_LL_Stop(pdev); 
+  
+  return USBD_OK;  
+}
+
+/**
+* @brief  USBD_RunTestMode 
+*         Launch test mode process
+* @param  pdev: device instance
+* @retval status
+*/
+USBD_StatusTypeDef  USBD_RunTestMode (USBD_HandleTypeDef  *pdev) 
+{
+  return USBD_OK;
+}
+
+
+/**
+* @brief  USBD_SetClassConfig 
+*        Configure device and start the interface
+* @param  pdev: device instance
+* @param  cfgidx: configuration index
+* @retval status
+*/
+
+USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef  *pdev, uint8_t cfgidx)
+{
+  USBD_StatusTypeDef   ret = USBD_FAIL;
+  
+  if(pdev->pClass != NULL)
+  {
+    /* Set configuration  and Start the Class*/
+    if(pdev->pClass->Init(pdev, cfgidx) == 0)
+    {
+      ret = USBD_OK;
+    }
+  }
+  return ret; 
+}
+
+/**
+* @brief  USBD_ClrClassConfig 
+*         Clear current configuration
+* @param  pdev: device instance
+* @param  cfgidx: configuration index
+* @retval status: USBD_StatusTypeDef
+*/
+USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef  *pdev, uint8_t cfgidx)
+{
+  /* Clear configuration  and De-initialize the Class process*/
+  pdev->pClass->DeInit(pdev, cfgidx);  
+  return USBD_OK;
+}
+
+
+/**
+* @brief  USBD_SetupStage 
+*         Handle the setup stage
+* @param  pdev: device instance
+* @retval status
+*/
+USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup)
+{
+
+  USBD_ParseSetupRequest(&pdev->request, psetup);
+  
+  pdev->ep0_state = USBD_EP0_SETUP;
+  pdev->ep0_data_len = pdev->request.wLength;
+  
+  switch (pdev->request.bmRequest & 0x1F) 
+  {
+  case USB_REQ_RECIPIENT_DEVICE:   
+    USBD_StdDevReq (pdev, &pdev->request);
+    break;
+    
+  case USB_REQ_RECIPIENT_INTERFACE:     
+    USBD_StdItfReq(pdev, &pdev->request);
+    break;
+    
+  case USB_REQ_RECIPIENT_ENDPOINT:        
+    USBD_StdEPReq(pdev, &pdev->request);   
+    break;
+    
+  default:           
+    USBD_LL_StallEP(pdev , pdev->request.bmRequest & 0x80);
+    break;
+  }  
+  return USBD_OK;  
+}
+
+/**
+* @brief  USBD_DataOutStage 
+*         Handle data OUT stage
+* @param  pdev: device instance
+* @param  epnum: endpoint index
+* @retval status
+*/
+USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev , uint8_t epnum, uint8_t *pdata)
+{
+  USBD_EndpointTypeDef    *pep;
+  
+  if(epnum == 0) 
+  {
+    pep = &pdev->ep_out[0];
+    
+    if ( pdev->ep0_state == USBD_EP0_DATA_OUT)
+    {
+      if(pep->rem_length > pep->maxpacket)
+      {
+        pep->rem_length -=  pep->maxpacket;
+       
+        USBD_CtlContinueRx (pdev, 
+                            pdata,
+                            MIN(pep->rem_length ,pep->maxpacket));
+      }
+      else
+      {
+        if((pdev->pClass->EP0_RxReady != NULL)&&
+           (pdev->dev_state == USBD_STATE_CONFIGURED))
+        {
+          pdev->pClass->EP0_RxReady(pdev); 
+        }
+        USBD_CtlSendStatus(pdev);
+      }
+    }
+  }
+  else if((pdev->pClass->DataOut != NULL)&&
+          (pdev->dev_state == USBD_STATE_CONFIGURED))
+  {
+    pdev->pClass->DataOut(pdev, epnum); 
+  }  
+  return USBD_OK;
+}
+
+/**
+* @brief  USBD_DataInStage 
+*         Handle data in stage
+* @param  pdev: device instance
+* @param  epnum: endpoint index
+* @retval status
+*/
+USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev ,uint8_t epnum, uint8_t *pdata)
+{
+  USBD_EndpointTypeDef    *pep;
+    
+  if(epnum == 0) 
+  {
+    pep = &pdev->ep_in[0];
+    
+    if ( pdev->ep0_state == USBD_EP0_DATA_IN)
+    {
+      if(pep->rem_length > pep->maxpacket)
+      {
+        pep->rem_length -=  pep->maxpacket;
+        
+        USBD_CtlContinueSendData (pdev, 
+                                  pdata, 
+                                  pep->rem_length);
+        
+        /* Prepare endpoint for premature end of transfer */
+        USBD_LL_PrepareReceive (pdev,
+                                0,
+                                NULL,
+                                0);  
+      }
+      else
+      { /* last packet is MPS multiple, so send ZLP packet */
+        if((pep->total_length % pep->maxpacket == 0) &&
+           (pep->total_length >= pep->maxpacket) &&
+             (pep->total_length < pdev->ep0_data_len ))
+        {
+          
+          USBD_CtlContinueSendData(pdev , NULL, 0);
+          pdev->ep0_data_len = 0;
+          
+        /* Prepare endpoint for premature end of transfer */
+        USBD_LL_PrepareReceive (pdev,
+                                0,
+                                NULL,
+                                0);
+        }
+        else
+        {
+          if((pdev->pClass->EP0_TxSent != NULL)&&
+             (pdev->dev_state == USBD_STATE_CONFIGURED))
+          {
+            pdev->pClass->EP0_TxSent(pdev); 
+          }          
+          USBD_CtlReceiveStatus(pdev);
+        }
+      }
+    }
+    if (pdev->dev_test_mode == 1)
+    {
+      USBD_RunTestMode(pdev); 
+      pdev->dev_test_mode = 0;
+    }
+  }
+  else if((pdev->pClass->DataIn != NULL)&& 
+          (pdev->dev_state == USBD_STATE_CONFIGURED))
+  {
+    pdev->pClass->DataIn(pdev, epnum); 
+  }  
+  return USBD_OK;
+}
+
+/**
+* @brief  USBD_LL_Reset 
+*         Handle Reset event
+* @param  pdev: device instance
+* @retval status
+*/
+
+USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef  *pdev)
+{
+  /* Open EP0 OUT */
+  USBD_LL_OpenEP(pdev,
+              0x00,
+              USBD_EP_TYPE_CTRL,
+              USB_MAX_EP0_SIZE);
+  
+  pdev->ep_out[0].maxpacket = USB_MAX_EP0_SIZE;
+  
+  /* Open EP0 IN */
+  USBD_LL_OpenEP(pdev,
+              0x80,
+              USBD_EP_TYPE_CTRL,
+              USB_MAX_EP0_SIZE);
+  
+  pdev->ep_in[0].maxpacket = USB_MAX_EP0_SIZE;
+  /* Upon Reset call user call back */
+  pdev->dev_state = USBD_STATE_DEFAULT;
+  
+  if (pdev->pClassData) 
+    pdev->pClass->DeInit(pdev, pdev->dev_config);  
+ 
+  
+  return USBD_OK;
+}
+
+
+
+
+/**
+* @brief  USBD_LL_Reset 
+*         Handle Reset event
+* @param  pdev: device instance
+* @retval status
+*/
+USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef  *pdev, USBD_SpeedTypeDef speed)
+{
+  pdev->dev_speed = speed;
+  return USBD_OK;
+}
+
+/**
+* @brief  USBD_Suspend 
+*         Handle Suspend event
+* @param  pdev: device instance
+* @retval status
+*/
+
+USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef  *pdev)
+{
+  pdev->dev_old_state =  pdev->dev_state;
+  pdev->dev_state  = USBD_STATE_SUSPENDED;
+  return USBD_OK;
+}
+
+/**
+* @brief  USBD_Resume 
+*         Handle Resume event
+* @param  pdev: device instance
+* @retval status
+*/
+
+USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef  *pdev)
+{
+  pdev->dev_state = pdev->dev_old_state;  
+  return USBD_OK;
+}
+
+/**
+* @brief  USBD_SOF 
+*         Handle SOF event
+* @param  pdev: device instance
+* @retval status
+*/
+
+USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef  *pdev)
+{
+  if(pdev->dev_state == USBD_STATE_CONFIGURED)
+  {
+    if(pdev->pClass->SOF != NULL)
+    {
+      pdev->pClass->SOF(pdev);
+    }
+  }
+  return USBD_OK;
+}
+
+/**
+* @brief  USBD_IsoINIncomplete 
+*         Handle iso in incomplete event
+* @param  pdev: device instance
+* @retval status
+*/
+USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef  *pdev, uint8_t epnum)
+{
+  return USBD_OK;
+}
+
+/**
+* @brief  USBD_IsoOUTIncomplete 
+*         Handle iso out incomplete event
+* @param  pdev: device instance
+* @retval status
+*/
+USBD_StatusTypeDef USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef  *pdev, uint8_t epnum)
+{
+  return USBD_OK;
+}
+
+/**
+* @brief  USBD_DevConnected 
+*         Handle device connection event
+* @param  pdev: device instance
+* @retval status
+*/
+USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef  *pdev)
+{
+  return USBD_OK;
+}
+
+/**
+* @brief  USBD_DevDisconnected 
+*         Handle device disconnection event
+* @param  pdev: device instance
+* @retval status
+*/
+USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef  *pdev)
+{
+  /* Free Class Resources */
+  pdev->dev_state = USBD_STATE_DEFAULT;
+  pdev->pClass->DeInit(pdev, pdev->dev_config);  
+   
+  return USBD_OK;
+}
+/**
+* @}
+*/ 
+
+
+/**
+* @}
+*/ 
+
+
+/**
+* @}
+*/ 
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
+
diff -r 000000000000 -r 7cf972f622d3 usbd_core.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbd_core.h	Sun Sep 09 19:03:18 2018 +0000
@@ -0,0 +1,168 @@
+/**
+  ******************************************************************************
+  * @file    usbd_core.h
+  * @author  MCD Application Team
+  * @version V2.4.2
+  * @date    11-December-2015
+  * @brief   Header file for usbd_core.c file
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT 2015 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.
+  *
+  ******************************************************************************
+  */ 
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USBD_CORE_H
+#define __USBD_CORE_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_conf.h"
+#include "usbd_def.h"
+#include "usbd_ioreq.h"
+#include "usbd_ctlreq.h"
+
+/** @addtogroup STM32_USB_DEVICE_LIBRARY
+  * @{
+  */
+  
+/** @defgroup USBD_CORE
+  * @brief This file is the Header file for usbd_core.c file
+  * @{
+  */ 
+
+
+/** @defgroup USBD_CORE_Exported_Defines
+  * @{
+  */ 
+
+/**
+  * @}
+  */ 
+
+
+/** @defgroup USBD_CORE_Exported_TypesDefinitions
+  * @{
+  */
+ 
+
+/**
+  * @}
+  */ 
+
+
+
+/** @defgroup USBD_CORE_Exported_Macros
+  * @{
+  */ 
+
+/**
+  * @}
+  */ 
+
+/** @defgroup USBD_CORE_Exported_Variables
+  * @{
+  */ 
+#define USBD_SOF          USBD_LL_SOF
+/**
+  * @}
+  */ 
+
+/** @defgroup USBD_CORE_Exported_FunctionsPrototype
+  * @{
+  */ 
+USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, USBD_DescriptorsTypeDef *pdesc, uint8_t id);
+USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev);
+USBD_StatusTypeDef USBD_Start  (USBD_HandleTypeDef *pdev);
+USBD_StatusTypeDef USBD_Stop   (USBD_HandleTypeDef *pdev);
+USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass);
+
+USBD_StatusTypeDef USBD_RunTestMode (USBD_HandleTypeDef  *pdev); 
+USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef  *pdev, uint8_t cfgidx);
+USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef  *pdev, uint8_t cfgidx);
+
+USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup);
+USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev , uint8_t epnum, uint8_t *pdata);
+USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev , uint8_t epnum, uint8_t *pdata);
+
+USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef  *pdev);
+USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef  *pdev, USBD_SpeedTypeDef speed);
+USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef  *pdev);
+USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef  *pdev);
+
+USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef  *pdev);
+USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef  *pdev, uint8_t epnum);
+USBD_StatusTypeDef USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef  *pdev, uint8_t epnum);
+
+USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef  *pdev);
+USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef  *pdev);
+
+/* USBD Low Level Driver */
+USBD_StatusTypeDef  USBD_LL_Init (USBD_HandleTypeDef *pdev);
+USBD_StatusTypeDef  USBD_LL_DeInit (USBD_HandleTypeDef *pdev);
+USBD_StatusTypeDef  USBD_LL_Start(USBD_HandleTypeDef *pdev);
+USBD_StatusTypeDef  USBD_LL_Stop (USBD_HandleTypeDef *pdev);
+USBD_StatusTypeDef  USBD_LL_OpenEP  (USBD_HandleTypeDef *pdev, 
+                                      uint8_t  ep_addr,                                      
+                                      uint8_t  ep_type,
+                                      uint16_t ep_mps);
+
+USBD_StatusTypeDef  USBD_LL_CloseEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr);   
+USBD_StatusTypeDef  USBD_LL_FlushEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr);   
+USBD_StatusTypeDef  USBD_LL_StallEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr);   
+USBD_StatusTypeDef  USBD_LL_ClearStallEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr);   
+uint8_t             USBD_LL_IsStallEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr);   
+USBD_StatusTypeDef  USBD_LL_SetUSBAddress (USBD_HandleTypeDef *pdev, uint8_t dev_addr);   
+USBD_StatusTypeDef  USBD_LL_Transmit (USBD_HandleTypeDef *pdev, 
+                                      uint8_t  ep_addr,                                      
+                                      uint8_t  *pbuf,
+                                      uint16_t  size);
+
+USBD_StatusTypeDef  USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, 
+                                           uint8_t  ep_addr,                                      
+                                           uint8_t  *pbuf,
+                                           uint16_t  size);
+
+uint32_t USBD_LL_GetRxDataSize  (USBD_HandleTypeDef *pdev, uint8_t  ep_addr);  
+void  USBD_LL_Delay (uint32_t Delay);
+
+/**
+  * @}
+  */ 
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __USBD_CORE_H */
+
+/**
+  * @}
+  */ 
+
+/**
+* @}
+*/ 
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
+
+
+
diff -r 000000000000 -r 7cf972f622d3 usbd_ctlreq.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbd_ctlreq.c	Sun Sep 09 19:03:18 2018 +0000
@@ -0,0 +1,783 @@
+/**
+  ******************************************************************************
+  * @file    usbd_req.c
+  * @author  MCD Application Team
+  * @version V2.4.2
+  * @date    11-December-2015 
+  * @brief   This file provides the standard USB requests following chapter 9.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT 2015 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.
+  *
+  ******************************************************************************
+  */ 
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_ctlreq.h"
+#include "usbd_ioreq.h"
+
+
+/** @addtogroup STM32_USBD_STATE_DEVICE_LIBRARY
+  * @{
+  */
+
+
+/** @defgroup USBD_REQ 
+  * @brief USB standard requests module
+  * @{
+  */ 
+
+/** @defgroup USBD_REQ_Private_TypesDefinitions
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+
+
+/** @defgroup USBD_REQ_Private_Defines
+  * @{
+  */ 
+
+/**
+  * @}
+  */ 
+
+
+/** @defgroup USBD_REQ_Private_Macros
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+
+
+/** @defgroup USBD_REQ_Private_Variables
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+
+
+/** @defgroup USBD_REQ_Private_FunctionPrototypes
+  * @{
+  */ 
+static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev , 
+                               USBD_SetupReqTypedef *req);
+
+static void USBD_SetAddress(USBD_HandleTypeDef *pdev , 
+                            USBD_SetupReqTypedef *req);
+
+static void USBD_SetConfig(USBD_HandleTypeDef *pdev , 
+                           USBD_SetupReqTypedef *req);
+
+static void USBD_GetConfig(USBD_HandleTypeDef *pdev , 
+                           USBD_SetupReqTypedef *req);
+
+static void USBD_GetStatus(USBD_HandleTypeDef *pdev , 
+                           USBD_SetupReqTypedef *req);
+
+static void USBD_SetFeature(USBD_HandleTypeDef *pdev , 
+                            USBD_SetupReqTypedef *req);
+
+static void USBD_ClrFeature(USBD_HandleTypeDef *pdev , 
+                            USBD_SetupReqTypedef *req);
+
+static uint8_t USBD_GetLen(uint8_t *buf);
+
+/**
+  * @}
+  */ 
+
+
+/** @defgroup USBD_REQ_Private_Functions
+  * @{
+  */ 
+
+
+/**
+* @brief  USBD_StdDevReq
+*         Handle standard usb device requests
+* @param  pdev: device instance
+* @param  req: usb request
+* @retval status
+*/
+USBD_StatusTypeDef  USBD_StdDevReq (USBD_HandleTypeDef *pdev , USBD_SetupReqTypedef  *req)
+{
+  USBD_StatusTypeDef ret = USBD_OK;  
+  
+  switch (req->bRequest) 
+  {
+  case USB_REQ_GET_DESCRIPTOR: 
+    
+    USBD_GetDescriptor (pdev, req) ;
+    break;
+    
+  case USB_REQ_SET_ADDRESS:                      
+    USBD_SetAddress(pdev, req);
+    break;
+    
+  case USB_REQ_SET_CONFIGURATION:                    
+    USBD_SetConfig (pdev , req);
+    break;
+    
+  case USB_REQ_GET_CONFIGURATION:                 
+    USBD_GetConfig (pdev , req);
+    break;
+    
+  case USB_REQ_GET_STATUS:                                  
+    USBD_GetStatus (pdev , req);
+    break;
+    
+    
+  case USB_REQ_SET_FEATURE:   
+    USBD_SetFeature (pdev , req);    
+    break;
+    
+  case USB_REQ_CLEAR_FEATURE:                                   
+    USBD_ClrFeature (pdev , req);
+    break;
+    
+  default:  
+    USBD_CtlError(pdev , req);
+    break;
+  }
+  
+  return ret;
+}
+
+/**
+* @brief  USBD_StdItfReq
+*         Handle standard usb interface requests
+* @param  pdev: device instance
+* @param  req: usb request
+* @retval status
+*/
+USBD_StatusTypeDef  USBD_StdItfReq (USBD_HandleTypeDef *pdev , USBD_SetupReqTypedef  *req)
+{
+  USBD_StatusTypeDef ret = USBD_OK; 
+  
+  switch (pdev->dev_state) 
+  {
+  case USBD_STATE_CONFIGURED:
+    
+    if (LOBYTE(req->wIndex) <= USBD_MAX_NUM_INTERFACES) 
+    {
+      pdev->pClass->Setup (pdev, req); 
+      
+      if((req->wLength == 0)&& (ret == USBD_OK))
+      {
+         USBD_CtlSendStatus(pdev);
+      }
+    } 
+    else 
+    {                                               
+       USBD_CtlError(pdev , req);
+    }
+    break;
+    
+  default:
+     USBD_CtlError(pdev , req);
+    break;
+  }
+  return USBD_OK;
+}
+
+/**
+* @brief  USBD_StdEPReq
+*         Handle standard usb endpoint requests
+* @param  pdev: device instance
+* @param  req: usb request
+* @retval status
+*/
+USBD_StatusTypeDef  USBD_StdEPReq (USBD_HandleTypeDef *pdev , USBD_SetupReqTypedef  *req)
+{
+  
+  uint8_t   ep_addr;
+  USBD_StatusTypeDef ret = USBD_OK; 
+  USBD_EndpointTypeDef   *pep;
+  ep_addr  = LOBYTE(req->wIndex);   
+  
+  /* Check if it is a class request */
+  if ((req->bmRequest & 0x60) == 0x20)
+  {
+    pdev->pClass->Setup (pdev, req);
+    
+    return USBD_OK;
+  }
+  
+  switch (req->bRequest) 
+  {
+    
+  case USB_REQ_SET_FEATURE :
+    
+    switch (pdev->dev_state) 
+    {
+    case USBD_STATE_ADDRESSED:          
+      if ((ep_addr != 0x00) && (ep_addr != 0x80)) 
+      {
+        USBD_LL_StallEP(pdev , ep_addr);
+      }
+      break;	
+      
+    case USBD_STATE_CONFIGURED:   
+      if (req->wValue == USB_FEATURE_EP_HALT)
+      {
+        if ((ep_addr != 0x00) && (ep_addr != 0x80)) 
+        { 
+          USBD_LL_StallEP(pdev , ep_addr);
+          
+        }
+      }
+      pdev->pClass->Setup (pdev, req);   
+      USBD_CtlSendStatus(pdev);
+      
+      break;
+      
+    default:                         
+      USBD_CtlError(pdev , req);
+      break;    
+    }
+    break;
+    
+  case USB_REQ_CLEAR_FEATURE :
+    
+    switch (pdev->dev_state) 
+    {
+    case USBD_STATE_ADDRESSED:          
+      if ((ep_addr != 0x00) && (ep_addr != 0x80)) 
+      {
+        USBD_LL_StallEP(pdev , ep_addr);
+      }
+      break;	
+      
+    case USBD_STATE_CONFIGURED:   
+      if (req->wValue == USB_FEATURE_EP_HALT)
+      {
+        if ((ep_addr & 0x7F) != 0x00) 
+        {        
+          USBD_LL_ClearStallEP(pdev , ep_addr);
+          pdev->pClass->Setup (pdev, req);
+        }
+        USBD_CtlSendStatus(pdev);
+      }
+      break;
+      
+    default:                         
+      USBD_CtlError(pdev , req);
+      break;    
+    }
+    break;
+    
+  case USB_REQ_GET_STATUS:                  
+    switch (pdev->dev_state) 
+    {
+    case USBD_STATE_ADDRESSED:          
+      if ((ep_addr & 0x7F) != 0x00) 
+      {
+        USBD_LL_StallEP(pdev , ep_addr);
+      }
+      break;	
+      
+    case USBD_STATE_CONFIGURED:
+      pep = ((ep_addr & 0x80) == 0x80) ? &pdev->ep_in[ep_addr & 0x7F]:\
+                                         &pdev->ep_out[ep_addr & 0x7F];
+      if(USBD_LL_IsStallEP(pdev, ep_addr))
+      {
+        pep->status = 0x0001;     
+      }
+      else
+      {
+        pep->status = 0x0000;  
+      }
+      
+      USBD_CtlSendData (pdev,
+                        (uint8_t *)&pep->status,
+                        2);
+      break;
+      
+    default:                         
+      USBD_CtlError(pdev , req);
+      break;
+    }
+    break;
+    
+  default:
+    break;
+  }
+  return ret;
+}
+/**
+* @brief  USBD_GetDescriptor
+*         Handle Get Descriptor requests
+* @param  pdev: device instance
+* @param  req: usb request
+* @retval status
+*/
+static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev , 
+                               USBD_SetupReqTypedef *req)
+{
+  uint16_t len;
+  uint8_t *pbuf;
+  
+    
+  switch (req->wValue >> 8)
+  { 
+#if (USBD_LPM_ENABLED == 1)
+  case USB_DESC_TYPE_BOS:
+    pbuf = pdev->pDesc->GetBOSDescriptor(pdev->dev_speed, &len);
+    break;
+#endif    
+  case USB_DESC_TYPE_DEVICE:
+    pbuf = pdev->pDesc->GetDeviceDescriptor(pdev->dev_speed, &len);
+    break;
+    
+  case USB_DESC_TYPE_CONFIGURATION:     
+    if(pdev->dev_speed == USBD_SPEED_HIGH )   
+    {
+      pbuf   = (uint8_t *)pdev->pClass->GetHSConfigDescriptor(&len);
+      pbuf[1] = USB_DESC_TYPE_CONFIGURATION;
+    }
+    else
+    {
+      pbuf   = (uint8_t *)pdev->pClass->GetFSConfigDescriptor(&len);
+      pbuf[1] = USB_DESC_TYPE_CONFIGURATION;
+    }
+    break;
+    
+  case USB_DESC_TYPE_STRING:
+    switch ((uint8_t)(req->wValue))
+    {
+    case USBD_IDX_LANGID_STR:
+     pbuf = pdev->pDesc->GetLangIDStrDescriptor(pdev->dev_speed, &len);        
+      break;
+      
+    case USBD_IDX_MFC_STR:
+      pbuf = pdev->pDesc->GetManufacturerStrDescriptor(pdev->dev_speed, &len);
+      break;
+      
+    case USBD_IDX_PRODUCT_STR:
+      pbuf = pdev->pDesc->GetProductStrDescriptor(pdev->dev_speed, &len);
+      break;
+      
+    case USBD_IDX_SERIAL_STR:
+      pbuf = pdev->pDesc->GetSerialStrDescriptor(pdev->dev_speed, &len);
+      break;
+      
+    case USBD_IDX_CONFIG_STR:
+      pbuf = pdev->pDesc->GetConfigurationStrDescriptor(pdev->dev_speed, &len);
+      break;
+      
+    case USBD_IDX_INTERFACE_STR:
+      pbuf = pdev->pDesc->GetInterfaceStrDescriptor(pdev->dev_speed, &len);
+      break;
+      
+    default:
+#if (USBD_SUPPORT_USER_STRING == 1)
+      pbuf = pdev->pClass->GetUsrStrDescriptor(pdev, (req->wValue) , &len);
+      break;
+#else      
+       USBD_CtlError(pdev , req);
+      return;
+#endif   
+    }
+    break;
+  case USB_DESC_TYPE_DEVICE_QUALIFIER:                   
+
+    if(pdev->dev_speed == USBD_SPEED_HIGH  )   
+    {
+      pbuf   = (uint8_t *)pdev->pClass->GetDeviceQualifierDescriptor(&len);
+      break;
+    }
+    else
+    {
+      USBD_CtlError(pdev , req);
+      return;
+    } 
+
+  case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION:
+    if(pdev->dev_speed == USBD_SPEED_HIGH  )   
+    {
+      pbuf   = (uint8_t *)pdev->pClass->GetOtherSpeedConfigDescriptor(&len);
+      pbuf[1] = USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION;
+      break; 
+    }
+    else
+    {
+      USBD_CtlError(pdev , req);
+      return;
+    }
+
+  default: 
+     USBD_CtlError(pdev , req);
+    return;
+  }
+  
+  if((len != 0)&& (req->wLength != 0))
+  {
+    
+    len = MIN(len , req->wLength);
+    
+    USBD_CtlSendData (pdev, 
+                      pbuf,
+                      len);
+  }
+  
+}
+
+/**
+* @brief  USBD_SetAddress
+*         Set device address
+* @param  pdev: device instance
+* @param  req: usb request
+* @retval status
+*/
+static void USBD_SetAddress(USBD_HandleTypeDef *pdev , 
+                            USBD_SetupReqTypedef *req)
+{
+  uint8_t  dev_addr; 
+  
+  if ((req->wIndex == 0) && (req->wLength == 0)) 
+  {
+    dev_addr = (uint8_t)(req->wValue) & 0x7F;     
+    
+    if (pdev->dev_state == USBD_STATE_CONFIGURED) 
+    {
+      USBD_CtlError(pdev , req);
+    } 
+    else 
+    {
+      pdev->dev_address = dev_addr;
+      USBD_LL_SetUSBAddress(pdev, dev_addr);               
+      USBD_CtlSendStatus(pdev);                         
+      
+      if (dev_addr != 0) 
+      {
+        pdev->dev_state  = USBD_STATE_ADDRESSED;
+      } 
+      else 
+      {
+        pdev->dev_state  = USBD_STATE_DEFAULT; 
+      }
+    }
+  } 
+  else 
+  {
+     USBD_CtlError(pdev , req);                        
+  } 
+}
+
+/**
+* @brief  USBD_SetConfig
+*         Handle Set device configuration request
+* @param  pdev: device instance
+* @param  req: usb request
+* @retval status
+*/
+static void USBD_SetConfig(USBD_HandleTypeDef *pdev , 
+                           USBD_SetupReqTypedef *req)
+{
+  
+  static uint8_t  cfgidx;
+  
+  cfgidx = (uint8_t)(req->wValue);                 
+  
+  if (cfgidx > USBD_MAX_NUM_CONFIGURATION ) 
+  {            
+     USBD_CtlError(pdev , req);                              
+  } 
+  else 
+  {
+    switch (pdev->dev_state) 
+    {
+    case USBD_STATE_ADDRESSED:
+      if (cfgidx) 
+      {                                			   							   							   				
+        pdev->dev_config = cfgidx;
+        pdev->dev_state = USBD_STATE_CONFIGURED;
+        if(USBD_SetClassConfig(pdev , cfgidx) == USBD_FAIL)
+        {
+          USBD_CtlError(pdev , req);  
+          return;
+        }
+        USBD_CtlSendStatus(pdev);
+      }
+      else 
+      {
+         USBD_CtlSendStatus(pdev);
+      }
+      break;
+      
+    case USBD_STATE_CONFIGURED:
+      if (cfgidx == 0) 
+      {                           
+        pdev->dev_state = USBD_STATE_ADDRESSED;
+        pdev->dev_config = cfgidx;          
+        USBD_ClrClassConfig(pdev , cfgidx);
+        USBD_CtlSendStatus(pdev);
+        
+      } 
+      else  if (cfgidx != pdev->dev_config) 
+      {
+        /* Clear old configuration */
+        USBD_ClrClassConfig(pdev , pdev->dev_config);
+        
+        /* set new configuration */
+        pdev->dev_config = cfgidx;
+        if(USBD_SetClassConfig(pdev , cfgidx) == USBD_FAIL)
+        {
+          USBD_CtlError(pdev , req);  
+          return;
+        }
+        USBD_CtlSendStatus(pdev);
+      }
+      else
+      {
+        USBD_CtlSendStatus(pdev);
+      }
+      break;
+      
+    default:					
+       USBD_CtlError(pdev , req);                     
+      break;
+    }
+  }
+}
+
+/**
+* @brief  USBD_GetConfig
+*         Handle Get device configuration request
+* @param  pdev: device instance
+* @param  req: usb request
+* @retval status
+*/
+static void USBD_GetConfig(USBD_HandleTypeDef *pdev , 
+                           USBD_SetupReqTypedef *req)
+{
+
+  if (req->wLength != 1) 
+  {                   
+     USBD_CtlError(pdev , req);
+  }
+  else 
+  {
+    switch (pdev->dev_state )  
+    {
+    case USBD_STATE_ADDRESSED:                     
+      pdev->dev_default_config = 0;
+      USBD_CtlSendData (pdev, 
+                        (uint8_t *)&pdev->dev_default_config,
+                        1);
+      break;
+      
+    case USBD_STATE_CONFIGURED:   
+      
+      USBD_CtlSendData (pdev, 
+                        (uint8_t *)&pdev->dev_config,
+                        1);
+      break;
+      
+    default:
+       USBD_CtlError(pdev , req);
+      break;
+    }
+  }
+}
+
+/**
+* @brief  USBD_GetStatus
+*         Handle Get Status request
+* @param  pdev: device instance
+* @param  req: usb request
+* @retval status
+*/
+static void USBD_GetStatus(USBD_HandleTypeDef *pdev , 
+                           USBD_SetupReqTypedef *req)
+{
+  
+    
+  switch (pdev->dev_state) 
+  {
+  case USBD_STATE_ADDRESSED:
+  case USBD_STATE_CONFIGURED:
+    
+#if ( USBD_SELF_POWERED == 1)
+    pdev->dev_config_status = USB_CONFIG_SELF_POWERED;                                  
+#else
+    pdev->dev_config_status = 0;                                   
+#endif
+                      
+    if (pdev->dev_remote_wakeup) 
+    {
+       pdev->dev_config_status |= USB_CONFIG_REMOTE_WAKEUP;                                
+    }
+    
+    USBD_CtlSendData (pdev, 
+                      (uint8_t *)& pdev->dev_config_status,
+                      2);
+    break;
+    
+  default :
+    USBD_CtlError(pdev , req);                        
+    break;
+  }
+}
+
+
+/**
+* @brief  USBD_SetFeature
+*         Handle Set device feature request
+* @param  pdev: device instance
+* @param  req: usb request
+* @retval status
+*/
+static void USBD_SetFeature(USBD_HandleTypeDef *pdev , 
+                            USBD_SetupReqTypedef *req)
+{
+
+  if (req->wValue == USB_FEATURE_REMOTE_WAKEUP)
+  {
+    pdev->dev_remote_wakeup = 1;  
+    pdev->pClass->Setup (pdev, req);   
+    USBD_CtlSendStatus(pdev);
+  }
+
+}
+
+
+/**
+* @brief  USBD_ClrFeature
+*         Handle clear device feature request
+* @param  pdev: device instance
+* @param  req: usb request
+* @retval status
+*/
+static void USBD_ClrFeature(USBD_HandleTypeDef *pdev , 
+                            USBD_SetupReqTypedef *req)
+{
+  switch (pdev->dev_state)
+  {
+  case USBD_STATE_ADDRESSED:
+  case USBD_STATE_CONFIGURED:
+    if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) 
+    {
+      pdev->dev_remote_wakeup = 0; 
+      pdev->pClass->Setup (pdev, req);   
+      USBD_CtlSendStatus(pdev);
+    }
+    break;
+    
+  default :
+     USBD_CtlError(pdev , req);
+    break;
+  }
+}
+
+/**
+* @brief  USBD_ParseSetupRequest 
+*         Copy buffer into setup structure
+* @param  pdev: device instance
+* @param  req: usb request
+* @retval None
+*/
+
+void USBD_ParseSetupRequest(USBD_SetupReqTypedef *req, uint8_t *pdata)
+{
+  req->bmRequest     = *(uint8_t *)  (pdata);
+  req->bRequest      = *(uint8_t *)  (pdata +  1);
+  req->wValue        = SWAPBYTE      (pdata +  2);
+  req->wIndex        = SWAPBYTE      (pdata +  4);
+  req->wLength       = SWAPBYTE      (pdata +  6);
+
+}
+
+/**
+* @brief  USBD_CtlError 
+*         Handle USB low level Error
+* @param  pdev: device instance
+* @param  req: usb request
+* @retval None
+*/
+
+void USBD_CtlError( USBD_HandleTypeDef *pdev ,
+                            USBD_SetupReqTypedef *req)
+{
+  USBD_LL_StallEP(pdev , 0x80);
+  USBD_LL_StallEP(pdev , 0);
+}
+
+
+/**
+  * @brief  USBD_GetString
+  *         Convert Ascii string into unicode one
+  * @param  desc : descriptor buffer
+  * @param  unicode : Formatted string buffer (unicode)
+  * @param  len : descriptor length
+  * @retval None
+  */
+void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len)
+{
+  uint8_t idx = 0;
+  
+  if (desc != NULL) 
+  {
+    *len =  USBD_GetLen(desc) * 2 + 2;    
+    unicode[idx++] = *len;
+    unicode[idx++] =  USB_DESC_TYPE_STRING;
+    
+    while (*desc != '\0') 
+    {
+      unicode[idx++] = *desc++;
+      unicode[idx++] =  0x00;
+    }
+  } 
+}
+
+/**
+  * @brief  USBD_GetLen
+  *         return the string length
+   * @param  buf : pointer to the ascii string buffer
+  * @retval string length
+  */
+static uint8_t USBD_GetLen(uint8_t *buf)
+{
+    uint8_t  len = 0;
+
+    while (*buf != '\0') 
+    {
+        len++;
+        buf++;
+    }
+
+    return len;
+}
+/**
+  * @}
+  */ 
+
+
+/**
+  * @}
+  */ 
+
+
+/**
+  * @}
+  */ 
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff -r 000000000000 -r 7cf972f622d3 usbd_ctlreq.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbd_ctlreq.h	Sun Sep 09 19:03:18 2018 +0000
@@ -0,0 +1,114 @@
+/**
+  ******************************************************************************
+  * @file    usbd_req.h
+  * @author  MCD Application Team
+  * @version V2.4.2
+  * @date    11-December-2015
+  * @brief   Header file for the usbd_req.c file
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT 2015 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.
+  *
+  ******************************************************************************
+  */ 
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_REQUEST_H
+#define __USB_REQUEST_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include  "usbd_def.h"
+
+
+/** @addtogroup STM32_USB_DEVICE_LIBRARY
+  * @{
+  */
+  
+/** @defgroup USBD_REQ
+  * @brief header file for the usbd_req.c file
+  * @{
+  */ 
+
+/** @defgroup USBD_REQ_Exported_Defines
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+
+
+/** @defgroup USBD_REQ_Exported_Types
+  * @{
+  */
+/**
+  * @}
+  */ 
+
+
+
+/** @defgroup USBD_REQ_Exported_Macros
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+
+/** @defgroup USBD_REQ_Exported_Variables
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+
+/** @defgroup USBD_REQ_Exported_FunctionsPrototype
+  * @{
+  */ 
+
+USBD_StatusTypeDef  USBD_StdDevReq (USBD_HandleTypeDef  *pdev, USBD_SetupReqTypedef  *req);
+USBD_StatusTypeDef  USBD_StdItfReq (USBD_HandleTypeDef  *pdev, USBD_SetupReqTypedef  *req);
+USBD_StatusTypeDef  USBD_StdEPReq  (USBD_HandleTypeDef  *pdev, USBD_SetupReqTypedef  *req);
+
+
+void USBD_CtlError  (USBD_HandleTypeDef  *pdev, USBD_SetupReqTypedef *req);
+
+void USBD_ParseSetupRequest (USBD_SetupReqTypedef *req, uint8_t *pdata);
+
+void USBD_GetString         (uint8_t *desc, uint8_t *unicode, uint16_t *len);
+/**
+  * @}
+  */ 
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __USB_REQUEST_H */
+
+/**
+  * @}
+  */ 
+
+/**
+* @}
+*/ 
+
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff -r 000000000000 -r 7cf972f622d3 usbd_def.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbd_def.h	Sun Sep 09 19:03:18 2018 +0000
@@ -0,0 +1,331 @@
+/**
+  ******************************************************************************
+  * @file    usbd_def.h
+  * @author  MCD Application Team
+  * @version V2.4.2
+  * @date    11-December-2015
+  * @brief   General defines for the usb device library 
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT 2015 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.
+  *
+  ******************************************************************************
+  */ 
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USBD_DEF_H
+#define __USBD_DEF_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_conf.h"
+
+/** @addtogroup STM32_USBD_DEVICE_LIBRARY
+  * @{
+  */
+  
+/** @defgroup USB_DEF
+  * @brief general defines for the usb device library file
+  * @{
+  */ 
+
+/** @defgroup USB_DEF_Exported_Defines
+  * @{
+  */ 
+
+#ifndef NULL
+#define NULL  0
+#endif
+
+
+#define  USB_LEN_DEV_QUALIFIER_DESC                     0x0A
+#define  USB_LEN_DEV_DESC                               0x12
+#define  USB_LEN_CFG_DESC                               0x09
+#define  USB_LEN_IF_DESC                                0x09
+#define  USB_LEN_EP_DESC                                0x07
+#define  USB_LEN_OTG_DESC                               0x03
+#define  USB_LEN_LANGID_STR_DESC                        0x04
+#define  USB_LEN_OTHER_SPEED_DESC_SIZ                   0x09
+
+#define  USBD_IDX_LANGID_STR                            0x00 
+#define  USBD_IDX_MFC_STR                               0x01 
+#define  USBD_IDX_PRODUCT_STR                           0x02
+#define  USBD_IDX_SERIAL_STR                            0x03 
+#define  USBD_IDX_CONFIG_STR                            0x04 
+#define  USBD_IDX_INTERFACE_STR                         0x05 
+
+#define  USB_REQ_TYPE_STANDARD                          0x00
+#define  USB_REQ_TYPE_CLASS                             0x20
+#define  USB_REQ_TYPE_VENDOR                            0x40
+#define  USB_REQ_TYPE_MASK                              0x60
+
+#define  USB_REQ_RECIPIENT_DEVICE                       0x00
+#define  USB_REQ_RECIPIENT_INTERFACE                    0x01
+#define  USB_REQ_RECIPIENT_ENDPOINT                     0x02
+#define  USB_REQ_RECIPIENT_MASK                         0x03
+
+#define  USB_REQ_GET_STATUS                             0x00
+#define  USB_REQ_CLEAR_FEATURE                          0x01
+#define  USB_REQ_SET_FEATURE                            0x03
+#define  USB_REQ_SET_ADDRESS                            0x05
+#define  USB_REQ_GET_DESCRIPTOR                         0x06
+#define  USB_REQ_SET_DESCRIPTOR                         0x07
+#define  USB_REQ_GET_CONFIGURATION                      0x08
+#define  USB_REQ_SET_CONFIGURATION                      0x09
+#define  USB_REQ_GET_INTERFACE                          0x0A
+#define  USB_REQ_SET_INTERFACE                          0x0B
+#define  USB_REQ_SYNCH_FRAME                            0x0C
+
+#define  USB_DESC_TYPE_DEVICE                              1
+#define  USB_DESC_TYPE_CONFIGURATION                       2
+#define  USB_DESC_TYPE_STRING                              3
+#define  USB_DESC_TYPE_INTERFACE                           4
+#define  USB_DESC_TYPE_ENDPOINT                            5
+#define  USB_DESC_TYPE_DEVICE_QUALIFIER                    6
+#define  USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION           7
+#define  USB_DESC_TYPE_BOS                                 0x0F
+
+#define USB_CONFIG_REMOTE_WAKEUP                           2
+#define USB_CONFIG_SELF_POWERED                            1
+
+#define USB_FEATURE_EP_HALT                                0
+#define USB_FEATURE_REMOTE_WAKEUP                          1
+#define USB_FEATURE_TEST_MODE                              2
+
+#define USB_DEVICE_CAPABITY_TYPE                           0x10
+
+#define USB_HS_MAX_PACKET_SIZE                            512
+#define USB_FS_MAX_PACKET_SIZE                            64
+#define USB_MAX_EP0_SIZE                                  64
+
+/*  Device Status */
+#define USBD_STATE_DEFAULT                                1
+#define USBD_STATE_ADDRESSED                              2
+#define USBD_STATE_CONFIGURED                             3
+#define USBD_STATE_SUSPENDED                              4
+
+
+/*  EP0 State */    
+#define USBD_EP0_IDLE                                     0
+#define USBD_EP0_SETUP                                    1
+#define USBD_EP0_DATA_IN                                  2
+#define USBD_EP0_DATA_OUT                                 3
+#define USBD_EP0_STATUS_IN                                4
+#define USBD_EP0_STATUS_OUT                               5
+#define USBD_EP0_STALL                                    6    
+
+#define USBD_EP_TYPE_CTRL                                 0
+#define USBD_EP_TYPE_ISOC                                 1
+#define USBD_EP_TYPE_BULK                                 2
+#define USBD_EP_TYPE_INTR                                 3
+
+
+/**
+  * @}
+  */ 
+
+
+/** @defgroup USBD_DEF_Exported_TypesDefinitions
+  * @{
+  */
+
+typedef  struct  usb_setup_req 
+{
+    
+    uint8_t   bmRequest;                      
+    uint8_t   bRequest;                           
+    uint16_t  wValue;                             
+    uint16_t  wIndex;                             
+    uint16_t  wLength;                            
+}USBD_SetupReqTypedef;
+
+struct _USBD_HandleTypeDef;
+    
+typedef struct _Device_cb
+{
+  uint8_t  (*Init)             (struct _USBD_HandleTypeDef *pdev , uint8_t cfgidx);
+  uint8_t  (*DeInit)           (struct _USBD_HandleTypeDef *pdev , uint8_t cfgidx);
+ /* Control Endpoints*/
+  uint8_t  (*Setup)            (struct _USBD_HandleTypeDef *pdev , USBD_SetupReqTypedef  *req);  
+  uint8_t  (*EP0_TxSent)       (struct _USBD_HandleTypeDef *pdev );    
+  uint8_t  (*EP0_RxReady)      (struct _USBD_HandleTypeDef *pdev );  
+  /* Class Specific Endpoints*/
+  uint8_t  (*DataIn)           (struct _USBD_HandleTypeDef *pdev , uint8_t epnum);   
+  uint8_t  (*DataOut)          (struct _USBD_HandleTypeDef *pdev , uint8_t epnum); 
+  uint8_t  (*SOF)              (struct _USBD_HandleTypeDef *pdev); 
+  uint8_t  (*IsoINIncomplete)  (struct _USBD_HandleTypeDef *pdev , uint8_t epnum); 
+  uint8_t  (*IsoOUTIncomplete) (struct _USBD_HandleTypeDef *pdev , uint8_t epnum);   
+
+  uint8_t  *(*GetHSConfigDescriptor)(uint16_t *length); 
+  uint8_t  *(*GetFSConfigDescriptor)(uint16_t *length);   
+  uint8_t  *(*GetOtherSpeedConfigDescriptor)(uint16_t *length);
+  uint8_t  *(*GetDeviceQualifierDescriptor)(uint16_t *length);
+#if (USBD_SUPPORT_USER_STRING == 1)
+  uint8_t  *(*GetUsrStrDescriptor)(struct _USBD_HandleTypeDef *pdev ,uint8_t index,  uint16_t *length);   
+#endif  
+  
+} USBD_ClassTypeDef;
+
+/* Following USB Device Speed */
+typedef enum 
+{
+  USBD_SPEED_HIGH  = 0,
+  USBD_SPEED_FULL  = 1,
+  USBD_SPEED_LOW   = 2,  
+}USBD_SpeedTypeDef;
+
+/* Following USB Device status */
+typedef enum {
+  USBD_OK   = 0,
+  USBD_BUSY,
+  USBD_FAIL,
+}USBD_StatusTypeDef;
+
+/* USB Device descriptors structure */
+typedef struct
+{
+  uint8_t  *(*GetDeviceDescriptor)( USBD_SpeedTypeDef speed , uint16_t *length);  
+  uint8_t  *(*GetLangIDStrDescriptor)( USBD_SpeedTypeDef speed , uint16_t *length); 
+  uint8_t  *(*GetManufacturerStrDescriptor)( USBD_SpeedTypeDef speed , uint16_t *length);  
+  uint8_t  *(*GetProductStrDescriptor)( USBD_SpeedTypeDef speed , uint16_t *length);  
+  uint8_t  *(*GetSerialStrDescriptor)( USBD_SpeedTypeDef speed , uint16_t *length);  
+  uint8_t  *(*GetConfigurationStrDescriptor)( USBD_SpeedTypeDef speed , uint16_t *length);  
+  uint8_t  *(*GetInterfaceStrDescriptor)( USBD_SpeedTypeDef speed , uint16_t *length); 
+#if (USBD_LPM_ENABLED == 1)
+  uint8_t  *(*GetBOSDescriptor)( USBD_SpeedTypeDef speed , uint16_t *length); 
+#endif  
+} USBD_DescriptorsTypeDef;
+
+/* USB Device handle structure */
+typedef struct
+{ 
+  uint32_t                status;
+  uint32_t                total_length;    
+  uint32_t                rem_length; 
+  uint32_t                maxpacket;   
+} USBD_EndpointTypeDef;
+
+/* USB Device handle structure */
+typedef struct _USBD_HandleTypeDef
+{
+  uint8_t                 id;
+  uint32_t                dev_config;
+  uint32_t                dev_default_config;
+  uint32_t                dev_config_status; 
+  USBD_SpeedTypeDef       dev_speed; 
+  USBD_EndpointTypeDef    ep_in[15];
+  USBD_EndpointTypeDef    ep_out[15];  
+  uint32_t                ep0_state;  
+  uint32_t                ep0_data_len;     
+  uint8_t                 dev_state;
+  uint8_t                 dev_old_state;
+  uint8_t                 dev_address;
+  uint8_t                 dev_connection_status;  
+  uint8_t                 dev_test_mode;
+  uint32_t                dev_remote_wakeup;
+
+  USBD_SetupReqTypedef    request;
+  USBD_DescriptorsTypeDef *pDesc;
+  USBD_ClassTypeDef       *pClass;
+  void                    *pClassData;  
+  void                    *pUserData;    
+  void                    *pData;    
+} USBD_HandleTypeDef;
+
+/**
+  * @}
+  */ 
+
+
+
+/** @defgroup USBD_DEF_Exported_Macros
+  * @{
+  */ 
+#define  SWAPBYTE(addr)        (((uint16_t)(*((uint8_t *)(addr)))) + \
+                               (((uint16_t)(*(((uint8_t *)(addr)) + 1))) << 8))
+
+#define LOBYTE(x)  ((uint8_t)(x & 0x00FF))
+#define HIBYTE(x)  ((uint8_t)((x & 0xFF00) >>8))
+#define MIN(a, b)  (((a) < (b)) ? (a) : (b))
+#define MAX(a, b)  (((a) > (b)) ? (a) : (b))
+
+
+#if  defined ( __GNUC__ )
+  #ifndef __weak
+    #define __weak   __attribute__((weak))
+  #endif /* __weak */
+  #ifndef __packed
+    #define __packed __attribute__((__packed__))
+  #endif /* __packed */
+#endif /* __GNUC__ */
+
+
+/* In HS mode and when the DMA is used, all variables and data structures dealing
+   with the DMA during the transaction process should be 4-bytes aligned */    
+
+#if defined   (__GNUC__)        /* GNU Compiler */
+  #define __ALIGN_END    __attribute__ ((aligned (4)))
+  #define __ALIGN_BEGIN         
+#else                           
+  #define __ALIGN_END
+  #if defined   (__CC_ARM)      /* ARM Compiler */
+    #define __ALIGN_BEGIN    __align(4)  
+  #elif defined (__ICCARM__)    /* IAR Compiler */
+    #define __ALIGN_BEGIN 
+  #elif defined  (__TASKING__)  /* TASKING Compiler */
+    #define __ALIGN_BEGIN    __align(4) 
+  #endif /* __CC_ARM */  
+#endif /* __GNUC__ */ 
+  
+
+/**
+  * @}
+  */ 
+
+/** @defgroup USBD_DEF_Exported_Variables
+  * @{
+  */ 
+
+/**
+  * @}
+  */ 
+
+/** @defgroup USBD_DEF_Exported_FunctionsPrototype
+  * @{
+  */ 
+
+/**
+  * @}
+  */ 
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __USBD_DEF_H */
+
+/**
+  * @}
+  */ 
+
+/**
+* @}
+*/ 
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff -r 000000000000 -r 7cf972f622d3 usbd_desc.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbd_desc.c	Sun Sep 09 19:03:18 2018 +0000
@@ -0,0 +1,326 @@
+/**
+  ******************************************************************************
+  * @file    Demonstrations/Src/usbd_desc.c
+  * @author  MCD Application Team
+  * @brief   This file provides the USBD descriptors and string formating method.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics International N.V. 
+  * All rights reserved.</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without 
+  * modification, are permitted, provided that the following conditions are met:
+  *
+  * 1. Redistribution of source code must retain the above copyright notice, 
+  *    this list of conditions and the following disclaimer.
+  * 2. Redistributions in binary form must reproduce the above copyright notice,
+  *    this list of conditions and the following disclaimer in the documentation
+  *    and/or other materials provided with the distribution.
+  * 3. Neither the name of STMicroelectronics nor the names of other 
+  *    contributors to this software may be used to endorse or promote products 
+  *    derived from this software without specific written permission.
+  * 4. This software, including modifications and/or derivative works of this 
+  *    software, must execute solely and exclusively on microcontroller or
+  *    microprocessor devices manufactured by or for STMicroelectronics.
+  * 5. Redistribution and use of this software other than as permitted under 
+  *    this license is void and will automatically terminate your rights under 
+  *    this license. 
+  *
+  * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" 
+  * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT 
+  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 
+  * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY
+  * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT 
+  * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
+  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
+  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */ 
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_core.h"
+#include "usbd_desc.h"
+#include "usbd_conf.h"
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+  * @{
+  */
+
+
+/** @defgroup USBD_DESC 
+  * @brief USBD descriptors module
+  * @{
+  */ 
+
+/** @defgroup USBD_DESC_Private_TypesDefinitions
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+
+
+/** @defgroup USBD_DESC_Private_Defines
+  * @{
+  */ 
+
+#define USBD_VID                   0x0483
+#define USBD_PID                   0x572B
+
+#define USBD_LANGID_STRING         0x409
+#define USBD_MANUFACTURER_STRING   "STMicroelectronics"
+
+
+#define USBD_PRODUCT_HS_STRING        "CDC Virtual COM"
+#define USBD_SERIALNUMBER_HS_STRING   "00000000001A"
+#define USBD_PRODUCT_FS_STRING        "CDC Virtual COM"
+#define USBD_SERIALNUMBER_FS_STRING   "00000000001B"
+#define USBD_CONFIGURATION_HS_STRING  "CDC Config"
+#define USBD_INTERFACE_HS_STRING      "CDC Interface"
+#define USBD_CONFIGURATION_FS_STRING  "CDC Config"
+#define USBD_INTERFACE_FS_STRING      "CDC Interface"
+/**
+  * @}
+  */ 
+
+
+/** @defgroup USBD_DESC_Private_Macros
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+
+
+/** @defgroup USBD_DESC_Private_Variables
+  * @{
+  */ 
+
+uint8_t *     USBD_CDC_DeviceDescriptor( USBD_SpeedTypeDef speed , uint16_t *length);
+uint8_t *     USBD_CDC_LangIDStrDescriptor( USBD_SpeedTypeDef speed , uint16_t *length);
+uint8_t *     USBD_CDC_ManufacturerStrDescriptor ( USBD_SpeedTypeDef speed , uint16_t *length);
+uint8_t *     USBD_CDC_ProductStrDescriptor ( USBD_SpeedTypeDef speed , uint16_t *length);
+uint8_t *     USBD_CDC_SerialStrDescriptor( USBD_SpeedTypeDef speed , uint16_t *length);
+uint8_t *     USBD_CDC_ConfigStrDescriptor( USBD_SpeedTypeDef speed , uint16_t *length);
+uint8_t *     USBD_CDC_InterfaceStrDescriptor( USBD_SpeedTypeDef speed , uint16_t *length);
+
+#ifdef USB_SUPPORT_USER_STRING_DESC
+uint8_t *     USBD_CDC_USRStringDesc (USBD_SpeedTypeDef speed, uint8_t idx , uint16_t *length);
+#endif /* USB_SUPPORT_USER_STRING_DESC */  
+
+
+USBD_DescriptorsTypeDef USB_Desc =
+{
+  USBD_CDC_DeviceDescriptor,
+  USBD_CDC_LangIDStrDescriptor,
+  USBD_CDC_ManufacturerStrDescriptor,
+  USBD_CDC_ProductStrDescriptor,
+  USBD_CDC_SerialStrDescriptor,
+  USBD_CDC_ConfigStrDescriptor,
+  USBD_CDC_InterfaceStrDescriptor,
+  
+};
+
+/* USB Standard Device Descriptor */
+#if defined ( __ICCARM__ ) /*!< IAR Compiler */
+  #pragma data_alignment=4   
+#endif
+__ALIGN_BEGIN uint8_t hUSBDDeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END =
+  {
+    0x12,                       /*bLength */
+    USB_DESC_TYPE_DEVICE,       /*bDescriptorType*/
+    0x10,                       /*bcdUSB */
+    0x01,
+    0x00,                       /*bDeviceClass*/
+    0x00,                       /*bDeviceSubClass*/
+    0x00,                       /*bDeviceProtocol*/
+    USB_MAX_EP0_SIZE,          /*bMaxPacketSize*/
+    LOBYTE(USBD_VID),           /*idVendor*/
+    HIBYTE(USBD_VID),           /*idVendor*/
+    LOBYTE(USBD_PID),           /*idVendor*/
+    HIBYTE(USBD_PID),           /*idVendor*/
+    0x00,                       /*bcdDevice rel. 1.00*/
+    0x01,
+    USBD_IDX_MFC_STR,           /*Index of manufacturer  string*/
+    USBD_IDX_PRODUCT_STR,       /*Index of product string*/
+    USBD_IDX_SERIAL_STR,        /*Index of serial number string*/
+    USBD_MAX_NUM_CONFIGURATION  /*bNumConfigurations*/
+  } ; /* USB_DeviceDescriptor */
+
+/* USB Standard Device Descriptor */
+#if defined ( __ICCARM__ ) /*!< IAR Compiler */
+  #pragma data_alignment=4   
+#endif
+__ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END =
+{
+     USB_LEN_LANGID_STR_DESC,         
+     USB_DESC_TYPE_STRING,       
+     LOBYTE(USBD_LANGID_STRING),
+     HIBYTE(USBD_LANGID_STRING), 
+};
+
+#if defined ( __ICCARM__ ) /*!< IAR Compiler */
+  #pragma data_alignment=4   
+#endif
+__ALIGN_BEGIN uint8_t USBD_StrDesc[USBD_MAX_STR_DESC_SIZ] __ALIGN_END;
+/**
+  * @}
+  */ 
+
+
+/** @defgroup USBD_DESC_Private_FunctionPrototypes
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+
+
+/** @defgroup USBD_DESC_Private_Functions
+  * @{
+  */ 
+
+/**
+* @brief  USBD_CDC_DeviceDescriptor
+*         return the device descriptor
+* @param  speed : current device speed
+* @param  length : pointer to data length variable
+* @retval pointer to descriptor buffer
+*/
+uint8_t *  USBD_CDC_DeviceDescriptor( USBD_SpeedTypeDef speed , uint16_t *length)
+{
+  *length = sizeof(hUSBDDeviceDesc);
+  return hUSBDDeviceDesc;
+}
+
+/**
+* @brief  USBD_CDC_LangIDStrDescriptor
+*         return the LangID string descriptor
+* @param  speed : current device speed
+* @param  length : pointer to data length variable
+* @retval pointer to descriptor buffer
+*/
+uint8_t *  USBD_CDC_LangIDStrDescriptor( USBD_SpeedTypeDef speed , uint16_t *length)
+{
+  *length =  sizeof(USBD_LangIDDesc);  
+  return USBD_LangIDDesc;
+}
+
+
+/**
+* @brief  USBD_CDC_ProductStrDescriptor
+*         return the product string descriptor
+* @param  speed : current device speed
+* @param  length : pointer to data length variable
+* @retval pointer to descriptor buffer
+*/
+uint8_t *  USBD_CDC_ProductStrDescriptor( USBD_SpeedTypeDef speed , uint16_t *length)
+{
+  if(speed == 0)
+  {   
+    USBD_GetString ((uint8_t *)USBD_PRODUCT_HS_STRING, USBD_StrDesc, length);
+  }
+  else
+  {
+    USBD_GetString ((uint8_t *)USBD_PRODUCT_FS_STRING, USBD_StrDesc, length);
+  }
+  return USBD_StrDesc;
+}
+
+/**
+* @brief  USBD_CDC_ManufacturerStrDescriptor
+*         return the manufacturer string descriptor
+* @param  speed : current device speed
+* @param  length : pointer to data length variable
+* @retval pointer to descriptor buffer
+*/
+uint8_t *  USBD_CDC_ManufacturerStrDescriptor( USBD_SpeedTypeDef speed , uint16_t *length)
+{
+  USBD_GetString ((uint8_t *)USBD_MANUFACTURER_STRING, USBD_StrDesc, length);
+  return USBD_StrDesc;
+}
+
+/**
+* @brief  USBD_CDC_SerialStrDescriptor
+*         return the serial number string descriptor
+* @param  speed : current device speed
+* @param  length : pointer to data length variable
+* @retval pointer to descriptor buffer
+*/
+uint8_t *  USBD_CDC_SerialStrDescriptor( USBD_SpeedTypeDef speed , uint16_t *length)
+{
+  if(speed  == USBD_SPEED_HIGH)
+  {    
+    USBD_GetString ((uint8_t *)USBD_SERIALNUMBER_HS_STRING, USBD_StrDesc, length);
+  }
+  else
+  {
+    USBD_GetString ((uint8_t *)USBD_SERIALNUMBER_FS_STRING, USBD_StrDesc, length);
+  }
+  return USBD_StrDesc;
+}
+
+/**
+* @brief  USBD_CDC_ConfigStrDescriptor
+*         return the configuration string descriptor
+* @param  speed : current device speed
+* @param  length : pointer to data length variable
+* @retval pointer to descriptor buffer
+*/
+uint8_t *  USBD_CDC_ConfigStrDescriptor( USBD_SpeedTypeDef speed , uint16_t *length)
+{
+  if(speed  == USBD_SPEED_HIGH)
+  {  
+    USBD_GetString ((uint8_t *)USBD_CONFIGURATION_HS_STRING, USBD_StrDesc, length);
+  }
+  else
+  {
+    USBD_GetString ((uint8_t *)USBD_CONFIGURATION_FS_STRING, USBD_StrDesc, length);
+  }
+  return USBD_StrDesc;  
+}
+
+
+/**
+* @brief  USBD_CDC_InterfaceStrDescriptor
+*         return the interface string descriptor
+* @param  speed : current device speed
+* @param  length : pointer to data length variable
+* @retval pointer to descriptor buffer
+*/
+uint8_t *  USBD_CDC_InterfaceStrDescriptor( USBD_SpeedTypeDef speed , uint16_t *length)
+{
+  if(speed == 0)
+  {
+    USBD_GetString ((uint8_t *)USBD_INTERFACE_HS_STRING, USBD_StrDesc, length);
+  }
+  else
+  {
+    USBD_GetString ((uint8_t *)USBD_INTERFACE_FS_STRING, USBD_StrDesc, length);
+  }
+  return USBD_StrDesc;  
+}
+
+/**
+  * @}
+  */ 
+
+
+/**
+  * @}
+  */ 
+
+
+/**
+  * @}
+  */ 
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
+
diff -r 000000000000 -r 7cf972f622d3 usbd_desc.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbd_desc.h	Sun Sep 09 19:03:18 2018 +0000
@@ -0,0 +1,117 @@
+/**
+  ******************************************************************************
+  * @file    usbd_desc.h
+  * @author  MCD Application Team
+  * @brief   header file for the usbd_desc.c file
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics International N.V. 
+  * All rights reserved.</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without 
+  * modification, are permitted, provided that the following conditions are met:
+  *
+  * 1. Redistribution of source code must retain the above copyright notice, 
+  *    this list of conditions and the following disclaimer.
+  * 2. Redistributions in binary form must reproduce the above copyright notice,
+  *    this list of conditions and the following disclaimer in the documentation
+  *    and/or other materials provided with the distribution.
+  * 3. Neither the name of STMicroelectronics nor the names of other 
+  *    contributors to this software may be used to endorse or promote products 
+  *    derived from this software without specific written permission.
+  * 4. This software, including modifications and/or derivative works of this 
+  *    software, must execute solely and exclusively on microcontroller or
+  *    microprocessor devices manufactured by or for STMicroelectronics.
+  * 5. Redistribution and use of this software other than as permitted under 
+  *    this license is void and will automatically terminate your rights under 
+  *    this license. 
+  *
+  * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" 
+  * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT 
+  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 
+  * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY
+  * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT 
+  * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
+  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
+  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */ 
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+
+#ifndef __USB_DESC_H
+#define __USB_DESC_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_def.h"
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+  * @{
+  */
+  
+/** @defgroup USB_DESC
+  * @brief general defines for the usb device library file
+  * @{
+  */ 
+
+/** @defgroup USB_DESC_Exported_Defines
+  * @{
+  */
+
+/**
+  * @}
+  */ 
+
+
+/** @defgroup USBD_DESC_Exported_TypesDefinitions
+  * @{
+  */
+/**
+  * @}
+  */ 
+
+
+
+/** @defgroup USBD_DESC_Exported_Macros
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+
+/** @defgroup USBD_DESC_Exported_Variables
+  * @{
+  */ 
+extern USBD_DescriptorsTypeDef USB_Desc;
+/**
+  * @}
+  */ 
+
+/** @defgroup USBD_DESC_Exported_FunctionsPrototype
+  * @{
+  */ 
+
+
+
+  
+/**
+  * @}
+  */ 
+
+#endif /* __USBD_DESC_H */
+
+/**
+  * @}
+  */ 
+
+/**
+* @}
+*/ 
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff -r 000000000000 -r 7cf972f622d3 usbd_ioreq.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbd_ioreq.c	Sun Sep 09 19:03:18 2018 +0000
@@ -0,0 +1,237 @@
+/**
+  ******************************************************************************
+  * @file    usbd_ioreq.c
+  * @author  MCD Application Team
+  * @version V2.4.2
+  * @date    11-December-2015
+  * @brief   This file provides the IO requests APIs for control endpoints.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT 2015 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.
+  *
+  ******************************************************************************
+  */ 
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_ioreq.h"
+
+/** @addtogroup STM32_USB_DEVICE_LIBRARY
+  * @{
+  */
+
+
+/** @defgroup USBD_IOREQ 
+  * @brief control I/O requests module
+  * @{
+  */ 
+
+/** @defgroup USBD_IOREQ_Private_TypesDefinitions
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+
+
+/** @defgroup USBD_IOREQ_Private_Defines
+  * @{
+  */ 
+
+/**
+  * @}
+  */ 
+
+
+/** @defgroup USBD_IOREQ_Private_Macros
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+
+
+/** @defgroup USBD_IOREQ_Private_Variables
+  * @{
+  */ 
+
+/**
+  * @}
+  */ 
+
+
+/** @defgroup USBD_IOREQ_Private_FunctionPrototypes
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+
+
+/** @defgroup USBD_IOREQ_Private_Functions
+  * @{
+  */ 
+
+/**
+* @brief  USBD_CtlSendData
+*         send data on the ctl pipe
+* @param  pdev: device instance
+* @param  buff: pointer to data buffer
+* @param  len: length of data to be sent
+* @retval status
+*/
+USBD_StatusTypeDef  USBD_CtlSendData (USBD_HandleTypeDef  *pdev, 
+                               uint8_t *pbuf,
+                               uint16_t len)
+{
+  /* Set EP0 State */
+  pdev->ep0_state          = USBD_EP0_DATA_IN;                                      
+  pdev->ep_in[0].total_length = len;
+  pdev->ep_in[0].rem_length   = len;
+ /* Start the transfer */
+  USBD_LL_Transmit (pdev, 0x00, pbuf, len);  
+  
+  return USBD_OK;
+}
+
+/**
+* @brief  USBD_CtlContinueSendData
+*         continue sending data on the ctl pipe
+* @param  pdev: device instance
+* @param  buff: pointer to data buffer
+* @param  len: length of data to be sent
+* @retval status
+*/
+USBD_StatusTypeDef  USBD_CtlContinueSendData (USBD_HandleTypeDef  *pdev, 
+                                       uint8_t *pbuf,
+                                       uint16_t len)
+{
+ /* Start the next transfer */
+  USBD_LL_Transmit (pdev, 0x00, pbuf, len);   
+  
+  return USBD_OK;
+}
+
+/**
+* @brief  USBD_CtlPrepareRx
+*         receive data on the ctl pipe
+* @param  pdev: device instance
+* @param  buff: pointer to data buffer
+* @param  len: length of data to be received
+* @retval status
+*/
+USBD_StatusTypeDef  USBD_CtlPrepareRx (USBD_HandleTypeDef  *pdev,
+                                  uint8_t *pbuf,                                  
+                                  uint16_t len)
+{
+  /* Set EP0 State */
+  pdev->ep0_state = USBD_EP0_DATA_OUT; 
+  pdev->ep_out[0].total_length = len;
+  pdev->ep_out[0].rem_length   = len;
+  /* Start the transfer */
+  USBD_LL_PrepareReceive (pdev,
+                          0,
+                          pbuf,
+                         len);
+  
+  return USBD_OK;
+}
+
+/**
+* @brief  USBD_CtlContinueRx
+*         continue receive data on the ctl pipe
+* @param  pdev: device instance
+* @param  buff: pointer to data buffer
+* @param  len: length of data to be received
+* @retval status
+*/
+USBD_StatusTypeDef  USBD_CtlContinueRx (USBD_HandleTypeDef  *pdev, 
+                                          uint8_t *pbuf,                                          
+                                          uint16_t len)
+{
+
+  USBD_LL_PrepareReceive (pdev,
+                          0,                     
+                          pbuf,                         
+                          len);
+  return USBD_OK;
+}
+/**
+* @brief  USBD_CtlSendStatus
+*         send zero lzngth packet on the ctl pipe
+* @param  pdev: device instance
+* @retval status
+*/
+USBD_StatusTypeDef  USBD_CtlSendStatus (USBD_HandleTypeDef  *pdev)
+{
+
+  /* Set EP0 State */
+  pdev->ep0_state = USBD_EP0_STATUS_IN;
+  
+ /* Start the transfer */
+  USBD_LL_Transmit (pdev, 0x00, NULL, 0);   
+  
+  return USBD_OK;
+}
+
+/**
+* @brief  USBD_CtlReceiveStatus
+*         receive zero lzngth packet on the ctl pipe
+* @param  pdev: device instance
+* @retval status
+*/
+USBD_StatusTypeDef  USBD_CtlReceiveStatus (USBD_HandleTypeDef  *pdev)
+{
+  /* Set EP0 State */
+  pdev->ep0_state = USBD_EP0_STATUS_OUT; 
+  
+ /* Start the transfer */  
+  USBD_LL_PrepareReceive ( pdev,
+                    0,
+                    NULL,
+                    0);  
+
+  return USBD_OK;
+}
+
+
+/**
+* @brief  USBD_GetRxCount
+*         returns the received data length
+* @param  pdev: device instance
+* @param  ep_addr: endpoint address
+* @retval Rx Data blength
+*/
+uint16_t  USBD_GetRxCount (USBD_HandleTypeDef  *pdev , uint8_t ep_addr)
+{
+  return USBD_LL_GetRxDataSize(pdev, ep_addr);
+}
+
+/**
+  * @}
+  */ 
+
+
+/**
+  * @}
+  */ 
+
+
+/**
+  * @}
+  */ 
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff -r 000000000000 -r 7cf972f622d3 usbd_ioreq.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbd_ioreq.h	Sun Sep 09 19:03:18 2018 +0000
@@ -0,0 +1,129 @@
+/**
+  ******************************************************************************
+  * @file    usbd_ioreq.h
+  * @author  MCD Application Team
+  * @version V2.4.2
+  * @date    11-December-2015
+  * @brief   Header file for the usbd_ioreq.c file
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT 2015 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.
+  *
+  ******************************************************************************
+  */ 
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USBD_IOREQ_H
+#define __USBD_IOREQ_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include  "usbd_def.h"
+#include  "usbd_core.h"
+
+/** @addtogroup STM32_USB_DEVICE_LIBRARY
+  * @{
+  */
+  
+/** @defgroup USBD_IOREQ
+  * @brief header file for the usbd_ioreq.c file
+  * @{
+  */ 
+
+/** @defgroup USBD_IOREQ_Exported_Defines
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+
+
+/** @defgroup USBD_IOREQ_Exported_Types
+  * @{
+  */
+
+
+/**
+  * @}
+  */ 
+
+
+
+/** @defgroup USBD_IOREQ_Exported_Macros
+  * @{
+  */ 
+
+/**
+  * @}
+  */ 
+
+/** @defgroup USBD_IOREQ_Exported_Variables
+  * @{
+  */ 
+
+/**
+  * @}
+  */ 
+
+/** @defgroup USBD_IOREQ_Exported_FunctionsPrototype
+  * @{
+  */ 
+
+USBD_StatusTypeDef  USBD_CtlSendData (USBD_HandleTypeDef  *pdev, 
+                               uint8_t *buf,
+                               uint16_t len);
+
+USBD_StatusTypeDef  USBD_CtlContinueSendData (USBD_HandleTypeDef  *pdev, 
+                               uint8_t *pbuf,
+                               uint16_t len);
+
+USBD_StatusTypeDef USBD_CtlPrepareRx (USBD_HandleTypeDef  *pdev, 
+                               uint8_t *pbuf,                                 
+                               uint16_t len);
+
+USBD_StatusTypeDef  USBD_CtlContinueRx (USBD_HandleTypeDef  *pdev, 
+                              uint8_t *pbuf,                                          
+                              uint16_t len);
+
+USBD_StatusTypeDef  USBD_CtlSendStatus (USBD_HandleTypeDef  *pdev);
+
+USBD_StatusTypeDef  USBD_CtlReceiveStatus (USBD_HandleTypeDef  *pdev);
+
+uint16_t  USBD_GetRxCount (USBD_HandleTypeDef  *pdev , 
+                           uint8_t epnum);
+
+/**
+  * @}
+  */ 
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __USBD_IOREQ_H */
+
+/**
+  * @}
+  */ 
+
+/**
+* @}
+*/ 
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+