USB device stack with Nucleo F401RE support. NOTE: the default clock config needs to be changed to in order for USB to work.

Fork of USBDevice by Tomas Cerskus

Slightly modified original USBDevice library to support F401RE.

On F401RE the data pins of your USB connector should be attached to PA12 (D+) and PA11(D-). It is also required to connect the +5V USB line to PA9.

F401RE requires 48MHz clock for USB. Therefore in order for this to work you will need to change the default clock settings:

Clock settings for USB

#include "stm32f4xx_hal.h"

RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = 16;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = 16;
RCC_OscInitStruct.PLL.PLLN = 336;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
RCC_OscInitStruct.PLL.PLLQ = 7;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
    error("RTC error: LSI clock initialization failed."); 
}

NOTE: Changing the clock frequency might affect the behavior of other libraries. I only tested the Serial library.

UPDATE: Clock settings should not to be changed anymore! Looks like the newer mbed library has the required clock enabled.

Files at this revision

API Documentation at this revision

Comitter:
mbed_official
Date:
Thu Dec 05 13:00:15 2013 +0000
Parent:
15:849c0c0f2769
Child:
17:bbd6dac92961
Commit message:
Synchronized with git revision fa451a0f0ae4ea99e333083931cc5bfc77b27b42

Full URL: https://github.com/mbedmicro/mbed/commit/fa451a0f0ae4ea99e333083931cc5bfc77b27b42/

Add initial USB Device support for STM32F4

Changed in this revision

USBDevice/USBEndpoints.h Show annotated file Show diff for this revision Revisions of this file
USBDevice/USBEndpoints_STM32F4.h Show annotated file Show diff for this revision Revisions of this file
USBDevice/USBHAL.h Show annotated file Show diff for this revision Revisions of this file
USBDevice/USBHAL_STM32F4.cpp Show annotated file Show diff for this revision Revisions of this file
USBDevice/USBRegs_STM32.h Show annotated file Show diff for this revision Revisions of this file
--- a/USBDevice/USBEndpoints.h	Tue Nov 05 09:45:23 2013 +0000
+++ b/USBDevice/USBEndpoints.h	Thu Dec 05 13:00:15 2013 +0000
@@ -43,6 +43,8 @@
 #include "USBEndpoints_LPC11U.h"
 #elif defined(TARGET_KL25Z)
 #include "USBEndpoints_KL25Z.h"
+#elif defined (TARGET_STM32F4XX)
+#include "USBEndpoints_STM32F4.h"
 #else
 #error "Unknown target type"
 #endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBEndpoints_STM32F4.h	Thu Dec 05 13:00:15 2013 +0000
@@ -0,0 +1,61 @@
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#define NUMBER_OF_LOGICAL_ENDPOINTS (4)
+#define NUMBER_OF_PHYSICAL_ENDPOINTS (NUMBER_OF_LOGICAL_ENDPOINTS * 2)
+
+/* Define physical endpoint numbers */
+
+/*      Endpoint    No.     Type(s)       MaxPacket   DoubleBuffer  */
+/*      ----------------    ------------  ----------  ---           */
+#define EP0OUT      (0)  /* Control       64          No            */
+#define EP0IN       (1)  /* Control       64          No            */
+#define EP1OUT      (2)  /* Int/Bulk/Iso  64/64/1023  Yes           */
+#define EP1IN       (3)  /* Int/Bulk/Iso  64/64/1023  Yes           */
+#define EP2OUT      (4)  /* Int/Bulk/Iso  64/64/1023  Yes           */
+#define EP2IN       (5)  /* Int/Bulk/Iso  64/64/1023  Yes           */
+#define EP3OUT      (6)  /* Int/Bulk/Iso  64/64/1023  Yes           */
+#define EP3IN       (7)  /* Int/Bulk/Iso  64/64/1023  Yes           */
+
+/* Maximum Packet sizes */
+
+#define MAX_PACKET_SIZE_EP0 (64)
+#define MAX_PACKET_SIZE_EP1 (64) /* Int/Bulk */
+#define MAX_PACKET_SIZE_EP2 (64) /* Int/Bulk */
+#define MAX_PACKET_SIZE_EP3 (64) /* Int/Bulk */
+
+#define MAX_PACKET_SIZE_EP1_ISO (1023) /* Isochronous */
+#define MAX_PACKET_SIZE_EP2_ISO (1023) /* Isochronous */
+#define MAX_PACKET_SIZE_EP3_ISO (1023) /* Isochronous */
+
+/* Generic endpoints - intended to be portable accross devices */
+/* and be suitable for simple USB devices. */
+
+/* Bulk endpoint */
+#define EPBULK_OUT  (EP2OUT)
+#define EPBULK_IN   (EP2IN)
+/* Interrupt endpoint */
+#define EPINT_OUT   (EP1OUT)
+#define EPINT_IN    (EP1IN)
+/* Isochronous endpoint */
+#define EPISO_OUT   (EP3OUT)
+#define EPISO_IN    (EP3IN)
+
+#define MAX_PACKET_SIZE_EPBULK  (MAX_PACKET_SIZE_EP2)
+#define MAX_PACKET_SIZE_EPINT   (MAX_PACKET_SIZE_EP1)
+#define MAX_PACKET_SIZE_EPISO   (MAX_PACKET_SIZE_EP3_ISO)
--- a/USBDevice/USBHAL.h	Tue Nov 05 09:45:23 2013 +0000
+++ b/USBDevice/USBHAL.h	Thu Dec 05 13:00:15 2013 +0000
@@ -74,9 +74,9 @@
     virtual bool EP2_IN_callback(){return false;};
     virtual bool EP3_OUT_callback(){return false;};
     virtual bool EP3_IN_callback(){return false;};
