diff --git a/example/stm32f4/STM32_USB_OTG_Driver/Release_Notes.html b/example/stm32f4/STM32_USB_OTG_Driver/Release_Notes.html
new file mode 100644
index 0000000..17d2a08
--- /dev/null
+++ b/example/stm32f4/STM32_USB_OTG_Driver/Release_Notes.html
@@ -0,0 +1,941 @@
+
+
+
+
+
+
+
+
+Release Notes for STM32F105/7xx and STM32F2xx USB OTG Driver
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to Release page
+
+
+
+
+ Release Notes for STM32F105/7xx and STM32F2xx USB OTG Driver
+ Copyright
+ 2011 STMicroelectronics
+
+
+
+
+
+
+
+
+ Contents
+
+ STM32F105/7xx and STM32F2xx USB OTG Driver update History
+ License
+
+ STM32F105/7xx and STM32F2xx USB OTG Driver update History V2.0.0 / 22-July-2011 Main
+Changes
+Second official version supporting STM32F105/7 and STM32F2xx devices Rename the Library from "STM32_USB_HOST_Driver " to "STM32_USB_OTG_Driver " Add support for STM32F2xx devices Add support for Device and OTG modes Change HCD layer to support High speed core Change the Low level driver to support multi core support for Host mode Add Stop mechanism for Host and Device modes Change VBUS enabling method, to use the external or the internal VBUS when using the ULPI V1.0.0 - 11/29/2010
+License
+ The use of this STM32 software is governed by the terms and conditions of the License Agreement "MCD-ST Liberty SW License Agreement 20Jul2011 v0.1.pdf" available in the root of this package.
+
+
+
+ For
+ complete documentation on STM32(CORTEX M3) 32-Bit
+ Microcontrollers visit www.st.com/STM32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_bsp.h b/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_bsp.h
new file mode 100644
index 0000000..0e7c12e
--- /dev/null
+++ b/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_bsp.h
@@ -0,0 +1,97 @@
+/**
+ ******************************************************************************
+ * @file usb_bsp.h
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 22-July-2011
+ * @brief Specific api's relative to the used hardware platform
+ ******************************************************************************
+ * @attention
+ *
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * © COPYRIGHT 2011 STMicroelectronics
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_BSP__H__
+#define __USB_BSP__H__
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_core.h"
+#include "stm32f4_discovery.h"
+
+/** @addtogroup USB_OTG_DRIVER
+ * @{
+ */
+
+/** @defgroup USB_BSP
+ * @brief This file is the
+ * @{
+ */
+
+
+/** @defgroup USB_BSP_Exported_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_BSP_Exported_Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_BSP_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USB_BSP_Exported_Variables
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USB_BSP_Exported_FunctionsPrototype
+ * @{
+ */
+void BSP_Init(void);
+
+void USB_OTG_BSP_Init (USB_OTG_CORE_HANDLE *pdev);
+void USB_OTG_BSP_uDelay (const uint32_t usec);
+void USB_OTG_BSP_mDelay (const uint32_t msec);
+void USB_OTG_BSP_EnableInterrupt (USB_OTG_CORE_HANDLE *pdev);
+#ifdef USE_HOST_MODE
+void USB_OTG_BSP_ConfigVBUS(USB_OTG_CORE_HANDLE *pdev);
+void USB_OTG_BSP_DriveVBUS(USB_OTG_CORE_HANDLE *pdev,uint8_t state);
+#endif
+/**
+ * @}
+ */
+
+#endif //__USB_BSP__H__
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
diff --git a/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_conf_template.h b/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_conf_template.h
new file mode 100644
index 0000000..39b3552
--- /dev/null
+++ b/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_conf_template.h
@@ -0,0 +1,287 @@
+/**
+ ******************************************************************************
+ * @file usb_conf.h
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 22-July-2011
+ * @brief general low level driver configuration
+ ******************************************************************************
+ * @attention
+ *
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * © COPYRIGHT 2011 STMicroelectronics
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_CONF__H__
+#define __USB_CONF__H__
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f2xx.h"
+
+
+/** @addtogroup USB_OTG_DRIVER
+ * @{
+ */
+
+/** @defgroup USB_CONF
+ * @brief USB low level driver configuration file
+ * @{
+ */
+
+/** @defgroup USB_CONF_Exported_Defines
+ * @{
+ */
+
+/* USB Core and PHY interface configuration.
+ Tip: To avoid modifying these defines each time you need to change the USB
+ configuration, you can declare the needed define in your toolchain
+ compiler preprocessor.
+ */
+#ifndef USE_USB_OTG_FS
+ //#define USE_USB_OTG_FS
+#endif /* USE_USB_OTG_FS */
+
+#ifndef USE_USB_OTG_HS
+ //#define USE_USB_OTG_HS
+#endif /* USE_USB_OTG_HS */
+
+#ifndef USE_ULPI_PHY
+ //#define USE_ULPI_PHY
+#endif /* USE_ULPI_PHY */
+
+#ifndef USE_EMBEDDED_PHY
+ //#define USE_EMBEDDED_PHY
+#endif /* USE_EMBEDDED_PHY */
+
+#ifndef USE_I2C_PHY
+ //#define USE_I2C_PHY
+#endif /* USE_I2C_PHY */
+
+
+#ifdef USE_USB_OTG_FS
+ #define USB_OTG_FS_CORE
+#endif
+
+#ifdef USE_USB_OTG_HS
+ #define USB_OTG_HS_CORE
+#endif
+
+/*******************************************************************************
+* FIFO Size Configuration in Device mode
+*
+* (i) Receive data FIFO size = RAM for setup packets +
+* OUT endpoint control information +
+* data OUT packets + miscellaneous
+* Space = ONE 32-bits words
+* --> RAM for setup packets = 10 spaces
+* (n is the nbr of CTRL EPs the device core supports)
+* --> OUT EP CTRL info = 1 space
+* (one space for status information written to the FIFO along with each
+* received packet)
+* --> data OUT packets = (Largest Packet Size / 4) + 1 spaces
+* (MINIMUM to receive packets)
+* --> OR data OUT packets = at least 2*(Largest Packet Size / 4) + 1 spaces
+* (if high-bandwidth EP is enabled or multiple isochronous EPs)
+* --> miscellaneous = 1 space per OUT EP
+* (one space for transfer complete status information also pushed to the
+* FIFO with each endpoint's last packet)
+*
+* (ii)MINIMUM RAM space required for each IN EP Tx FIFO = MAX packet size for
+* that particular IN EP. More space allocated in the IN EP Tx FIFO results
+* in a better performance on the USB and can hide latencies on the AHB.
+*
+* (iii) TXn min size = 16 words. (n : Transmit FIFO index)
+* (iv) When a TxFIFO is not used, the Configuration should be as follows:
+* case 1 : n > m and Txn is not used (n,m : Transmit FIFO indexes)
+* --> Txm can use the space allocated for Txn.
+* case2 : n < m and Txn is not used (n,m : Transmit FIFO indexes)
+* --> Txn should be configured with the minimum space of 16 words
+* (v) The FIFO is used optimally when used TxFIFOs are allocated in the top
+* of the FIFO.Ex: use EP1 and EP2 as IN instead of EP1 and EP3 as IN ones.
+*******************************************************************************/
+
+/*******************************************************************************
+* FIFO Size Configuration in Host mode
+*
+* (i) Receive data FIFO size = (Largest Packet Size / 4) + 1 or
+* 2x (Largest Packet Size / 4) + 1, If a
+* high-bandwidth channel or multiple isochronous
+* channels are enabled
+*
+* (ii) For the host nonperiodic Transmit FIFO is the largest maximum packet size
+* for all supported nonperiodic OUT channels. Typically, a space
+* corresponding to two Largest Packet Size is recommended.
+*
+* (iii) The minimum amount of RAM required for Host periodic Transmit FIFO is
+* the largest maximum packet size for all supported periodic OUT channels.
+* If there is at least one High Bandwidth Isochronous OUT endpoint,
+* then the space must be at least two times the maximum packet size for
+* that channel.
+*******************************************************************************/
+
+/****************** USB OTG HS CONFIGURATION **********************************/
+#ifdef USB_OTG_HS_CORE
+ #define RX_FIFO_HS_SIZE 512
+ #define TX0_FIFO_HS_SIZE 512
+ #define TX1_FIFO_HS_SIZE 512
+ #define TX2_FIFO_HS_SIZE 0
+ #define TX3_FIFO_HS_SIZE 0
+ #define TX4_FIFO_HS_SIZE 0
+ #define TX5_FIFO_HS_SIZE 0
+ #define TXH_NP_HS_FIFOSIZ 96
+ #define TXH_P_HS_FIFOSIZ 96
+
+ //#define USB_OTG_HS_LOW_PWR_MGMT_SUPPORT
+ //#define USB_OTG_HS_SOF_OUTPUT_ENABLED
+
+ //#define USB_OTG_INTERNAL_VBUS_ENABLED
+ #define USB_OTG_EXTERNAL_VBUS_ENABLED
+
+ #ifdef USE_ULPI_PHY
+ #define USB_OTG_ULPI_PHY_ENABLED
+ #endif
+ #ifdef USE_EMBEDDED_PHY
+ #define USB_OTG_EMBEDDED_PHY_ENABLED
+ #endif
+ #ifdef USE_I2C_PHY
+ #define USB_OTG_I2C_PHY_ENABLED
+ #endif
+ #define USB_OTG_HS_INTERNAL_DMA_ENABLED
+ #define USB_OTG_HS_DEDICATED_EP1_ENABLED
+#endif
+
+/****************** USB OTG FS CONFIGURATION **********************************/
+#ifdef USB_OTG_FS_CORE
+ #define RX_FIFO_FS_SIZE 128
+ #define TX0_FIFO_FS_SIZE 64
+ #define TX1_FIFO_FS_SIZE 128
+ #define TX2_FIFO_FS_SIZE 0
+ #define TX3_FIFO_FS_SIZE 0
+ #define TXH_NP_HS_FIFOSIZ 96
+ #define TXH_P_HS_FIFOSIZ 96
+
+ //#define USB_OTG_FS_LOW_PWR_MGMT_SUPPORT
+ //#define USB_OTG_FS_SOF_OUTPUT_ENABLED
+#endif
+
+/****************** USB OTG MODE CONFIGURATION ********************************/
+//#define USE_HOST_MODE
+#define USE_DEVICE_MODE
+//#define USE_OTG_MODE
+
+
+#ifndef USB_OTG_FS_CORE
+ #ifndef USB_OTG_HS_CORE
+ #error "USB_OTG_HS_CORE or USB_OTG_FS_CORE should be defined"
+ #endif
+#endif
+
+
+#ifndef USE_DEVICE_MODE
+ #ifndef USE_HOST_MODE
+ #error "USE_DEVICE_MODE or USE_HOST_MODE should be defined"
+ #endif
+#endif
+
+#ifndef USE_USB_OTG_HS
+ #ifndef USE_USB_OTG_FS
+ #error "USE_USB_OTG_HS or USE_USB_OTG_FS should be defined"
+ #endif
+#else //USE_USB_OTG_HS
+ #ifndef USE_ULPI_PHY
+ #ifndef USE_EMBEDDED_PHY
+ #ifndef USE_I2C_PHY
+ #error "USE_ULPI_PHY or USE_EMBEDDED_PHY or USE_I2C_PHY should be defined"
+ #endif
+ #endif
+ #endif
+#endif
+
+/****************** C Compilers dependant keywords ****************************/
+/* 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 */
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+ #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__ */
+#else
+ #define __ALIGN_BEGIN
+ #define __ALIGN_END
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+
+/* __packed keyword used to decrease the data type alignment to 1-byte */
+#if defined (__CC_ARM) /* ARM Compiler */
+ #define __packed __packed
+#elif defined (__ICCARM__) /* IAR Compiler */
+ #define __packed __packed
+#elif defined ( __GNUC__ ) /* GNU Compiler */
+ #define __packed __attribute__ ((__packed__))
+#elif defined (__TASKING__) /* TASKING Compiler */
+ #define __packed __unaligned
+#endif /* __CC_ARM */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_CONF_Exported_Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_CONF_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USB_CONF_Exported_Variables
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USB_CONF_Exported_FunctionsPrototype
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+#endif //__USB_CONF__H__
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
diff --git a/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_core.h b/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_core.h
new file mode 100644
index 0000000..82a09e1
--- /dev/null
+++ b/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_core.h
@@ -0,0 +1,408 @@
+/**
+ ******************************************************************************
+ * @file usb_core.h
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 22-July-2011
+ * @brief Header of the Core Layer
+ ******************************************************************************
+ * @attention
+ *
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * © COPYRIGHT 2011 STMicroelectronics
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_CORE_H__
+#define __USB_CORE_H__
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_conf.h"
+#include "usb_regs.h"
+#include "usb_defines.h"
+
+
+/** @addtogroup USB_OTG_DRIVER
+ * @{
+ */
+
+/** @defgroup USB_CORE
+ * @brief usb otg driver core layer
+ * @{
+ */
+
+
+/** @defgroup USB_CORE_Exported_Defines
+ * @{
+ */
+
+#define USB_OTG_EP0_IDLE 0
+#define USB_OTG_EP0_SETUP 1
+#define USB_OTG_EP0_DATA_IN 2
+#define USB_OTG_EP0_DATA_OUT 3
+#define USB_OTG_EP0_STATUS_IN 4
+#define USB_OTG_EP0_STATUS_OUT 5
+#define USB_OTG_EP0_STALL 6
+
+#define USB_OTG_EP_TX_DIS 0x0000
+#define USB_OTG_EP_TX_STALL 0x0010
+#define USB_OTG_EP_TX_NAK 0x0020
+#define USB_OTG_EP_TX_VALID 0x0030
+
+#define USB_OTG_EP_RX_DIS 0x0000
+#define USB_OTG_EP_RX_STALL 0x1000
+#define USB_OTG_EP_RX_NAK 0x2000
+#define USB_OTG_EP_RX_VALID 0x3000
+/**
+ * @}
+ */
+#define MAX_DATA_LENGTH 0xFF
+
+/** @defgroup USB_CORE_Exported_Types
+ * @{
+ */
+
+
+typedef enum {
+ USB_OTG_OK = 0,
+ USB_OTG_FAIL
+}USB_OTG_STS;
+
+typedef enum {
+ HC_IDLE = 0,
+ HC_XFRC,
+ HC_HALTED,
+ HC_NAK,
+ HC_NYET,
+ HC_STALL,
+ HC_XACTERR,
+ HC_BBLERR,
+ HC_DATATGLERR,
+}HC_STATUS;
+
+typedef enum {
+ URB_IDLE = 0,
+ URB_DONE,
+ URB_NOTREADY,
+ URB_ERROR,
+ URB_STALL
+}URB_STATE;
+
+typedef enum {
+ CTRL_START = 0,
+ CTRL_XFRC,
+ CTRL_HALTED,
+ CTRL_NAK,
+ CTRL_STALL,
+ CTRL_XACTERR,
+ CTRL_BBLERR,
+ CTRL_DATATGLERR,
+ CTRL_FAIL
+}CTRL_STATUS;
+
+
+typedef struct USB_OTG_hc
+{
+ uint8_t dev_addr ;
+ uint8_t ep_num;
+ uint8_t ep_is_in;
+ uint8_t speed;
+ uint8_t do_ping;
+ uint8_t ep_type;
+ uint16_t max_packet;
+ uint8_t data_pid;
+ uint8_t *xfer_buff;
+ uint32_t xfer_len;
+ uint32_t xfer_count;
+ uint8_t toggle_in;
+ uint8_t toggle_out;
+ uint32_t dma_addr;
+}
+USB_OTG_HC , *PUSB_OTG_HC;
+
+typedef struct USB_OTG_ep
+{
+ uint8_t num;
+ uint8_t is_in;
+ uint8_t is_stall;
+ uint8_t type;
+ uint8_t data_pid_start;
+ uint8_t even_odd_frame;
+ uint16_t tx_fifo_num;
+ uint32_t maxpacket;
+ /* transaction level variables*/
+ uint8_t *xfer_buff;
+ uint32_t dma_addr;
+ uint32_t xfer_len;
+ uint32_t xfer_count;
+ /* Transfer level variables*/
+ uint32_t rem_data_len;
+ uint32_t total_data_len;
+ uint32_t ctl_data_len;
+
+}
+
+USB_OTG_EP , *PUSB_OTG_EP;
+
+
+
+typedef struct USB_OTG_core_cfg
+{
+ uint8_t host_channels;
+ uint8_t dev_endpoints;
+ uint8_t speed;
+ uint8_t dma_enable;
+ uint16_t mps;
+ uint16_t TotalFifoSize;
+ uint8_t phy_itface;
+ uint8_t Sof_output;
+ uint8_t low_power;
+ uint8_t coreID;
+
+}
+USB_OTG_CORE_CFGS, *PUSB_OTG_CORE_CFGS;
+
+
+
+typedef struct usb_setup_req {
+
+ uint8_t bmRequest;
+ uint8_t bRequest;
+ uint16_t wValue;
+ uint16_t wIndex;
+ uint16_t wLength;
+} USB_SETUP_REQ;
+
+typedef struct _Device_TypeDef
+{
+ uint8_t *(*GetDeviceDescriptor)( uint8_t speed , uint16_t *length);
+ uint8_t *(*GetLangIDStrDescriptor)( uint8_t speed , uint16_t *length);
+ uint8_t *(*GetManufacturerStrDescriptor)( uint8_t speed , uint16_t *length);
+ uint8_t *(*GetProductStrDescriptor)( uint8_t speed , uint16_t *length);
+ uint8_t *(*GetSerialStrDescriptor)( uint8_t speed , uint16_t *length);
+ uint8_t *(*GetConfigurationStrDescriptor)( uint8_t speed , uint16_t *length);
+ uint8_t *(*GetInterfaceStrDescriptor)( uint8_t speed , uint16_t *length);
+} USBD_DEVICE, *pUSBD_DEVICE;
+
+typedef struct USB_OTG_hPort
+{
+ void (*Disconnect) (void *phost);
+ void (*Connect) (void *phost);
+ uint8_t ConnStatus;
+ uint8_t DisconnStatus;
+ uint8_t ConnHandled;
+ uint8_t DisconnHandled;
+} USB_OTG_hPort_TypeDef;
+
+typedef struct _Device_cb
+{
+ uint8_t (*Init) (void *pdev , uint8_t cfgidx);
+ uint8_t (*DeInit) (void *pdev , uint8_t cfgidx);
+ /* Control Endpoints*/
+ uint8_t (*Setup) (void *pdev , USB_SETUP_REQ *req);
+ uint8_t (*EP0_TxSent) (void *pdev );
+ uint8_t (*EP0_RxReady) (void *pdev );
+ /* Class Specific Endpoints*/
+ uint8_t (*DataIn) (void *pdev , uint8_t epnum);
+ uint8_t (*DataOut) (void *pdev , uint8_t epnum);
+ uint8_t (*SOF) (void *pdev);
+ uint8_t (*IsoINIncomplete) (void *pdev);
+ uint8_t (*IsoOUTIncomplete) (void *pdev);
+
+ uint8_t *(*GetConfigDescriptor)( uint8_t speed , uint16_t *length);
+#ifdef USB_OTG_HS_CORE
+ uint8_t *(*GetOtherConfigDescriptor)( uint8_t speed , uint16_t *length);
+#endif
+
+#ifdef USB_SUPPORT_USER_STRING_DESC
+ uint8_t *(*GetUsrStrDescriptor)( uint8_t speed ,uint8_t index, uint16_t *length);
+#endif
+
+} USBD_Class_cb_TypeDef;
+
+
+
+typedef struct _USBD_USR_PROP
+{
+ void (*Init)(void);
+ void (*DeviceReset)(uint8_t speed);
+ void (*DeviceConfigured)(void);
+ void (*DeviceSuspended)(void);
+ void (*DeviceResumed)(void);
+
+ void (*DeviceConnected)(void);
+ void (*DeviceDisconnected)(void);
+
+}
+USBD_Usr_cb_TypeDef;
+
+typedef struct _DCD
+{
+ uint8_t device_config;
+ uint8_t device_state;
+ uint8_t device_status;
+ uint8_t device_address;
+ uint32_t DevRemoteWakeup;
+ USB_OTG_EP in_ep [USB_OTG_MAX_TX_FIFOS];
+ USB_OTG_EP out_ep [USB_OTG_MAX_TX_FIFOS];
+ uint8_t setup_packet [8*3];
+ USBD_Class_cb_TypeDef *class_cb;
+ USBD_Usr_cb_TypeDef *usr_cb;
+ USBD_DEVICE *usr_device;
+ uint8_t *pConfig_descriptor;
+ }
+DCD_DEV , *DCD_PDEV;
+
+
+typedef struct _HCD
+{
+ uint8_t Rx_Buffer [MAX_DATA_LENGTH];
+ __IO uint32_t ConnSts;
+ __IO uint32_t ErrCnt[USB_OTG_MAX_TX_FIFOS];
+ __IO uint32_t XferCnt[USB_OTG_MAX_TX_FIFOS];
+ __IO HC_STATUS HC_Status[USB_OTG_MAX_TX_FIFOS];
+ __IO URB_STATE URB_State[USB_OTG_MAX_TX_FIFOS];
+ USB_OTG_HC hc [USB_OTG_MAX_TX_FIFOS];
+ uint16_t channel [USB_OTG_MAX_TX_FIFOS];
+ USB_OTG_hPort_TypeDef *port_cb;
+}
+HCD_DEV , *USB_OTG_USBH_PDEV;
+
+
+typedef struct _OTG
+{
+ uint8_t OTG_State;
+ uint8_t OTG_PrevState;
+ uint8_t OTG_Mode;
+}
+OTG_DEV , *USB_OTG_USBO_PDEV;
+
+typedef struct USB_OTG_handle
+{
+ USB_OTG_CORE_CFGS cfg;
+ USB_OTG_CORE_REGS regs;
+#ifdef USE_DEVICE_MODE
+ DCD_DEV dev;
+#endif
+#ifdef USE_HOST_MODE
+ HCD_DEV host;
+#endif
+#ifdef USE_OTG_MODE
+ OTG_DEV otg;
+#endif
+}
+USB_OTG_CORE_HANDLE , *PUSB_OTG_CORE_HANDLE;
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_CORE_Exported_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USB_CORE_Exported_Variables
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USB_CORE_Exported_FunctionsPrototype
+ * @{
+ */
+
+
+USB_OTG_STS USB_OTG_CoreInit (USB_OTG_CORE_HANDLE *pdev);
+USB_OTG_STS USB_OTG_SelectCore (USB_OTG_CORE_HANDLE *pdev,
+ USB_OTG_CORE_ID_TypeDef coreID);
+USB_OTG_STS USB_OTG_EnableGlobalInt (USB_OTG_CORE_HANDLE *pdev);
+USB_OTG_STS USB_OTG_DisableGlobalInt(USB_OTG_CORE_HANDLE *pdev);
+void* USB_OTG_ReadPacket (USB_OTG_CORE_HANDLE *pdev ,
+ uint8_t *dest,
+ uint16_t len);
+USB_OTG_STS USB_OTG_WritePacket (USB_OTG_CORE_HANDLE *pdev ,
+ uint8_t *src,
+ uint8_t ch_ep_num,
+ uint16_t len);
+USB_OTG_STS USB_OTG_FlushTxFifo (USB_OTG_CORE_HANDLE *pdev , uint32_t num);
+USB_OTG_STS USB_OTG_FlushRxFifo (USB_OTG_CORE_HANDLE *pdev);
+
+uint32_t USB_OTG_ReadCoreItr (USB_OTG_CORE_HANDLE *pdev);
+uint32_t USB_OTG_ReadOtgItr (USB_OTG_CORE_HANDLE *pdev);
+uint8_t USB_OTG_IsHostMode (USB_OTG_CORE_HANDLE *pdev);
+uint8_t USB_OTG_IsDeviceMode (USB_OTG_CORE_HANDLE *pdev);
+uint32_t USB_OTG_GetMode (USB_OTG_CORE_HANDLE *pdev);
+USB_OTG_STS USB_OTG_PhyInit (USB_OTG_CORE_HANDLE *pdev);
+USB_OTG_STS USB_OTG_SetCurrentMode (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t mode);
+
+/*********************** HOST APIs ********************************************/
+#ifdef USE_HOST_MODE
+USB_OTG_STS USB_OTG_CoreInitHost (USB_OTG_CORE_HANDLE *pdev);
+USB_OTG_STS USB_OTG_EnableHostInt (USB_OTG_CORE_HANDLE *pdev);
+USB_OTG_STS USB_OTG_HC_Init (USB_OTG_CORE_HANDLE *pdev, uint8_t hc_num);
+USB_OTG_STS USB_OTG_HC_Halt (USB_OTG_CORE_HANDLE *pdev, uint8_t hc_num);
+USB_OTG_STS USB_OTG_HC_StartXfer (USB_OTG_CORE_HANDLE *pdev, uint8_t hc_num);
+USB_OTG_STS USB_OTG_HC_DoPing (USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num);
+uint32_t USB_OTG_ReadHostAllChannels_intr (USB_OTG_CORE_HANDLE *pdev);
+uint32_t USB_OTG_ResetPort (USB_OTG_CORE_HANDLE *pdev);
+uint32_t USB_OTG_ReadHPRT0 (USB_OTG_CORE_HANDLE *pdev);
+void USB_OTG_DriveVbus (USB_OTG_CORE_HANDLE *pdev, uint8_t state);
+void USB_OTG_InitFSLSPClkSel (USB_OTG_CORE_HANDLE *pdev ,uint8_t freq);
+uint8_t USB_OTG_IsEvenFrame (USB_OTG_CORE_HANDLE *pdev) ;
+void USB_OTG_StopHost (USB_OTG_CORE_HANDLE *pdev);
+#endif
+/********************* DEVICE APIs ********************************************/
+#ifdef USE_DEVICE_MODE
+USB_OTG_STS USB_OTG_CoreInitDev (USB_OTG_CORE_HANDLE *pdev);
+USB_OTG_STS USB_OTG_EnableDevInt (USB_OTG_CORE_HANDLE *pdev);
+uint32_t USB_OTG_ReadDevAllInEPItr (USB_OTG_CORE_HANDLE *pdev);
+enum USB_OTG_SPEED USB_OTG_GetDeviceSpeed (USB_OTG_CORE_HANDLE *pdev);
+USB_OTG_STS USB_OTG_EP0Activate (USB_OTG_CORE_HANDLE *pdev);
+USB_OTG_STS USB_OTG_EPActivate (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep);
+USB_OTG_STS USB_OTG_EPDeactivate(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep);
+USB_OTG_STS USB_OTG_EPStartXfer (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep);
+USB_OTG_STS USB_OTG_EP0StartXfer(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep);
+USB_OTG_STS USB_OTG_EPSetStall (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep);
+USB_OTG_STS USB_OTG_EPClearStall (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep);
+uint32_t USB_OTG_ReadDevAllOutEp_itr (USB_OTG_CORE_HANDLE *pdev);
+uint32_t USB_OTG_ReadDevOutEP_itr (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum);
+uint32_t USB_OTG_ReadDevAllInEPItr (USB_OTG_CORE_HANDLE *pdev);
+void USB_OTG_InitDevSpeed (USB_OTG_CORE_HANDLE *pdev , uint8_t speed);
+uint8_t USBH_IsEvenFrame (USB_OTG_CORE_HANDLE *pdev);
+void USB_OTG_EP0_OutStart(USB_OTG_CORE_HANDLE *pdev);
+void USB_OTG_ActiveRemoteWakeup(USB_OTG_CORE_HANDLE *pdev);
+void USB_OTG_UngateClock(USB_OTG_CORE_HANDLE *pdev);
+void USB_OTG_StopDevice(USB_OTG_CORE_HANDLE *pdev);
+void USB_OTG_SetEPStatus (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep , uint32_t Status);
+uint32_t USB_OTG_GetEPStatus(USB_OTG_CORE_HANDLE *pdev ,USB_OTG_EP *ep);
+#endif
+/**
+ * @}
+ */
+
+#endif /* __USB_CORE_H__ */
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
diff --git a/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_dcd.h b/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_dcd.h
new file mode 100644
index 0000000..6bfd899
--- /dev/null
+++ b/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_dcd.h
@@ -0,0 +1,158 @@
+/**
+ ******************************************************************************
+ * @file usb_dcd.h
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 22-July-2011
+ * @brief Peripheral Driver Header file
+ ******************************************************************************
+ * @attention
+ *
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * © COPYRIGHT 2011 STMicroelectronics
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __DCD_H__
+#define __DCD_H__
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_core.h"
+
+
+/** @addtogroup USB_OTG_DRIVER
+* @{
+*/
+
+/** @defgroup USB_DCD
+* @brief This file is the
+* @{
+*/
+
+
+/** @defgroup USB_DCD_Exported_Defines
+* @{
+*/
+#define USB_OTG_EP_CONTROL 0
+#define USB_OTG_EP_ISOC 1
+#define USB_OTG_EP_BULK 2
+#define USB_OTG_EP_INT 3
+#define USB_OTG_EP_MASK 3
+
+/* Device Status */
+#define USB_OTG_DEFAULT 1
+#define USB_OTG_ADDRESSED 2
+#define USB_OTG_CONFIGURED 3
+#define USB_OTG_SUSPENDED 4
+
+/**
+* @}
+*/
+
+
+/** @defgroup USB_DCD_Exported_Types
+* @{
+*/
+/********************************************************************************
+Data structure type
+********************************************************************************/
+typedef struct
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint8_t bEndpointAddress;
+ uint8_t bmAttributes;
+ uint16_t wMaxPacketSize;
+ uint8_t bInterval;
+}
+EP_DESCRIPTOR , *PEP_DESCRIPTOR;
+
+/**
+* @}
+*/
+
+
+/** @defgroup USB_DCD_Exported_Macros
+* @{
+*/
+/**
+* @}
+*/
+
+/** @defgroup USB_DCD_Exported_Variables
+* @{
+*/
+/**
+* @}
+*/
+
+/** @defgroup USB_DCD_Exported_FunctionsPrototype
+* @{
+*/
+/********************************************************************************
+EXPORTED FUNCTION FROM THE USB-OTG LAYER
+********************************************************************************/
+void DCD_Init(USB_OTG_CORE_HANDLE *pdev ,
+ USB_OTG_CORE_ID_TypeDef coreID);
+
+void DCD_DevConnect (USB_OTG_CORE_HANDLE *pdev);
+void DCD_DevDisconnect (USB_OTG_CORE_HANDLE *pdev);
+void DCD_EP_SetAddress (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t address);
+uint32_t DCD_EP_Open(USB_OTG_CORE_HANDLE *pdev ,
+ uint8_t ep_addr,
+ uint16_t ep_mps,
+ uint8_t ep_type);
+
+uint32_t DCD_EP_Close (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t ep_addr);
+
+
+uint32_t DCD_EP_PrepareRx ( USB_OTG_CORE_HANDLE *pdev,
+ uint8_t ep_addr,
+ uint8_t *pbuf,
+ uint16_t buf_len);
+
+uint32_t DCD_EP_Tx (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t ep_addr,
+ uint8_t *pbuf,
+ uint32_t buf_len);
+uint32_t DCD_EP_Stall (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t epnum);
+uint32_t DCD_EP_ClrStall (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t epnum);
+uint32_t DCD_EP_Flush (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t epnum);
+uint32_t DCD_Handle_ISR(USB_OTG_CORE_HANDLE *pdev);
+
+uint32_t DCD_GetEPStatus(USB_OTG_CORE_HANDLE *pdev ,
+ uint8_t epnum);
+
+void DCD_SetEPStatus (USB_OTG_CORE_HANDLE *pdev ,
+ uint8_t epnum ,
+ uint32_t Status);
+
+/**
+* @}
+*/
+
+
+#endif //__DCD_H__
+
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
diff --git a/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_dcd_int.h b/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_dcd_int.h
new file mode 100644
index 0000000..9df1a41
--- /dev/null
+++ b/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_dcd_int.h
@@ -0,0 +1,121 @@
+/**
+ ******************************************************************************
+ * @file usb_dcd_int.h
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 22-July-2011
+ * @brief Peripheral Device Interface Layer
+ ******************************************************************************
+ * @attention
+ *
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * © COPYRIGHT 2011 STMicroelectronics
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef USB_DCD_INT_H__
+#define USB_DCD_INT_H__
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_dcd.h"
+
+
+
+/** @addtogroup USB_OTG_DRIVER
+ * @{
+ */
+
+/** @defgroup USB_DCD_INT
+ * @brief This file is the
+ * @{
+ */
+
+
+/** @defgroup USB_DCD_INT_Exported_Defines
+ * @{
+ */
+
+typedef struct _USBD_DCD_INT
+{
+ uint8_t (* DataOutStage) (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum);
+ uint8_t (* DataInStage) (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum);
+ uint8_t (* SetupStage) (USB_OTG_CORE_HANDLE *pdev);
+ uint8_t (* SOF) (USB_OTG_CORE_HANDLE *pdev);
+ uint8_t (* Reset) (USB_OTG_CORE_HANDLE *pdev);
+ uint8_t (* Suspend) (USB_OTG_CORE_HANDLE *pdev);
+ uint8_t (* Resume) (USB_OTG_CORE_HANDLE *pdev);
+ uint8_t (* IsoINIncomplete) (USB_OTG_CORE_HANDLE *pdev);
+ uint8_t (* IsoOUTIncomplete) (USB_OTG_CORE_HANDLE *pdev);
+
+ uint8_t (* DevConnected) (USB_OTG_CORE_HANDLE *pdev);
+ uint8_t (* DevDisconnected) (USB_OTG_CORE_HANDLE *pdev);
+
+}USBD_DCD_INT_cb_TypeDef;
+
+extern USBD_DCD_INT_cb_TypeDef *USBD_DCD_INT_fops;
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_DCD_INT_Exported_Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USB_DCD_INT_Exported_Macros
+ * @{
+ */
+
+#define CLEAR_IN_EP_INTR(epnum,intr) \
+ diepint.d32=0; \
+ diepint.b.intr = 1; \
+ USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[epnum]->DIEPINT,diepint.d32);
+
+#define CLEAR_OUT_EP_INTR(epnum,intr) \
+ doepint.d32=0; \
+ doepint.b.intr = 1; \
+ USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[epnum]->DOEPINT,doepint.d32);
+
+/**
+ * @}
+ */
+
+/** @defgroup USB_DCD_INT_Exported_Variables
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USB_DCD_INT_Exported_FunctionsPrototype
+ * @{
+ */
+
+uint32_t USBD_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev);
+
+/**
+ * @}
+ */
+
+
+#endif // USB_DCD_INT_H__
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
diff --git a/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_defines.h b/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_defines.h
new file mode 100644
index 0000000..b119c25
--- /dev/null
+++ b/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_defines.h
@@ -0,0 +1,244 @@
+/**
+ ******************************************************************************
+ * @file usb_defines.h
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 22-July-2011
+ * @brief Header of the Core Layer
+ ******************************************************************************
+ * @attention
+ *
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * © COPYRIGHT 2011 STMicroelectronics
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_DEF_H__
+#define __USB_DEF_H__
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_conf.h"
+
+/** @addtogroup USB_OTG_DRIVER
+ * @{
+ */
+
+/** @defgroup USB_DEFINES
+ * @brief This file is the
+ * @{
+ */
+
+
+/** @defgroup USB_DEFINES_Exported_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup _CORE_DEFINES_
+ * @{
+ */
+
+#define USB_OTG_SPEED_PARAM_HIGH 0
+#define USB_OTG_SPEED_PARAM_HIGH_IN_FULL 1
+#define USB_OTG_SPEED_PARAM_FULL 3
+
+#define USB_OTG_SPEED_HIGH 0
+#define USB_OTG_SPEED_FULL 1
+
+#define USB_OTG_ULPI_PHY 1
+#define USB_OTG_EMBEDDED_PHY 2
+#define USB_OTG_I2C_PHY 3
+
+/**
+ * @}
+ */
+
+
+/** @defgroup _GLOBAL_DEFINES_
+ * @{
+ */
+#define GAHBCFG_TXFEMPTYLVL_EMPTY 1
+#define GAHBCFG_TXFEMPTYLVL_HALFEMPTY 0
+#define GAHBCFG_GLBINT_ENABLE 1
+#define GAHBCFG_INT_DMA_BURST_SINGLE 0
+#define GAHBCFG_INT_DMA_BURST_INCR 1
+#define GAHBCFG_INT_DMA_BURST_INCR4 3
+#define GAHBCFG_INT_DMA_BURST_INCR8 5
+#define GAHBCFG_INT_DMA_BURST_INCR16 7
+#define GAHBCFG_DMAENABLE 1
+#define GAHBCFG_TXFEMPTYLVL_EMPTY 1
+#define GAHBCFG_TXFEMPTYLVL_HALFEMPTY 0
+#define GRXSTS_PKTSTS_IN 2
+#define GRXSTS_PKTSTS_IN_XFER_COMP 3
+#define GRXSTS_PKTSTS_DATA_TOGGLE_ERR 5
+#define GRXSTS_PKTSTS_CH_HALTED 7
+/**
+ * @}
+ */
+
+
+/** @defgroup _OnTheGo_DEFINES_
+ * @{
+ */
+#define MODE_HNP_SRP_CAPABLE 0
+#define MODE_SRP_ONLY_CAPABLE 1
+#define MODE_NO_HNP_SRP_CAPABLE 2
+#define MODE_SRP_CAPABLE_DEVICE 3
+#define MODE_NO_SRP_CAPABLE_DEVICE 4
+#define MODE_SRP_CAPABLE_HOST 5
+#define MODE_NO_SRP_CAPABLE_HOST 6
+#define A_HOST 1
+#define A_SUSPEND 2
+#define A_PERIPHERAL 3
+#define B_PERIPHERAL 4
+#define B_HOST 5
+#define DEVICE_MODE 0
+#define HOST_MODE 1
+#define OTG_MODE 2
+/**
+ * @}
+ */
+
+
+/** @defgroup __DEVICE_DEFINES_
+ * @{
+ */
+#define DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ 0
+#define DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ 1
+#define DSTS_ENUMSPD_LS_PHY_6MHZ 2
+#define DSTS_ENUMSPD_FS_PHY_48MHZ 3
+
+#define DCFG_FRAME_INTERVAL_80 0
+#define DCFG_FRAME_INTERVAL_85 1
+#define DCFG_FRAME_INTERVAL_90 2
+#define DCFG_FRAME_INTERVAL_95 3
+
+#define DEP0CTL_MPS_64 0
+#define DEP0CTL_MPS_32 1
+#define DEP0CTL_MPS_16 2
+#define DEP0CTL_MPS_8 3
+
+#define EP_SPEED_LOW 0
+#define EP_SPEED_FULL 1
+#define EP_SPEED_HIGH 2
+
+#define EP_TYPE_CTRL 0
+#define EP_TYPE_ISOC 1
+#define EP_TYPE_BULK 2
+#define EP_TYPE_INTR 3
+#define EP_TYPE_MSK 3
+
+#define STS_GOUT_NAK 1
+#define STS_DATA_UPDT 2
+#define STS_XFER_COMP 3
+#define STS_SETUP_COMP 4
+#define STS_SETUP_UPDT 6
+/**
+ * @}
+ */
+
+
+/** @defgroup __HOST_DEFINES_
+ * @{
+ */
+#define HC_PID_DATA0 0
+#define HC_PID_DATA2 1
+#define HC_PID_DATA1 2
+#define HC_PID_SETUP 3
+
+#define HPRT0_PRTSPD_HIGH_SPEED 0
+#define HPRT0_PRTSPD_FULL_SPEED 1
+#define HPRT0_PRTSPD_LOW_SPEED 2
+
+#define HCFG_30_60_MHZ 0
+#define HCFG_48_MHZ 1
+#define HCFG_6_MHZ 2
+
+#define HCCHAR_CTRL 0
+#define HCCHAR_ISOC 1
+#define HCCHAR_BULK 2
+#define HCCHAR_INTR 3
+
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_DEFINES_Exported_Types
+ * @{
+ */
+
+typedef enum
+{
+ USB_OTG_HS_CORE_ID = 0,
+ USB_OTG_FS_CORE_ID = 1
+}USB_OTG_CORE_ID_TypeDef;
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_DEFINES_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USB_DEFINES_Exported_Variables
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USB_DEFINES_Exported_FunctionsPrototype
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup Internal_Macro's
+ * @{
+ */
+#define USB_OTG_READ_REG32(reg) (*(__IO uint32_t *)reg)
+#define USB_OTG_WRITE_REG32(reg,value) (*(__IO uint32_t *)reg = value)
+#define USB_OTG_MODIFY_REG32(reg,clear_mask,set_mask) \
+ USB_OTG_WRITE_REG32(reg, (((USB_OTG_READ_REG32(reg)) & ~clear_mask) | set_mask ) )
+
+/********************************************************************************
+ ENUMERATION TYPE
+********************************************************************************/
+enum USB_OTG_SPEED {
+ USB_SPEED_UNKNOWN = 0,
+ USB_SPEED_LOW,
+ USB_SPEED_FULL,
+ USB_SPEED_HIGH
+};
+
+#endif //__USB_DEFINES__H__
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
diff --git a/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_hcd.h b/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_hcd.h
new file mode 100644
index 0000000..15e8ab1
--- /dev/null
+++ b/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_hcd.h
@@ -0,0 +1,102 @@
+/**
+ ******************************************************************************
+ * @file usb_hcd.h
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 22-July-2011
+ * @brief Host layer Header file
+ ******************************************************************************
+ * @attention
+ *
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * © COPYRIGHT 2011 STMicroelectronics
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_HCD_H__
+#define __USB_HCD_H__
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_regs.h"
+#include "usb_core.h"
+
+
+/** @addtogroup USB_OTG_DRIVER
+ * @{
+ */
+
+/** @defgroup USB_HCD
+ * @brief This file is the
+ * @{
+ */
+
+
+/** @defgroup USB_HCD_Exported_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_HCD_Exported_Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_HCD_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USB_HCD_Exported_Variables
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USB_HCD_Exported_FunctionsPrototype
+ * @{
+ */
+uint32_t HCD_Init (USB_OTG_CORE_HANDLE *pdev ,
+ USB_OTG_CORE_ID_TypeDef coreID);
+uint32_t HCD_HC_Init (USB_OTG_CORE_HANDLE *pdev ,
+ uint8_t hc_num);
+uint32_t HCD_SubmitRequest (USB_OTG_CORE_HANDLE *pdev ,
+ uint8_t hc_num) ;
+uint32_t HCD_GetCurrentSpeed (USB_OTG_CORE_HANDLE *pdev);
+uint32_t HCD_ResetPort (USB_OTG_CORE_HANDLE *pdev);
+uint32_t HCD_IsDeviceConnected (USB_OTG_CORE_HANDLE *pdev);
+uint32_t HCD_GetCurrentFrame (USB_OTG_CORE_HANDLE *pdev) ;
+URB_STATE HCD_GetURB_State (USB_OTG_CORE_HANDLE *pdev, uint8_t ch_num);
+uint32_t HCD_GetXferCnt (USB_OTG_CORE_HANDLE *pdev, uint8_t ch_num);
+HC_STATUS HCD_GetHCState (USB_OTG_CORE_HANDLE *pdev, uint8_t ch_num) ;
+/**
+ * @}
+ */
+
+#endif //__USB_HCD_H__
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
diff --git a/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_hcd_int.h b/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_hcd_int.h
new file mode 100644
index 0000000..c95c59f
--- /dev/null
+++ b/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_hcd_int.h
@@ -0,0 +1,126 @@
+/**
+ ******************************************************************************
+ * @file usb_hcd_int.h
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 22-July-2011
+ * @brief Peripheral Device Interface Layer
+ ******************************************************************************
+ * @attention
+ *
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * © COPYRIGHT 2011 STMicroelectronics
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __HCD_INT_H__
+#define __HCD_INT_H__
+
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_hcd.h"
+
+
+/** @addtogroup USB_OTG_DRIVER
+ * @{
+ */
+
+/** @defgroup USB_HCD_INT
+ * @brief This file is the
+ * @{
+ */
+
+
+/** @defgroup USB_HCD_INT_Exported_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_HCD_INT_Exported_Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_HCD_INT_Exported_Macros
+ * @{
+ */
+
+#define CLEAR_HC_INT(HC_REGS, intr) \
+ {\
+ USB_OTG_HCINTn_TypeDef hcint_clear; \
+ hcint_clear.d32 = 0; \
+ hcint_clear.b.intr = 1; \
+ USB_OTG_WRITE_REG32(&((HC_REGS)->HCINT), hcint_clear.d32);\
+ }\
+
+#define MASK_HOST_INT_CHH(hc_num) { USB_OTG_HCGINTMSK_TypeDef GINTMSK; \
+ GINTMSK.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK); \
+ GINTMSK.b.chhltd = 0; \
+ USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK, GINTMSK.d32);}
+
+#define UNMASK_HOST_INT_CHH(hc_num) { USB_OTG_HCGINTMSK_TypeDef GINTMSK; \
+ GINTMSK.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK); \
+ GINTMSK.b.chhltd = 1; \
+ USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK, GINTMSK.d32);}
+
+#define MASK_HOST_INT_ACK(hc_num) { USB_OTG_HCGINTMSK_TypeDef GINTMSK; \
+ GINTMSK.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK); \
+ GINTMSK.b.ack = 0; \
+ USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK, GINTMSK.d32);}
+
+#define UNMASK_HOST_INT_ACK(hc_num) { USB_OTG_HCGINTMSK_TypeDef GINTMSK; \
+ GINTMSK.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK); \
+ GINTMSK.b.ack = 1; \
+ USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK, GINTMSK.d32);}
+
+/**
+ * @}
+ */
+
+/** @defgroup USB_HCD_INT_Exported_Variables
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USB_HCD_INT_Exported_FunctionsPrototype
+ * @{
+ */
+/* Callbacks handler */
+void ConnectCallback_Handler(USB_OTG_CORE_HANDLE *pdev);
+void Disconnect_Callback_Handler(USB_OTG_CORE_HANDLE *pdev);
+void Overcurrent_Callback_Handler(USB_OTG_CORE_HANDLE *pdev);
+uint32_t USBH_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev);
+
+/**
+ * @}
+ */
+
+
+
+#endif //__HCD_INT_H__
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
diff --git a/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_otg.h b/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_otg.h
new file mode 100644
index 0000000..54d61b8
--- /dev/null
+++ b/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_otg.h
@@ -0,0 +1,94 @@
+/**
+ ******************************************************************************
+ * @file usb_otg.h
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 22-July-2011
+ * @brief OTG Core Header
+ ******************************************************************************
+ * @attention
+ *
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * © COPYRIGHT 2011 STMicroelectronics
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_OTG__
+#define __USB_OTG__
+
+
+/** @addtogroup USB_OTG_DRIVER
+ * @{
+ */
+
+/** @defgroup USB_OTG
+ * @brief This file is the
+ * @{
+ */
+
+
+/** @defgroup USB_OTG_Exported_Defines
+ * @{
+ */
+
+
+void USB_OTG_InitiateSRP(void);
+void USB_OTG_InitiateHNP(uint8_t state , uint8_t mode);
+void USB_OTG_Switchback (USB_OTG_CORE_HANDLE *pdev);
+uint32_t USB_OTG_GetCurrentState (USB_OTG_CORE_HANDLE *pdev);
+
+uint32_t STM32_USBO_OTG_ISR_Handler(USB_OTG_CORE_HANDLE *pdev);
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_OTG_Exported_Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_OTG_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USB_OTG_Exported_Variables
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USB_OTG_Exported_FunctionsPrototype
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+#endif //__USB_OTG__
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
diff --git a/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_regs.h b/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_regs.h
new file mode 100644
index 0000000..cd71ddf
--- /dev/null
+++ b/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_regs.h
@@ -0,0 +1,1206 @@
+/**
+ ******************************************************************************
+ * @file usb_regs.h
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 22-July-2011
+ * @brief hardware registers
+ ******************************************************************************
+ * @attention
+ *
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * © COPYRIGHT 2011 STMicroelectronics
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_OTG_REGS_H__
+#define __USB_OTG_REGS_H__
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_conf.h"
+
+
+/** @addtogroup USB_OTG_DRIVER
+ * @{
+ */
+
+/** @defgroup USB_REGS
+ * @brief This file is the
+ * @{
+ */
+
+
+/** @defgroup USB_REGS_Exported_Defines
+ * @{
+ */
+
+#define USB_OTG_HS_BASE_ADDR 0x40040000
+#define USB_OTG_FS_BASE_ADDR 0x50000000
+
+#define USB_OTG_CORE_GLOBAL_REGS_OFFSET 0x000
+#define USB_OTG_DEV_GLOBAL_REG_OFFSET 0x800
+#define USB_OTG_DEV_IN_EP_REG_OFFSET 0x900
+#define USB_OTG_EP_REG_OFFSET 0x20
+#define USB_OTG_DEV_OUT_EP_REG_OFFSET 0xB00
+#define USB_OTG_HOST_GLOBAL_REG_OFFSET 0x400
+#define USB_OTG_HOST_PORT_REGS_OFFSET 0x440
+#define USB_OTG_HOST_CHAN_REGS_OFFSET 0x500
+#define USB_OTG_CHAN_REGS_OFFSET 0x20
+#define USB_OTG_PCGCCTL_OFFSET 0xE00
+#define USB_OTG_DATA_FIFO_OFFSET 0x1000
+#define USB_OTG_DATA_FIFO_SIZE 0x1000
+
+
+#define USB_OTG_MAX_TX_FIFOS 15
+
+#define USB_OTG_HS_MAX_PACKET_SIZE 512
+#define USB_OTG_FS_MAX_PACKET_SIZE 64
+#define USB_OTG_MAX_EP0_SIZE 64
+/**
+ * @}
+ */
+
+/** @defgroup USB_REGS_Exported_Types
+ * @{
+ */
+
+/** @defgroup __USB_OTG_Core_register
+ * @{
+ */
+typedef struct _USB_OTG_GREGS //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*/
+ __IO uint32_t GI2CCTL; /* I2C Access Register 030h*/
+ uint32_t Reserved34; /* PHY Vendor Control Register 034h*/
+ __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[USB_OTG_MAX_TX_FIFOS];/* dev Periodic Transmit FIFO */
+}
+USB_OTG_GREGS;
+/**
+ * @}
+ */
+
+
+/** @defgroup __device_Registers
+ * @{
+ */
+typedef struct _USB_OTG_DREGS // 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*/
+ __IO uint32_t DEACHINT; /* dedicated EP interrupt 838h*/
+ __IO uint32_t DEACHMSK; /* dedicated EP msk 83Ch*/
+ uint32_t Reserved40; /* dedicated EP mask 840h*/
+ __IO uint32_t DINEP1MSK; /* dedicated EP mask 844h*/
+ uint32_t Reserved44[15]; /* Reserved 844-87Ch*/
+ __IO uint32_t DOUTEP1MSK; /* dedicated EP msk 884h*/
+}
+USB_OTG_DREGS;
+/**
+ * @}
+ */
+
+
+/** @defgroup __IN_Endpoint-Specific_Register
+ * @{
+ */
+typedef struct _USB_OTG_INEPREGS
+{
+ __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*/
+ __IO uint32_t DIEPDMA; /* IN Endpoint DMA Address Reg 900h + (ep_num * 20h) + 14h*/
+ __IO uint32_t DTXFSTS;/*IN Endpoint Tx FIFO Status Reg 900h + (ep_num * 20h) + 18h*/
+ uint32_t Reserved18; /* Reserved 900h+(ep_num*20h)+1Ch-900h+ (ep_num * 20h) + 1Ch*/
+}
+USB_OTG_INEPREGS;
+/**
+ * @}
+ */
+
+
+/** @defgroup __OUT_Endpoint-Specific_Registers
+ * @{
+ */
+typedef struct _USB_OTG_OUTEPREGS
+{
+ __IO uint32_t DOEPCTL; /* dev OUT Endpoint Control Reg B00h + (ep_num * 20h) + 00h*/
+ __IO uint32_t DOUTEPFRM; /* dev OUT Endpoint Frame number 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*/
+ __IO uint32_t DOEPDMA; /* dev OUT Endpoint DMA Address B00h + (ep_num * 20h) + 14h*/
+ uint32_t Reserved18[2]; /* Reserved B00h + (ep_num * 20h) + 18h - B00h + (ep_num * 20h) + 1Ch*/
+}
+USB_OTG_OUTEPREGS;
+/**
+ * @}
+ */
+
+
+/** @defgroup __Host_Mode_Register_Structures
+ * @{
+ */
+typedef struct _USB_OTG_HREGS
+{
+ __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;
+/**
+ * @}
+ */
+
+
+/** @defgroup __Host_Channel_Specific_Registers
+ * @{
+ */
+typedef struct _USB_OTG_HC_REGS
+{
+ __IO uint32_t HCCHAR;
+ __IO uint32_t HCSPLT;
+ __IO uint32_t HCINT;
+ __IO uint32_t HCGINTMSK;
+ __IO uint32_t HCTSIZ;
+ __IO uint32_t HCDMA;
+ uint32_t Reserved[2];
+}
+USB_OTG_HC_REGS;
+/**
+ * @}
+ */
+
+
+/** @defgroup __otg_Core_registers
+ * @{
+ */
+typedef struct USB_OTG_core_regs //000h
+{
+ USB_OTG_GREGS *GREGS;
+ USB_OTG_DREGS *DREGS;
+ USB_OTG_HREGS *HREGS;
+ USB_OTG_INEPREGS *INEP_REGS[USB_OTG_MAX_TX_FIFOS];
+ USB_OTG_OUTEPREGS *OUTEP_REGS[USB_OTG_MAX_TX_FIFOS];
+ USB_OTG_HC_REGS *HC_REGS[USB_OTG_MAX_TX_FIFOS];
+ __IO uint32_t *HPRT0;
+ __IO uint32_t *DFIFO[USB_OTG_MAX_TX_FIFOS];
+ __IO uint32_t *PCGCCTL;
+}
+USB_OTG_CORE_REGS , *PUSB_OTG_CORE_REGS;
+typedef union _USB_OTG_OTGCTL_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t sesreqscs :
+ 1;
+uint32_t sesreq :
+ 1;
+uint32_t Reserved2_7 :
+ 6;
+uint32_t hstnegscs :
+ 1;
+uint32_t hnpreq :
+ 1;
+uint32_t hstsethnpen :
+ 1;
+uint32_t devhnpen :
+ 1;
+uint32_t Reserved12_15 :
+ 4;
+uint32_t conidsts :
+ 1;
+uint32_t Reserved17 :
+ 1;
+uint32_t asesvld :
+ 1;
+uint32_t bsesvld :
+ 1;
+uint32_t currmod :
+ 1;
+uint32_t Reserved21_31 :
+ 11;
+ }
+ b;
+} USB_OTG_OTGCTL_TypeDef ;
+typedef union _USB_OTG_GOTGINT_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t Reserved0_1 :
+ 2;
+uint32_t sesenddet :
+ 1;
+uint32_t Reserved3_7 :
+ 5;
+uint32_t sesreqsucstschng :
+ 1;
+uint32_t hstnegsucstschng :
+ 1;
+uint32_t reserver10_16 :
+ 7;
+uint32_t hstnegdet :
+ 1;
+uint32_t adevtoutchng :
+ 1;
+uint32_t debdone :
+ 1;
+uint32_t Reserved31_20 :
+ 12;
+ }
+ b;
+} USB_OTG_GOTGINT_TypeDef ;
+typedef union _USB_OTG_GAHBCFG_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t glblintrmsk :
+ 1;
+uint32_t hburstlen :
+ 4;
+uint32_t dmaenable :
+ 1;
+uint32_t Reserved :
+ 1;
+uint32_t nptxfemplvl_txfemplvl :
+ 1;
+uint32_t ptxfemplvl :
+ 1;
+uint32_t Reserved9_31 :
+ 23;
+ }
+ b;
+} USB_OTG_GAHBCFG_TypeDef ;
+typedef union _USB_OTG_GUSBCFG_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t toutcal :
+ 3;
+uint32_t phyif :
+ 1;
+uint32_t ulpi_utmi_sel :
+ 1;
+uint32_t fsintf :
+ 1;
+uint32_t physel :
+ 1;
+uint32_t ddrsel :
+ 1;
+uint32_t srpcap :
+ 1;
+uint32_t hnpcap :
+ 1;
+uint32_t usbtrdtim :
+ 4;
+uint32_t nptxfrwnden :
+ 1;
+uint32_t phylpwrclksel :
+ 1;
+uint32_t otgutmifssel :
+ 1;
+uint32_t ulpi_fsls :
+ 1;
+uint32_t ulpi_auto_res :
+ 1;
+uint32_t ulpi_clk_sus_m :
+ 1;
+uint32_t ulpi_ext_vbus_drv :
+ 1;
+uint32_t ulpi_int_vbus_indicator :
+ 1;
+uint32_t term_sel_dl_pulse :
+ 1;
+uint32_t Reserved :
+ 6;
+uint32_t force_host :
+ 1;
+uint32_t force_dev :
+ 1;
+uint32_t corrupt_tx :
+ 1;
+ }
+ b;
+} USB_OTG_GUSBCFG_TypeDef ;
+typedef union _USB_OTG_GRSTCTL_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t csftrst :
+ 1;
+uint32_t hsftrst :
+ 1;
+uint32_t hstfrm :
+ 1;
+uint32_t intknqflsh :
+ 1;
+uint32_t rxfflsh :
+ 1;
+uint32_t txfflsh :
+ 1;
+uint32_t txfnum :
+ 5;
+uint32_t Reserved11_29 :
+ 19;
+uint32_t dmareq :
+ 1;
+uint32_t ahbidle :
+ 1;
+ }
+ b;
+} USB_OTG_GRSTCTL_TypeDef ;
+typedef union _USB_OTG_GINTMSK_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t Reserved0 :
+ 1;
+uint32_t modemismatch :
+ 1;
+uint32_t otgintr :
+ 1;
+uint32_t sofintr :
+ 1;
+uint32_t rxstsqlvl :
+ 1;
+uint32_t nptxfempty :
+ 1;
+uint32_t ginnakeff :
+ 1;
+uint32_t goutnakeff :
+ 1;
+uint32_t Reserved8 :
+ 1;
+uint32_t i2cintr :
+ 1;
+uint32_t erlysuspend :
+ 1;
+uint32_t usbsuspend :
+ 1;
+uint32_t usbreset :
+ 1;
+uint32_t enumdone :
+ 1;
+uint32_t isooutdrop :
+ 1;
+uint32_t eopframe :
+ 1;
+uint32_t Reserved16 :
+ 1;
+uint32_t epmismatch :
+ 1;
+uint32_t inepintr :
+ 1;
+uint32_t outepintr :
+ 1;
+uint32_t incomplisoin :
+ 1;
+uint32_t incomplisoout :
+ 1;
+uint32_t Reserved22_23 :
+ 2;
+uint32_t portintr :
+ 1;
+uint32_t hcintr :
+ 1;
+uint32_t ptxfempty :
+ 1;
+uint32_t Reserved27 :
+ 1;
+uint32_t conidstschng :
+ 1;
+uint32_t disconnect :
+ 1;
+uint32_t sessreqintr :
+ 1;
+uint32_t wkupintr :
+ 1;
+ }
+ b;
+} USB_OTG_GINTMSK_TypeDef ;
+typedef union _USB_OTG_GINTSTS_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t curmode :
+ 1;
+uint32_t modemismatch :
+ 1;
+uint32_t otgintr :
+ 1;
+uint32_t sofintr :
+ 1;
+uint32_t rxstsqlvl :
+ 1;
+uint32_t nptxfempty :
+ 1;
+uint32_t ginnakeff :
+ 1;
+uint32_t goutnakeff :
+ 1;
+uint32_t Reserved8 :
+ 1;
+uint32_t i2cintr :
+ 1;
+uint32_t erlysuspend :
+ 1;
+uint32_t usbsuspend :
+ 1;
+uint32_t usbreset :
+ 1;
+uint32_t enumdone :
+ 1;
+uint32_t isooutdrop :
+ 1;
+uint32_t eopframe :
+ 1;
+uint32_t intimerrx :
+ 1;
+uint32_t epmismatch :
+ 1;
+uint32_t inepint:
+ 1;
+uint32_t outepintr :
+ 1;
+uint32_t incomplisoin :
+ 1;
+uint32_t incomplisoout :
+ 1;
+uint32_t Reserved22_23 :
+ 2;
+uint32_t portintr :
+ 1;
+uint32_t hcintr :
+ 1;
+uint32_t ptxfempty :
+ 1;
+uint32_t Reserved27 :
+ 1;
+uint32_t conidstschng :
+ 1;
+uint32_t disconnect :
+ 1;
+uint32_t sessreqintr :
+ 1;
+uint32_t wkupintr :
+ 1;
+ }
+ b;
+} USB_OTG_GINTSTS_TypeDef ;
+typedef union _USB_OTG_DRXSTS_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t epnum :
+ 4;
+uint32_t bcnt :
+ 11;
+uint32_t dpid :
+ 2;
+uint32_t pktsts :
+ 4;
+uint32_t fn :
+ 4;
+uint32_t Reserved :
+ 7;
+ }
+ b;
+} USB_OTG_DRXSTS_TypeDef ;
+typedef union _USB_OTG_GRXSTS_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t chnum :
+ 4;
+uint32_t bcnt :
+ 11;
+uint32_t dpid :
+ 2;
+uint32_t pktsts :
+ 4;
+uint32_t Reserved :
+ 11;
+ }
+ b;
+} USB_OTG_GRXFSTS_TypeDef ;
+typedef union _USB_OTG_FSIZ_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t startaddr :
+ 16;
+uint32_t depth :
+ 16;
+ }
+ b;
+} USB_OTG_FSIZ_TypeDef ;
+typedef union _USB_OTG_HNPTXSTS_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t nptxfspcavail :
+ 16;
+uint32_t nptxqspcavail :
+ 8;
+uint32_t nptxqtop_terminate :
+ 1;
+uint32_t nptxqtop_timer :
+ 2;
+uint32_t nptxqtop :
+ 2;
+uint32_t chnum :
+ 2;
+uint32_t Reserved :
+ 1;
+ }
+ b;
+} USB_OTG_HNPTXSTS_TypeDef ;
+typedef union _USB_OTG_DTXFSTSn_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t txfspcavail :
+ 16;
+uint32_t Reserved :
+ 16;
+ }
+ b;
+} USB_OTG_DTXFSTSn_TypeDef ;
+typedef union _USB_OTG_GI2CCTL_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t rwdata :
+ 8;
+uint32_t regaddr :
+ 8;
+uint32_t addr :
+ 7;
+uint32_t i2cen :
+ 1;
+uint32_t ack :
+ 1;
+uint32_t i2csuspctl :
+ 1;
+uint32_t i2cdevaddr :
+ 2;
+uint32_t dat_se0:
+ 1;
+uint32_t Reserved :
+ 1;
+uint32_t rw :
+ 1;
+uint32_t bsydne :
+ 1;
+ }
+ b;
+} USB_OTG_GI2CCTL_TypeDef ;
+typedef union _USB_OTG_GCCFG_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t Reserved_in :
+ 16;
+uint32_t pwdn :
+ 1;
+uint32_t i2cifen :
+ 1;
+uint32_t vbussensingA :
+ 1;
+uint32_t vbussensingB :
+ 1;
+uint32_t sofouten :
+ 1;
+uint32_t disablevbussensing :
+ 1;
+uint32_t Reserved_out :
+ 10;
+ }
+ b;
+} USB_OTG_GCCFG_TypeDef ;
+
+typedef union _USB_OTG_DCFG_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t devspd :
+ 2;
+uint32_t nzstsouthshk :
+ 1;
+uint32_t Reserved3 :
+ 1;
+uint32_t devaddr :
+ 7;
+uint32_t perfrint :
+ 2;
+uint32_t Reserved13_17 :
+ 5;
+uint32_t epmscnt :
+ 4;
+ }
+ b;
+} USB_OTG_DCFG_TypeDef ;
+typedef union _USB_OTG_DCTL_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t rmtwkupsig :
+ 1;
+uint32_t sftdiscon :
+ 1;
+uint32_t gnpinnaksts :
+ 1;
+uint32_t goutnaksts :
+ 1;
+uint32_t tstctl :
+ 3;
+uint32_t sgnpinnak :
+ 1;
+uint32_t cgnpinnak :
+ 1;
+uint32_t sgoutnak :
+ 1;
+uint32_t cgoutnak :
+ 1;
+uint32_t Reserved :
+ 21;
+ }
+ b;
+} USB_OTG_DCTL_TypeDef ;
+typedef union _USB_OTG_DSTS_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t suspsts :
+ 1;
+uint32_t enumspd :
+ 2;
+uint32_t errticerr :
+ 1;
+uint32_t Reserved4_7:
+ 4;
+uint32_t soffn :
+ 14;
+uint32_t Reserved22_31 :
+ 10;
+ }
+ b;
+} USB_OTG_DSTS_TypeDef ;
+typedef union _USB_OTG_DIEPINTn_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t xfercompl :
+ 1;
+uint32_t epdisabled :
+ 1;
+uint32_t ahberr :
+ 1;
+uint32_t timeout :
+ 1;
+uint32_t intktxfemp :
+ 1;
+uint32_t intknepmis :
+ 1;
+uint32_t inepnakeff :
+ 1;
+uint32_t emptyintr :
+ 1;
+uint32_t txfifoundrn :
+ 1;
+uint32_t Reserved08_31 :
+ 23;
+ }
+ b;
+} USB_OTG_DIEPINTn_TypeDef ;
+typedef union _USB_OTG_DIEPINTn_TypeDef USB_OTG_DIEPMSK_TypeDef ;
+typedef union _USB_OTG_DOEPINTn_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t xfercompl :
+ 1;
+uint32_t epdisabled :
+ 1;
+uint32_t ahberr :
+ 1;
+uint32_t setup :
+ 1;
+uint32_t Reserved04_31 :
+ 28;
+ }
+ b;
+} USB_OTG_DOEPINTn_TypeDef ;
+typedef union _USB_OTG_DOEPINTn_TypeDef USB_OTG_DOEPMSK_TypeDef ;
+
+typedef union _USB_OTG_DAINT_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t in :
+ 16;
+uint32_t out :
+ 16;
+ }
+ ep;
+} USB_OTG_DAINT_TypeDef ;
+
+typedef union _USB_OTG_DTHRCTL_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t non_iso_thr_en :
+ 1;
+uint32_t iso_thr_en :
+ 1;
+uint32_t tx_thr_len :
+ 9;
+uint32_t Reserved11_15 :
+ 5;
+uint32_t rx_thr_en :
+ 1;
+uint32_t rx_thr_len :
+ 9;
+uint32_t Reserved26_31 :
+ 6;
+ }
+ b;
+} USB_OTG_DTHRCTL_TypeDef ;
+typedef union _USB_OTG_DEPCTL_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t mps :
+ 11;
+uint32_t reserved :
+ 4;
+uint32_t usbactep :
+ 1;
+uint32_t dpid :
+ 1;
+uint32_t naksts :
+ 1;
+uint32_t eptype :
+ 2;
+uint32_t snp :
+ 1;
+uint32_t stall :
+ 1;
+uint32_t txfnum :
+ 4;
+uint32_t cnak :
+ 1;
+uint32_t snak :
+ 1;
+uint32_t setd0pid :
+ 1;
+uint32_t setd1pid :
+ 1;
+uint32_t epdis :
+ 1;
+uint32_t epena :
+ 1;
+ }
+ b;
+} USB_OTG_DEPCTL_TypeDef ;
+typedef union _USB_OTG_DEPXFRSIZ_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t xfersize :
+ 19;
+uint32_t pktcnt :
+ 10;
+uint32_t mc :
+ 2;
+uint32_t Reserved :
+ 1;
+ }
+ b;
+} USB_OTG_DEPXFRSIZ_TypeDef ;
+typedef union _USB_OTG_DEP0XFRSIZ_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t xfersize :
+ 7;
+uint32_t Reserved7_18 :
+ 12;
+uint32_t pktcnt :
+ 2;
+uint32_t Reserved20_28 :
+ 9;
+uint32_t supcnt :
+ 2;
+ uint32_t Reserved31;
+ }
+ b;
+} USB_OTG_DEP0XFRSIZ_TypeDef ;
+typedef union _USB_OTG_HCFG_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t fslspclksel :
+ 2;
+uint32_t fslssupp :
+ 1;
+ }
+ b;
+} USB_OTG_HCFG_TypeDef ;
+typedef union _USB_OTG_HFRMINTRVL_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t frint :
+ 16;
+uint32_t Reserved :
+ 16;
+ }
+ b;
+} USB_OTG_HFRMINTRVL_TypeDef ;
+
+typedef union _USB_OTG_HFNUM_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t frnum :
+ 16;
+uint32_t frrem :
+ 16;
+ }
+ b;
+} USB_OTG_HFNUM_TypeDef ;
+typedef union _USB_OTG_HPTXSTS_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t ptxfspcavail :
+ 16;
+uint32_t ptxqspcavail :
+ 8;
+uint32_t ptxqtop_terminate :
+ 1;
+uint32_t ptxqtop_timer :
+ 2;
+uint32_t ptxqtop :
+ 2;
+uint32_t chnum :
+ 2;
+uint32_t ptxqtop_odd :
+ 1;
+ }
+ b;
+} USB_OTG_HPTXSTS_TypeDef ;
+typedef union _USB_OTG_HPRT0_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t prtconnsts :
+ 1;
+uint32_t prtconndet :
+ 1;
+uint32_t prtena :
+ 1;
+uint32_t prtenchng :
+ 1;
+uint32_t prtovrcurract :
+ 1;
+uint32_t prtovrcurrchng :
+ 1;
+uint32_t prtres :
+ 1;
+uint32_t prtsusp :
+ 1;
+uint32_t prtrst :
+ 1;
+uint32_t Reserved9 :
+ 1;
+uint32_t prtlnsts :
+ 2;
+uint32_t prtpwr :
+ 1;
+uint32_t prttstctl :
+ 4;
+uint32_t prtspd :
+ 2;
+uint32_t Reserved19_31 :
+ 13;
+ }
+ b;
+} USB_OTG_HPRT0_TypeDef ;
+typedef union _USB_OTG_HAINT_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t chint :
+ 16;
+uint32_t Reserved :
+ 16;
+ }
+ b;
+} USB_OTG_HAINT_TypeDef ;
+typedef union _USB_OTG_HAINTMSK_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t chint :
+ 16;
+uint32_t Reserved :
+ 16;
+ }
+ b;
+} USB_OTG_HAINTMSK_TypeDef ;
+typedef union _USB_OTG_HCCHAR_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t mps :
+ 11;
+uint32_t epnum :
+ 4;
+uint32_t epdir :
+ 1;
+uint32_t Reserved :
+ 1;
+uint32_t lspddev :
+ 1;
+uint32_t eptype :
+ 2;
+uint32_t multicnt :
+ 2;
+uint32_t devaddr :
+ 7;
+uint32_t oddfrm :
+ 1;
+uint32_t chdis :
+ 1;
+uint32_t chen :
+ 1;
+ }
+ b;
+} USB_OTG_HCCHAR_TypeDef ;
+typedef union _USB_OTG_HCSPLT_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t prtaddr :
+ 7;
+uint32_t hubaddr :
+ 7;
+uint32_t xactpos :
+ 2;
+uint32_t compsplt :
+ 1;
+uint32_t Reserved :
+ 14;
+uint32_t spltena :
+ 1;
+ }
+ b;
+} USB_OTG_HCSPLT_TypeDef ;
+typedef union _USB_OTG_HCINTn_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t xfercompl :
+ 1;
+uint32_t chhltd :
+ 1;
+uint32_t ahberr :
+ 1;
+uint32_t stall :
+ 1;
+uint32_t nak :
+ 1;
+uint32_t ack :
+ 1;
+uint32_t nyet :
+ 1;
+uint32_t xacterr :
+ 1;
+uint32_t bblerr :
+ 1;
+uint32_t frmovrun :
+ 1;
+uint32_t datatglerr :
+ 1;
+uint32_t Reserved :
+ 21;
+ }
+ b;
+} USB_OTG_HCINTn_TypeDef ;
+typedef union _USB_OTG_HCTSIZn_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t xfersize :
+ 19;
+uint32_t pktcnt :
+ 10;
+uint32_t pid :
+ 2;
+uint32_t dopng :
+ 1;
+ }
+ b;
+} USB_OTG_HCTSIZn_TypeDef ;
+typedef union _USB_OTG_HCGINTMSK_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t xfercompl :
+ 1;
+uint32_t chhltd :
+ 1;
+uint32_t ahberr :
+ 1;
+uint32_t stall :
+ 1;
+uint32_t nak :
+ 1;
+uint32_t ack :
+ 1;
+uint32_t nyet :
+ 1;
+uint32_t xacterr :
+ 1;
+uint32_t bblerr :
+ 1;
+uint32_t frmovrun :
+ 1;
+uint32_t datatglerr :
+ 1;
+uint32_t Reserved :
+ 21;
+ }
+ b;
+} USB_OTG_HCGINTMSK_TypeDef ;
+typedef union _USB_OTG_PCGCCTL_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t stoppclk :
+ 1;
+uint32_t gatehclk :
+ 1;
+uint32_t Reserved :
+ 30;
+ }
+ b;
+} USB_OTG_PCGCCTL_TypeDef ;
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_REGS_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USB_REGS_Exported_Variables
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USB_REGS_Exported_FunctionsPrototype
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+#endif //__USB_OTG_REGS_H__
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
diff --git a/example/stm32f4/STM32_USB_OTG_Driver/src/usb_bsp_template.c b/example/stm32f4/STM32_USB_OTG_Driver/src/usb_bsp_template.c
new file mode 100644
index 0000000..c3f515b
--- /dev/null
+++ b/example/stm32f4/STM32_USB_OTG_Driver/src/usb_bsp_template.c
@@ -0,0 +1,200 @@
+/**
+ ******************************************************************************
+ * @file usb_bsp.c
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 22-July-2011
+ * @brief This file is responsible to offer board support package and is
+ * configurable by user.
+ ******************************************************************************
+ * @attention
+ *
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * © COPYRIGHT 2011 STMicroelectronics
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_bsp.h"
+
+/** @addtogroup USB_OTG_DRIVER
+* @{
+*/
+
+/** @defgroup USB_BSP
+ * @brief This file is responsible to offer board support package
+ * @{
+ */
+
+/** @defgroup USB_BSP_Private_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_BSP_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+
+
+
+/** @defgroup USB_BSP_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBH_BSP_Private_Variables
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBH_BSP_Private_FunctionPrototypes
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USB_BSP_Private_Functions
+ * @{
+ */
+
+
+/**
+ * @brief USB_OTG_BSP_Init
+ * Initilizes BSP configurations
+ * @param None
+ * @retval None
+ */
+
+void USB_OTG_BSP_Init(void)
+{
+
+}
+/**
+ * @brief USB_OTG_BSP_EnableInterrupt
+ * Enabele USB Global interrupt
+ * @param None
+ * @retval None
+ */
+void USB_OTG_BSP_EnableInterrupt(void)
+{
+
+}
+
+/**
+ * @brief BSP_Drive_VBUS
+ * Drives the Vbus signal through IO
+ * @param speed : Full, Low
+ * @param state : VBUS states
+ * @retval None
+ */
+
+void USB_OTG_BSP_DriveVBUS(uint32_t speed, uint8_t state)
+{
+
+}
+
+/**
+ * @brief USB_OTG_BSP_ConfigVBUS
+ * Configures the IO for the Vbus and OverCurrent
+ * @param Speed : Full, Low
+ * @retval None
+ */
+
+void USB_OTG_BSP_ConfigVBUS(uint32_t speed)
+{
+
+}
+
+/**
+ * @brief USB_OTG_BSP_TimeInit
+ * Initialises delay unit Systick timer /Timer2
+ * @param None
+ * @retval None
+ */
+void USB_OTG_BSP_TimeInit ( void )
+{
+
+}
+
+/**
+ * @brief USB_OTG_BSP_uDelay
+ * This function provides delay time in micro sec
+ * @param usec : Value of delay required in micro sec
+ * @retval None
+ */
+void USB_OTG_BSP_uDelay (const uint32_t usec)
+{
+
+ uint32_t count = 0;
+ const uint32_t utime = (120 * usec / 7);
+ do
+ {
+ if ( ++count > utime )
+ {
+ return ;
+ }
+ }
+ while (1);
+
+}
+
+
+/**
+ * @brief USB_OTG_BSP_mDelay
+ * This function provides delay time in milli sec
+ * @param msec : Value of delay required in milli sec
+ * @retval None
+ */
+void USB_OTG_BSP_mDelay (const uint32_t msec)
+{
+
+ USB_OTG_BSP_uDelay(msec * 1000);
+
+}
+
+
+/**
+ * @brief USB_OTG_BSP_TimerIRQ
+ * Time base IRQ
+ * @param None
+ * @retval None
+ */
+
+void USB_OTG_BSP_TimerIRQ (void)
+{
+
+}
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
diff --git a/example/stm32f4/STM32_USB_OTG_Driver/src/usb_core.c b/example/stm32f4/STM32_USB_OTG_Driver/src/usb_core.c
new file mode 100644
index 0000000..74e432a
--- /dev/null
+++ b/example/stm32f4/STM32_USB_OTG_Driver/src/usb_core.c
@@ -0,0 +1,2187 @@
+/**
+ ******************************************************************************
+ * @file usb_core.c
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 22-July-2011
+ * @brief USB-OTG Core Layer
+ ******************************************************************************
+ * @attention
+ *
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * © COPYRIGHT 2011 STMicroelectronics
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_core.h"
+#include "usb_bsp.h"
+
+
+/** @addtogroup USB_OTG_DRIVER
+* @{
+*/
+
+/** @defgroup USB_CORE
+* @brief This file includes the USB-OTG Core Layer
+* @{
+*/
+
+
+/** @defgroup USB_CORE_Private_Defines
+* @{
+*/
+
+/**
+* @}
+*/
+
+
+/** @defgroup USB_CORE_Private_TypesDefinitions
+* @{
+*/
+/**
+* @}
+*/
+
+
+
+/** @defgroup USB_CORE_Private_Macros
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USB_CORE_Private_Variables
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USB_CORE_Private_FunctionPrototypes
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USB_CORE_Private_Functions
+* @{
+*/
+
+/**
+* @brief USB_OTG_EnableCommonInt
+* Initializes the commmon interrupts, used in both device and modes
+* @param pdev : Selected device
+* @retval None
+*/
+static void USB_OTG_EnableCommonInt(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_GINTMSK_TypeDef int_mask;
+
+ int_mask.d32 = 0;
+ /* Clear any pending USB_OTG Interrupts */
+#ifndef USE_OTG_MODE
+ USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GOTGINT, 0xFFFFFFFF);
+#endif
+ /* Clear any pending interrupts */
+ USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTSTS, 0xFFFFFFFF);
+ /* Enable the interrupts in the INTMSK */
+ int_mask.b.wkupintr = 1;
+ int_mask.b.usbsuspend = 1;
+
+#ifdef USE_OTG_MODE
+ int_mask.b.otgintr = 1;
+ int_mask.b.sessreqintr = 1;
+ int_mask.b.conidstschng = 1;
+#endif
+ USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTMSK, int_mask.d32);
+}
+
+/**
+* @brief USB_OTG_CoreReset : Soft reset of the core
+* @param pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+static USB_OTG_STS USB_OTG_CoreReset(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ __IO USB_OTG_GRSTCTL_TypeDef greset;
+ uint32_t count = 0;
+
+ greset.d32 = 0;
+ /* Wait for AHB master IDLE state. */
+ do
+ {
+ USB_OTG_BSP_uDelay(3);
+ greset.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GRSTCTL);
+ if (++count > 200000)
+ {
+ return USB_OTG_OK;
+ }
+ }
+ while (greset.b.ahbidle == 0);
+ /* Core Soft Reset */
+ count = 0;
+ greset.b.csftrst = 1;
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GRSTCTL, greset.d32 );
+ do
+ {
+ greset.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GRSTCTL);
+ if (++count > 200000)
+ {
+ break;
+ }
+ }
+ while (greset.b.csftrst == 1);
+ /* Wait for 3 PHY Clocks*/
+ USB_OTG_BSP_uDelay(3);
+ return status;
+}
+
+/**
+* @brief USB_OTG_WritePacket : Writes a packet into the Tx FIFO associated
+* with the EP
+* @param pdev : Selected device
+* @param src : source pointer
+* @param ch_ep_num : end point number
+* @param bytes : No. of bytes
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_WritePacket(USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *src,
+ uint8_t ch_ep_num,
+ uint16_t len)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ if (pdev->cfg.dma_enable == 0)
+ {
+ uint32_t count32b= 0 , i= 0;
+ __IO uint32_t *fifo;
+
+ count32b = (len + 3) / 4;
+ fifo = pdev->regs.DFIFO[ch_ep_num];
+ for (i = 0; i < count32b; i++, src+=4)
+ {
+ USB_OTG_WRITE_REG32( fifo, *((__packed uint32_t *)src) );
+ }
+ }
+ return status;
+}
+
+
+/**
+* @brief USB_OTG_ReadPacket : Reads a packet from the Rx FIFO
+* @param pdev : Selected device
+* @param dest : Destination Pointer
+* @param bytes : No. of bytes
+* @retval None
+*/
+void *USB_OTG_ReadPacket(USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *dest,
+ uint16_t len)
+{
+ uint32_t i=0;
+ uint32_t count32b = (len + 3) / 4;
+
+ __IO uint32_t *fifo = pdev->regs.DFIFO[0];
+
+ for ( i = 0; i < count32b; i++, dest += 4 )
+ {
+ *(__packed uint32_t *)dest = USB_OTG_READ_REG32(fifo);
+
+ }
+ return ((void *)dest);
+}
+
+/**
+* @brief USB_OTG_SelectCore
+* Initialize core registers address.
+* @param pdev : Selected device
+* @param coreID : USB OTG Core ID
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_SelectCore(USB_OTG_CORE_HANDLE *pdev,
+ USB_OTG_CORE_ID_TypeDef coreID)
+{
+ uint32_t i , baseAddress = 0;
+ USB_OTG_STS status = USB_OTG_OK;
+
+ pdev->cfg.dma_enable = 0;
+
+ /* at startup the core is in FS mode */
+ pdev->cfg.speed = USB_OTG_SPEED_FULL;
+ pdev->cfg.mps = USB_OTG_FS_MAX_PACKET_SIZE ;
+
+ /* initialize device cfg following its address */
+ if (coreID == USB_OTG_FS_CORE_ID)
+ {
+ baseAddress = USB_OTG_FS_BASE_ADDR;
+ pdev->cfg.coreID = USB_OTG_FS_CORE_ID;
+ pdev->cfg.host_channels = 8 ;
+ pdev->cfg.dev_endpoints = 4 ;
+ pdev->cfg.TotalFifoSize = 320; /* in 32-bits */
+ pdev->cfg.phy_itface = USB_OTG_EMBEDDED_PHY;
+
+#ifdef USB_OTG_FS_SOF_OUTPUT_ENABLED
+ pdev->cfg.Sof_output = 1;
+#endif
+
+#ifdef USB_OTG_FS_LOW_PWR_MGMT_SUPPORT
+ pdev->cfg.low_power = 1;
+#endif
+ }
+ else if (coreID == USB_OTG_HS_CORE_ID)
+ {
+ baseAddress = USB_OTG_HS_BASE_ADDR;
+ pdev->cfg.coreID = USB_OTG_HS_CORE_ID;
+ pdev->cfg.host_channels = 12 ;
+ pdev->cfg.dev_endpoints = 6 ;
+ pdev->cfg.TotalFifoSize = 1280;/* in 32-bits */
+
+#ifdef USB_OTG_ULPI_PHY_ENABLED
+ pdev->cfg.phy_itface = USB_OTG_ULPI_PHY;
+#else
+ #ifdef USB_OTG_EMBEDDED_PHY_ENABLED
+ pdev->cfg.phy_itface = USB_OTG_EMBEDDED_PHY;
+ #else
+ #ifdef USB_OTG_I2C_PHY_ENABLED
+ pdev->cfg.phy_itface = USB_OTG_I2C_PHY;
+ #endif
+ #endif
+#endif
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+ pdev->cfg.dma_enable = 1;
+#endif
+
+#ifdef USB_OTG_HS_SOF_OUTPUT_ENABLED
+ pdev->cfg.Sof_output = 1;
+#endif
+
+#ifdef USB_OTG_HS_LOW_PWR_MGMT_SUPPORT
+ pdev->cfg.low_power = 1;
+#endif
+
+ }
+
+ pdev->regs.GREGS = (USB_OTG_GREGS *)(baseAddress + \
+ USB_OTG_CORE_GLOBAL_REGS_OFFSET);
+ pdev->regs.DREGS = (USB_OTG_DREGS *) (baseAddress + \
+ USB_OTG_DEV_GLOBAL_REG_OFFSET);
+
+ for (i = 0; i < pdev->cfg.dev_endpoints; i++)
+ {
+ pdev->regs.INEP_REGS[i] = (USB_OTG_INEPREGS *) \
+ (baseAddress + USB_OTG_DEV_IN_EP_REG_OFFSET + \
+ (i * USB_OTG_EP_REG_OFFSET));
+ pdev->regs.OUTEP_REGS[i] = (USB_OTG_OUTEPREGS *) \
+ (baseAddress + USB_OTG_DEV_OUT_EP_REG_OFFSET + \
+ (i * USB_OTG_EP_REG_OFFSET));
+ }
+ pdev->regs.HREGS = (USB_OTG_HREGS *)(baseAddress + \
+ USB_OTG_HOST_GLOBAL_REG_OFFSET);
+ pdev->regs.HPRT0 = (uint32_t *)(baseAddress + USB_OTG_HOST_PORT_REGS_OFFSET);
+
+ for (i = 0; i < pdev->cfg.host_channels; i++)
+ {
+ pdev->regs.HC_REGS[i] = (USB_OTG_HC_REGS *)(baseAddress + \
+ USB_OTG_HOST_CHAN_REGS_OFFSET + \
+ (i * USB_OTG_CHAN_REGS_OFFSET));
+ }
+ for (i = 0; i < pdev->cfg.host_channels; i++)
+ {
+ pdev->regs.DFIFO[i] = (uint32_t *)(baseAddress + USB_OTG_DATA_FIFO_OFFSET +\
+ (i * USB_OTG_DATA_FIFO_SIZE));
+ }
+ pdev->regs.PCGCCTL = (uint32_t *)(baseAddress + USB_OTG_PCGCCTL_OFFSET);
+
+ return status;
+}
+
+
+/**
+* @brief USB_OTG_CoreInit
+* Initializes the USB_OTG controller registers and prepares the core
+* device mode or host mode operation.
+* @param pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_CoreInit(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ USB_OTG_GUSBCFG_TypeDef usbcfg;
+ USB_OTG_GCCFG_TypeDef gccfg;
+ USB_OTG_GI2CCTL_TypeDef i2cctl;
+ USB_OTG_GAHBCFG_TypeDef ahbcfg;
+
+ usbcfg.d32 = 0;
+ gccfg.d32 = 0;
+ ahbcfg.d32 = 0;
+
+
+
+ if (pdev->cfg.phy_itface == USB_OTG_ULPI_PHY)
+ {
+ gccfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GCCFG);
+ gccfg.b.pwdn = 0;
+
+ if (pdev->cfg.Sof_output)
+ {
+ gccfg.b.sofouten = 1;
+ }
+ USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GCCFG, gccfg.d32);
+
+ /* Init The ULPI Interface */
+ usbcfg.d32 = 0;
+ usbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG);
+
+ usbcfg.b.physel = 0; /* HS Interface */
+#ifdef USB_OTG_INTERNAL_VBUS_ENABLED
+ usbcfg.b.ulpi_ext_vbus_drv = 0; /* Use internal VBUS */
+#else
+ #ifdef USB_OTG_EXTERNAL_VBUS_ENABLED
+ usbcfg.b.ulpi_ext_vbus_drv = 1; /* Use external VBUS */
+ #endif
+#endif
+ usbcfg.b.term_sel_dl_pulse = 0; /* Data line pulsing using utmi_txvalid */
+ usbcfg.b.ulpi_utmi_sel = 1; /* ULPI seleInterfacect */
+
+ usbcfg.b.phyif = 0; /* 8 bits */
+ usbcfg.b.ddrsel = 0; /* single data rate */
+
+ usbcfg.b.ulpi_fsls = 0;
+ usbcfg.b.ulpi_clk_sus_m = 0;
+ USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GUSBCFG, usbcfg.d32);
+
+ /* Reset after a PHY select */
+ USB_OTG_CoreReset(pdev);
+
+ if(pdev->cfg.dma_enable == 1)
+ {
+
+ ahbcfg.b.hburstlen = 5; /* 64 x 32-bits*/
+ ahbcfg.b.dmaenable = 1;
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GAHBCFG, ahbcfg.d32);
+
+ }
+ }
+ else /* FS interface (embedded Phy or I2C Phy) */
+ {
+
+ usbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG);;
+ usbcfg.b.physel = 1; /* FS Interface */
+ USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GUSBCFG, usbcfg.d32);
+ /* Reset after a PHY select and set Host mode */
+ USB_OTG_CoreReset(pdev);
+ /* Enable the I2C interface and deactivate the power down*/
+ gccfg.d32 = 0;
+ gccfg.b.pwdn = 1;
+
+ if(pdev->cfg.phy_itface == USB_OTG_I2C_PHY)
+ {
+ gccfg.b.i2cifen = 1;
+ }
+ gccfg.b.vbussensingA = 1 ;
+ gccfg.b.vbussensingB = 1 ;
+#ifndef VBUS_SENSING_ENABLED
+ gccfg.b.disablevbussensing = 1;
+#endif
+
+ if(pdev->cfg.Sof_output)
+ {
+ gccfg.b.sofouten = 1;
+ }
+
+ USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GCCFG, gccfg.d32);
+ USB_OTG_BSP_mDelay(20);
+ /* Program GUSBCFG.OtgUtmifsSel to I2C*/
+ usbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG);
+
+ if(pdev->cfg.phy_itface == USB_OTG_I2C_PHY)
+ {
+ usbcfg.b.otgutmifssel = 1;
+ }
+
+ USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GUSBCFG, usbcfg.d32);
+
+ if(pdev->cfg.phy_itface == USB_OTG_I2C_PHY)
+ {
+ /*Program GI2CCTL.I2CEn*/
+ i2cctl.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GI2CCTL);
+ i2cctl.b.i2cdevaddr = 1;
+ i2cctl.b.i2cen = 0;
+ i2cctl.b.dat_se0 = 1;
+ i2cctl.b.addr = 0x2D;
+ USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GI2CCTL, i2cctl.d32);
+
+ USB_OTG_BSP_mDelay(200);
+
+ i2cctl.b.i2cen = 1;
+ USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GI2CCTL, i2cctl.d32);
+ USB_OTG_BSP_mDelay(200);
+ }
+ }
+ /* case the HS core is working in FS mode */
+ if(pdev->cfg.dma_enable == 1)
+ {
+
+ ahbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GAHBCFG);
+ ahbcfg.b.hburstlen = 5; /* 64 x 32-bits*/
+ ahbcfg.b.dmaenable = 1;
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GAHBCFG, ahbcfg.d32);
+
+ }
+ /* initialize OTG features */
+#ifdef USE_OTG_MODE
+ usbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG);
+ usbcfg.b.hnpcap = 1;
+ usbcfg.b.srpcap = 1;
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GUSBCFG, usbcfg.d32);
+ USB_OTG_EnableCommonInt(pdev);
+#endif
+ return status;
+}
+/**
+* @brief USB_OTG_EnableGlobalInt
+* Enables the controller's Global Int in the AHB Config reg
+* @param pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_EnableGlobalInt(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ USB_OTG_GAHBCFG_TypeDef ahbcfg;
+
+ ahbcfg.d32 = 0;
+ ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */
+ USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GAHBCFG, 0, ahbcfg.d32);
+ return status;
+}
+
+
+/**
+* @brief USB_OTG_DisableGlobalInt
+* Enables the controller's Global Int in the AHB Config reg
+* @param pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_DisableGlobalInt(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ USB_OTG_GAHBCFG_TypeDef ahbcfg;
+ ahbcfg.d32 = 0;
+ ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */
+ USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GAHBCFG, ahbcfg.d32, 0);
+ return status;
+}
+
+
+/**
+* @brief USB_OTG_FlushTxFifo : Flush a Tx FIFO
+* @param pdev : Selected device
+* @param num : FO num
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_FlushTxFifo (USB_OTG_CORE_HANDLE *pdev , uint32_t num )
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ __IO USB_OTG_GRSTCTL_TypeDef greset;
+
+ uint32_t count = 0;
+ greset.d32 = 0;
+ greset.b.txfflsh = 1;
+ greset.b.txfnum = num;
+ USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GRSTCTL, greset.d32 );
+ do
+ {
+ greset.d32 = USB_OTG_READ_REG32( &pdev->regs.GREGS->GRSTCTL);
+ if (++count > 200000)
+ {
+ break;
+ }
+ }
+ while (greset.b.txfflsh == 1);
+ /* Wait for 3 PHY Clocks*/
+ USB_OTG_BSP_uDelay(3);
+ return status;
+}
+
+
+/**
+* @brief USB_OTG_FlushRxFifo : Flush a Rx FIFO
+* @param pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_FlushRxFifo( USB_OTG_CORE_HANDLE *pdev )
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ __IO USB_OTG_GRSTCTL_TypeDef greset;
+ uint32_t count = 0;
+
+ greset.d32 = 0;
+ greset.b.rxfflsh = 1;
+ USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GRSTCTL, greset.d32 );
+ do
+ {
+ greset.d32 = USB_OTG_READ_REG32( &pdev->regs.GREGS->GRSTCTL);
+ if (++count > 200000)
+ {
+ break;
+ }
+ }
+ while (greset.b.rxfflsh == 1);
+ /* Wait for 3 PHY Clocks*/
+ USB_OTG_BSP_uDelay(3);
+ return status;
+}
+
+
+/**
+* @brief USB_OTG_SetCurrentMode : Set ID line
+* @param pdev : Selected device
+* @param mode : (Host/device)
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_SetCurrentMode(USB_OTG_CORE_HANDLE *pdev , uint8_t mode)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ USB_OTG_GUSBCFG_TypeDef usbcfg;
+
+ usbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG);
+
+ usbcfg.b.force_host = 0;
+ usbcfg.b.force_dev = 0;
+
+ if ( mode == HOST_MODE)
+ {
+ usbcfg.b.force_host = 1;
+ }
+ else if ( mode == DEVICE_MODE)
+ {
+ usbcfg.b.force_dev = 1;
+ }
+
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GUSBCFG, usbcfg.d32);
+ USB_OTG_BSP_mDelay(50);
+ return status;
+}
+
+
+/**
+* @brief USB_OTG_GetMode : Get current mode
+* @param pdev : Selected device
+* @retval current mode
+*/
+uint32_t USB_OTG_GetMode(USB_OTG_CORE_HANDLE *pdev)
+{
+ return (USB_OTG_READ_REG32(&pdev->regs.GREGS->GINTSTS ) & 0x1);
+}
+
+
+/**
+* @brief USB_OTG_IsDeviceMode : Check if it is device mode
+* @param pdev : Selected device
+* @retval num_in_ep
+*/
+uint8_t USB_OTG_IsDeviceMode(USB_OTG_CORE_HANDLE *pdev)
+{
+ return (USB_OTG_GetMode(pdev) != HOST_MODE);
+}
+
+
+/**
+* @brief USB_OTG_IsHostMode : Check if it is host mode
+* @param pdev : Selected device
+* @retval num_in_ep
+*/
+uint8_t USB_OTG_IsHostMode(USB_OTG_CORE_HANDLE *pdev)
+{
+ return (USB_OTG_GetMode(pdev) == HOST_MODE);
+}
+
+
+/**
+* @brief USB_OTG_ReadCoreItr : returns the Core Interrupt register
+* @param pdev : Selected device
+* @retval Status
+*/
+uint32_t USB_OTG_ReadCoreItr(USB_OTG_CORE_HANDLE *pdev)
+{
+ uint32_t v = 0;
+ v = USB_OTG_READ_REG32(&pdev->regs.GREGS->GINTSTS);
+ v &= USB_OTG_READ_REG32(&pdev->regs.GREGS->GINTMSK);
+ return v;
+}
+
+
+/**
+* @brief USB_OTG_ReadOtgItr : returns the USB_OTG Interrupt register
+* @param pdev : Selected device
+* @retval Status
+*/
+uint32_t USB_OTG_ReadOtgItr (USB_OTG_CORE_HANDLE *pdev)
+{
+ return (USB_OTG_READ_REG32 (&pdev->regs.GREGS->GOTGINT));
+}
+
+#ifdef USE_HOST_MODE
+/**
+* @brief USB_OTG_CoreInitHost : Initializes USB_OTG controller for host mode
+* @param pdev : Selected device
+* @retval status
+*/
+USB_OTG_STS USB_OTG_CoreInitHost(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ USB_OTG_FSIZ_TypeDef nptxfifosize;
+ USB_OTG_FSIZ_TypeDef ptxfifosize;
+ USB_OTG_HCFG_TypeDef hcfg;
+
+#ifdef USE_OTG_MODE
+ USB_OTG_OTGCTL_TypeDef gotgctl;
+#endif
+
+ uint32_t i = 0;
+
+ nptxfifosize.d32 = 0;
+ ptxfifosize.d32 = 0;
+#ifdef USE_OTG_MODE
+ gotgctl.d32 = 0;
+#endif
+ hcfg.d32 = 0;
+
+
+ /* configure charge pump IO */
+ USB_OTG_BSP_ConfigVBUS(pdev);
+
+ /* Restart the Phy Clock */
+ USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, 0);
+
+ /* Initialize Host Configuration Register */
+ USB_OTG_InitFSLSPClkSel(pdev , HCFG_48_MHZ); /* in init phase */
+
+ hcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HCFG);
+ hcfg.b.fslssupp = 0;
+ USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HCFG, hcfg.d32);
+
+ /* Configure data FIFO sizes */
+ /* Rx FIFO */
+#ifdef USB_OTG_FS_CORE
+ if(pdev->cfg.coreID == USB_OTG_FS_CORE_ID)
+ {
+ /* set Rx FIFO size */
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GRXFSIZ, RX_FIFO_FS_SIZE);
+ nptxfifosize.b.startaddr = RX_FIFO_FS_SIZE;
+ nptxfifosize.b.depth = TXH_NP_FS_FIFOSIZ;
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->DIEPTXF0_HNPTXFSIZ, nptxfifosize.d32);
+
+ ptxfifosize.b.startaddr = RX_FIFO_FS_SIZE + TXH_NP_FS_FIFOSIZ;
+ ptxfifosize.b.depth = TXH_P_FS_FIFOSIZ;
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->HPTXFSIZ, ptxfifosize.d32);
+ }
+#endif
+#ifdef USB_OTG_HS_CORE
+ if (pdev->cfg.coreID == USB_OTG_HS_CORE_ID)
+ {
+ /* set Rx FIFO size */
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GRXFSIZ, RX_FIFO_HS_SIZE);
+ nptxfifosize.b.startaddr = RX_FIFO_HS_SIZE;
+ nptxfifosize.b.depth = TXH_NP_HS_FIFOSIZ;
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->DIEPTXF0_HNPTXFSIZ, nptxfifosize.d32);
+
+ ptxfifosize.b.startaddr = RX_FIFO_HS_SIZE + TXH_NP_HS_FIFOSIZ;
+ ptxfifosize.b.depth = TXH_P_HS_FIFOSIZ;
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->HPTXFSIZ, ptxfifosize.d32);
+ }
+#endif
+
+#ifdef USE_OTG_MODE
+ /* Clear Host Set HNP Enable in the USB_OTG Control Register */
+ gotgctl.b.hstsethnpen = 1;
+ USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GOTGCTL, gotgctl.d32, 0);
+#endif
+
+ /* Make sure the FIFOs are flushed. */
+ USB_OTG_FlushTxFifo(pdev, 0x10 ); /* all Tx FIFOs */
+ USB_OTG_FlushRxFifo(pdev);
+
+
+ /* Clear all pending HC Interrupts */
+ for (i = 0; i < pdev->cfg.host_channels; i++)
+ {
+ USB_OTG_WRITE_REG32( &pdev->regs.HC_REGS[i]->HCINT, 0xFFFFFFFF );
+ USB_OTG_WRITE_REG32( &pdev->regs.HC_REGS[i]->HCGINTMSK, 0 );
+ }
+#ifndef USE_OTG_MODE
+ USB_OTG_DriveVbus(pdev, 1);
+#endif
+
+ USB_OTG_EnableHostInt(pdev);
+ return status;
+}
+
+/**
+* @brief USB_OTG_IsEvenFrame
+* This function returns the frame number for sof packet
+* @param pdev : Selected device
+* @retval Frame number
+*/
+uint8_t USB_OTG_IsEvenFrame (USB_OTG_CORE_HANDLE *pdev)
+{
+ return !(USB_OTG_READ_REG32(&pdev->regs.HREGS->HFNUM) & 0x1);
+}
+
+/**
+* @brief USB_OTG_DriveVbus : set/reset vbus
+* @param pdev : Selected device
+* @param state : VBUS state
+* @retval None
+*/
+void USB_OTG_DriveVbus (USB_OTG_CORE_HANDLE *pdev, uint8_t state)
+{
+ USB_OTG_HPRT0_TypeDef hprt0;
+
+ hprt0.d32 = 0;
+
+ /* enable disable the external charge pump */
+ USB_OTG_BSP_DriveVBUS(pdev, state);
+
+ /* Turn on the Host port power. */
+ hprt0.d32 = USB_OTG_ReadHPRT0(pdev);
+ if ((hprt0.b.prtpwr == 0 ) && (state == 1 ))
+ {
+ hprt0.b.prtpwr = 1;
+ USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0.d32);
+ }
+ if ((hprt0.b.prtpwr == 1 ) && (state == 0 ))
+ {
+ hprt0.b.prtpwr = 0;
+ USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0.d32);
+ }
+
+ USB_OTG_BSP_mDelay(200);
+}
+/**
+* @brief USB_OTG_EnableHostInt: Enables the Host mode interrupts
+* @param pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_EnableHostInt(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ USB_OTG_GINTMSK_TypeDef intmsk;
+ intmsk.d32 = 0;
+ /* Disable all interrupts. */
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTMSK, 0);
+
+ /* Clear any pending interrupts. */
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, 0xFFFFFFFF);
+
+ /* Enable the common interrupts */
+ USB_OTG_EnableCommonInt(pdev);
+
+ if (pdev->cfg.dma_enable == 0)
+ {
+ intmsk.b.rxstsqlvl = 1;
+ }
+ intmsk.b.portintr = 1;
+ intmsk.b.hcintr = 1;
+ intmsk.b.disconnect = 1;
+ intmsk.b.sofintr = 1;
+ intmsk.b.incomplisoout = 1;
+ USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GINTMSK, intmsk.d32, intmsk.d32);
+ return status;
+}
+
+/**
+* @brief USB_OTG_InitFSLSPClkSel : Initializes the FSLSPClkSel field of the
+* HCFG register on the PHY type
+* @param pdev : Selected device
+* @param freq : clock frequency
+* @retval None
+*/
+void USB_OTG_InitFSLSPClkSel(USB_OTG_CORE_HANDLE *pdev , uint8_t freq)
+{
+ USB_OTG_HCFG_TypeDef hcfg;
+
+ hcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HCFG);
+ hcfg.b.fslspclksel = freq;
+ USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HCFG, hcfg.d32);
+}
+
+
+/**
+* @brief USB_OTG_ReadHPRT0 : Reads HPRT0 to modify later
+* @param pdev : Selected device
+* @retval HPRT0 value
+*/
+uint32_t USB_OTG_ReadHPRT0(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_HPRT0_TypeDef hprt0;
+
+ hprt0.d32 = USB_OTG_READ_REG32(pdev->regs.HPRT0);
+ hprt0.b.prtena = 0;
+ hprt0.b.prtconndet = 0;
+ hprt0.b.prtenchng = 0;
+ hprt0.b.prtovrcurrchng = 0;
+ return hprt0.d32;
+}
+
+
+/**
+* @brief USB_OTG_ReadHostAllChannels_intr : Register PCD Callbacks
+* @param pdev : Selected device
+* @retval Status
+*/
+uint32_t USB_OTG_ReadHostAllChannels_intr (USB_OTG_CORE_HANDLE *pdev)
+{
+ return (USB_OTG_READ_REG32 (&pdev->regs.HREGS->HAINT));
+}
+
+
+/**
+* @brief USB_OTG_ResetPort : Reset Host Port
+* @param pdev : Selected device
+* @retval status
+* @note : (1)The application must wait at least 10 ms (+ 10 ms security)
+* before clearing the reset bit.
+*/
+uint32_t USB_OTG_ResetPort(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_HPRT0_TypeDef hprt0;
+
+ hprt0.d32 = USB_OTG_ReadHPRT0(pdev);
+ hprt0.b.prtrst = 1;
+ USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0.d32);
+ USB_OTG_BSP_mDelay (10); /* See Note #1 */
+ hprt0.b.prtrst = 0;
+ USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0.d32);
+ USB_OTG_BSP_mDelay (20);
+ return 1;
+}
+
+
+/**
+* @brief USB_OTG_HC_Init : Prepares a host channel for transferring packets
+* @param pdev : Selected device
+* @param hc_num : channel number
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_HC_Init(USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ uint32_t intr_enable = 0;
+ USB_OTG_HCGINTMSK_TypeDef hcintmsk;
+ USB_OTG_GINTMSK_TypeDef gintmsk;
+ USB_OTG_HCCHAR_TypeDef hcchar;
+ USB_OTG_HCINTn_TypeDef hcint;
+
+
+ gintmsk.d32 = 0;
+ hcintmsk.d32 = 0;
+ hcchar.d32 = 0;
+
+ /* Clear old interrupt conditions for this host channel. */
+ hcint.d32 = 0xFFFFFFFF;
+ USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCINT, hcint.d32);
+
+ /* Enable channel interrupts required for this transfer. */
+ hcintmsk.d32 = 0;
+
+ if (pdev->cfg.dma_enable == 1)
+ {
+ hcintmsk.b.ahberr = 1;
+ }
+
+ switch (pdev->host.hc[hc_num].ep_type)
+ {
+ case EP_TYPE_CTRL:
+ case EP_TYPE_BULK:
+ hcintmsk.b.xfercompl = 1;
+ hcintmsk.b.stall = 1;
+ hcintmsk.b.xacterr = 1;
+ hcintmsk.b.datatglerr = 1;
+ hcintmsk.b.nak = 1;
+ if (pdev->host.hc[hc_num].ep_is_in)
+ {
+ hcintmsk.b.bblerr = 1;
+ }
+ else
+ {
+ hcintmsk.b.nyet = 1;
+ if (pdev->host.hc[hc_num].do_ping)
+ {
+ hcintmsk.b.ack = 1;
+ }
+ }
+ break;
+ case EP_TYPE_INTR:
+ hcintmsk.b.xfercompl = 1;
+ hcintmsk.b.nak = 1;
+ hcintmsk.b.stall = 1;
+ hcintmsk.b.xacterr = 1;
+ hcintmsk.b.datatglerr = 1;
+ hcintmsk.b.frmovrun = 1;
+
+ if (pdev->host.hc[hc_num].ep_is_in)
+ {
+ hcintmsk.b.bblerr = 1;
+ }
+
+ break;
+ case EP_TYPE_ISOC:
+ hcintmsk.b.xfercompl = 1;
+ hcintmsk.b.frmovrun = 1;
+ hcintmsk.b.ack = 1;
+
+ if (pdev->host.hc[hc_num].ep_is_in)
+ {
+ hcintmsk.b.xacterr = 1;
+ hcintmsk.b.bblerr = 1;
+ }
+ break;
+ }
+
+
+ USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK, hcintmsk.d32);
+
+
+ /* Enable the top level host channel interrupt. */
+ intr_enable = (1 << hc_num);
+ USB_OTG_MODIFY_REG32(&pdev->regs.HREGS->HAINTMSK, 0, intr_enable);
+
+ /* Make sure host channel interrupts are enabled. */
+ gintmsk.b.hcintr = 1;
+ USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GINTMSK, 0, gintmsk.d32);
+
+ /* Program the HCCHAR register */
+ hcchar.d32 = 0;
+ hcchar.b.devaddr = pdev->host.hc[hc_num].dev_addr;
+ hcchar.b.epnum = pdev->host.hc[hc_num].ep_num;
+ hcchar.b.epdir = pdev->host.hc[hc_num].ep_is_in;
+ hcchar.b.lspddev = (pdev->host.hc[hc_num].speed == HPRT0_PRTSPD_LOW_SPEED);
+ hcchar.b.eptype = pdev->host.hc[hc_num].ep_type;
+ hcchar.b.mps = pdev->host.hc[hc_num].max_packet;
+ if (pdev->host.hc[hc_num].ep_type == HCCHAR_INTR)
+ {
+ hcchar.b.oddfrm = 1;
+ }
+ USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR, hcchar.d32);
+ return status;
+}
+
+
+/**
+* @brief USB_OTG_HC_StartXfer : Start transfer
+* @param pdev : Selected device
+* @param hc_num : channel number
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_HC_StartXfer(USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ USB_OTG_HCCHAR_TypeDef hcchar;
+ USB_OTG_HCTSIZn_TypeDef hctsiz;
+ USB_OTG_HNPTXSTS_TypeDef hnptxsts;
+ USB_OTG_HPTXSTS_TypeDef hptxsts;
+ USB_OTG_GINTMSK_TypeDef intmsk;
+ uint16_t len_words = 0;
+
+ uint16_t num_packets;
+ uint16_t max_hc_pkt_count;
+
+ max_hc_pkt_count = 256;
+ hctsiz.d32 = 0;
+ hcchar.d32 = 0;
+ intmsk.d32 = 0;
+
+ /* Compute the expected number of packets associated to the transfer */
+ if (pdev->host.hc[hc_num].xfer_len > 0)
+ {
+ num_packets = (pdev->host.hc[hc_num].xfer_len + \
+ pdev->host.hc[hc_num].max_packet - 1) / pdev->host.hc[hc_num].max_packet;
+
+ if (num_packets > max_hc_pkt_count)
+ {
+ num_packets = max_hc_pkt_count;
+ pdev->host.hc[hc_num].xfer_len = num_packets * \
+ pdev->host.hc[hc_num].max_packet;
+ }
+ }
+ else
+ {
+ num_packets = 1;
+ }
+ if (pdev->host.hc[hc_num].ep_is_in)
+ {
+ pdev->host.hc[hc_num].xfer_len = num_packets * \
+ pdev->host.hc[hc_num].max_packet;
+ }
+ /* Initialize the HCTSIZn register */
+ hctsiz.b.xfersize = pdev->host.hc[hc_num].xfer_len;
+ hctsiz.b.pktcnt = num_packets;
+ hctsiz.b.pid = pdev->host.hc[hc_num].data_pid;
+ USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCTSIZ, hctsiz.d32);
+
+ if (pdev->cfg.dma_enable == 1)
+ {
+ USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCDMA, (unsigned int)pdev->host.hc[hc_num].xfer_buff);
+ }
+
+
+ hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR);
+ hcchar.b.oddfrm = USB_OTG_IsEvenFrame(pdev);
+
+ /* Set host channel enable */
+ hcchar.b.chen = 1;
+ hcchar.b.chdis = 0;
+ USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR, hcchar.d32);
+
+ if (pdev->cfg.dma_enable == 0) /* Slave mode */
+ {
+ if((pdev->host.hc[hc_num].ep_is_in == 0) &&
+ (pdev->host.hc[hc_num].xfer_len > 0))
+ {
+ switch(pdev->host.hc[hc_num].ep_type)
+ {
+ /* Non periodic transfer */
+ case EP_TYPE_CTRL:
+ case EP_TYPE_BULK:
+
+ hnptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->HNPTXSTS);
+ len_words = (pdev->host.hc[hc_num].xfer_len + 3) / 4;
+
+ /* check if there is enough space in FIFO space */
+ if(len_words > hnptxsts.b.nptxfspcavail)
+ {
+ /* need to process data in nptxfempty interrupt */
+ intmsk.b.nptxfempty = 1;
+ USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, 0, intmsk.d32);
+ }
+
+ break;
+ /* Periodic transfer */
+ case EP_TYPE_INTR:
+ case EP_TYPE_ISOC:
+ hptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HPTXSTS);
+ len_words = (pdev->host.hc[hc_num].xfer_len + 3) / 4;
+ /* check if there is enough space in FIFO space */
+ if(len_words > hptxsts.b.ptxfspcavail) /* split the transfer */
+ {
+ /* need to process data in ptxfempty interrupt */
+ intmsk.b.ptxfempty = 1;
+ USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, 0, intmsk.d32);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Write packet into the Tx FIFO. */
+ USB_OTG_WritePacket(pdev,
+ pdev->host.hc[hc_num].xfer_buff ,
+ hc_num, pdev->host.hc[hc_num].xfer_len);
+ }
+ }
+ return status;
+}
+
+
+/**
+* @brief USB_OTG_HC_Halt : Halt channel
+* @param pdev : Selected device
+* @param hc_num : channel number
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_HC_Halt(USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ USB_OTG_HNPTXSTS_TypeDef nptxsts;
+ USB_OTG_HPTXSTS_TypeDef hptxsts;
+ USB_OTG_HCCHAR_TypeDef hcchar;
+
+ nptxsts.d32 = 0;
+ hptxsts.d32 = 0;
+ hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR);
+ hcchar.b.chen = 1;
+ hcchar.b.chdis = 1;
+
+ /* Check for space in the request queue to issue the halt. */
+ if (hcchar.b.eptype == HCCHAR_CTRL || hcchar.b.eptype == HCCHAR_BULK)
+ {
+ nptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->HNPTXSTS);
+ if (nptxsts.b.nptxqspcavail == 0)
+ {
+ hcchar.b.chen = 0;
+ }
+ }
+ else
+ {
+ hptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HPTXSTS);
+ if (hptxsts.b.ptxqspcavail == 0)
+ {
+ hcchar.b.chen = 0;
+ }
+ }
+ USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR, hcchar.d32);
+ return status;
+}
+
+/**
+* @brief Issue a ping token
+* @param None
+* @retval : None
+*/
+USB_OTG_STS USB_OTG_HC_DoPing(USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ USB_OTG_HCCHAR_TypeDef hcchar;
+ USB_OTG_HCTSIZn_TypeDef hctsiz;
+
+ hctsiz.d32 = 0;
+ hctsiz.b.dopng = 1;
+ hctsiz.b.pktcnt = 1;
+ USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCTSIZ, hctsiz.d32);
+
+ hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR);
+ hcchar.b.chen = 1;
+ hcchar.b.chdis = 0;
+ USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR, hcchar.d32);
+ return status;
+}
+
+/**
+* @brief Stop the device and clean up fifo's
+* @param None
+* @retval : None
+*/
+void USB_OTG_StopHost(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_HCCHAR_TypeDef hcchar;
+ uint32_t i;
+
+ USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HAINTMSK , 0);
+ USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HAINT, 0xFFFFFFFF);
+ /* Flush out any leftover queued requests. */
+
+ for (i = 0; i < pdev->cfg.host_channels; i++)
+ {
+ hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[i]->HCCHAR);
+ hcchar.b.chen = 0;
+ hcchar.b.chdis = 1;
+ hcchar.b.epdir = 0;
+ USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[i]->HCCHAR, hcchar.d32);
+ }
+
+ /* Flush the FIFO */
+ USB_OTG_FlushRxFifo(pdev);
+ USB_OTG_FlushTxFifo(pdev , 0x10 );
+}
+#endif
+#ifdef USE_DEVICE_MODE
+/* PCD Core Layer */
+
+/**
+* @brief USB_OTG_InitDevSpeed :Initializes the DevSpd field of DCFG register
+* depending the PHY type and the enumeration speed of the device.
+* @param pdev : Selected device
+* @retval : None
+*/
+void USB_OTG_InitDevSpeed(USB_OTG_CORE_HANDLE *pdev , uint8_t speed)
+{
+ USB_OTG_DCFG_TypeDef dcfg;
+
+ dcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DCFG);
+ dcfg.b.devspd = speed;
+ USB_OTG_WRITE_REG32(&pdev->regs.DREGS->DCFG, dcfg.d32);
+}
+
+
+/**
+* @brief USB_OTG_CoreInitDev : Initializes the USB_OTG controller registers
+* for device mode
+* @param pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_CoreInitDev (USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ USB_OTG_DEPCTL_TypeDef depctl;
+ uint32_t i;
+ USB_OTG_DCFG_TypeDef dcfg;
+ USB_OTG_FSIZ_TypeDef nptxfifosize;
+ USB_OTG_FSIZ_TypeDef txfifosize;
+ USB_OTG_DIEPMSK_TypeDef msk;
+ USB_OTG_DTHRCTL_TypeDef dthrctl;
+
+ depctl.d32 = 0;
+ dcfg.d32 = 0;
+ nptxfifosize.d32 = 0;
+ txfifosize.d32 = 0;
+ msk.d32 = 0;
+
+ /* Restart the Phy Clock */
+ USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, 0);
+ /* Device configuration register */
+ dcfg.d32 = USB_OTG_READ_REG32( &pdev->regs.DREGS->DCFG);
+ dcfg.b.perfrint = DCFG_FRAME_INTERVAL_80;
+ USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DCFG, dcfg.d32 );
+
+#ifdef USB_OTG_FS_CORE
+ if(pdev->cfg.coreID == USB_OTG_FS_CORE_ID )
+ {
+
+ /* Set Full speed phy */
+ USB_OTG_InitDevSpeed (pdev , USB_OTG_SPEED_PARAM_FULL);
+
+ /* set Rx FIFO size */
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GRXFSIZ, RX_FIFO_FS_SIZE);
+
+ /* EP0 TX*/
+ nptxfifosize.b.depth = TX0_FIFO_FS_SIZE;
+ nptxfifosize.b.startaddr = RX_FIFO_FS_SIZE;
+ USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF0_HNPTXFSIZ, nptxfifosize.d32 );
+
+
+ /* EP1 TX*/
+ txfifosize.b.startaddr = nptxfifosize.b.startaddr + nptxfifosize.b.depth;
+ txfifosize.b.depth = TX1_FIFO_FS_SIZE;
+ USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[0], txfifosize.d32 );
+
+
+ /* EP2 TX*/
+ txfifosize.b.startaddr += txfifosize.b.depth;
+ txfifosize.b.depth = TX2_FIFO_FS_SIZE;
+ USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[1], txfifosize.d32 );
+
+
+ /* EP3 TX*/
+ txfifosize.b.startaddr += txfifosize.b.depth;
+ txfifosize.b.depth = TX3_FIFO_FS_SIZE;
+ USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[2], txfifosize.d32 );
+ }
+#endif
+#ifdef USB_OTG_HS_CORE
+ if(pdev->cfg.coreID == USB_OTG_HS_CORE_ID )
+ {
+
+ /* Set High speed phy */
+
+ if(pdev->cfg.phy_itface == USB_OTG_ULPI_PHY)
+ {
+ USB_OTG_InitDevSpeed (pdev , USB_OTG_SPEED_PARAM_HIGH);
+ }
+ else /* set High speed phy in Full speed mode */
+ {
+ USB_OTG_InitDevSpeed (pdev , USB_OTG_SPEED_PARAM_HIGH_IN_FULL);
+ }
+
+ /* set Rx FIFO size */
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GRXFSIZ, RX_FIFO_HS_SIZE);
+
+ /* EP0 TX*/
+ nptxfifosize.b.depth = TX0_FIFO_HS_SIZE;
+ nptxfifosize.b.startaddr = RX_FIFO_HS_SIZE;
+ USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF0_HNPTXFSIZ, nptxfifosize.d32 );
+
+
+ /* EP1 TX*/
+ txfifosize.b.startaddr = nptxfifosize.b.startaddr + nptxfifosize.b.depth;
+ txfifosize.b.depth = TX1_FIFO_HS_SIZE;
+ USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[0], txfifosize.d32 );
+
+
+ /* EP2 TX*/
+ txfifosize.b.startaddr += txfifosize.b.depth;
+ txfifosize.b.depth = TX2_FIFO_HS_SIZE;
+ USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[1], txfifosize.d32 );
+
+
+ /* EP3 TX*/
+ txfifosize.b.startaddr += txfifosize.b.depth;
+ txfifosize.b.depth = TX3_FIFO_HS_SIZE;
+ USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[2], txfifosize.d32 );
+
+ /* EP4 TX*/
+ txfifosize.b.startaddr += txfifosize.b.depth;
+ txfifosize.b.depth = TX4_FIFO_HS_SIZE;
+ USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[3], txfifosize.d32 );
+
+
+ /* EP5 TX*/
+ txfifosize.b.startaddr += txfifosize.b.depth;
+ txfifosize.b.depth = TX5_FIFO_HS_SIZE;
+ USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[4], txfifosize.d32 );
+ }
+#endif
+ /* Flush the FIFOs */
+ USB_OTG_FlushTxFifo(pdev , 0x10); /* all Tx FIFOs */
+ USB_OTG_FlushRxFifo(pdev);
+ /* Clear all pending Device Interrupts */
+ USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DIEPMSK, 0 );
+ USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DOEPMSK, 0 );
+ USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINT, 0xFFFFFFFF );
+ USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINTMSK, 0 );
+
+ for (i = 0; i < pdev->cfg.dev_endpoints; i++)
+ {
+ depctl.d32 = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[i]->DIEPCTL);
+ if (depctl.b.epena)
+ {
+ depctl.d32 = 0;
+ depctl.b.epdis = 1;
+ depctl.b.snak = 1;
+ }
+ else
+ {
+ depctl.d32 = 0;
+ }
+ USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPCTL, depctl.d32);
+ USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPTSIZ, 0);
+ USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPINT, 0xFF);
+ }
+ for (i = 0; i < pdev->cfg.dev_endpoints; i++)
+ {
+ USB_OTG_DEPCTL_TypeDef depctl;
+ depctl.d32 = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[i]->DOEPCTL);
+ if (depctl.b.epena)
+ {
+ depctl.d32 = 0;
+ depctl.b.epdis = 1;
+ depctl.b.snak = 1;
+ }
+ else
+ {
+ depctl.d32 = 0;
+ }
+ USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[i]->DOEPCTL, depctl.d32);
+ USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[i]->DOEPTSIZ, 0);
+ USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[i]->DOEPINT, 0xFF);
+ }
+ msk.d32 = 0;
+ msk.b.txfifoundrn = 1;
+ USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPMSK, msk.d32, msk.d32);
+
+ if (pdev->cfg.dma_enable == 1)
+ {
+ dthrctl.d32 = 0;
+ dthrctl.b.non_iso_thr_en = 1;
+ dthrctl.b.iso_thr_en = 1;
+ dthrctl.b.tx_thr_len = 64;
+ dthrctl.b.rx_thr_en = 1;
+ dthrctl.b.rx_thr_len = 64;
+ USB_OTG_WRITE_REG32(&pdev->regs.DREGS->DTHRCTL, dthrctl.d32);
+ }
+ USB_OTG_EnableDevInt(pdev);
+ return status;
+}
+
+
+/**
+* @brief USB_OTG_EnableDevInt : Enables the Device mode interrupts
+* @param pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_EnableDevInt(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ USB_OTG_GINTMSK_TypeDef intmsk;
+
+ intmsk.d32 = 0;
+
+ /* Disable all interrupts. */
+ USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTMSK, 0);
+ /* Clear any pending interrupts */
+ USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTSTS, 0xFFFFFFFF);
+ /* Enable the common interrupts */
+ USB_OTG_EnableCommonInt(pdev);
+
+ if (pdev->cfg.dma_enable == 0)
+ {
+ intmsk.b.rxstsqlvl = 1;
+ }
+
+ /* Enable interrupts matching to the Device mode ONLY */
+ intmsk.b.usbsuspend = 1;
+ intmsk.b.usbreset = 1;
+ intmsk.b.enumdone = 1;
+ intmsk.b.inepintr = 1;
+ intmsk.b.outepintr = 1;
+ intmsk.b.sofintr = 1;
+
+ intmsk.b.incomplisoin = 1;
+ intmsk.b.incomplisoout = 1;
+#ifdef VBUS_SENSING_ENABLED
+ intmsk.b.sessreqintr = 1;
+ intmsk.b.otgintr = 1;
+#endif
+ USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, intmsk.d32, intmsk.d32);
+ return status;
+}
+
+
+/**
+* @brief USB_OTG_GetDeviceSpeed
+* Get the device speed from the device status register
+* @param None
+* @retval status
+*/
+enum USB_OTG_SPEED USB_OTG_GetDeviceSpeed (USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_DSTS_TypeDef dsts;
+ enum USB_OTG_SPEED speed = USB_SPEED_UNKNOWN;
+
+
+ dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS);
+
+ switch (dsts.b.enumspd)
+ {
+ case DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ:
+ speed = USB_SPEED_HIGH;
+ break;
+ case DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ:
+ case DSTS_ENUMSPD_FS_PHY_48MHZ:
+ speed = USB_SPEED_FULL;
+ break;
+
+ case DSTS_ENUMSPD_LS_PHY_6MHZ:
+ speed = USB_SPEED_LOW;
+ break;
+ }
+
+ return speed;
+}
+/**
+* @brief enables EP0 OUT to receive SETUP packets and configures EP0
+* for transmitting packets
+* @param None
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_EP0Activate(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ USB_OTG_DSTS_TypeDef dsts;
+ USB_OTG_DEPCTL_TypeDef diepctl;
+ USB_OTG_DCTL_TypeDef dctl;
+
+ dctl.d32 = 0;
+ /* Read the Device Status and Endpoint 0 Control registers */
+ dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS);
+ diepctl.d32 = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[0]->DIEPCTL);
+ /* Set the MPS of the IN EP based on the enumeration speed */
+ switch (dsts.b.enumspd)
+ {
+ case DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ:
+ case DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ:
+ case DSTS_ENUMSPD_FS_PHY_48MHZ:
+ diepctl.b.mps = DEP0CTL_MPS_64;
+ break;
+ case DSTS_ENUMSPD_LS_PHY_6MHZ:
+ diepctl.b.mps = DEP0CTL_MPS_8;
+ break;
+ }
+ USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[0]->DIEPCTL, diepctl.d32);
+ dctl.b.cgnpinnak = 1;
+ USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, dctl.d32, dctl.d32);
+ return status;
+}
+
+
+/**
+* @brief USB_OTG_EPActivate : Activates an EP
+* @param pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_EPActivate(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ USB_OTG_DEPCTL_TypeDef depctl;
+ USB_OTG_DAINT_TypeDef daintmsk;
+ __IO uint32_t *addr;
+
+
+ depctl.d32 = 0;
+ daintmsk.d32 = 0;
+ /* Read DEPCTLn register */
+ if (ep->is_in == 1)
+ {
+ addr = &pdev->regs.INEP_REGS[ep->num]->DIEPCTL;
+ daintmsk.ep.in = 1 << ep->num;
+ }
+ else
+ {
+ addr = &pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL;
+ daintmsk.ep.out = 1 << ep->num;
+ }
+ /* If the EP is already active don't change the EP Control
+ * register. */
+ depctl.d32 = USB_OTG_READ_REG32(addr);
+ if (!depctl.b.usbactep)
+ {
+ depctl.b.mps = ep->maxpacket;
+ depctl.b.eptype = ep->type;
+ depctl.b.txfnum = ep->tx_fifo_num;
+ depctl.b.setd0pid = 1;
+ depctl.b.usbactep = 1;
+ USB_OTG_WRITE_REG32(addr, depctl.d32);
+ }
+ /* Enable the Interrupt for this EP */
+#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED
+ if((ep->num == 1)&&(pdev->cfg.coreID == USB_OTG_HS_CORE_ID))
+ {
+ USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DEACHMSK, 0, daintmsk.d32);
+ }
+ else
+#endif
+ USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DAINTMSK, 0, daintmsk.d32);
+ return status;
+}
+
+
+/**
+* @brief USB_OTG_EPDeactivate : Deactivates an EP
+* @param pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_EPDeactivate(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ USB_OTG_DEPCTL_TypeDef depctl;
+ USB_OTG_DAINT_TypeDef daintmsk;
+ __IO uint32_t *addr;
+
+ depctl.d32 = 0;
+ daintmsk.d32 = 0;
+ /* Read DEPCTLn register */
+ if (ep->is_in == 1)
+ {
+ addr = &pdev->regs.INEP_REGS[ep->num]->DIEPCTL;
+ daintmsk.ep.in = 1 << ep->num;
+ }
+ else
+ {
+ addr = &pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL;
+ daintmsk.ep.out = 1 << ep->num;
+ }
+ depctl.b.usbactep = 0;
+ USB_OTG_WRITE_REG32(addr, depctl.d32);
+ /* Disable the Interrupt for this EP */
+
+#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED
+ if((ep->num == 1)&&(pdev->cfg.coreID == USB_OTG_HS_CORE_ID))
+ {
+ USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DEACHMSK, daintmsk.d32, 0);
+ }
+ else
+#endif
+ USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DAINTMSK, daintmsk.d32, 0);
+ return status;
+}
+
+
+/**
+* @brief USB_OTG_EPStartXfer : Handle the setup for data xfer for an EP and
+* starts the xfer
+* @param pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_EPStartXfer(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ USB_OTG_DEPCTL_TypeDef depctl;
+ USB_OTG_DEPXFRSIZ_TypeDef deptsiz;
+ USB_OTG_DSTS_TypeDef dsts;
+ uint32_t fifoemptymsk = 0;
+
+ depctl.d32 = 0;
+ deptsiz.d32 = 0;
+ /* IN endpoint */
+ if (ep->is_in == 1)
+ {
+ depctl.d32 = USB_OTG_READ_REG32(&(pdev->regs.INEP_REGS[ep->num]->DIEPCTL));
+ deptsiz.d32 = USB_OTG_READ_REG32(&(pdev->regs.INEP_REGS[ep->num]->DIEPTSIZ));
+ /* Zero Length Packet? */
+ if (ep->xfer_len == 0)
+ {
+ deptsiz.b.xfersize = 0;
+ deptsiz.b.pktcnt = 1;
+ }
+ else
+ {
+ /* Program the transfer size and packet count
+ * as follows: xfersize = N * maxpacket +
+ * short_packet pktcnt = N + (short_packet
+ * exist ? 1 : 0)
+ */
+ deptsiz.b.xfersize = ep->xfer_len;
+ deptsiz.b.pktcnt = (ep->xfer_len - 1 + ep->maxpacket) / ep->maxpacket;
+
+ if (ep->type == EP_TYPE_ISOC)
+ {
+ deptsiz.b.mc = 1;
+ }
+ }
+ USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[ep->num]->DIEPTSIZ, deptsiz.d32);
+
+ if (pdev->cfg.dma_enable == 1)
+ {
+ USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[ep->num]->DIEPDMA, ep->dma_addr);
+ }
+ else
+ {
+ if (ep->type != EP_TYPE_ISOC)
+ {
+ /* Enable the Tx FIFO Empty Interrupt for this EP */
+ if (ep->xfer_len > 0)
+ {
+ fifoemptymsk = 1 << ep->num;
+ USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, 0, fifoemptymsk);
+ }
+ }
+ }
+
+
+ if (ep->type == EP_TYPE_ISOC)
+ {
+ dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS);
+
+ if (((dsts.b.soffn)&0x1) == 0)
+ {
+ depctl.b.setd1pid = 1;
+ }
+ else
+ {
+ depctl.b.setd0pid = 1;
+ }
+ }
+
+ /* EP enable, IN data in FIFO */
+ depctl.b.cnak = 1;
+ depctl.b.epena = 1;
+ USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[ep->num]->DIEPCTL, depctl.d32);
+
+ if (ep->type == EP_TYPE_ISOC)
+ {
+ USB_OTG_WritePacket(pdev, ep->xfer_buff, ep->num, ep->xfer_len);
+ }
+ }
+ else
+ {
+ /* OUT endpoint */
+ depctl.d32 = USB_OTG_READ_REG32(&(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL));
+ deptsiz.d32 = USB_OTG_READ_REG32(&(pdev->regs.OUTEP_REGS[ep->num]->DOEPTSIZ));
+ /* Program the transfer size and packet count as follows:
+ * pktcnt = N
+ * xfersize = N * maxpacket
+ */
+ if (ep->xfer_len == 0)
+ {
+ deptsiz.b.xfersize = ep->maxpacket;
+ deptsiz.b.pktcnt = 1;
+ }
+ else
+ {
+ deptsiz.b.pktcnt = (ep->xfer_len + (ep->maxpacket - 1)) / ep->maxpacket;
+ deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket;
+ }
+ USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPTSIZ, deptsiz.d32);
+
+ if (pdev->cfg.dma_enable == 1)
+ {
+ USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPDMA, ep->dma_addr);
+ }
+
+ if (ep->type == EP_TYPE_ISOC)
+ {
+ if (ep->even_odd_frame)
+ {
+ depctl.b.setd1pid = 1;
+ }
+ else
+ {
+ depctl.b.setd0pid = 1;
+ }
+ }
+ /* EP enable */
+ depctl.b.cnak = 1;
+ depctl.b.epena = 1;
+ USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL, depctl.d32);
+ }
+ return status;
+}
+
+
+/**
+* @brief USB_OTG_EP0StartXfer : Handle the setup for a data xfer for EP0 and
+* starts the xfer
+* @param pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_EP0StartXfer(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ USB_OTG_DEPCTL_TypeDef depctl;
+ USB_OTG_DEP0XFRSIZ_TypeDef deptsiz;
+ USB_OTG_INEPREGS *in_regs;
+ uint32_t fifoemptymsk = 0;
+
+ depctl.d32 = 0;
+ deptsiz.d32 = 0;
+ /* IN endpoint */
+ if (ep->is_in == 1)
+ {
+ in_regs = pdev->regs.INEP_REGS[0];
+ depctl.d32 = USB_OTG_READ_REG32(&in_regs->DIEPCTL);
+ deptsiz.d32 = USB_OTG_READ_REG32(&in_regs->DIEPTSIZ);
+ /* Zero Length Packet? */
+ if (ep->xfer_len == 0)
+ {
+ deptsiz.b.xfersize = 0;
+ deptsiz.b.pktcnt = 1;
+
+ }
+ else
+ {
+ if (ep->xfer_len > ep->maxpacket)
+ {
+ ep->xfer_len = ep->maxpacket;
+ deptsiz.b.xfersize = ep->maxpacket;
+ }
+ else
+ {
+ deptsiz.b.xfersize = ep->xfer_len;
+ }
+ deptsiz.b.pktcnt = 1;
+ }
+ USB_OTG_WRITE_REG32(&in_regs->DIEPTSIZ, deptsiz.d32);
+
+ if (pdev->cfg.dma_enable == 1)
+ {
+ USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[ep->num]->DIEPDMA, ep->dma_addr);
+ }
+
+ /* EP enable, IN data in FIFO */
+ depctl.b.cnak = 1;
+ depctl.b.epena = 1;
+ USB_OTG_WRITE_REG32(&in_regs->DIEPCTL, depctl.d32);
+
+
+
+ if (pdev->cfg.dma_enable == 0)
+ {
+ /* Enable the Tx FIFO Empty Interrupt for this EP */
+ if (ep->xfer_len > 0)
+ {
+ {
+ fifoemptymsk |= 1 << ep->num;
+ USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, 0, fifoemptymsk);
+ }
+ }
+ }
+ }
+ else
+ {
+ /* OUT endpoint */
+ depctl.d32 = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL);
+ deptsiz.d32 = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPTSIZ);
+ /* Program the transfer size and packet count as follows:
+ * xfersize = N * (maxpacket + 4 - (maxpacket % 4))
+ * pktcnt = N */
+ if (ep->xfer_len == 0)
+ {
+ deptsiz.b.xfersize = ep->maxpacket;
+ deptsiz.b.pktcnt = 1;
+ }
+ else
+ {
+ ep->xfer_len = ep->maxpacket;
+ deptsiz.b.xfersize = ep->maxpacket;
+ deptsiz.b.pktcnt = 1;
+ }
+ USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPTSIZ, deptsiz.d32);
+ if (pdev->cfg.dma_enable == 1)
+ {
+ USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPDMA, ep->dma_addr);
+ }
+ /* EP enable */
+ depctl.b.cnak = 1;
+ depctl.b.epena = 1;
+ USB_OTG_WRITE_REG32 (&(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL), depctl.d32);
+
+ }
+ return status;
+}
+
+
+/**
+* @brief USB_OTG_EPSetStall : Set the EP STALL
+* @param pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_EPSetStall(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ USB_OTG_DEPCTL_TypeDef depctl;
+ __IO uint32_t *depctl_addr;
+
+ depctl.d32 = 0;
+ if (ep->is_in == 1)
+ {
+ depctl_addr = &(pdev->regs.INEP_REGS[ep->num]->DIEPCTL);
+ depctl.d32 = USB_OTG_READ_REG32(depctl_addr);
+ /* set the disable and stall bits */
+ if (depctl.b.epena)
+ {
+ depctl.b.epdis = 1;
+ }
+ depctl.b.stall = 1;
+ USB_OTG_WRITE_REG32(depctl_addr, depctl.d32);
+ }
+ else
+ {
+ depctl_addr = &(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL);
+ depctl.d32 = USB_OTG_READ_REG32(depctl_addr);
+ /* set the stall bit */
+ depctl.b.stall = 1;
+ USB_OTG_WRITE_REG32(depctl_addr, depctl.d32);
+ }
+ return status;
+}
+
+
+/**
+* @brief Clear the EP STALL
+* @param pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_EPClearStall(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ USB_OTG_DEPCTL_TypeDef depctl;
+ __IO uint32_t *depctl_addr;
+
+ depctl.d32 = 0;
+
+ if (ep->is_in == 1)
+ {
+ depctl_addr = &(pdev->regs.INEP_REGS[ep->num]->DIEPCTL);
+ }
+ else
+ {
+ depctl_addr = &(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL);
+ }
+ depctl.d32 = USB_OTG_READ_REG32(depctl_addr);
+ /* clear the stall bits */
+ depctl.b.stall = 0;
+ if (ep->type == EP_TYPE_INTR || ep->type == EP_TYPE_BULK)
+ {
+ depctl.b.setd0pid = 1; /* DATA0 */
+ }
+ USB_OTG_WRITE_REG32(depctl_addr, depctl.d32);
+ return status;
+}
+
+
+/**
+* @brief USB_OTG_ReadDevAllOutEp_itr : returns OUT endpoint interrupt bits
+* @param pdev : Selected device
+* @retval OUT endpoint interrupt bits
+*/
+uint32_t USB_OTG_ReadDevAllOutEp_itr(USB_OTG_CORE_HANDLE *pdev)
+{
+ uint32_t v;
+ v = USB_OTG_READ_REG32(&pdev->regs.DREGS->DAINT);
+ v &= USB_OTG_READ_REG32(&pdev->regs.DREGS->DAINTMSK);
+ return ((v & 0xffff0000) >> 16);
+}
+
+
+/**
+* @brief USB_OTG_ReadDevOutEP_itr : returns Device OUT EP Interrupt register
+* @param pdev : Selected device
+* @param ep : end point number
+* @retval Device OUT EP Interrupt register
+*/
+uint32_t USB_OTG_ReadDevOutEP_itr(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum)
+{
+ uint32_t v;
+ v = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[epnum]->DOEPINT);
+ v &= USB_OTG_READ_REG32(&pdev->regs.DREGS->DOEPMSK);
+ return v;
+}
+
+
+/**
+* @brief USB_OTG_ReadDevAllInEPItr : Get int status register
+* @param pdev : Selected device
+* @retval int status register
+*/
+uint32_t USB_OTG_ReadDevAllInEPItr(USB_OTG_CORE_HANDLE *pdev)
+{
+ uint32_t v;
+ v = USB_OTG_READ_REG32(&pdev->regs.DREGS->DAINT);
+ v &= USB_OTG_READ_REG32(&pdev->regs.DREGS->DAINTMSK);
+ return (v & 0xffff);
+}
+
+/**
+* @brief configures EPO to receive SETUP packets
+* @param None
+* @retval : None
+*/
+void USB_OTG_EP0_OutStart(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_DEP0XFRSIZ_TypeDef doeptsize0;
+ doeptsize0.d32 = 0;
+ doeptsize0.b.supcnt = 3;
+ doeptsize0.b.pktcnt = 1;
+ doeptsize0.b.xfersize = 8 * 3;
+ USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[0]->DOEPTSIZ, doeptsize0.d32 );
+
+ if (pdev->cfg.dma_enable == 1)
+ {
+ USB_OTG_DEPCTL_TypeDef doepctl;
+ doepctl.d32 = 0;
+ USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[0]->DOEPDMA,
+ (uint32_t)&pdev->dev.setup_packet);
+
+ /* EP enable */
+ doepctl.d32 = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[0]->DOEPCTL);
+ doepctl.b.epena = 1;
+ doepctl.d32 = 0x80008000;
+ USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[0]->DOEPCTL, doepctl.d32);
+ }
+}
+
+/**
+* @brief USB_OTG_RemoteWakeup : active remote wakeup signalling
+* @param None
+* @retval : None
+*/
+void USB_OTG_ActiveRemoteWakeup(USB_OTG_CORE_HANDLE *pdev)
+{
+
+ USB_OTG_DCTL_TypeDef dctl;
+ USB_OTG_DSTS_TypeDef dsts;
+ USB_OTG_PCGCCTL_TypeDef power;
+
+ if (pdev->dev.DevRemoteWakeup)
+ {
+ dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS);
+ if(dsts.b.suspsts == 1)
+ {
+ if(pdev->cfg.low_power)
+ {
+ /* un-gate USB Core clock */
+ power.d32 = USB_OTG_READ_REG32(&pdev->regs.PCGCCTL);
+ power.b.gatehclk = 0;
+ power.b.stoppclk = 0;
+ USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, power.d32);
+ }
+ /* active Remote wakeup signaling */
+ dctl.d32 = 0;
+ dctl.b.rmtwkupsig = 1;
+ USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, 0, dctl.d32);
+ USB_OTG_BSP_mDelay(5);
+ USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, dctl.d32, 0 );
+ }
+ }
+}
+
+
+/**
+* @brief USB_OTG_UngateClock : active USB Core clock
+* @param None
+* @retval : None
+*/
+void USB_OTG_UngateClock(USB_OTG_CORE_HANDLE *pdev)
+{
+ if(pdev->cfg.low_power)
+ {
+
+ USB_OTG_DSTS_TypeDef dsts;
+ USB_OTG_PCGCCTL_TypeDef power;
+
+ dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS);
+
+ if(dsts.b.suspsts == 1)
+ {
+ /* un-gate USB Core clock */
+ power.d32 = USB_OTG_READ_REG32(&pdev->regs.PCGCCTL);
+ power.b.gatehclk = 0;
+ power.b.stoppclk = 0;
+ USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, power.d32);
+
+ }
+ }
+}
+
+/**
+* @brief Stop the device and clean up fifo's
+* @param None
+* @retval : None
+*/
+void USB_OTG_StopDevice(USB_OTG_CORE_HANDLE *pdev)
+{
+ uint32_t i;
+
+ pdev->dev.device_status = 1;
+
+ for (i = 0; i < pdev->cfg.dev_endpoints ; i++)
+ {
+ USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPINT, 0xFF);
+ USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[i]->DOEPINT, 0xFF);
+ }
+
+ USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DIEPMSK, 0 );
+ USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DOEPMSK, 0 );
+ USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINTMSK, 0 );
+ USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINT, 0xFFFFFFFF );
+
+ /* Flush the FIFO */
+ USB_OTG_FlushRxFifo(pdev);
+ USB_OTG_FlushTxFifo(pdev , 0x10 );
+}
+
+/**
+* @brief returns the EP Status
+* @param pdev : Selected device
+* ep : endpoint structure
+* @retval : EP status
+*/
+
+uint32_t USB_OTG_GetEPStatus(USB_OTG_CORE_HANDLE *pdev ,USB_OTG_EP *ep)
+{
+ USB_OTG_DEPCTL_TypeDef depctl;
+ __IO uint32_t *depctl_addr;
+ uint32_t Status = 0;
+
+ depctl.d32 = 0;
+ if (ep->is_in == 1)
+ {
+ depctl_addr = &(pdev->regs.INEP_REGS[ep->num]->DIEPCTL);
+ depctl.d32 = USB_OTG_READ_REG32(depctl_addr);
+
+ if (depctl.b.stall == 1)
+ Status = USB_OTG_EP_TX_STALL;
+ else if (depctl.b.naksts == 1)
+ Status = USB_OTG_EP_TX_NAK;
+ else
+ Status = USB_OTG_EP_TX_VALID;
+
+ }
+ else
+ {
+ depctl_addr = &(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL);
+ depctl.d32 = USB_OTG_READ_REG32(depctl_addr);
+ if (depctl.b.stall == 1)
+ Status = USB_OTG_EP_RX_STALL;
+ else if (depctl.b.naksts == 1)
+ Status = USB_OTG_EP_RX_NAK;
+ else
+ Status = USB_OTG_EP_RX_VALID;
+ }
+
+ /* Return the current status */
+ return Status;
+}
+
+/**
+* @brief Set the EP Status
+* @param pdev : Selected device
+* Status : new Status
+* ep : EP structure
+* @retval : None
+*/
+void USB_OTG_SetEPStatus (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep , uint32_t Status)
+{
+ USB_OTG_DEPCTL_TypeDef depctl;
+ __IO uint32_t *depctl_addr;
+
+ depctl.d32 = 0;
+
+ /* Process for IN endpoint */
+ if (ep->is_in == 1)
+ {
+ depctl_addr = &(pdev->regs.INEP_REGS[ep->num]->DIEPCTL);
+ depctl.d32 = USB_OTG_READ_REG32(depctl_addr);
+
+ if (Status == USB_OTG_EP_TX_STALL)
+ {
+ USB_OTG_EPSetStall(pdev, ep); return;
+ }
+ else if (Status == USB_OTG_EP_TX_NAK)
+ depctl.b.snak = 1;
+ else if (Status == USB_OTG_EP_TX_VALID)
+ {
+ if (depctl.b.stall == 1)
+ {
+ ep->even_odd_frame = 0;
+ USB_OTG_EPClearStall(pdev, ep);
+ return;
+ }
+ depctl.b.cnak = 1;
+ depctl.b.usbactep = 1;
+ depctl.b.epena = 1;
+ }
+ else if (Status == USB_OTG_EP_TX_DIS)
+ depctl.b.usbactep = 0;
+ }
+ else /* Process for OUT endpoint */
+ {
+ depctl_addr = &(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL);
+ depctl.d32 = USB_OTG_READ_REG32(depctl_addr);
+
+ if (Status == USB_OTG_EP_RX_STALL) {
+ depctl.b.stall = 1;
+ }
+ else if (Status == USB_OTG_EP_RX_NAK)
+ depctl.b.snak = 1;
+ else if (Status == USB_OTG_EP_RX_VALID)
+ {
+ if (depctl.b.stall == 1)
+ {
+ ep->even_odd_frame = 0;
+ USB_OTG_EPClearStall(pdev, ep);
+ return;
+ }
+ depctl.b.cnak = 1;
+ depctl.b.usbactep = 1;
+ depctl.b.epena = 1;
+ }
+ else if (Status == USB_OTG_EP_RX_DIS)
+ {
+ depctl.b.usbactep = 0;
+ }
+ }
+
+ USB_OTG_WRITE_REG32(depctl_addr, depctl.d32);
+}
+
+#endif
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
diff --git a/example/stm32f4/STM32_USB_OTG_Driver/src/usb_dcd.c b/example/stm32f4/STM32_USB_OTG_Driver/src/usb_dcd.c
new file mode 100644
index 0000000..c3336cb
--- /dev/null
+++ b/example/stm32f4/STM32_USB_OTG_Driver/src/usb_dcd.c
@@ -0,0 +1,472 @@
+/**
+ ******************************************************************************
+ * @file usb_dcd.c
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 22-July-2011
+ * @brief Peripheral Device Interface Layer
+ ******************************************************************************
+ * @attention
+ *
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * © COPYRIGHT 2011 STMicroelectronics
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_dcd.h"
+#include "usb_bsp.h"
+
+
+/** @addtogroup USB_OTG_DRIVER
+* @{
+*/
+
+/** @defgroup USB_DCD
+* @brief This file is the interface between EFSL ans Host mass-storage class
+* @{
+*/
+
+
+/** @defgroup USB_DCD_Private_Defines
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USB_DCD_Private_TypesDefinitions
+* @{
+*/
+/**
+* @}
+*/
+
+
+
+/** @defgroup USB_DCD_Private_Macros
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USB_DCD_Private_Variables
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USB_DCD_Private_FunctionPrototypes
+* @{
+*/
+
+/**
+* @}
+*/
+
+
+/** @defgroup USB_DCD_Private_Functions
+* @{
+*/
+
+
+
+void DCD_Init(USB_OTG_CORE_HANDLE *pdev ,
+ USB_OTG_CORE_ID_TypeDef coreID)
+{
+ uint32_t i;
+ USB_OTG_EP *ep;
+
+ USB_OTG_SelectCore (pdev , coreID);
+
+ pdev->dev.device_status = USB_OTG_DEFAULT;
+ pdev->dev.device_address = 0;
+
+ /* Init ep structure */
+ for (i = 0; i < pdev->cfg.dev_endpoints ; i++)
+ {
+ ep = &pdev->dev.in_ep[i];
+ /* Init ep structure */
+ ep->is_in = 1;
+ ep->num = i;
+ ep->tx_fifo_num = i;
+ /* Control until ep is actvated */
+ ep->type = EP_TYPE_CTRL;
+ ep->maxpacket = USB_OTG_MAX_EP0_SIZE;
+ ep->xfer_buff = 0;
+ ep->xfer_len = 0;
+ }
+
+ for (i = 0; i < pdev->cfg.dev_endpoints; i++)
+ {
+ ep = &pdev->dev.out_ep[i];
+ /* Init ep structure */
+ ep->is_in = 0;
+ ep->num = i;
+ ep->tx_fifo_num = i;
+ /* Control until ep is activated */
+ ep->type = EP_TYPE_CTRL;
+ ep->maxpacket = USB_OTG_MAX_EP0_SIZE;
+ ep->xfer_buff = 0;
+ ep->xfer_len = 0;
+ }
+
+ USB_OTG_DisableGlobalInt(pdev);
+
+ /*Init the Core (common init.) */
+ USB_OTG_CoreInit(pdev);
+
+
+ /* Force Device Mode*/
+ USB_OTG_SetCurrentMode(pdev, DEVICE_MODE);
+
+ /* Init Device */
+ USB_OTG_CoreInitDev(pdev);
+
+
+ /* Enable USB Global interrupt */
+ USB_OTG_EnableGlobalInt(pdev);
+}
+
+
+/**
+* @brief Configure an EP
+* @param pdev : Device instance
+* @param epdesc : Endpoint Descriptor
+* @retval : status
+*/
+uint32_t DCD_EP_Open(USB_OTG_CORE_HANDLE *pdev ,
+ uint8_t ep_addr,
+ uint16_t ep_mps,
+ uint8_t ep_type)
+{
+ USB_OTG_EP *ep;
+
+ if ((ep_addr & 0x80) == 0x80)
+ {
+ ep = &pdev->dev.in_ep[ep_addr & 0x7F];
+ }
+ else
+ {
+ ep = &pdev->dev.out_ep[ep_addr & 0x7F];
+ }
+ ep->num = ep_addr & 0x7F;
+
+ ep->is_in = (0x80 & ep_addr) != 0;
+ ep->maxpacket = ep_mps;
+ ep->type = ep_type;
+ if (ep->is_in)
+ {
+ /* Assign a Tx FIFO */
+ ep->tx_fifo_num = ep->num;
+ }
+ /* Set initial data PID. */
+ if (ep_type == USB_OTG_EP_BULK )
+ {
+ ep->data_pid_start = 0;
+ }
+ USB_OTG_EPActivate(pdev , ep );
+ return 0;
+}
+/**
+* @brief called when an EP is disabled
+* @param pdev: device instance
+* @param ep_addr: endpoint address
+* @retval : status
+*/
+uint32_t DCD_EP_Close(USB_OTG_CORE_HANDLE *pdev , uint8_t ep_addr)
+{
+ USB_OTG_EP *ep;
+
+ if ((ep_addr&0x80) == 0x80)
+ {
+ ep = &pdev->dev.in_ep[ep_addr & 0x7F];
+ }
+ else
+ {
+ ep = &pdev->dev.out_ep[ep_addr & 0x7F];
+ }
+ ep->num = ep_addr & 0x7F;
+ ep->is_in = (0x80 & ep_addr) != 0;
+ USB_OTG_EPDeactivate(pdev , ep );
+ return 0;
+}
+
+
+/**
+* @brief DCD_EP_PrepareRx
+* @param pdev: device instance
+* @param ep_addr: endpoint address
+* @param pbuf: pointer to Rx buffer
+* @param buf_len: data length
+* @retval : status
+*/
+uint32_t DCD_EP_PrepareRx( USB_OTG_CORE_HANDLE *pdev,
+ uint8_t ep_addr,
+ uint8_t *pbuf,
+ uint16_t buf_len)
+{
+ USB_OTG_EP *ep;
+
+ ep = &pdev->dev.out_ep[ep_addr & 0x7F];
+
+ /*setup and start the Xfer */
+ ep->xfer_buff = pbuf;
+ ep->xfer_len = buf_len;
+ ep->xfer_count = 0;
+ ep->is_in = 0;
+ ep->num = ep_addr & 0x7F;
+
+ if (pdev->cfg.dma_enable == 1)
+ {
+ ep->dma_addr = (uint32_t)pbuf;
+ }
+
+ if ( ep->num == 0 )
+ {
+ USB_OTG_EP0StartXfer(pdev , ep);
+ }
+ else
+ {
+ USB_OTG_EPStartXfer(pdev, ep );
+ }
+ return 0;
+}
+
+/**
+* @brief Transmit data over USB
+* @param pdev: device instance
+* @param ep_addr: endpoint address
+* @param pbuf: pointer to Tx buffer
+* @param buf_len: data length
+* @retval : status
+*/
+uint32_t DCD_EP_Tx ( USB_OTG_CORE_HANDLE *pdev,
+ uint8_t ep_addr,
+ uint8_t *pbuf,
+ uint32_t buf_len)
+{
+ USB_OTG_EP *ep;
+
+ ep = &pdev->dev.in_ep[ep_addr & 0x7F];
+
+ /* Setup and start the Transfer */
+ ep->is_in = 1;
+ ep->num = ep_addr & 0x7F;
+ ep->xfer_buff = pbuf;
+ ep->dma_addr = (uint32_t)pbuf;
+ ep->xfer_count = 0;
+ ep->xfer_len = buf_len;
+
+ if ( ep->num == 0 )
+ {
+ USB_OTG_EP0StartXfer(pdev , ep);
+ }
+ else
+ {
+ USB_OTG_EPStartXfer(pdev, ep );
+ }
+ return 0;
+}
+
+
+/**
+* @brief Stall an endpoint.
+* @param pdev: device instance
+* @param epnum: endpoint address
+* @retval : status
+*/
+uint32_t DCD_EP_Stall (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum)
+{
+ USB_OTG_EP *ep;
+ if ((0x80 & epnum) == 0x80)
+ {
+ ep = &pdev->dev.in_ep[epnum & 0x7F];
+ }
+ else
+ {
+ ep = &pdev->dev.out_ep[epnum];
+ }
+
+ ep->is_stall = 1;
+ ep->num = epnum & 0x7F;
+ ep->is_in = ((epnum & 0x80) == 0x80);
+
+ USB_OTG_EPSetStall(pdev , ep);
+ return (0);
+}
+
+
+/**
+* @brief Clear stall condition on endpoints.
+* @param pdev: device instance
+* @param epnum: endpoint address
+* @retval : status
+*/
+uint32_t DCD_EP_ClrStall (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum)
+{
+ USB_OTG_EP *ep;
+ if ((0x80 & epnum) == 0x80)
+ {
+ ep = &pdev->dev.in_ep[epnum & 0x7F];
+ }
+ else
+ {
+ ep = &pdev->dev.out_ep[epnum];
+ }
+
+ ep->is_stall = 0;
+ ep->num = epnum & 0x7F;
+ ep->is_in = ((epnum & 0x80) == 0x80);
+
+ USB_OTG_EPClearStall(pdev , ep);
+ return (0);
+}
+
+
+/**
+* @brief This Function flushes the FIFOs.
+* @param pdev: device instance
+* @param epnum: endpoint address
+* @retval : status
+*/
+uint32_t DCD_EP_Flush (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum)
+{
+
+ if ((epnum & 0x80) == 0x80)
+ {
+ USB_OTG_FlushTxFifo(pdev, epnum & 0x7F);
+ }
+ else
+ {
+ USB_OTG_FlushRxFifo(pdev);
+ }
+
+ return (0);
+}
+
+
+/**
+* @brief This Function set USB device address
+* @param pdev: device instance
+* @param address: new device address
+* @retval : status
+*/
+void DCD_EP_SetAddress (USB_OTG_CORE_HANDLE *pdev, uint8_t address)
+{
+ USB_OTG_DCFG_TypeDef dcfg;
+ dcfg.d32 = 0;
+ dcfg.b.devaddr = address;
+ USB_OTG_MODIFY_REG32( &pdev->regs.DREGS->DCFG, 0, dcfg.d32);
+}
+
+/**
+* @brief Connect device (enable internal pull-up)
+* @param pdev: device instance
+* @retval : None
+*/
+void DCD_DevConnect (USB_OTG_CORE_HANDLE *pdev)
+{
+#ifndef USE_OTG_MODE
+ USB_OTG_DCTL_TypeDef dctl;
+ dctl.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DCTL);
+ /* Connect device */
+ dctl.b.sftdiscon = 0;
+ USB_OTG_WRITE_REG32(&pdev->regs.DREGS->DCTL, dctl.d32);
+ USB_OTG_BSP_mDelay(3);
+#endif
+}
+
+
+/**
+* @brief Disconnect device (disable internal pull-up)
+* @param pdev: device instance
+* @retval : None
+*/
+void DCD_DevDisconnect (USB_OTG_CORE_HANDLE *pdev)
+{
+#ifndef USE_OTG_MODE
+ USB_OTG_DCTL_TypeDef dctl;
+ dctl.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DCTL);
+ /* Disconnect device for 3ms */
+ dctl.b.sftdiscon = 1;
+ USB_OTG_WRITE_REG32(&pdev->regs.DREGS->DCTL, dctl.d32);
+ USB_OTG_BSP_mDelay(3);
+#endif
+}
+
+
+/**
+* @brief returns the EP Status
+* @param pdev : Selected device
+* epnum : endpoint address
+* @retval : EP status
+*/
+
+uint32_t DCD_GetEPStatus(USB_OTG_CORE_HANDLE *pdev ,uint8_t epnum)
+{
+ USB_OTG_EP *ep;
+ uint32_t Status = 0;
+
+ if ((0x80 & epnum) == 0x80)
+ {
+ ep = &pdev->dev.in_ep[epnum & 0x7F];
+ }
+ else
+ {
+ ep = &pdev->dev.out_ep[epnum];
+ }
+
+ Status = USB_OTG_GetEPStatus(pdev ,ep);
+
+ /* Return the current status */
+ return Status;
+}
+
+/**
+* @brief Set the EP Status
+* @param pdev : Selected device
+* Status : new Status
+* epnum : EP address
+* @retval : None
+*/
+void DCD_SetEPStatus (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum , uint32_t Status)
+{
+ USB_OTG_EP *ep;
+
+ if ((0x80 & epnum) == 0x80)
+ {
+ ep = &pdev->dev.in_ep[epnum & 0x7F];
+ }
+ else
+ {
+ ep = &pdev->dev.out_ep[epnum];
+ }
+
+ USB_OTG_SetEPStatus(pdev ,ep , Status);
+}
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
diff --git a/example/stm32f4/STM32_USB_OTG_Driver/src/usb_dcd_int.c b/example/stm32f4/STM32_USB_OTG_Driver/src/usb_dcd_int.c
new file mode 100644
index 0000000..eac902e
--- /dev/null
+++ b/example/stm32f4/STM32_USB_OTG_Driver/src/usb_dcd_int.c
@@ -0,0 +1,886 @@
+/**
+ ******************************************************************************
+ * @file usb_dcd_int.c
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 22-July-2011
+ * @brief Peripheral Device interrupt subroutines
+ ******************************************************************************
+ * @attention
+ *
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * © COPYRIGHT 2011 STMicroelectronics
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_dcd_int.h"
+/** @addtogroup USB_OTG_DRIVER
+* @{
+*/
+
+/** @defgroup USB_DCD_INT
+* @brief This file contains the interrupt subroutines for the Device mode.
+* @{
+*/
+
+
+/** @defgroup USB_DCD_INT_Private_Defines
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USB_DCD_INT_Private_TypesDefinitions
+* @{
+*/
+/**
+* @}
+*/
+
+
+
+/** @defgroup USB_DCD_INT_Private_Macros
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USB_DCD_INT_Private_Variables
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USB_DCD_INT_Private_FunctionPrototypes
+* @{
+*/
+/* static functions */
+static uint32_t DCD_ReadDevInEP (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum);
+
+/* Interrupt Handlers */
+static uint32_t DCD_HandleInEP_ISR(USB_OTG_CORE_HANDLE *pdev);
+static uint32_t DCD_HandleOutEP_ISR(USB_OTG_CORE_HANDLE *pdev);
+static uint32_t DCD_HandleSof_ISR(USB_OTG_CORE_HANDLE *pdev);
+
+static uint32_t DCD_HandleRxStatusQueueLevel_ISR(USB_OTG_CORE_HANDLE *pdev);
+static uint32_t DCD_WriteEmptyTxFifo(USB_OTG_CORE_HANDLE *pdev , uint32_t epnum);
+
+static uint32_t DCD_HandleUsbReset_ISR(USB_OTG_CORE_HANDLE *pdev);
+static uint32_t DCD_HandleEnumDone_ISR(USB_OTG_CORE_HANDLE *pdev);
+static uint32_t DCD_HandleResume_ISR(USB_OTG_CORE_HANDLE *pdev);
+static uint32_t DCD_HandleUSBSuspend_ISR(USB_OTG_CORE_HANDLE *pdev);
+
+static uint32_t DCD_IsoINIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev);
+static uint32_t DCD_IsoOUTIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev);
+#ifdef VBUS_SENSING_ENABLED
+static uint32_t DCD_SessionRequest_ISR(USB_OTG_CORE_HANDLE *pdev);
+static uint32_t DCD_OTG_ISR(USB_OTG_CORE_HANDLE *pdev);
+#endif
+
+/**
+* @}
+*/
+
+
+/** @defgroup USB_DCD_INT_Private_Functions
+* @{
+*/
+
+
+#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED
+/**
+* @brief USBD_OTG_EP1OUT_ISR_Handler
+* handles all USB Interrupts
+* @param pdev: device instance
+* @retval status
+*/
+uint32_t USBD_OTG_EP1OUT_ISR_Handler (USB_OTG_CORE_HANDLE *pdev)
+{
+
+ USB_OTG_DOEPINTn_TypeDef doepint;
+ USB_OTG_DEPXFRSIZ_TypeDef deptsiz;
+
+ doepint.d32 = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[1]->DOEPINT);
+ doepint.d32&= USB_OTG_READ_REG32(&pdev->regs.DREGS->DOUTEP1MSK);
+
+ /* Transfer complete */
+ if ( doepint.b.xfercompl )
+ {
+ /* Clear the bit in DOEPINTn for this interrupt */
+ CLEAR_OUT_EP_INTR(1, xfercompl);
+ if (pdev->cfg.dma_enable == 1)
+ {
+ deptsiz.d32 = USB_OTG_READ_REG32(&(pdev->regs.OUTEP_REGS[1]->DOEPTSIZ));
+ /*ToDo : handle more than one single MPS size packet */
+ pdev->dev.out_ep[1].xfer_count = pdev->dev.out_ep[1].maxpacket - \
+ deptsiz.b.xfersize;
+ }
+ /* Inform upper layer: data ready */
+ /* RX COMPLETE */
+ USBD_DCD_INT_fops->DataOutStage(pdev , 1);
+
+ }
+
+ /* Endpoint disable */
+ if ( doepint.b.epdisabled )
+ {
+ /* Clear the bit in DOEPINTn for this interrupt */
+ CLEAR_OUT_EP_INTR(1, epdisabled);
+ }
+ /* AHB Error */
+ if ( doepint.b.ahberr )
+ {
+ CLEAR_OUT_EP_INTR(1, ahberr);
+ }
+ return 1;
+}
+
+/**
+* @brief USBD_OTG_EP1IN_ISR_Handler
+* handles all USB Interrupts
+* @param pdev: device instance
+* @retval status
+*/
+uint32_t USBD_OTG_EP1IN_ISR_Handler (USB_OTG_CORE_HANDLE *pdev)
+{
+
+ USB_OTG_DIEPINTn_TypeDef diepint;
+ uint32_t fifoemptymsk, msk, emp;
+
+ msk = USB_OTG_READ_REG32(&pdev->regs.DREGS->DINEP1MSK);
+ emp = USB_OTG_READ_REG32(&pdev->regs.DREGS->DIEPEMPMSK);
+ msk |= ((emp >> 1 ) & 0x1) << 7;
+ diepint.d32 = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[1]->DIEPINT) & msk;
+
+ if ( diepint.b.xfercompl )
+ {
+ fifoemptymsk = 0x1 << 1;
+ USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, fifoemptymsk, 0);
+ CLEAR_IN_EP_INTR(1, xfercompl);
+ /* TX COMPLETE */
+ USBD_DCD_INT_fops->DataInStage(pdev , 1);
+ }
+ if ( diepint.b.ahberr )
+ {
+ CLEAR_IN_EP_INTR(1, ahberr);
+ }
+ if ( diepint.b.epdisabled )
+ {
+ CLEAR_IN_EP_INTR(1, epdisabled);
+ }
+ if ( diepint.b.timeout )
+ {
+ CLEAR_IN_EP_INTR(1, timeout);
+ }
+ if (diepint.b.intktxfemp)
+ {
+ CLEAR_IN_EP_INTR(1, intktxfemp);
+ }
+ if (diepint.b.intknepmis)
+ {
+ CLEAR_IN_EP_INTR(1, intknepmis);
+ }
+ if (diepint.b.inepnakeff)
+ {
+ CLEAR_IN_EP_INTR(1, inepnakeff);
+ }
+ if (diepint.b.emptyintr)
+ {
+ DCD_WriteEmptyTxFifo(pdev , 1);
+ CLEAR_IN_EP_INTR(1, emptyintr);
+ }
+ return 1;
+}
+#endif
+
+/**
+* @brief STM32_USBF_OTG_ISR_Handler
+* handles all USB Interrupts
+* @param pdev: device instance
+* @retval status
+*/
+uint32_t USBD_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_GINTSTS_TypeDef gintr_status;
+ uint32_t retval = 0;
+
+ if (USB_OTG_IsDeviceMode(pdev)) /* ensure that we are in device mode */
+ {
+ gintr_status.d32 = USB_OTG_ReadCoreItr(pdev);
+ if (!gintr_status.d32) /* avoid spurious interrupt */
+ {
+ return 0;
+ }
+
+ if (gintr_status.b.outepintr)
+ {
+ retval |= DCD_HandleOutEP_ISR(pdev);
+ }
+
+ if (gintr_status.b.inepint)
+ {
+ retval |= DCD_HandleInEP_ISR(pdev);
+ }
+
+ if (gintr_status.b.modemismatch)
+ {
+ USB_OTG_GINTSTS_TypeDef gintsts;
+
+ /* Clear interrupt */
+ gintsts.d32 = 0;
+ gintsts.b.modemismatch = 1;
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
+ }
+
+ if (gintr_status.b.wkupintr)
+ {
+ retval |= DCD_HandleResume_ISR(pdev);
+ }
+
+ if (gintr_status.b.usbsuspend)
+ {
+ retval |= DCD_HandleUSBSuspend_ISR(pdev);
+ }
+ if (gintr_status.b.sofintr)
+ {
+ retval |= DCD_HandleSof_ISR(pdev);
+
+ }
+
+ if (gintr_status.b.rxstsqlvl)
+ {
+ retval |= DCD_HandleRxStatusQueueLevel_ISR(pdev);
+
+ }
+
+ if (gintr_status.b.usbreset)
+ {
+ retval |= DCD_HandleUsbReset_ISR(pdev);
+
+ }
+ if (gintr_status.b.enumdone)
+ {
+ retval |= DCD_HandleEnumDone_ISR(pdev);
+ }
+
+ if (gintr_status.b.incomplisoin)
+ {
+ retval |= DCD_IsoINIncomplete_ISR(pdev);
+ }
+
+ if (gintr_status.b.incomplisoout)
+ {
+ retval |= DCD_IsoOUTIncomplete_ISR(pdev);
+ }
+#ifdef VBUS_SENSING_ENABLED
+ if (gintr_status.b.sessreqintr)
+ {
+ retval |= DCD_SessionRequest_ISR(pdev);
+ }
+
+ if (gintr_status.b.otgintr)
+ {
+ retval |= DCD_OTG_ISR(pdev);
+ }
+#endif
+ }
+ return retval;
+}
+
+#ifdef VBUS_SENSING_ENABLED
+/**
+* @brief DCD_SessionRequest_ISR
+* Indicates that the USB_OTG controller has detected a connection
+* @param pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_SessionRequest_ISR(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_GINTSTS_TypeDef gintsts;
+ USBD_DCD_INT_fops->DevConnected (pdev);
+
+ /* Clear interrupt */
+ gintsts.d32 = 0;
+ gintsts.b.sessreqintr = 1;
+ USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, gintsts.d32);
+ return 1;
+}
+
+/**
+* @brief DCD_OTG_ISR
+* Indicates that the USB_OTG controller has detected an OTG event:
+* used to detect the end of session i.e. disconnection
+* @param pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_OTG_ISR(USB_OTG_CORE_HANDLE *pdev)
+{
+
+ USB_OTG_GOTGINT_TypeDef gotgint;
+
+ gotgint.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GOTGINT);
+
+ if (gotgint.b.sesenddet)
+ {
+ USBD_DCD_INT_fops->DevDisconnected (pdev);
+ }
+ /* Clear OTG interrupt */
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GOTGINT, gotgint.d32);
+ return 1;
+}
+#endif
+/**
+* @brief DCD_HandleResume_ISR
+* Indicates that the USB_OTG controller has detected a resume or
+* remote Wake-up sequence
+* @param pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_HandleResume_ISR(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_GINTSTS_TypeDef gintsts;
+ USB_OTG_DCTL_TypeDef devctl;
+ USB_OTG_PCGCCTL_TypeDef power;
+
+ if(pdev->cfg.low_power)
+ {
+ /* un-gate USB Core clock */
+ power.d32 = USB_OTG_READ_REG32(&pdev->regs.PCGCCTL);
+ power.b.gatehclk = 0;
+ power.b.stoppclk = 0;
+ USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, power.d32);
+ }
+
+ /* Clear the Remote Wake-up Signaling */
+ devctl.d32 = 0;
+ devctl.b.rmtwkupsig = 1;
+ USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, devctl.d32, 0);
+
+ /* Inform upper layer by the Resume Event */
+ USBD_DCD_INT_fops->Resume (pdev);
+
+ /* Clear interrupt */
+ gintsts.d32 = 0;
+ gintsts.b.wkupintr = 1;
+ USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, gintsts.d32);
+ return 1;
+}
+
+/**
+* @brief USB_OTG_HandleUSBSuspend_ISR
+* Indicates that SUSPEND state has been detected on the USB
+* @param pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_HandleUSBSuspend_ISR(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_GINTSTS_TypeDef gintsts;
+ USB_OTG_PCGCCTL_TypeDef power;
+ USB_OTG_DSTS_TypeDef dsts;
+
+ USBD_DCD_INT_fops->Suspend (pdev);
+
+ dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS);
+
+ /* Clear interrupt */
+ gintsts.d32 = 0;
+ gintsts.b.usbsuspend = 1;
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
+
+ if((pdev->cfg.low_power) && (dsts.b.suspsts == 1))
+ {
+ /* switch-off the clocks */
+ power.d32 = 0;
+ power.b.stoppclk = 1;
+ USB_OTG_MODIFY_REG32(pdev->regs.PCGCCTL, 0, power.d32);
+
+ power.b.gatehclk = 1;
+ USB_OTG_MODIFY_REG32(pdev->regs.PCGCCTL, 0, power.d32);
+
+ /* Request to enter Sleep mode after exit from current ISR */
+ SCB->SCR |= (SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk);
+ }
+ return 1;
+}
+
+/**
+* @brief DCD_HandleInEP_ISR
+* Indicates that an IN EP has a pending Interrupt
+* @param pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_HandleInEP_ISR(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_DIEPINTn_TypeDef diepint;
+
+ uint32_t ep_intr;
+ uint32_t epnum = 0;
+ uint32_t fifoemptymsk;
+ diepint.d32 = 0;
+ ep_intr = USB_OTG_ReadDevAllInEPItr(pdev);
+
+ while ( ep_intr )
+ {
+ if (ep_intr&0x1) /* In ITR */
+ {
+ diepint.d32 = DCD_ReadDevInEP(pdev , epnum); /* Get In ITR status */
+ if ( diepint.b.xfercompl )
+ {
+ fifoemptymsk = 0x1 << epnum;
+ USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, fifoemptymsk, 0);
+ CLEAR_IN_EP_INTR(epnum, xfercompl);
+ /* TX COMPLETE */
+ USBD_DCD_INT_fops->DataInStage(pdev , epnum);
+
+ if (pdev->cfg.dma_enable == 1)
+ {
+ if((epnum == 0) && (pdev->dev.device_state == USB_OTG_EP0_STATUS_IN))
+ {
+ /* prepare to rx more setup packets */
+ USB_OTG_EP0_OutStart(pdev);
+ }
+ }
+ }
+ if ( diepint.b.ahberr )
+ {
+ CLEAR_IN_EP_INTR(epnum, ahberr);
+ }
+ if ( diepint.b.timeout )
+ {
+ CLEAR_IN_EP_INTR(epnum, timeout);
+ }
+ if (diepint.b.intktxfemp)
+ {
+ CLEAR_IN_EP_INTR(epnum, intktxfemp);
+ }
+ if (diepint.b.intknepmis)
+ {
+ CLEAR_IN_EP_INTR(epnum, intknepmis);
+ }
+ if (diepint.b.inepnakeff)
+ {
+ CLEAR_IN_EP_INTR(epnum, inepnakeff);
+ }
+ if ( diepint.b.epdisabled )
+ {
+ CLEAR_IN_EP_INTR(epnum, epdisabled);
+ }
+ if (diepint.b.emptyintr)
+ {
+
+ DCD_WriteEmptyTxFifo(pdev , epnum);
+
+ CLEAR_IN_EP_INTR(epnum, emptyintr);
+ }
+ }
+ epnum++;
+ ep_intr >>= 1;
+ }
+
+ return 1;
+}
+
+/**
+* @brief DCD_HandleOutEP_ISR
+* Indicates that an OUT EP has a pending Interrupt
+* @param pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_HandleOutEP_ISR(USB_OTG_CORE_HANDLE *pdev)
+{
+ uint32_t ep_intr;
+ USB_OTG_DOEPINTn_TypeDef doepint;
+ USB_OTG_DEPXFRSIZ_TypeDef deptsiz;
+ uint32_t epnum = 0;
+
+ doepint.d32 = 0;
+
+ /* Read in the device interrupt bits */
+ ep_intr = USB_OTG_ReadDevAllOutEp_itr(pdev);
+
+ while ( ep_intr )
+ {
+ if (ep_intr&0x1)
+ {
+
+ doepint.d32 = USB_OTG_ReadDevOutEP_itr(pdev, epnum);
+
+ /* Transfer complete */
+ if ( doepint.b.xfercompl )
+ {
+ /* Clear the bit in DOEPINTn for this interrupt */
+ CLEAR_OUT_EP_INTR(epnum, xfercompl);
+ if (pdev->cfg.dma_enable == 1)
+ {
+ deptsiz.d32 = USB_OTG_READ_REG32(&(pdev->regs.OUTEP_REGS[epnum]->DOEPTSIZ));
+ /*ToDo : handle more than one single MPS size packet */
+ pdev->dev.out_ep[epnum].xfer_count = pdev->dev.out_ep[epnum].maxpacket - \
+ deptsiz.b.xfersize;
+ }
+ /* Inform upper layer: data ready */
+ /* RX COMPLETE */
+ USBD_DCD_INT_fops->DataOutStage(pdev , epnum);
+
+ if (pdev->cfg.dma_enable == 1)
+ {
+ if((epnum == 0) && (pdev->dev.device_state == USB_OTG_EP0_STATUS_OUT))
+ {
+ /* prepare to rx more setup packets */
+ USB_OTG_EP0_OutStart(pdev);
+ }
+ }
+ }
+ /* Endpoint disable */
+ if ( doepint.b.epdisabled )
+ {
+ /* Clear the bit in DOEPINTn for this interrupt */
+ CLEAR_OUT_EP_INTR(epnum, epdisabled);
+ }
+ /* AHB Error */
+ if ( doepint.b.ahberr )
+ {
+ CLEAR_OUT_EP_INTR(epnum, ahberr);
+ }
+ /* Setup Phase Done (control EPs) */
+ if ( doepint.b.setup )
+ {
+
+ /* inform the upper layer that a setup packet is available */
+ /* SETUP COMPLETE */
+ USBD_DCD_INT_fops->SetupStage(pdev);
+ CLEAR_OUT_EP_INTR(epnum, setup);
+ }
+ }
+ epnum++;
+ ep_intr >>= 1;
+ }
+ return 1;
+}
+
+/**
+* @brief DCD_HandleSof_ISR
+* Handles the SOF Interrupts
+* @param pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_HandleSof_ISR(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_GINTSTS_TypeDef GINTSTS;
+
+
+ USBD_DCD_INT_fops->SOF(pdev);
+
+ /* Clear interrupt */
+ GINTSTS.d32 = 0;
+ GINTSTS.b.sofintr = 1;
+ USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, GINTSTS.d32);
+
+ return 1;
+}
+
+/**
+* @brief DCD_HandleRxStatusQueueLevel_ISR
+* Handles the Rx Status Queue Level Interrupt
+* @param pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_HandleRxStatusQueueLevel_ISR(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_GINTMSK_TypeDef int_mask;
+ USB_OTG_DRXSTS_TypeDef status;
+ USB_OTG_EP *ep;
+
+ /* Disable the Rx Status Queue Level interrupt */
+ int_mask.d32 = 0;
+ int_mask.b.rxstsqlvl = 1;
+ USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, int_mask.d32, 0);
+
+ /* Get the Status from the top of the FIFO */
+ status.d32 = USB_OTG_READ_REG32( &pdev->regs.GREGS->GRXSTSP );
+
+ ep = &pdev->dev.out_ep[status.b.epnum];
+
+ switch (status.b.pktsts)
+ {
+ case STS_GOUT_NAK:
+ break;
+ case STS_DATA_UPDT:
+ if (status.b.bcnt)
+ {
+ USB_OTG_ReadPacket(pdev,ep->xfer_buff, status.b.bcnt);
+ ep->xfer_buff += status.b.bcnt;
+ ep->xfer_count += status.b.bcnt;
+ }
+ break;
+ case STS_XFER_COMP:
+ break;
+ case STS_SETUP_COMP:
+ break;
+ case STS_SETUP_UPDT:
+ /* Copy the setup packet received in FIFO into the setup buffer in RAM */
+ USB_OTG_ReadPacket(pdev , pdev->dev.setup_packet, 8);
+ ep->xfer_count += status.b.bcnt;
+ break;
+ default:
+ break;
+ }
+
+ /* Enable the Rx Status Queue Level interrupt */
+ USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, 0, int_mask.d32);
+
+ return 1;
+}
+
+/**
+* @brief DCD_WriteEmptyTxFifo
+* check FIFO for the next packet to be loaded
+* @param pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_WriteEmptyTxFifo(USB_OTG_CORE_HANDLE *pdev, uint32_t epnum)
+{
+ USB_OTG_DTXFSTSn_TypeDef txstatus;
+ USB_OTG_EP *ep;
+ uint32_t len = 0;
+ uint32_t len32b;
+ txstatus.d32 = 0;
+
+ ep = &pdev->dev.in_ep[epnum];
+
+ len = ep->xfer_len - ep->xfer_count;
+
+ if (len > ep->maxpacket)
+ {
+ len = ep->maxpacket;
+ }
+
+ len32b = (len + 3) / 4;
+ txstatus.d32 = USB_OTG_READ_REG32( &pdev->regs.INEP_REGS[epnum]->DTXFSTS);
+
+
+
+ while (txstatus.b.txfspcavail > len32b &&
+ ep->xfer_count < ep->xfer_len &&
+ ep->xfer_len != 0)
+ {
+ /* Write the FIFO */
+ len = ep->xfer_len - ep->xfer_count;
+
+ if (len > ep->maxpacket)
+ {
+ len = ep->maxpacket;
+ }
+ len32b = (len + 3) / 4;
+
+ USB_OTG_WritePacket (pdev , ep->xfer_buff, epnum, len);
+
+ ep->xfer_buff += len;
+ ep->xfer_count += len;
+
+ txstatus.d32 = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[epnum]->DTXFSTS);
+ }
+
+ return 1;
+}
+
+/**
+* @brief DCD_HandleUsbReset_ISR
+* This interrupt occurs when a USB Reset is detected
+* @param pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_HandleUsbReset_ISR(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_DAINT_TypeDef daintmsk;
+ USB_OTG_DOEPMSK_TypeDef doepmsk;
+ USB_OTG_DIEPMSK_TypeDef diepmsk;
+ USB_OTG_DCFG_TypeDef dcfg;
+ USB_OTG_DCTL_TypeDef dctl;
+ USB_OTG_GINTSTS_TypeDef gintsts;
+ uint32_t i;
+
+ dctl.d32 = 0;
+ daintmsk.d32 = 0;
+ doepmsk.d32 = 0;
+ diepmsk.d32 = 0;
+ dcfg.d32 = 0;
+ gintsts.d32 = 0;
+
+ /* Clear the Remote Wake-up Signaling */
+ dctl.b.rmtwkupsig = 1;
+ USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, dctl.d32, 0 );
+
+ /* Flush the Tx FIFO */
+ USB_OTG_FlushTxFifo(pdev , 0 );
+
+ for (i = 0; i < pdev->cfg.dev_endpoints ; i++)
+ {
+ USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPINT, 0xFF);
+ USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[i]->DOEPINT, 0xFF);
+ }
+ USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINT, 0xFFFFFFFF );
+
+ daintmsk.ep.in = 1;
+ daintmsk.ep.out = 1;
+ USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINTMSK, daintmsk.d32 );
+
+ doepmsk.b.setup = 1;
+ doepmsk.b.xfercompl = 1;
+ doepmsk.b.ahberr = 1;
+ doepmsk.b.epdisabled = 1;
+ USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DOEPMSK, doepmsk.d32 );
+#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED
+ USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DOUTEP1MSK, doepmsk.d32 );
+#endif
+ diepmsk.b.xfercompl = 1;
+ diepmsk.b.timeout = 1;
+ diepmsk.b.epdisabled = 1;
+ diepmsk.b.ahberr = 1;
+ diepmsk.b.intknepmis = 1;
+ USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DIEPMSK, diepmsk.d32 );
+#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED
+ USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DINEP1MSK, diepmsk.d32 );
+#endif
+ /* Reset Device Address */
+ dcfg.d32 = USB_OTG_READ_REG32( &pdev->regs.DREGS->DCFG);
+ dcfg.b.devaddr = 0;
+ USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DCFG, dcfg.d32);
+
+
+ /* setup EP0 to receive SETUP packets */
+ USB_OTG_EP0_OutStart(pdev);
+
+ /* Clear interrupt */
+ gintsts.d32 = 0;
+ gintsts.b.usbreset = 1;
+ USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, gintsts.d32);
+
+ /*Reset internal state machine */
+ USBD_DCD_INT_fops->Reset(pdev);
+ return 1;
+}
+
+/**
+* @brief DCD_HandleEnumDone_ISR
+* Read the device status register and set the device speed
+* @param pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_HandleEnumDone_ISR(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_GINTSTS_TypeDef gintsts;
+ USB_OTG_GUSBCFG_TypeDef gusbcfg;
+
+ USB_OTG_EP0Activate(pdev);
+
+ /* Set USB turn-around time based on device speed and PHY interface. */
+ gusbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG);
+
+ /* Full or High speed */
+ if ( USB_OTG_GetDeviceSpeed(pdev) == USB_SPEED_HIGH)
+ {
+ pdev->cfg.speed = USB_OTG_SPEED_HIGH;
+ pdev->cfg.mps = USB_OTG_HS_MAX_PACKET_SIZE ;
+ gusbcfg.b.usbtrdtim = 9;
+ }
+ else
+ {
+ pdev->cfg.speed = USB_OTG_SPEED_FULL;
+ pdev->cfg.mps = USB_OTG_FS_MAX_PACKET_SIZE ;
+ gusbcfg.b.usbtrdtim = 5;
+ }
+
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GUSBCFG, gusbcfg.d32);
+
+ /* Clear interrupt */
+ gintsts.d32 = 0;
+ gintsts.b.enumdone = 1;
+ USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTSTS, gintsts.d32 );
+ return 1;
+}
+
+
+/**
+* @brief DCD_IsoINIncomplete_ISR
+* handle the ISO IN incomplete interrupt
+* @param pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_IsoINIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_GINTSTS_TypeDef gintsts;
+
+ gintsts.d32 = 0;
+
+ USBD_DCD_INT_fops->IsoINIncomplete (pdev);
+
+ /* Clear interrupt */
+ gintsts.b.incomplisoin = 1;
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
+
+ return 1;
+}
+
+/**
+* @brief DCD_IsoOUTIncomplete_ISR
+* handle the ISO OUT incomplete interrupt
+* @param pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_IsoOUTIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_GINTSTS_TypeDef gintsts;
+
+ gintsts.d32 = 0;
+
+ USBD_DCD_INT_fops->IsoOUTIncomplete (pdev);
+
+ /* Clear interrupt */
+ gintsts.b.incomplisoout = 1;
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
+ return 1;
+}
+/**
+* @brief DCD_ReadDevInEP
+* Reads ep flags
+* @param pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_ReadDevInEP (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum)
+{
+ uint32_t v, msk, emp;
+ msk = USB_OTG_READ_REG32(&pdev->regs.DREGS->DIEPMSK);
+ emp = USB_OTG_READ_REG32(&pdev->regs.DREGS->DIEPEMPMSK);
+ msk |= ((emp >> epnum) & 0x1) << 7;
+ v = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[epnum]->DIEPINT) & msk;
+ return v;
+}
+
+
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
diff --git a/example/stm32f4/STM32_USB_OTG_Driver/src/usb_hcd.c b/example/stm32f4/STM32_USB_OTG_Driver/src/usb_hcd.c
new file mode 100644
index 0000000..689d061
--- /dev/null
+++ b/example/stm32f4/STM32_USB_OTG_Driver/src/usb_hcd.c
@@ -0,0 +1,256 @@
+/**
+ ******************************************************************************
+ * @file usb_hcd.c
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 22-July-2011
+ * @brief Host Interface Layer
+ ******************************************************************************
+ * @attention
+ *
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * © COPYRIGHT 2011 STMicroelectronics
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_core.h"
+#include "usb_hcd.h"
+#include "usb_conf.h"
+#include "usb_bsp.h"
+
+
+/** @addtogroup USB_OTG_DRIVER
+ * @{
+ */
+
+/** @defgroup USB_HCD
+ * @brief This file is the interface between EFSL ans Host mass-storage class
+ * @{
+ */
+
+
+/** @defgroup USB_HCD_Private_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_HCD_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+
+/** @defgroup USB_HCD_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_HCD_Private_Variables
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_HCD_Private_FunctionPrototypes
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_HCD_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief HCD_Init
+ * Initialize the HOST portion of the driver.
+ * @param pdev: Selected device
+ * @param base_address: OTG base address
+ * @retval Status
+ */
+uint32_t HCD_Init(USB_OTG_CORE_HANDLE *pdev ,
+ USB_OTG_CORE_ID_TypeDef coreID)
+{
+ uint8_t i = 0;
+ pdev->host.ConnSts = 0;
+
+ for (i= 0; i< USB_OTG_MAX_TX_FIFOS; i++)
+ {
+ pdev->host.ErrCnt[i] = 0;
+ pdev->host.XferCnt[i] = 0;
+ pdev->host.HC_Status[i] = HC_IDLE;
+ }
+ pdev->host.hc[0].max_packet = 8;
+
+ USB_OTG_SelectCore(pdev, coreID);
+#ifndef DUAL_ROLE_MODE_ENABLED
+ USB_OTG_DisableGlobalInt(pdev);
+ USB_OTG_CoreInit(pdev);
+
+ /* Force Host Mode*/
+ USB_OTG_SetCurrentMode(pdev , HOST_MODE);
+ USB_OTG_CoreInitHost(pdev);
+ USB_OTG_EnableGlobalInt(pdev);
+#endif
+
+ return 0;
+}
+
+
+/**
+ * @brief HCD_GetCurrentSpeed
+ * Get Current device Speed.
+ * @param pdev : Selected device
+ * @retval Status
+ */
+
+uint32_t HCD_GetCurrentSpeed (USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_HPRT0_TypeDef HPRT0;
+ HPRT0.d32 = USB_OTG_READ_REG32(pdev->regs.HPRT0);
+
+ return HPRT0.b.prtspd;
+}
+
+/**
+ * @brief HCD_ResetPort
+ * Issues the reset command to device
+ * @param pdev : Selected device
+ * @retval Status
+ */
+uint32_t HCD_ResetPort(USB_OTG_CORE_HANDLE *pdev)
+{
+ /*
+ Before starting to drive a USB reset, the application waits for the OTG
+ interrupt triggered by the debounce done bit (DBCDNE bit in OTG_FS_GOTGINT),
+ which indicates that the bus is stable again after the electrical debounce
+ caused by the attachment of a pull-up resistor on DP (FS) or DM (LS).
+ */
+
+ USB_OTG_ResetPort(pdev);
+ return 0;
+}
+
+/**
+ * @brief HCD_IsDeviceConnected
+ * Check if the device is connected.
+ * @param pdev : Selected device
+ * @retval Device connection status. 1 -> connected and 0 -> disconnected
+ *
+ */
+uint32_t HCD_IsDeviceConnected(USB_OTG_CORE_HANDLE *pdev)
+{
+ return (pdev->host.ConnSts);
+}
+
+/**
+ * @brief HCD_GetCurrentFrame
+ * This function returns the frame number for sof packet
+ * @param pdev : Selected device
+ * @retval Frame number
+ *
+ */
+uint32_t HCD_GetCurrentFrame (USB_OTG_CORE_HANDLE *pdev)
+{
+ return (USB_OTG_READ_REG32(&pdev->regs.HREGS->HFNUM) & 0xFFFF) ;
+}
+
+/**
+ * @brief HCD_GetURB_State
+ * This function returns the last URBstate
+ * @param pdev: Selected device
+ * @retval URB_STATE
+ *
+ */
+URB_STATE HCD_GetURB_State (USB_OTG_CORE_HANDLE *pdev , uint8_t ch_num)
+{
+ return pdev->host.URB_State[ch_num] ;
+}
+
+/**
+ * @brief HCD_GetXferCnt
+ * This function returns the last URBstate
+ * @param pdev: Selected device
+ * @retval No. of data bytes transferred
+ *
+ */
+uint32_t HCD_GetXferCnt (USB_OTG_CORE_HANDLE *pdev, uint8_t ch_num)
+{
+ return pdev->host.XferCnt[ch_num] ;
+}
+
+
+
+/**
+ * @brief HCD_GetHCState
+ * This function returns the HC Status
+ * @param pdev: Selected device
+ * @retval HC_STATUS
+ *
+ */
+HC_STATUS HCD_GetHCState (USB_OTG_CORE_HANDLE *pdev , uint8_t ch_num)
+{
+ return pdev->host.HC_Status[ch_num] ;
+}
+
+/**
+ * @brief HCD_HC_Init
+ * This function prepare a HC and start a transfer
+ * @param pdev: Selected device
+ * @param hc_num: Channel number
+ * @retval status
+ */
+uint32_t HCD_HC_Init (USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num)
+{
+ return USB_OTG_HC_Init(pdev, hc_num);
+}
+
+/**
+ * @brief HCD_SubmitRequest
+ * This function prepare a HC and start a transfer
+ * @param pdev: Selected device
+ * @param hc_num: Channel number
+ * @retval status
+ */
+uint32_t HCD_SubmitRequest (USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num)
+{
+
+ pdev->host.URB_State[hc_num] = URB_IDLE;
+ pdev->host.hc[hc_num].xfer_count = 0 ;
+ return USB_OTG_HC_StartXfer(pdev, hc_num);
+}
+
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
diff --git a/example/stm32f4/STM32_USB_OTG_Driver/src/usb_hcd_int.c b/example/stm32f4/STM32_USB_OTG_Driver/src/usb_hcd_int.c
new file mode 100644
index 0000000..bd4081f
--- /dev/null
+++ b/example/stm32f4/STM32_USB_OTG_Driver/src/usb_hcd_int.c
@@ -0,0 +1,832 @@
+/**
+ ******************************************************************************
+ * @file usb_hcd_int.c
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 22-July-2011
+ * @brief Host driver interrupt subroutines
+ ******************************************************************************
+ * @attention
+ *
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * © COPYRIGHT 2011 STMicroelectronics
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_core.h"
+#include "usb_defines.h"
+#include "usb_hcd_int.h"
+
+#if defined (__CC_ARM) /*!< ARM Compiler */
+ #pragma O0
+#elif defined ( __ICCARM__ ) /*!< IAR Compiler */
+ #pragma O0
+#elif defined (__GNUC__) /*!< GNU Compiler */
+ #pragma GCC optimize ("O0")
+#elif defined (__TASKING__) /*!< TASKING Compiler */
+ #pragma optimize=0
+
+#endif /* __CC_ARM */
+
+/** @addtogroup USB_OTG_DRIVER
+ * @{
+ */
+
+/** @defgroup USB_HCD_INT
+ * @brief This file contains the interrupt subroutines for the Host mode.
+ * @{
+ */
+
+
+/** @defgroup USB_HCD_INT_Private_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_HCD_INT_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+
+/** @defgroup USB_HCD_INT_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_HCD_INT_Private_Variables
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_HCD_INT_Private_FunctionPrototypes
+ * @{
+ */
+
+static uint32_t USB_OTG_USBH_handle_sof_ISR(USB_OTG_CORE_HANDLE *pdev);
+static uint32_t USB_OTG_USBH_handle_port_ISR(USB_OTG_CORE_HANDLE *pdev);
+static uint32_t USB_OTG_USBH_handle_hc_ISR (USB_OTG_CORE_HANDLE *pdev);
+static uint32_t USB_OTG_USBH_handle_hc_n_In_ISR (USB_OTG_CORE_HANDLE *pdev ,
+ uint32_t num);
+static uint32_t USB_OTG_USBH_handle_hc_n_Out_ISR (USB_OTG_CORE_HANDLE *pdev ,
+ uint32_t num);
+static uint32_t USB_OTG_USBH_handle_rx_qlvl_ISR (USB_OTG_CORE_HANDLE *pdev);
+static uint32_t USB_OTG_USBH_handle_nptxfempty_ISR (USB_OTG_CORE_HANDLE *pdev);
+static uint32_t USB_OTG_USBH_handle_ptxfempty_ISR (USB_OTG_CORE_HANDLE *pdev);
+static uint32_t USB_OTG_USBH_handle_Disconnect_ISR (USB_OTG_CORE_HANDLE *pdev);
+static uint32_t USB_OTG_USBH_handle_IncompletePeriodicXfer_ISR (USB_OTG_CORE_HANDLE *pdev);
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_HCD_INT_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief HOST_Handle_ISR
+ * This function handles all USB Host Interrupts
+ * @param pdev: Selected device
+ * @retval status
+ */
+
+uint32_t USBH_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_GINTSTS_TypeDef gintsts;
+ uint32_t retval = 0;
+
+ gintsts.d32 = 0;
+
+ /* Check if HOST Mode */
+ if (USB_OTG_IsHostMode(pdev))
+ {
+ gintsts.d32 = USB_OTG_ReadCoreItr(pdev);
+ if (!gintsts.d32)
+ {
+ return 0;
+ }
+
+ if (gintsts.b.sofintr)
+ {
+ retval |= USB_OTG_USBH_handle_sof_ISR (pdev);
+ }
+
+ if (gintsts.b.rxstsqlvl)
+ {
+ retval |= USB_OTG_USBH_handle_rx_qlvl_ISR (pdev);
+ }
+
+ if (gintsts.b.nptxfempty)
+ {
+ retval |= USB_OTG_USBH_handle_nptxfempty_ISR (pdev);
+ }
+
+ if (gintsts.b.ptxfempty)
+ {
+ retval |= USB_OTG_USBH_handle_ptxfempty_ISR (pdev);
+ }
+
+ if (gintsts.b.hcintr)
+ {
+ retval |= USB_OTG_USBH_handle_hc_ISR (pdev);
+ }
+
+ if (gintsts.b.portintr)
+ {
+ retval |= USB_OTG_USBH_handle_port_ISR (pdev);
+ }
+
+ if (gintsts.b.disconnect)
+ {
+ retval |= USB_OTG_USBH_handle_Disconnect_ISR (pdev);
+
+ }
+
+ if (gintsts.b.incomplisoout)
+ {
+ retval |= USB_OTG_USBH_handle_IncompletePeriodicXfer_ISR (pdev);
+ }
+
+
+ }
+ return retval;
+}
+
+/**
+ * @brief USB_OTG_USBH_handle_hc_ISR
+ * This function indicates that one or more host channels has a pending
+ * @param pdev: Selected device
+ * @retval status
+ */
+static uint32_t USB_OTG_USBH_handle_hc_ISR (USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_HAINT_TypeDef haint;
+ USB_OTG_HCCHAR_TypeDef hcchar;
+ uint32_t i = 0;
+ uint32_t retval = 0;
+
+ /* Clear appropriate bits in HCINTn to clear the interrupt bit in
+ * GINTSTS */
+
+ haint.d32 = USB_OTG_ReadHostAllChannels_intr(pdev);
+
+ for (i = 0; i < pdev->cfg.host_channels ; i++)
+ {
+ if (haint.b.chint & (1 << i))
+ {
+ hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[i]->HCCHAR);
+
+ if (hcchar.b.epdir)
+ {
+ retval |= USB_OTG_USBH_handle_hc_n_In_ISR (pdev, i);
+ }
+ else
+ {
+ retval |= USB_OTG_USBH_handle_hc_n_Out_ISR (pdev, i);
+ }
+ }
+ }
+
+ return retval;
+}
+
+/**
+ * @brief USB_OTG_otg_hcd_handle_sof_intr
+ * Handles the start-of-frame interrupt in host mode.
+ * @param pdev: Selected device
+ * @retval status
+ */
+static uint32_t USB_OTG_USBH_handle_sof_ISR (USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_GINTSTS_TypeDef gintsts;
+
+
+ gintsts.d32 = 0;
+ /* Clear interrupt */
+ gintsts.b.sofintr = 1;
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
+
+ return 1;
+}
+
+/**
+ * @brief USB_OTG_USBH_handle_Disconnect_ISR
+ * Handles disconnect event.
+ * @param pdev: Selected device
+ * @retval status
+ */
+static uint32_t USB_OTG_USBH_handle_Disconnect_ISR (USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_GINTSTS_TypeDef gintsts;
+
+ pdev->host.ConnSts = 0;
+ gintsts.d32 = 0;
+
+ pdev->host.port_cb->Disconnect(pdev);
+
+ /* Clear interrupt */
+ gintsts.b.disconnect = 1;
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
+
+ return 1;
+}
+
+/**
+ * @brief USB_OTG_USBH_handle_nptxfempty_ISR
+ * Handles non periodic tx fifo empty.
+ * @param pdev: Selected device
+ * @retval status
+ */
+static uint32_t USB_OTG_USBH_handle_nptxfempty_ISR (USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_GINTMSK_TypeDef intmsk;
+ USB_OTG_HNPTXSTS_TypeDef hnptxsts;
+ uint16_t len_words , len;
+
+ hnptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->HNPTXSTS);
+
+ len_words = (pdev->host.hc[hnptxsts.b.chnum].xfer_len + 3) / 4;
+
+ while ((hnptxsts.b.nptxfspcavail > len_words)&&
+ (pdev->host.hc[hnptxsts.b.chnum].xfer_len != 0))
+ {
+
+ len = hnptxsts.b.nptxfspcavail * 4;
+
+ if (len > pdev->host.hc[hnptxsts.b.chnum].xfer_len)
+ {
+ /* Last packet */
+ len = pdev->host.hc[hnptxsts.b.chnum].xfer_len;
+
+ intmsk.d32 = 0;
+ intmsk.b.nptxfempty = 1;
+ USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, intmsk.d32, 0);
+ }
+
+ len_words = (pdev->host.hc[hnptxsts.b.chnum].xfer_len + 3) / 4;
+
+ USB_OTG_WritePacket (pdev , pdev->host.hc[hnptxsts.b.chnum].xfer_buff, hnptxsts.b.chnum, len);
+
+ pdev->host.hc[hnptxsts.b.chnum].xfer_buff += len;
+ pdev->host.hc[hnptxsts.b.chnum].xfer_len -= len;
+ pdev->host.hc[hnptxsts.b.chnum].xfer_count += len;
+
+ hnptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->HNPTXSTS);
+ }
+
+ return 1;
+}
+
+/**
+ * @brief USB_OTG_USBH_handle_ptxfempty_ISR
+ * Handles periodic tx fifo empty
+ * @param pdev: Selected device
+ * @retval status
+ */
+static uint32_t USB_OTG_USBH_handle_ptxfempty_ISR (USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_GINTMSK_TypeDef intmsk;
+ USB_OTG_HPTXSTS_TypeDef hptxsts;
+ uint16_t len_words , len;
+
+ hptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HPTXSTS);
+
+ len_words = (pdev->host.hc[hptxsts.b.chnum].xfer_len + 3) / 4;
+
+ while ((hptxsts.b.ptxfspcavail > len_words)&&
+ (pdev->host.hc[hptxsts.b.chnum].xfer_len != 0))
+ {
+
+ len = hptxsts.b.ptxfspcavail * 4;
+
+ if (len > pdev->host.hc[hptxsts.b.chnum].xfer_len)
+ {
+ len = pdev->host.hc[hptxsts.b.chnum].xfer_len;
+ /* Last packet */
+ intmsk.d32 = 0;
+ intmsk.b.ptxfempty = 1;
+ USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, intmsk.d32, 0);
+ }
+
+ len_words = (pdev->host.hc[hptxsts.b.chnum].xfer_len + 3) / 4;
+
+ USB_OTG_WritePacket (pdev , pdev->host.hc[hptxsts.b.chnum].xfer_buff, hptxsts.b.chnum, len);
+
+ pdev->host.hc[hptxsts.b.chnum].xfer_buff += len;
+ pdev->host.hc[hptxsts.b.chnum].xfer_len -= len;
+ pdev->host.hc[hptxsts.b.chnum].xfer_count += len;
+
+ hptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HPTXSTS);
+ }
+
+ return 1;
+}
+
+/**
+ * @brief USB_OTG_USBH_handle_port_ISR
+ * This function determines which interrupt conditions have occurred
+ * @param pdev: Selected device
+ * @retval status
+ */
+static uint32_t USB_OTG_USBH_handle_port_ISR (USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_HPRT0_TypeDef hprt0;
+ USB_OTG_HPRT0_TypeDef hprt0_dup;
+ USB_OTG_HCFG_TypeDef hcfg;
+ uint32_t do_reset = 0;
+ uint32_t retval = 0;
+
+ hcfg.d32 = 0;
+ hprt0.d32 = 0;
+ hprt0_dup.d32 = 0;
+
+ hprt0.d32 = USB_OTG_READ_REG32(pdev->regs.HPRT0);
+ hprt0_dup.d32 = USB_OTG_READ_REG32(pdev->regs.HPRT0);
+
+ /* Clear the interrupt bits in GINTSTS */
+
+ hprt0_dup.b.prtena = 0;
+ hprt0_dup.b.prtconndet = 0;
+ hprt0_dup.b.prtenchng = 0;
+ hprt0_dup.b.prtovrcurrchng = 0;
+
+ /* Port Connect Detected */
+ if (hprt0.b.prtconndet)
+ {
+ pdev->host.port_cb->Connect(pdev);
+ hprt0_dup.b.prtconndet = 1;
+ do_reset = 1;
+ retval |= 1;
+ }
+
+ /* Port Enable Changed */
+ if (hprt0.b.prtenchng)
+ {
+ hprt0_dup.b.prtenchng = 1;
+ if (hprt0.b.prtena == 1)
+ {
+ pdev->host.ConnSts = 1;
+
+ if ((hprt0.b.prtspd == HPRT0_PRTSPD_LOW_SPEED) ||
+ (hprt0.b.prtspd == HPRT0_PRTSPD_FULL_SPEED))
+ {
+
+ hcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HCFG);
+
+ if (hprt0.b.prtspd == HPRT0_PRTSPD_LOW_SPEED)
+ {
+ USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HFIR, 6000 );
+ if (hcfg.b.fslspclksel != HCFG_6_MHZ)
+ {
+ if(pdev->cfg.coreID == USB_OTG_FS_CORE_ID)
+ {
+ USB_OTG_InitFSLSPClkSel(pdev ,HCFG_6_MHZ );
+ }
+ do_reset = 1;
+ }
+ }
+ else
+ {
+
+ USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HFIR, 48000 );
+ if (hcfg.b.fslspclksel != HCFG_48_MHZ)
+ {
+ USB_OTG_InitFSLSPClkSel(pdev ,HCFG_48_MHZ );
+ do_reset = 1;
+ }
+ }
+ }
+ else
+ {
+ do_reset = 1;
+ }
+ }
+ }
+ /* Overcurrent Change Interrupt */
+ if (hprt0.b.prtovrcurrchng)
+ {
+ hprt0_dup.b.prtovrcurrchng = 1;
+ retval |= 1;
+ }
+ if (do_reset)
+ {
+ USB_OTG_ResetPort(pdev);
+
+ }
+ /* Clear Port Interrupts */
+ USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0_dup.d32);
+
+ return retval;
+}
+
+/**
+ * @brief USB_OTG_USBH_handle_hc_n_Out_ISR
+ * Handles interrupt for a specific Host Channel
+ * @param pdev: Selected device
+ * @param hc_num: Channel number
+ * @retval status
+ */
+uint32_t USB_OTG_USBH_handle_hc_n_Out_ISR (USB_OTG_CORE_HANDLE *pdev , uint32_t num)
+{
+
+ USB_OTG_HCINTn_TypeDef hcint;
+ USB_OTG_HCGINTMSK_TypeDef hcintmsk;
+ USB_OTG_HC_REGS *hcreg;
+ USB_OTG_HCCHAR_TypeDef hcchar;
+
+ hcreg = pdev->regs.HC_REGS[num];
+ hcint.d32 = USB_OTG_READ_REG32(&hcreg->HCINT);
+ hcintmsk.d32 = USB_OTG_READ_REG32(&hcreg->HCGINTMSK);
+ hcint.d32 = hcint.d32 & hcintmsk.d32;
+
+ hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[num]->HCCHAR);
+
+ if (hcint.b.ahberr)
+ {
+ CLEAR_HC_INT(hcreg ,ahberr);
+ UNMASK_HOST_INT_CHH (num);
+ }
+ else if (hcint.b.ack)
+ {
+ CLEAR_HC_INT(hcreg , ack);
+ }
+
+ else if (hcint.b.xfercompl)
+ {
+ pdev->host.ErrCnt[num] = 0;
+ UNMASK_HOST_INT_CHH (num);
+ USB_OTG_HC_Halt(pdev, num);
+ CLEAR_HC_INT(hcreg , xfercompl);
+ pdev->host.HC_Status[num] = HC_XFRC;
+ }
+
+ else if (hcint.b.stall)
+ {
+ CLEAR_HC_INT(hcreg , stall);
+ UNMASK_HOST_INT_CHH (num);
+ USB_OTG_HC_Halt(pdev, num);
+ pdev->host.HC_Status[num] = HC_STALL;
+ }
+
+ else if (hcint.b.nak)
+ {
+ pdev->host.ErrCnt[num] = 0;
+ UNMASK_HOST_INT_CHH (num);
+ USB_OTG_HC_Halt(pdev, num);
+ CLEAR_HC_INT(hcreg , nak);
+ pdev->host.HC_Status[num] = HC_NAK;
+ }
+
+ else if (hcint.b.xacterr)
+ {
+ UNMASK_HOST_INT_CHH (num);
+ USB_OTG_HC_Halt(pdev, num);
+ pdev->host.ErrCnt[num] ++;
+ pdev->host.HC_Status[num] = HC_XACTERR;
+ CLEAR_HC_INT(hcreg , xacterr);
+ }
+ else if (hcint.b.nyet)
+ {
+ pdev->host.ErrCnt[num] = 0;
+ UNMASK_HOST_INT_CHH (num);
+ USB_OTG_HC_Halt(pdev, num);
+ CLEAR_HC_INT(hcreg , nyet);
+ pdev->host.HC_Status[num] = HC_NYET;
+ }
+ else if (hcint.b.datatglerr)
+ {
+
+ UNMASK_HOST_INT_CHH (num);
+ USB_OTG_HC_Halt(pdev, num);
+ CLEAR_HC_INT(hcreg , nak);
+ pdev->host.HC_Status[num] = HC_DATATGLERR;
+
+ CLEAR_HC_INT(hcreg , datatglerr);
+ }
+ else if (hcint.b.chhltd)
+ {
+ MASK_HOST_INT_CHH (num);
+
+ if(pdev->host.HC_Status[num] == HC_XFRC)
+ {
+ pdev->host.URB_State[num] = URB_DONE;
+
+ if (hcchar.b.eptype == EP_TYPE_BULK)
+ {
+ pdev->host.hc[num].toggle_out ^= 1;
+ }
+ }
+ else if(pdev->host.HC_Status[num] == HC_NAK)
+ {
+ pdev->host.URB_State[num] = URB_NOTREADY;
+ }
+ else if(pdev->host.HC_Status[num] == HC_NYET)
+ {
+ if(pdev->host.hc[num].do_ping == 1)
+ {
+ USB_OTG_HC_DoPing(pdev, num);
+ }
+ pdev->host.URB_State[num] = URB_NOTREADY;
+ }
+ else if(pdev->host.HC_Status[num] == HC_STALL)
+ {
+ pdev->host.URB_State[num] = URB_STALL;
+ }
+ else if(pdev->host.HC_Status[num] == HC_XACTERR)
+ {
+ if (pdev->host.ErrCnt[num] == 3)
+ {
+ pdev->host.URB_State[num] = URB_ERROR;
+ pdev->host.ErrCnt[num] = 0;
+ }
+ }
+ CLEAR_HC_INT(hcreg , chhltd);
+ }
+
+
+ return 1;
+}
+
+/**
+ * @brief USB_OTG_USBH_handle_hc_n_In_ISR
+ * Handles interrupt for a specific Host Channel
+ * @param pdev: Selected device
+ * @param hc_num: Channel number
+ * @retval status
+ */
+uint32_t USB_OTG_USBH_handle_hc_n_In_ISR (USB_OTG_CORE_HANDLE *pdev , uint32_t num)
+{
+ USB_OTG_HCINTn_TypeDef hcint;
+ USB_OTG_HCGINTMSK_TypeDef hcintmsk;
+ USB_OTG_HCCHAR_TypeDef hcchar;
+ USB_OTG_HCTSIZn_TypeDef hctsiz;
+ USB_OTG_HC_REGS *hcreg;
+
+
+ hcreg = pdev->regs.HC_REGS[num];
+ hcint.d32 = USB_OTG_READ_REG32(&hcreg->HCINT);
+ hcintmsk.d32 = USB_OTG_READ_REG32(&hcreg->HCGINTMSK);
+ hcint.d32 = hcint.d32 & hcintmsk.d32;
+ hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[num]->HCCHAR);
+ hcintmsk.d32 = 0;
+
+
+ if (hcint.b.ahberr)
+ {
+ CLEAR_HC_INT(hcreg ,ahberr);
+ UNMASK_HOST_INT_CHH (num);
+ }
+ else if (hcint.b.ack)
+ {
+ CLEAR_HC_INT(hcreg ,ack);
+ }
+
+ else if (hcint.b.stall)
+ {
+ UNMASK_HOST_INT_CHH (num);
+ pdev->host.HC_Status[num] = HC_STALL;
+ CLEAR_HC_INT(hcreg , nak); /* Clear the NAK Condition */
+ CLEAR_HC_INT(hcreg , stall); /* Clear the STALL Condition */
+ hcint.b.nak = 0; /* NOTE: When there is a 'stall', reset also nak,
+ else, the pdev->host.HC_Status = HC_STALL
+ will be overwritten by 'nak' in code below */
+ USB_OTG_HC_Halt(pdev, num);
+ }
+ else if (hcint.b.datatglerr)
+ {
+
+ UNMASK_HOST_INT_CHH (num);
+ USB_OTG_HC_Halt(pdev, num);
+ CLEAR_HC_INT(hcreg , nak);
+ pdev->host.HC_Status[num] = HC_DATATGLERR;
+ CLEAR_HC_INT(hcreg , datatglerr);
+ }
+
+ if (hcint.b.frmovrun)
+ {
+ UNMASK_HOST_INT_CHH (num);
+ USB_OTG_HC_Halt(pdev, num);
+ CLEAR_HC_INT(hcreg ,frmovrun);
+ }
+
+ else if (hcint.b.xfercompl)
+ {
+
+ if (pdev->cfg.dma_enable == 1)
+ {
+ hctsiz.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[num]->HCTSIZ);
+ pdev->host.XferCnt[num] = pdev->host.hc[num].xfer_len - hctsiz.b.xfersize;
+ }
+
+ pdev->host.HC_Status[num] = HC_XFRC;
+ pdev->host.ErrCnt [num]= 0;
+ CLEAR_HC_INT(hcreg , xfercompl);
+
+ if ((hcchar.b.eptype == EP_TYPE_CTRL)||
+ (hcchar.b.eptype == EP_TYPE_BULK))
+ {
+ UNMASK_HOST_INT_CHH (num);
+ USB_OTG_HC_Halt(pdev, num);
+ CLEAR_HC_INT(hcreg , nak);
+ pdev->host.hc[num].toggle_in ^= 1;
+
+ }
+ else if(hcchar.b.eptype == EP_TYPE_INTR)
+ {
+ hcchar.b.oddfrm = 1;
+ USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[num]->HCCHAR, hcchar.d32);
+ pdev->host.URB_State[num] = URB_DONE;
+ }
+
+ }
+ else if (hcint.b.chhltd)
+ {
+ MASK_HOST_INT_CHH (num);
+
+ if(pdev->host.HC_Status[num] == HC_XFRC)
+ {
+ pdev->host.URB_State[num] = URB_DONE;
+ }
+
+ else if (pdev->host.HC_Status[num] == HC_STALL)
+ {
+ pdev->host.URB_State[num] = URB_STALL;
+ }
+
+ else if((pdev->host.HC_Status[num] == HC_XACTERR) ||
+ (pdev->host.HC_Status[num] == HC_DATATGLERR))
+ {
+ pdev->host.ErrCnt[num] = 0;
+ pdev->host.URB_State[num] = URB_ERROR;
+
+ }
+ else if(hcchar.b.eptype == EP_TYPE_INTR)
+ {
+ pdev->host.hc[num].toggle_in ^= 1;
+ }
+
+ CLEAR_HC_INT(hcreg , chhltd);
+
+ }
+ else if (hcint.b.xacterr)
+ {
+ UNMASK_HOST_INT_CHH (num);
+ pdev->host.ErrCnt[num] ++;
+ pdev->host.HC_Status[num] = HC_XACTERR;
+ USB_OTG_HC_Halt(pdev, num);
+ CLEAR_HC_INT(hcreg , xacterr);
+
+ }
+ else if (hcint.b.nak)
+ {
+ if(hcchar.b.eptype == EP_TYPE_INTR)
+ {
+ UNMASK_HOST_INT_CHH (num);
+ USB_OTG_HC_Halt(pdev, num);
+ CLEAR_HC_INT(hcreg , nak);
+ }
+ else if ((hcchar.b.eptype == EP_TYPE_CTRL)||
+ (hcchar.b.eptype == EP_TYPE_BULK))
+ {
+ /* re-activate the channel */
+ hcchar.b.chen = 1;
+ hcchar.b.chdis = 0;
+ USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[num]->HCCHAR, hcchar.d32);
+ }
+ pdev->host.HC_Status[num] = HC_NAK;
+ }
+
+
+ return 1;
+
+}
+
+/**
+ * @brief USB_OTG_USBH_handle_rx_qlvl_ISR
+ * Handles the Rx Status Queue Level Interrupt
+ * @param pdev: Selected device
+ * @retval status
+ */
+
+static uint32_t USB_OTG_USBH_handle_rx_qlvl_ISR (USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_GRXFSTS_TypeDef grxsts;
+ USB_OTG_GINTMSK_TypeDef intmsk;
+ USB_OTG_HCTSIZn_TypeDef hctsiz;
+ USB_OTG_HCCHAR_TypeDef hcchar;
+ __IO uint8_t channelnum =0;
+ uint32_t count;
+
+ /* Disable the Rx Status Queue Level interrupt */
+ intmsk.d32 = 0;
+ intmsk.b.rxstsqlvl = 1;
+ USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, intmsk.d32, 0);
+
+ grxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GRXSTSP);
+ channelnum = grxsts.b.chnum;
+ hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[channelnum]->HCCHAR);
+
+ switch (grxsts.b.pktsts)
+ {
+ case GRXSTS_PKTSTS_IN:
+ /* Read the data into the host buffer. */
+ if ((grxsts.b.bcnt > 0) && (pdev->host.hc[channelnum].xfer_buff != (void *)0))
+ {
+
+ USB_OTG_ReadPacket(pdev, pdev->host.hc[channelnum].xfer_buff, grxsts.b.bcnt);
+ /*manage multiple Xfer */
+ pdev->host.hc[grxsts.b.chnum].xfer_buff += grxsts.b.bcnt;
+ pdev->host.hc[grxsts.b.chnum].xfer_count += grxsts.b.bcnt;
+
+
+ count = pdev->host.hc[channelnum].xfer_count;
+ pdev->host.XferCnt[channelnum] = count;
+
+ hctsiz.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[channelnum]->HCTSIZ);
+ if(hctsiz.b.pktcnt > 0)
+ {
+ /* re-activate the channel when more packets are expected */
+ hcchar.b.chen = 1;
+ hcchar.b.chdis = 0;
+ USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[channelnum]->HCCHAR, hcchar.d32);
+ }
+ }
+ break;
+
+ case GRXSTS_PKTSTS_IN_XFER_COMP:
+
+ case GRXSTS_PKTSTS_DATA_TOGGLE_ERR:
+ case GRXSTS_PKTSTS_CH_HALTED:
+ default:
+ break;
+ }
+
+ /* Enable the Rx Status Queue Level interrupt */
+ intmsk.b.rxstsqlvl = 1;
+ USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GINTMSK, 0, intmsk.d32);
+ return 1;
+}
+
+/**
+ * @brief USB_OTG_USBH_handle_IncompletePeriodicXfer_ISR
+ * Handles the incomplete Periodic transfer Interrupt
+ * @param pdev: Selected device
+ * @retval status
+ */
+static uint32_t USB_OTG_USBH_handle_IncompletePeriodicXfer_ISR (USB_OTG_CORE_HANDLE *pdev)
+{
+
+ USB_OTG_GINTSTS_TypeDef gintsts;
+ USB_OTG_HCCHAR_TypeDef hcchar;
+
+
+
+
+ hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[0]->HCCHAR);
+ hcchar.b.chen = 1;
+ hcchar.b.chdis = 1;
+ USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[0]->HCCHAR, hcchar.d32);
+
+ gintsts.d32 = 0;
+ /* Clear interrupt */
+ gintsts.b.incomplisoout = 1;
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
+
+ return 1;
+}
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
diff --git a/example/stm32f4/STM32_USB_OTG_Driver/src/usb_otg.c b/example/stm32f4/STM32_USB_OTG_Driver/src/usb_otg.c
new file mode 100644
index 0000000..fbb71ec
--- /dev/null
+++ b/example/stm32f4/STM32_USB_OTG_Driver/src/usb_otg.c
@@ -0,0 +1,175 @@
+/**
+ ******************************************************************************
+ * @file usb_otg.c
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 22-July-2011
+ * @brief OTG Core Layer
+ ******************************************************************************
+ * @attention
+ *
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * © COPYRIGHT 2011 STMicroelectronics
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_defines.h"
+#include "usb_regs.h"
+#include "usb_core.h"
+#include "usb_otg.h"
+
+/** @addtogroup USB_OTG_DRIVER
+ * @{
+ */
+
+/** @defgroup USB_OTG
+ * @brief This file is the interface between EFSL ans Host mass-storage class
+ * @{
+ */
+
+
+/** @defgroup USB_OTG_Private_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_OTG_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+
+/** @defgroup USB_OTG_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_OTG_Private_Variables
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_OTG_Private_FunctionPrototypes
+ * @{
+ */
+
+static uint32_t USB_OTG_Read_itr(USB_OTG_CORE_HANDLE *pdev);
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_OTG_Private_Functions
+ * @{
+ */
+
+
+/* OTG Interrupt Handler */
+
+
+/**
+ * @brief STM32_USBO_OTG_ISR_Handler
+ *
+ * @param None
+ * @retval : None
+ */
+uint32_t STM32_USBO_OTG_ISR_Handler(USB_OTG_CORE_HANDLE *pdev)
+{
+ uint32_t retval = 0;
+ USB_OTG_GINTSTS_TypeDef gintsts ;
+ gintsts.d32 = 0;
+
+ gintsts.d32 = USB_OTG_Read_itr(pdev);
+ if (gintsts.d32 == 0)
+ {
+ return 0;
+ }
+ if (gintsts.b.otgintr)
+ {
+ retval |= 1;//USB_OTG_HandleOTG_ISR(pdev);
+ }
+ if (gintsts.b.conidstschng)
+ {
+ retval |= 2;//USB_OTG_HandleConnectorIDStatusChange_ISR(pdev);
+ }
+ if (gintsts.b.sessreqintr)
+ {
+ retval |= 3;//USB_OTG_HandleSessionRequest_ISR(pdev);
+ }
+ return retval;
+}
+
+
+/**
+ * @brief USB_OTG_Read_itr
+ * returns the Core Interrupt register
+ * @param None
+ * @retval : status
+ */
+static uint32_t USB_OTG_Read_itr(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_GINTSTS_TypeDef gintsts;
+ USB_OTG_GINTMSK_TypeDef gintmsk;
+ USB_OTG_GINTMSK_TypeDef gintmsk_common;
+
+
+ gintsts.d32 = 0;
+ gintmsk.d32 = 0;
+ gintmsk_common.d32 = 0;
+
+ /* OTG interrupts */
+ gintmsk_common.b.sessreqintr = 1;
+ gintmsk_common.b.conidstschng = 1;
+ gintmsk_common.b.otgintr = 1;
+
+ gintsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GINTSTS);
+ gintmsk.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GINTMSK);
+ return ((gintsts.d32 & gintmsk.d32 ) & gintmsk_common.d32);
+}
+
+
+/**
+ * @brief USB_OTG_GetCurrentState
+ * Return current OTG State
+ * @param None
+ * @retval : None
+ */
+uint32_t USB_OTG_GetCurrentState (USB_OTG_CORE_HANDLE *pdev)
+{
+ return pdev->otg.OTG_State;
+}
+
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/