+#if !defined(TARGET_STM32F4)
     virtual bool EP4_OUT_callback(){return false;};
     virtual bool EP4_IN_callback(){return false;};
-    
 #if !defined(TARGET_LPC11U24)
     virtual bool EP5_OUT_callback(){return false;};
     virtual bool EP5_IN_callback(){return false;};
@@ -101,6 +101,7 @@
     virtual bool EP15_OUT_callback(){return false;};
     virtual bool EP15_IN_callback(){return false;};
 #endif
+#endif
     
 private:
     void usbisr(void);
@@ -109,6 +110,8 @@
 
 #if defined(TARGET_LPC11U24)
         bool (USBHAL::*epCallback[10 - 2])(void);
+#elif defined(TARGET_STM32F4XX)
+        bool (USBHAL::*epCallback[8 - 2])(void);
 #else
         bool (USBHAL::*epCallback[32 - 2])(void);
 #endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBHAL_STM32F4.cpp	Thu Dec 05 13:00:15 2013 +0000
@@ -0,0 +1,402 @@
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#if defined(TARGET_STM32F4XX)
+
+#include "USBHAL.h"
+#include "USBRegs_STM32.h"
+#include "pinmap.h"
+
+USBHAL * USBHAL::instance;
+
+static volatile int epComplete = 0;
+
+static uint32_t bufferEnd = 0;
+static const uint32_t rxFifoSize = 512;
+static uint32_t rxFifoCount = 0;
+
+static uint32_t setupBuffer[MAX_PACKET_SIZE_EP0 >> 2];
+
+uint32_t USBHAL::endpointReadcore(uint8_t endpoint, uint8_t *buffer) {
+    return 0;
+}
+
+USBHAL::USBHAL(void) {    
+    NVIC_DisableIRQ(OTG_FS_IRQn);
+    epCallback[0] = &USBHAL::EP1_OUT_callback;
+    epCallback[1] = &USBHAL::EP1_IN_callback;
+    epCallback[2] = &USBHAL::EP2_OUT_callback;
+    epCallback[3] = &USBHAL::EP2_IN_callback;
+    epCallback[4] = &USBHAL::EP3_OUT_callback;
+    epCallback[5] = &USBHAL::EP3_IN_callback;
+
+    // Enable power and clocking
+    RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
+
+    pin_function(PA_8, STM_PIN_DATA(2, 10));
+    pin_function(PA_9, STM_PIN_DATA(0, 0));
+    pin_function(PA_10, STM_PIN_DATA(2, 10));
+    pin_function(PA_11, STM_PIN_DATA(2, 10));
+    pin_function(PA_12, STM_PIN_DATA(2, 10));
+
+    // Set ID pin to open drain with pull-up resistor
+    pin_mode(PA_10, OpenDrain);
+    GPIOA->PUPDR &= ~(0x3 << 20);
+    GPIOA->PUPDR |= 1 << 20;
+
+    // Set VBUS pin to open drain
+    pin_mode(PA_9, OpenDrain);
+
+    RCC->AHB2ENR |= RCC_AHB2ENR_OTGFSEN;
+    
+    // Enable interrupts
+    OTG_FS->GREGS.GAHBCFG |= (1 << 0);
+
+    // Turnaround time to maximum value - too small causes packet loss
+    OTG_FS->GREGS.GUSBCFG |= (0xF << 10);
+
+    // Unmask global interrupts
+    OTG_FS->GREGS.GINTMSK |= (1 << 3) | // SOF
+                             (1 << 4) | // RX FIFO not empty
+                             (1 << 12); // USB reset
+
+    OTG_FS->DREGS.DCFG |= (0x3 << 0) | // Full speed
+                          (1 << 2); // Non-zero-length status OUT handshake
+
+    OTG_FS->GREGS.GCCFG |= (1 << 19) | // Enable VBUS sensing
+                           (1 << 16); // Power Up
+
+    instance = this;
+    NVIC_SetVector(OTG_FS_IRQn, (uint32_t)&_usbisr);
+    NVIC_SetPriority(OTG_FS_IRQn, 1);
+}
+
+USBHAL::~USBHAL(void) {
+}
+
+void USBHAL::connect(void) {
+    NVIC_EnableIRQ(OTG_FS_IRQn);
+}
+
+void USBHAL::disconnect(void) {
+    NVIC_DisableIRQ(OTG_FS_IRQn);
+}
+
+void USBHAL::configureDevice(void) {
+    // Not needed
+}
+
+void USBHAL::unconfigureDevice(void) {
+    // Not needed
+}
+
+void USBHAL::setAddress(uint8_t address) {
+    OTG_FS->DREGS.DCFG |= (address << 4);
+    EP0write(0, 0);
+}
+
+bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket,
+                             uint32_t flags) {
+    uint32_t epIndex = endpoint >> 1;
+
+    uint32_t type;
+    switch (endpoint) {
+        case EP0IN:  
+        case EP0OUT:
+            type = 0;
+            break;   
+        case EPISO_IN:
+        case EPISO_OUT:
+            type = 1; 
+        case EPBULK_IN:
+        case EPBULK_OUT:
+            type = 2;  
+            break;   
+        case EPINT_IN:
+        case EPINT_OUT:
+            type = 3; 
+            break;   
+    }
+
+    // Generic in or out EP controls
+    uint32_t control = (maxPacket << 0) | // Packet size
+                       (1 << 15) | // Active endpoint
+                       (type << 18); // Endpoint type
+
+    if (endpoint & 0x1) { // In Endpoint
+        // Set up the Tx FIFO
+        if (endpoint == EP0IN) {
+            OTG_FS->GREGS.DIEPTXF0_HNPTXFSIZ = ((maxPacket >> 2) << 16) |
+                                               (bufferEnd << 0);
+        }
+        else {
+            OTG_FS->GREGS.DIEPTXF[epIndex - 1] = ((maxPacket >> 2) << 16) |
+                                                 (bufferEnd << 0);
+        }
+        bufferEnd += maxPacket >> 2;
+
+        // Set the In EP specific control settings
+        if (endpoint != EP0IN) {
+            control |= (1 << 28); // SD0PID
+        }
+        
+        control |= (epIndex << 22) | // TxFIFO index
+                   (1 << 27); // SNAK
+        OTG_FS->INEP_REGS[epIndex].DIEPCTL = control;
+
+        // Unmask the interrupt
+        OTG_FS->DREGS.DAINTMSK |= (1 << epIndex);
+    }
+    else { // Out endpoint
+        // Set the out EP specific control settings
+        control |= (1 << 26); // CNAK
+        OTG_FS->OUTEP_REGS[epIndex].DOEPCTL = control;
+        
+        // Unmask the interrupt
+        OTG_FS->DREGS.DAINTMSK |= (1 << (epIndex + 16));
+    }
+    return true;
+}
+
+// read setup packet
+void USBHAL::EP0setup(uint8_t *buffer) {
+    memcpy(buffer, setupBuffer, MAX_PACKET_SIZE_EP0);
+}
+
+void USBHAL::EP0readStage(void) {
+}
+
+void USBHAL::EP0read(void) {
+}
+
+uint32_t USBHAL::EP0getReadResult(uint8_t *buffer) {
+    uint32_t* buffer32 = (uint32_t *) buffer;
+    uint32_t length = rxFifoCount;
+    for (uint32_t i = 0; i < length; i += 4) {
+        buffer32[i >> 2] = OTG_FS->FIFO[0][0];
+    }
+                        
+    rxFifoCount = 0;
+    return length;
+}
+
+void USBHAL::EP0write(uint8_t *buffer, uint32_t size) {
+    endpointWrite(0, buffer, size);
+}
+
+void USBHAL::EP0getWriteResult(void) {
+}
+
+void USBHAL::EP0stall(void) {
+    // If we stall the out endpoint here then we have problems transferring
+    // and setup requests after the (stalled) get device qualifier requests.
+    // TODO: Find out if this is correct behavior, or whether we are doing
+    // something else wrong
+    stallEndpoint(EP0IN);
+//    stallEndpoint(EP0OUT);
+}
+
+EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize) {
+    uint32_t epIndex = endpoint >> 1;
+    uint32_t size = (1 << 19) | // 1 packet
+                    (maximumSize << 0); // Packet size
+//    if (endpoint == EP0OUT) {
+        size |= (1 << 29); // 1 setup packet
+//    }
+    OTG_FS->OUTEP_REGS[epIndex].DOEPTSIZ = size;
+    OTG_FS->OUTEP_REGS[epIndex].DOEPCTL |= (1 << 31) | // Enable endpoint
+                                           (1 << 26); // Clear NAK
+
+    epComplete &= ~(1 << endpoint);
+    return EP_PENDING;
+}
+
+EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t * buffer, uint32_t *bytesRead) {
+    if (!(epComplete & (1 << endpoint))) {
+        return EP_PENDING;
+    }
+
+    uint32_t* buffer32 = (uint32_t *) buffer;
+    uint32_t length = rxFifoCount;
+    for (uint32_t i = 0; i < length; i += 4) {
+        buffer32[i >> 2] = OTG_FS->FIFO[endpoint >> 1][0];
+    }
+    rxFifoCount = 0;
+    *bytesRead = length;
+    return EP_COMPLETED;
+}
+
+EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size) {
+    uint32_t epIndex = endpoint >> 1;
+    OTG_FS->INEP_REGS[epIndex].DIEPTSIZ = (1 << 19) | // 1 packet
+                                          (size << 0); // Size of packet
+    OTG_FS->INEP_REGS[epIndex].DIEPCTL |= (1 << 31) | // Enable endpoint
+                                          (1 << 26); // CNAK
+    OTG_FS->DREGS.DIEPEMPMSK = (1 << epIndex);
+
+    while ((OTG_FS->INEP_REGS[epIndex].DTXFSTS & 0XFFFF) < ((size + 3) >> 2));
+
+    for (uint32_t i=0; i<(size + 3) >> 2; i++, data+=4) {
+        OTG_FS->FIFO[epIndex][0] = *(uint32_t *)data;
+    }
+
+    epComplete &= ~(1 << endpoint);
+
+    return EP_PENDING;
+}
+
+EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint) {
+    if (epComplete & (1 << endpoint)) {
+        epComplete &= ~(1 << endpoint);
+        return EP_COMPLETED;
+    }
+
+    return EP_PENDING; 
+}
+
+void USBHAL::stallEndpoint(uint8_t endpoint) {
+    if (endpoint & 0x1) { // In EP
+        OTG_FS->INEP_REGS[endpoint >> 1].DIEPCTL |= (1 << 30) | // Disable
+                                                    (1 << 21); // Stall
+    }
+    else {  // Out EP
+        OTG_FS->DREGS.DCTL |= (1 << 9); // Set global out NAK
+        OTG_FS->OUTEP_REGS[endpoint >> 1].DOEPCTL |= (1 << 30) | // Disable
+                                                     (1 << 21); // Stall
+    }
+}
+
+void USBHAL::unstallEndpoint(uint8_t endpoint) {
+    
+}
+
+bool USBHAL::getEndpointStallState(uint8_t endpoint) {
+    return false;
+}
+
+void USBHAL::remoteWakeup(void) {
+}
+
+
+void USBHAL::_usbisr(void) {
+    instance->usbisr();
+}
+
+
+void USBHAL::usbisr(void) {
+    if (OTG_FS->GREGS.GINTSTS & (1 << 12)) { // USB Reset
+        // Set SNAK bits
+        OTG_FS->OUTEP_REGS[0].DOEPCTL |= (1 << 27);
+        OTG_FS->OUTEP_REGS[1].DOEPCTL |= (1 << 27);
+        OTG_FS->OUTEP_REGS[2].DOEPCTL |= (1 << 27);
+        OTG_FS->OUTEP_REGS[3].DOEPCTL |= (1 << 27);
+
+        OTG_FS->DREGS.DIEPMSK = (1 << 0);
+
+        bufferEnd = 0;
+
+        // Set the receive FIFO size
+        OTG_FS->GREGS.GRXFSIZ = rxFifoSize >> 2;
+        bufferEnd += rxFifoSize >> 2;
+
+        // Create the endpoints, and wait for setup packets on out EP0
+        realiseEndpoint(EP0IN, MAX_PACKET_SIZE_EP0, 0);
+        realiseEndpoint(EP0OUT, MAX_PACKET_SIZE_EP0, 0);
+        endpointRead(EP0OUT, MAX_PACKET_SIZE_EP0);
+
+        OTG_FS->GREGS.GINTSTS = (1 << 12);
+    }
+
+    if (OTG_FS->GREGS.GINTSTS & (1 << 4)) { // RX FIFO not empty
+        uint32_t status = OTG_FS->GREGS.GRXSTSP;
+
+        uint32_t endpoint = (status & 0xF) << 1;
+        uint32_t length = (status >> 4) & 0x7FF;
+        uint32_t type = (status >> 17) & 0xF;
+
+        rxFifoCount = length;
+
+        if (type == 0x6) {
+            // Setup packet
+            for (uint32_t i=0; i<length; i+=4) {
+                setupBuffer[i >> 2] = OTG_FS->FIFO[0][i >> 2];
+            }
+            rxFifoCount = 0;
+        }
+
+        if (type == 0x4) {
+            // Setup complete
+            EP0setupCallback();
+            endpointRead(EP0OUT, MAX_PACKET_SIZE_EP0);
+        }
+
+        if (type == 0x2) {
+            // Out packet
+            if (endpoint == EP0OUT) {
+                EP0out();
+            }
+            else {
+                epComplete |= (1 << endpoint);
+                if ((instance->*(epCallback[endpoint - 2]))()) {
+                    epComplete &= (1 << endpoint);
+                }
+            }
+        }
+
+        for (uint32_t i=0; i<rxFifoCount; i+=4) {
+            (void) OTG_FS->FIFO[0][0];
+        }
+        OTG_FS->GREGS.GINTSTS = (1 << 4);
+    }
+
+    if (OTG_FS->GREGS.GINTSTS & (1 << 18)) { // In endpoint interrupt
+        // Loop through the in endpoints
+        for (uint32_t i=0; i<4; i++) {
+            if (OTG_FS->DREGS.DAINT & (1 << i)) { // Interrupt is on endpoint
+
+                if (OTG_FS->INEP_REGS[i].DIEPINT & (1 << 7)) {// Tx FIFO empty
+                    // If the Tx FIFO is empty on EP0 we need to send a further
+                    // packet, so call EP0in()
+                    if (i == 0) {
+                        EP0in();
+                    }
+                    // Clear the interrupt
+                    OTG_FS->INEP_REGS[i].DIEPINT = (1 << 7);
+                    // Stop firing Tx empty interrupts
+                    // Will get turned on again if another write is called
+                    OTG_FS->DREGS.DIEPEMPMSK &= ~(1 << i);
+                }
+
+                // If the transfer is complete
+                if (OTG_FS->INEP_REGS[i].DIEPINT & (1 << 0)) { // Tx Complete
+                    epComplete |= (1 << (1 + (i << 1)));
+                    OTG_FS->INEP_REGS[i].DIEPINT = (1 << 0);
+                }
+            }
+        }
+        OTG_FS->GREGS.GINTSTS = (1 << 18);
+    }
+
+    if (OTG_FS->GREGS.GINTSTS & (1 << 3)) { // Start of frame
+        SOF((OTG_FS->GREGS.GRXSTSR >> 17) & 0xF);
+        OTG_FS->GREGS.GINTSTS = (1 << 3);
+    }
+}
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBRegs_STM32.h	Thu Dec 05 13:00:15 2013 +0000
@@ -0,0 +1,149 @@
+/**
+  ******************************************************************************
+  * @file    usb_regs.h
+  * @author  MCD Application Team
+  * @version V2.1.0
+  * @date    19-March-2012
+  * @brief   hardware registers
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
+  *
+  * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+  * You may not use this file except in compliance with the License.
+  * You may obtain a copy of the License at:
+  *
+  *        http://www.st.com/software_license_agreement_liberty_v2
+  *
+  * Unless required by applicable law or agreed to in writing, software 
+  * distributed under the License is distributed on an "AS IS" BASIS, 
+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  * See the License for the specific language governing permissions and
+  * limitations under the License.
+  *
+  ******************************************************************************
+  */
+
+#ifndef __USB_OTG_REGS_H__
+#define __USB_OTG_REGS_H__
+
+typedef struct //000h
+{
+  __IO uint32_t GOTGCTL;      /* USB_OTG Control and Status Register    000h*/
+  __IO uint32_t GOTGINT;      /* USB_OTG Interrupt Register             004h*/
+  __IO uint32_t GAHBCFG;      /* Core AHB Configuration Register    008h*/
+  __IO uint32_t GUSBCFG;      /* Core USB Configuration Register    00Ch*/
+  __IO uint32_t GRSTCTL;      /* Core Reset Register                010h*/
+  __IO uint32_t GINTSTS;      /* Core Interrupt Register            014h*/
+  __IO uint32_t GINTMSK;      /* Core Interrupt Mask Register       018h*/
+  __IO uint32_t GRXSTSR;      /* Receive Sts Q Read Register        01Ch*/
+  __IO uint32_t GRXSTSP;      /* Receive Sts Q Read & POP Register  020h*/
+  __IO uint32_t GRXFSIZ;      /* Receive FIFO Size Register         024h*/
+  __IO uint32_t DIEPTXF0_HNPTXFSIZ;   /* EP0 / Non Periodic Tx FIFO Size Register 028h*/
+  __IO uint32_t HNPTXSTS;     /* Non Periodic Tx FIFO/Queue Sts reg 02Ch*/
+  uint32_t Reserved30[2];     /* Reserved                           030h*/
+  __IO uint32_t GCCFG;        /* General Purpose IO Register        038h*/
+  __IO uint32_t CID;          /* User ID Register                   03Ch*/
+  uint32_t  Reserved40[48];   /* Reserved                      040h-0FFh*/
+  __IO uint32_t HPTXFSIZ; /* Host Periodic Tx FIFO Size Reg     100h*/
+  __IO uint32_t DIEPTXF[3];/* dev Periodic Transmit FIFO */
+}
+USB_OTG_GREGS;
+
+typedef struct // 800h
+{
+  __IO uint32_t DCFG;         /* dev Configuration Register   800h*/
+  __IO uint32_t DCTL;         /* dev Control Register         804h*/
+  __IO uint32_t DSTS;         /* dev Status Register (RO)     808h*/
+  uint32_t Reserved0C;           /* Reserved                     80Ch*/
+  __IO uint32_t DIEPMSK;   /* dev IN Endpoint Mask         810h*/
+  __IO uint32_t DOEPMSK;  /* dev OUT Endpoint Mask        814h*/
+  __IO uint32_t DAINT;     /* dev All Endpoints Itr Reg    818h*/
+  __IO uint32_t DAINTMSK; /* dev All Endpoints Itr Mask   81Ch*/
+  uint32_t  Reserved20;          /* Reserved                     820h*/
+  uint32_t Reserved9;       /* Reserved                     824h*/
+  __IO uint32_t DVBUSDIS;    /* dev VBUS discharge Register  828h*/
+  __IO uint32_t DVBUSPULSE;  /* dev VBUS Pulse Register      82Ch*/
+  __IO uint32_t DTHRCTL;     /* dev thr                      830h*/
+  __IO uint32_t DIEPEMPMSK; /* dev empty msk             834h*/
+}
+USB_OTG_DREGS;
+
+typedef struct 
+{
+  __IO uint32_t DIEPCTL; /* dev IN Endpoint Control Reg 900h + (ep_num * 20h) + 00h*/
+  uint32_t Reserved04;             /* Reserved                       900h + (ep_num * 20h) + 04h*/
+  __IO uint32_t DIEPINT; /* dev IN Endpoint Itr Reg     900h + (ep_num * 20h) + 08h*/
+  uint32_t Reserved0C;             /* Reserved                       900h + (ep_num * 20h) + 0Ch*/
+  __IO uint32_t DIEPTSIZ; /* IN Endpoint Txfer Size   900h + (ep_num * 20h) + 10h*/
+  uint32_t Reserved14;
+  __IO uint32_t DTXFSTS;/*IN Endpoint Tx FIFO Status Reg 900h + (ep_num * 20h) + 18h*/
+  uint32_t Reserved1C;             /* Reserved  900h+(ep_num*20h)+1Ch-900h+ (ep_num * 20h) + 1Ch*/
+}
+USB_OTG_INEPREGS;
+
+typedef struct 
+{
+  __IO uint32_t DOEPCTL;       /* dev OUT Endpoint Control Reg  B00h + (ep_num * 20h) + 00h*/
+  uint32_t Reserved04;         /* Reserved                      B00h + (ep_num * 20h) + 04h*/
+  __IO uint32_t DOEPINT;       /* dev OUT Endpoint Itr Reg      B00h + (ep_num * 20h) + 08h*/
+  uint32_t Reserved0C;         /* Reserved                      B00h + (ep_num * 20h) + 0Ch*/
+  __IO uint32_t DOEPTSIZ;      /* dev OUT Endpoint Txfer Size   B00h + (ep_num * 20h) + 10h*/
+  uint32_t Reserved14[3];
+}
+USB_OTG_OUTEPREGS;
+
+typedef struct
+{
+  __IO uint32_t HCFG;             /* Host Configuration Register    400h*/
+  __IO uint32_t HFIR;      /* Host Frame Interval Register   404h*/
+  __IO uint32_t HFNUM;         /* Host Frame Nbr/Frame Remaining 408h*/
+  uint32_t Reserved40C;                   /* Reserved                       40Ch*/
+  __IO uint32_t HPTXSTS;   /* Host Periodic Tx FIFO/ Queue Status 410h*/
+  __IO uint32_t HAINT;   /* Host All Channels Interrupt Register 414h*/
+  __IO uint32_t HAINTMSK;   /* Host All Channels Interrupt Mask 418h*/
+}
+USB_OTG_HREGS;
+
+typedef struct
+{
+  __IO uint32_t HCCHAR;
+  __IO uint32_t HCSPLT;
+  __IO uint32_t HCINT;
+  __IO uint32_t HCINTMSK;
+  __IO uint32_t HCTSIZ;
+  uint32_t Reserved[3];
+}
+USB_OTG_HC_REGS;
+
+typedef struct 
+{
+    USB_OTG_GREGS         GREGS;
+    uint32_t RESERVED0[188];
+    USB_OTG_HREGS         HREGS;
+    uint32_t RESERVED1[9];
+    __IO uint32_t         HPRT;
+    uint32_t RESERVED2[47];
+    USB_OTG_HC_REGS       HC_REGS[8];
+    uint32_t RESERVED3[128];
+    USB_OTG_DREGS         DREGS;
+    uint32_t RESERVED4[50];
+    USB_OTG_INEPREGS      INEP_REGS[4];
+    uint32_t RESERVED5[96];
+    USB_OTG_OUTEPREGS     OUTEP_REGS[4];
+    uint32_t RESERVED6[160];
+    __IO uint32_t         PCGCCTL;
+    uint32_t RESERVED7[127];
+    __IO uint32_t         FIFO[4][1024];
+}
+USB_OTG_CORE_REGS;
+
+
+#define OTG_FS_BASE (AHB2PERIPH_BASE + 0x0000)
+#define OTG_FS ((USB_OTG_CORE_REGS *) OTG_FS_BASE)
+
+#endif //__USB_OTG_REGS_H__
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+