--- /dev/null
+/**
+ ******************************************************************************
+ * @file usbh_hid_core.h
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 22-July-2011
+ * @brief This file contains all the prototypes for the usbh_hid_core.c
+ ******************************************************************************
+ * @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.
+ *
+ * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive ----------------------------------------------*/
+#ifndef __USBH_HID_CORE_H
+#define __USBH_HID_CORE_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbh_core.h"
+#include "usbh_stdreq.h"
+#include "usb_bsp.h"
+#include "usbh_ioreq.h"
+#include "usbh_hcs.h"
+
+/** @addtogroup USBH_LIB
+ * @{
+ */
+
+/** @addtogroup USBH_CLASS
+ * @{
+ */
+
+/** @addtogroup USBH_HID_CLASS
+ * @{
+ */
+
+/** @defgroup USBH_HID_CORE
+ * @brief This file is the Header file for USBH_HID_CORE.c
+ * @{
+ */
+
+
+/** @defgroup USBH_HID_CORE_Exported_Types
+ * @{
+ */
+
+
+/* States for HID State Machine */
+typedef enum
+{
+ HID_IDLE= 0,
+ HID_SEND_DATA,
+ HID_BUSY,
+ HID_GET_DATA,
+ HID_POLL,
+ HID_ERROR,
+}
+HID_State;
+
+typedef enum
+{
+ HID_REQ_IDLE = 0,
+ HID_REQ_GET_REPORT_DESC,
+ HID_REQ_GET_HID_DESC,
+ HID_REQ_SET_IDLE,
+ HID_REQ_SET_PROTOCOL,
+ HID_REQ_SET_REPORT,
+
+}
+HID_CtlState;
+
+typedef struct HID_cb
+{
+ void (*Init) (void);
+ void (*Decode) (uint8_t *data);
+
+} HID_cb_TypeDef;
+
+typedef struct _HID_Report
+{
+ uint8_t ReportID;
+ uint8_t ReportType;
+ uint16_t UsagePage;
+ uint32_t Usage[2];
+ uint32_t NbrUsage;
+ uint32_t UsageMin;
+ uint32_t UsageMax;
+ int32_t LogMin;
+ int32_t LogMax;
+ int32_t PhyMin;
+ int32_t PhyMax;
+ int32_t UnitExp;
+ uint32_t Unit;
+ uint32_t ReportSize;
+ uint32_t ReportCnt;
+ uint32_t Flag;
+ uint32_t PhyUsage;
+ uint32_t AppUsage;
+ uint32_t LogUsage;
+}
+HID_Report_TypeDef;
+
+/* Structure for HID process */
+typedef struct _HID_Process
+{
+ uint8_t buff[64];
+ uint8_t hc_num_in;
+ uint8_t hc_num_out;
+ HID_State state;
+ uint8_t HIDIntOutEp;
+ uint8_t HIDIntInEp;
+ HID_CtlState ctl_state;
+ uint16_t length;
+ uint8_t ep_addr;
+ uint16_t poll;
+ __IO uint16_t timer;
+ HID_cb_TypeDef *cb;
+}
+HID_Machine_TypeDef;
+
+/**
+ * @}
+ */
+
+/** @defgroup USBH_HID_CORE_Exported_Defines
+ * @{
+ */
+
+#define USB_HID_REQ_GET_REPORT 0x01
+#define USB_HID_GET_IDLE 0x02
+#define USB_HID_GET_PROTOCOL 0x03
+#define USB_HID_SET_REPORT 0x09
+#define USB_HID_SET_IDLE 0x0A
+#define USB_HID_SET_PROTOCOL 0x0B
+/**
+ * @}
+ */
+
+/** @defgroup USBH_HID_CORE_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBH_HID_CORE_Exported_Variables
+ * @{
+ */
+extern USBH_Class_cb_TypeDef HID_cb;
+/**
+ * @}
+ */
+
+/** @defgroup USBH_HID_CORE_Exported_FunctionsPrototype
+ * @{
+ */
+
+USBH_Status USBH_Set_Report (USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t reportType,
+ uint8_t reportId,
+ uint8_t reportLen,
+ uint8_t* reportBuff);
+/**
+ * @}
+ */
+
+
+#endif /* __USBH_HID_CORE_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
--- /dev/null
+/**
+ ******************************************************************************
+ * @file usbh_hid_keybd.h
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 22-July-2011
+ * @brief This file contains all the prototypes for the usbh_hid_keybd.c
+ ******************************************************************************
+ * @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.
+ *
+ * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive -----------------------------------------------*/
+#ifndef __USBH_HID_KEYBD_H
+#define __USBH_HID_KEYBD_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_conf.h"
+#include "usbh_hid_core.h"
+
+/** @addtogroup USBH_LIB
+ * @{
+ */
+
+/** @addtogroup USBH_CLASS
+ * @{
+ */
+
+/** @addtogroup USBH_HID_CLASS
+ * @{
+ */
+
+/** @defgroup USBH_HID_KEYBD
+ * @brief This file is the Header file for USBH_HID_KEYBD.c
+ * @{
+ */
+
+
+/** @defgroup USBH_HID_KEYBD_Exported_Types
+ * @{
+ */
+
+
+/**
+ * @}
+ */
+
+/** @defgroup USBH_HID_KEYBD_Exported_Defines
+ * @{
+ */
+//#define QWERTY_KEYBOARD
+#define AZERTY_KEYBOARD
+
+#define KBD_LEFT_CTRL 0x01
+#define KBD_LEFT_SHIFT 0x02
+#define KBD_LEFT_ALT 0x04
+#define KBD_LEFT_GUI 0x08
+#define KBD_RIGHT_CTRL 0x10
+#define KBD_RIGHT_SHIFT 0x20
+#define KBD_RIGHT_ALT 0x40
+#define KBD_RIGHT_GUI 0x80
+
+#define KBR_MAX_NBR_PRESSED 6
+
+/**
+ * @}
+ */
+
+/** @defgroup USBH_HID_KEYBD_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBH_HID_KEYBD_Exported_Variables
+ * @{
+ */
+
+extern HID_cb_TypeDef HID_KEYBRD_cb;
+/**
+ * @}
+ */
+
+/** @defgroup USBH_HID_KEYBD_Exported_FunctionsPrototype
+ * @{
+ */
+void USR_KEYBRD_Init (void);
+void USR_KEYBRD_ProcessData (uint8_t pbuf);
+/**
+ * @}
+ */
+
+#endif /* __USBH_HID_KEYBD_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
--- /dev/null
+/**
+ ******************************************************************************
+ * @file usbh_hid_mouse.h
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 22-July-2011
+ * @brief This file contains all the prototypes for the usbh_hid_mouse.c
+ ******************************************************************************
+ * @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.
+ *
+ * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
+ ******************************************************************************
+ */
+
+
+/* Define to prevent recursive ----------------------------------------------*/
+#ifndef __USBH_HID_MOUSE_H
+#define __USBH_HID_MOUSE_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbh_hid_core.h"
+
+/** @addtogroup USBH_LIB
+ * @{
+ */
+
+/** @addtogroup USBH_CLASS
+ * @{
+ */
+
+/** @addtogroup USBH_HID_CLASS
+ * @{
+ */
+
+/** @defgroup USBH_HID_MOUSE
+ * @brief This file is the Header file for USBH_HID_MOUSE.c
+ * @{
+ */
+
+
+/** @defgroup USBH_HID_MOUSE_Exported_Types
+ * @{
+ */
+typedef struct _HID_MOUSE_Data
+{
+ uint8_t x;
+ uint8_t y;
+ uint8_t z; /* Not Supported */
+ uint8_t button;
+}
+HID_MOUSE_Data_TypeDef;
+
+/**
+ * @}
+ */
+
+/** @defgroup USBH_HID_MOUSE_Exported_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBH_HID_MOUSE_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBH_HID_MOUSE_Exported_Variables
+ * @{
+ */
+
+extern HID_cb_TypeDef HID_MOUSE_cb;
+extern HID_MOUSE_Data_TypeDef HID_MOUSE_Data;
+/**
+ * @}
+ */
+
+/** @defgroup USBH_HID_MOUSE_Exported_FunctionsPrototype
+ * @{
+ */
+void USR_MOUSE_Init (void);
+void USR_MOUSE_ProcessData (HID_MOUSE_Data_TypeDef *data);
+/**
+ * @}
+ */
+
+#endif /* __USBH_HID_MOUSE_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
--- /dev/null
+/**
+ ******************************************************************************
+ * @file usbh_hid_core.c
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 22-July-2011
+ * @brief This file is the HID Layer Handlers for USB Host HID class.
+ *
+ * @verbatim
+ *
+ * ===================================================================
+ * HID Class Description
+ * ===================================================================
+ * This module manages the MSC class V1.11 following the "Device Class Definition
+ * for Human Interface Devices (HID) Version 1.11 Jun 27, 2001".
+ * This driver implements the following aspects of the specification:
+ * - The Boot Interface Subclass
+ * - The Mouse and Keyboard protocols
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @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.
+ *
+ * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbh_hid_core.h"
+#include "usbh_hid_mouse.h"
+#include "usbh_hid_keybd.h"
+
+/** @addtogroup USBH_LIB
+* @{
+*/
+
+/** @addtogroup USBH_CLASS
+* @{
+*/
+
+/** @addtogroup USBH_HID_CLASS
+* @{
+*/
+
+/** @defgroup USBH_HID_CORE
+* @brief This file includes HID Layer Handlers for USB Host HID class.
+* @{
+*/
+
+/** @defgroup USBH_HID_CORE_Private_TypesDefinitions
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_HID_CORE_Private_Defines
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_HID_CORE_Private_Macros
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_HID_CORE_Private_Variables
+* @{
+*/
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+ #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+ #pragma data_alignment=4
+ #endif
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+__ALIGN_BEGIN HID_Machine_TypeDef HID_Machine __ALIGN_END ;
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+ #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+ #pragma data_alignment=4
+ #endif
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+__ALIGN_BEGIN HID_Report_TypeDef HID_Report __ALIGN_END ;
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+ #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+ #pragma data_alignment=4
+ #endif
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+__ALIGN_BEGIN USB_Setup_TypeDef HID_Setup __ALIGN_END ;
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+ #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+ #pragma data_alignment=4
+ #endif
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+__ALIGN_BEGIN USBH_HIDDesc_TypeDef HID_Desc __ALIGN_END ;
+
+__IO uint8_t flag = 0;
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_HID_CORE_Private_FunctionPrototypes
+* @{
+*/
+
+static USBH_Status USBH_HID_InterfaceInit (USB_OTG_CORE_HANDLE *pdev ,
+ void *phost);
+
+static void USBH_ParseHIDDesc (USBH_HIDDesc_TypeDef *desc, uint8_t *buf);
+
+static void USBH_HID_InterfaceDeInit (USB_OTG_CORE_HANDLE *pdev ,
+ void *phost);
+
+static USBH_Status USBH_HID_Handle(USB_OTG_CORE_HANDLE *pdev ,
+ void *phost);
+
+static USBH_Status USBH_HID_ClassRequest(USB_OTG_CORE_HANDLE *pdev ,
+ void *phost);
+
+static USBH_Status USBH_Get_HID_ReportDescriptor (USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint16_t length);
+
+static USBH_Status USBH_Get_HID_Descriptor (USB_OTG_CORE_HANDLE *pdev,\
+ USBH_HOST *phost,
+ uint16_t length);
+
+static USBH_Status USBH_Set_Idle (USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t duration,
+ uint8_t reportId);
+
+static USBH_Status USBH_Set_Protocol (USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t protocol);
+
+
+USBH_Class_cb_TypeDef HID_cb =
+{
+ USBH_HID_InterfaceInit,
+ USBH_HID_InterfaceDeInit,
+ USBH_HID_ClassRequest,
+ USBH_HID_Handle
+};
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_HID_CORE_Private_Functions
+* @{
+*/
+
+/**
+* @brief USBH_HID_InterfaceInit
+* The function init the HID class.
+* @param pdev: Selected device
+* @param hdev: Selected device property
+* @retval USBH_Status :Response for USB HID driver intialization
+*/
+static USBH_Status USBH_HID_InterfaceInit ( USB_OTG_CORE_HANDLE *pdev,
+ void *phost)
+{
+ uint8_t maxEP;
+ USBH_HOST *pphost = phost;
+
+ uint8_t num =0;
+ USBH_Status status = USBH_BUSY ;
+ HID_Machine.state = HID_ERROR;
+
+
+ if(pphost->device_prop.Itf_Desc[0].bInterfaceSubClass == HID_BOOT_CODE)
+ {
+ /*Decode Bootclass Protocl: Mouse or Keyboard*/
+ if(pphost->device_prop.Itf_Desc[0].bInterfaceProtocol == HID_KEYBRD_BOOT_CODE)
+ {
+ HID_Machine.cb = &HID_KEYBRD_cb;
+ }
+ else if(pphost->device_prop.Itf_Desc[0].bInterfaceProtocol == HID_MOUSE_BOOT_CODE)
+ {
+ HID_Machine.cb = &HID_MOUSE_cb;
+ }
+
+ HID_Machine.state = HID_IDLE;
+ HID_Machine.ctl_state = HID_REQ_IDLE;
+ HID_Machine.ep_addr = pphost->device_prop.Ep_Desc[0][0].bEndpointAddress;
+ HID_Machine.length = pphost->device_prop.Ep_Desc[0][0].wMaxPacketSize;
+ HID_Machine.poll = pphost->device_prop.Ep_Desc[0][0].bInterval ;
+
+ /* Check fo available number of endpoints */
+ /* Find the number of EPs in the Interface Descriptor */
+ /* Choose the lower number in order not to overrun the buffer allocated */
+ maxEP = ( (pphost->device_prop.Itf_Desc[0].bNumEndpoints <= USBH_MAX_NUM_ENDPOINTS) ?
+ pphost->device_prop.Itf_Desc[0].bNumEndpoints :
+ USBH_MAX_NUM_ENDPOINTS);
+
+
+ /* Decode endpoint IN and OUT address from interface descriptor */
+ for (num=0; num < maxEP; num++)
+ {
+ if(pphost->device_prop.Ep_Desc[0][num].bEndpointAddress & 0x80)
+ {
+ HID_Machine.HIDIntInEp = (pphost->device_prop.Ep_Desc[0][num].bEndpointAddress);
+ HID_Machine.hc_num_in =\
+ USBH_Alloc_Channel(pdev,
+ pphost->device_prop.Ep_Desc[0][num].bEndpointAddress);
+
+ /* Open channel for IN endpoint */
+ USBH_Open_Channel (pdev,
+ HID_Machine.hc_num_in,
+ pphost->device_prop.address,
+ pphost->device_prop.speed,
+ EP_TYPE_INTR,
+ HID_Machine.length);
+ }
+ else
+ {
+ HID_Machine.HIDIntOutEp = (pphost->device_prop.Ep_Desc[0][num].bEndpointAddress);
+ HID_Machine.hc_num_out =\
+ USBH_Alloc_Channel(pdev,
+ pphost->device_prop.Ep_Desc[0][num].bEndpointAddress);
+
+ /* Open channel for OUT endpoint */
+ USBH_Open_Channel (pdev,
+ HID_Machine.hc_num_out,
+ pphost->device_prop.address,
+ pphost->device_prop.speed,
+ EP_TYPE_INTR,
+ HID_Machine.length);
+ }
+
+ }
+
+ flag =0;
+ status = USBH_OK;
+ }
+ else
+ {
+ pphost->usr_cb->USBH_USR_DeviceNotSupported();
+ }
+
+ return status;
+
+}
+
+
+
+/**
+* @brief USBH_HID_InterfaceDeInit
+* The function DeInit the Host Channels used for the HID class.
+* @param pdev: Selected device
+* @param hdev: Selected device property
+* @retval None
+*/
+void USBH_HID_InterfaceDeInit ( USB_OTG_CORE_HANDLE *pdev,
+ void *phost)
+{
+ //USBH_HOST *pphost = phost;
+
+ if(HID_Machine.hc_num_in != 0x00)
+ {
+ USB_OTG_HC_Halt(pdev, HID_Machine.hc_num_in);
+ USBH_Free_Channel (pdev, HID_Machine.hc_num_in);
+ HID_Machine.hc_num_in = 0; /* Reset the Channel as Free */
+ }
+
+ if(HID_Machine.hc_num_out != 0x00)
+ {
+ USB_OTG_HC_Halt(pdev, HID_Machine.hc_num_out);
+ USBH_Free_Channel (pdev, HID_Machine.hc_num_out);
+ HID_Machine.hc_num_out = 0; /* Reset the Channel as Free */
+ }
+
+ flag = 0;
+}
+
+/**
+* @brief USBH_HID_ClassRequest
+* The function is responsible for handling HID Class requests
+* for HID class.
+* @param pdev: Selected device
+* @param hdev: Selected device property
+* @retval USBH_Status :Response for USB Set Protocol request
+*/
+static USBH_Status USBH_HID_ClassRequest(USB_OTG_CORE_HANDLE *pdev ,
+ void *phost)
+{
+ USBH_HOST *pphost = phost;
+
+ USBH_Status status = USBH_BUSY;
+ USBH_Status classReqStatus = USBH_BUSY;
+
+
+ /* Switch HID state machine */
+ switch (HID_Machine.ctl_state)
+ {
+ case HID_IDLE:
+ case HID_REQ_GET_HID_DESC:
+
+ /* Get HID Desc */
+ if (USBH_Get_HID_Descriptor (pdev, pphost, USB_HID_DESC_SIZE)== USBH_OK)
+ {
+
+ USBH_ParseHIDDesc(&HID_Desc, pdev->host.Rx_Buffer);
+ HID_Machine.ctl_state = HID_REQ_GET_REPORT_DESC;
+ }
+
+ break;
+ case HID_REQ_GET_REPORT_DESC:
+
+
+ /* Get Report Desc */
+ if (USBH_Get_HID_ReportDescriptor(pdev , pphost, HID_Desc.wItemLength) == USBH_OK)
+ {
+ HID_Machine.ctl_state = HID_REQ_SET_IDLE;
+ }
+
+ break;
+
+ case HID_REQ_SET_IDLE:
+
+ classReqStatus = USBH_Set_Idle (pdev, pphost, 0, 0);
+
+ /* set Idle */
+ if (classReqStatus == USBH_OK)
+ {
+ HID_Machine.ctl_state = HID_REQ_SET_PROTOCOL;
+ }
+ else if(classReqStatus == USBH_NOT_SUPPORTED)
+ {
+ HID_Machine.ctl_state = HID_REQ_SET_PROTOCOL;
+ }
+ break;
+
+ case HID_REQ_SET_PROTOCOL:
+ /* set protocol */
+ if (USBH_Set_Protocol (pdev ,pphost, 0) == USBH_OK)
+ {
+ HID_Machine.ctl_state = HID_REQ_IDLE;
+
+ /* all requests performed*/
+ status = USBH_OK;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return status;
+}
+
+
+/**
+* @brief USBH_HID_Handle
+* The function is for managing state machine for HID data transfers
+* @param pdev: Selected device
+* @param hdev: Selected device property
+* @retval USBH_Status
+*/
+static USBH_Status USBH_HID_Handle(USB_OTG_CORE_HANDLE *pdev ,
+ void *phost)
+{
+ USBH_HOST *pphost = phost;
+ USBH_Status status = USBH_OK;
+
+ switch (HID_Machine.state)
+ {
+
+ case HID_IDLE:
+ HID_Machine.cb->Init();
+ HID_Machine.state = HID_GET_DATA;
+ break;
+
+ case HID_GET_DATA:
+
+ /* Sync with start of Even Frame */
+ while(USB_OTG_IsEvenFrame(pdev) == FALSE);
+
+ USBH_InterruptReceiveData(pdev,
+ HID_Machine.buff,
+ HID_Machine.length,
+ HID_Machine.hc_num_in);
+ flag = 1;
+
+ HID_Machine.state = HID_POLL;
+ HID_Machine.timer = HCD_GetCurrentFrame(pdev);
+ break;
+
+ case HID_POLL:
+ if(( HCD_GetCurrentFrame(pdev) - HID_Machine.timer) >= HID_Machine.poll)
+ {
+ HID_Machine.state = HID_GET_DATA;
+ }
+ else if(HCD_GetURB_State(pdev , HID_Machine.hc_num_in) == URB_DONE)
+ {
+ if(flag == 1) /* handle data once */
+ {
+ flag = 0;
+ HID_Machine.cb->Decode(HID_Machine.buff);
+ }
+ }
+ else if(HCD_GetURB_State(pdev, HID_Machine.hc_num_in) == URB_STALL) /* IN Endpoint Stalled */
+ {
+
+ /* Issue Clear Feature on interrupt IN endpoint */
+ if( (USBH_ClrFeature(pdev,
+ pphost,
+ HID_Machine.ep_addr,
+ HID_Machine.hc_num_in)) == USBH_OK)
+ {
+ /* Change state to issue next IN token */
+ HID_Machine.state = HID_GET_DATA;
+
+ }
+
+ }
+ break;
+
+ default:
+ break;
+ }
+ return status;
+}
+
+
+/**
+* @brief USBH_Get_HID_ReportDescriptor
+* Issue report Descriptor command to the device. Once the response
+* received, parse the report descriptor and update the status.
+* @param pdev : Selected device
+* @param Length : HID Report Descriptor Length
+* @retval USBH_Status : Response for USB HID Get Report Descriptor Request
+*/
+static USBH_Status USBH_Get_HID_ReportDescriptor (USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint16_t length)
+{
+
+ USBH_Status status;
+
+ status = USBH_GetDescriptor(pdev,
+ phost,
+ USB_REQ_RECIPIENT_INTERFACE
+ | USB_REQ_TYPE_STANDARD,
+ USB_DESC_HID_REPORT,
+ pdev->host.Rx_Buffer,
+ length);
+
+ /* HID report descriptor is available in pdev->host.Rx_Buffer.
+ In case of USB Boot Mode devices for In report handling ,
+ HID report descriptor parsing is not required.
+ In case, for supporting Non-Boot Protocol devices and output reports,
+ user may parse the report descriptor*/
+
+
+ return status;
+}
+
+/**
+* @brief USBH_Get_HID_Descriptor
+* Issue HID Descriptor command to the device. Once the response
+* received, parse the report descriptor and update the status.
+* @param pdev : Selected device
+* @param Length : HID Descriptor Length
+* @retval USBH_Status : Response for USB HID Get Report Descriptor Request
+*/
+static USBH_Status USBH_Get_HID_Descriptor (USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint16_t length)
+{
+
+ USBH_Status status;
+
+ status = USBH_GetDescriptor(pdev,
+ phost,
+ USB_REQ_RECIPIENT_INTERFACE
+ | USB_REQ_TYPE_STANDARD,
+ USB_DESC_HID,
+ pdev->host.Rx_Buffer,
+ length);
+
+ return status;
+}
+
+/**
+* @brief USBH_Set_Idle
+* Set Idle State.
+* @param pdev: Selected device
+* @param duration: Duration for HID Idle request
+* @param reportID : Targetted report ID for Set Idle request
+* @retval USBH_Status : Response for USB Set Idle request
+*/
+static USBH_Status USBH_Set_Idle (USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t duration,
+ uint8_t reportId)
+{
+
+ phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_INTERFACE |\
+ USB_REQ_TYPE_CLASS;
+
+
+ phost->Control.setup.b.bRequest = USB_HID_SET_IDLE;
+ phost->Control.setup.b.wValue.w = (duration << 8 ) | reportId;
+
+ phost->Control.setup.b.wIndex.w = 0;
+ phost->Control.setup.b.wLength.w = 0;
+
+ return USBH_CtlReq(pdev, phost, 0 , 0 );
+}
+
+
+/**
+* @brief USBH_Set_Report
+* Issues Set Report
+* @param pdev: Selected device
+* @param reportType : Report type to be sent
+* @param reportID : Targetted report ID for Set Report request
+* @param reportLen : Length of data report to be send
+* @param reportBuff : Report Buffer
+* @retval USBH_Status : Response for USB Set Idle request
+*/
+USBH_Status USBH_Set_Report (USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t reportType,
+ uint8_t reportId,
+ uint8_t reportLen,
+ uint8_t* reportBuff)
+{
+
+ phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_INTERFACE |\
+ USB_REQ_TYPE_CLASS;
+
+
+ phost->Control.setup.b.bRequest = USB_HID_SET_REPORT;
+ phost->Control.setup.b.wValue.w = (reportType << 8 ) | reportId;
+
+ phost->Control.setup.b.wIndex.w = 0;
+ phost->Control.setup.b.wLength.w = reportLen;
+
+ return USBH_CtlReq(pdev, phost, reportBuff , reportLen );
+}
+
+
+/**
+* @brief USBH_Set_Protocol
+* Set protocol State.
+* @param pdev: Selected device
+* @param protocol : Set Protocol for HID : boot/report protocol
+* @retval USBH_Status : Response for USB Set Protocol request
+*/
+static USBH_Status USBH_Set_Protocol(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t protocol)
+{
+
+
+ phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_INTERFACE |\
+ USB_REQ_TYPE_CLASS;
+
+
+ phost->Control.setup.b.bRequest = USB_HID_SET_PROTOCOL;
+
+ if(protocol != 0)
+ {
+ /* Boot Protocol */
+ phost->Control.setup.b.wValue.w = 0;
+ }
+ else
+ {
+ /*Report Protocol*/
+ phost->Control.setup.b.wValue.w = 1;
+ }
+
+ phost->Control.setup.b.wIndex.w = 0;
+ phost->Control.setup.b.wLength.w = 0;
+
+ return USBH_CtlReq(pdev, phost, 0 , 0 );
+
+}
+
+/**
+* @brief USBH_ParseHIDDesc
+* This function Parse the HID descriptor
+* @param buf: Buffer where the source descriptor is available
+* @retval None
+*/
+static void USBH_ParseHIDDesc (USBH_HIDDesc_TypeDef *desc, uint8_t *buf)
+{
+
+ desc->bLength = *(uint8_t *) (buf + 0);
+ desc->bDescriptorType = *(uint8_t *) (buf + 1);
+ desc->bcdHID = LE16 (buf + 2);
+ desc->bCountryCode = *(uint8_t *) (buf + 4);
+ desc->bNumDescriptors = *(uint8_t *) (buf + 5);
+ desc->bReportDescriptorType = *(uint8_t *) (buf + 6);
+ desc->wItemLength = LE16 (buf + 7);
+
+}
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+
+/**
+* @}
+*/
+
+
+/**
+* @}
+*/
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
--- /dev/null
+/**
+ ******************************************************************************
+ * @file usbh_hid_keybd.c
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 22-July-2011
+ * @brief This file is the application layer for USB Host HID Keyboard handling
+ * QWERTY and AZERTY Keyboard are supported as per the selection in
+ * usbh_hid_keybd.h
+ ******************************************************************************
+ * @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.
+ *
+ * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
+ ******************************************************************************
+ */
+
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbh_hid_keybd.h"
+
+/** @addtogroup USBH_LIB
+* @{
+*/
+
+/** @addtogroup USBH_CLASS
+* @{
+*/
+
+/** @addtogroup USBH_HID_CLASS
+* @{
+*/
+
+/** @defgroup USBH_HID_KEYBD
+* @brief This file includes HID Layer Handlers for USB Host HID class.
+* @{
+*/
+
+/** @defgroup USBH_HID_KEYBD_Private_TypesDefinitions
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_HID_KEYBD_Private_Defines
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_HID_KEYBD_Private_Macros
+* @{
+*/
+/**
+* @}
+*/
+
+/** @defgroup USBH_HID_KEYBD_Private_FunctionPrototypes
+* @{
+*/
+static void KEYBRD_Init (void);
+static void KEYBRD_Decode(uint8_t *data);
+
+/**
+* @}
+*/
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+ #if defined (__CC_ARM) /*!< ARM Compiler */
+ __align(4)
+ #elif defined ( __ICCARM__ ) /*!< IAR Compiler */
+ #pragma data_alignment=4
+ #elif defined (__GNUC__) /*!< GNU Compiler */
+ #pragma pack(4)
+ #elif defined (__TASKING__) /*!< TASKING Compiler */
+ __align(4)
+ #endif /* __CC_ARM */
+#endif
+
+/** @defgroup USBH_HID_KEYBD_Private_Variables
+* @{
+*/
+HID_cb_TypeDef HID_KEYBRD_cb=
+{
+ KEYBRD_Init,
+ KEYBRD_Decode
+};
+
+/*
+*******************************************************************************
+* LOCAL CONSTANTS
+*******************************************************************************
+*/
+
+static const uint8_t HID_KEYBRD_Codes[] = {
+ 0, 0, 0, 0, 31, 50, 48, 33,
+ 19, 34, 35, 36, 24, 37, 38, 39, /* 0x00 - 0x0F */
+ 52, 51, 25, 26, 17, 20, 32, 21,
+ 23, 49, 18, 47, 22, 46, 2, 3, /* 0x10 - 0x1F */
+ 4, 5, 6, 7, 8, 9, 10, 11,
+ 43, 110, 15, 16, 61, 12, 13, 27, /* 0x20 - 0x2F */
+ 28, 29, 42, 40, 41, 1, 53, 54,
+ 55, 30, 112, 113, 114, 115, 116, 117, /* 0x30 - 0x3F */
+ 118, 119, 120, 121, 122, 123, 124, 125,
+ 126, 75, 80, 85, 76, 81, 86, 89, /* 0x40 - 0x4F */
+ 79, 84, 83, 90, 95, 100, 105, 106,
+ 108, 93, 98, 103, 92, 97, 102, 91, /* 0x50 - 0x5F */
+ 96, 101, 99, 104, 45, 129, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60 - 0x6F */
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70 - 0x7F */
+ 0, 0, 0, 0, 0, 107, 0, 56,
+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 - 0x8F */
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 - 0x9F */
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0 - 0xAF */
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0xB0 - 0xBF */
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0xC0 - 0xCF */
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0xD0 - 0xDF */
+ 58, 44, 60, 127, 64, 57, 62, 128 /* 0xE0 - 0xE7 */
+};
+
+#ifdef QWERTY_KEYBOARD
+static const int8_t HID_KEYBRD_Key[] = {
+ '\0', '`', '1', '2', '3', '4', '5', '6',
+ '7', '8', '9', '0', '-', '=', '\0', '\r',
+ '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u',
+ 'i', 'o', 'p', '[', ']', '\\',
+ '\0', 'a', 's', 'd', 'f', 'g', 'h', 'j',
+ 'k', 'l', ';', '\'', '\0', '\n',
+ '\0', '\0', 'z', 'x', 'c', 'v', 'b', 'n',
+ 'm', ',', '.', '/', '\0', '\0',
+ '\0', '\0', '\0', ' ', '\0', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0', '\0', '\r', '\0', '\0',
+ '\0', '\0', '\0', '\0', '\0', '\0',
+ '\0', '\0', '7', '4', '1',
+ '\0', '/', '8', '5', '2',
+ '0', '*', '9', '6', '3',
+ '.', '-', '+', '\0', '\n', '\0', '\0', '\0', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0'
+};
+
+static const int8_t HID_KEYBRD_ShiftKey[] = {
+ '\0', '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')',
+ '_', '+', '\0', '\0', '\0', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U',
+ 'I', 'O', 'P', '{', '}', '|', '\0', 'A', 'S', 'D', 'F', 'G',
+ 'H', 'J', 'K', 'L', ':', '"', '\0', '\n', '\0', '\0', 'Z', 'X',
+ 'C', 'V', 'B', 'N', 'M', '<', '>', '?', '\0', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'
+};
+
+#else
+
+static const int8_t HID_KEYBRD_Key[] = {
+ '\0', '`', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
+ '-', '=', '\0', '\r', '\t', 'a', 'z', 'e', 'r', 't', 'y', 'u',
+ 'i', 'o', 'p', '[', ']', '\\', '\0', 'q', 's', 'd', 'f', 'g',
+ 'h', 'j', 'k', 'l', 'm', '\0', '\0', '\n', '\0', '\0', 'w', 'x',
+ 'c', 'v', 'b', 'n', ',', ';', ':', '!', '\0', '\0', '\0', '\0',
+ '\0', ' ', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\r', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0', '\0', '\0', '\0', '7', '4', '1','\0', '/',
+ '8', '5', '2', '0', '*', '9', '6', '3', '.', '-', '+', '\0',
+ '\n', '\0', '\0', '\0', '\0', '\0', '\0','\0', '\0', '\0', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'
+};
+
+static const int8_t HID_KEYBRD_ShiftKey[] = {
+ '\0', '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_',
+ '+', '\0', '\0', '\0', 'A', 'Z', 'E', 'R', 'T', 'Y', 'U', 'I', 'O',
+ 'P', '{', '}', '*', '\0', 'Q', 'S', 'D', 'F', 'G', 'H', 'J', 'K',
+ 'L', 'M', '%', '\0', '\n', '\0', '\0', 'W', 'X', 'C', 'V', 'B', 'N',
+ '?', '.', '/', '\0', '\0', '\0','\0', '\0', '\0', '\0', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'
+};
+#endif
+
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_HID_KEYBD_Private_Functions
+* @{
+*/
+
+
+/**
+* @brief KEYBRD_Init.
+* Initialize the keyboard function.
+* @param None
+* @retval None
+*/
+static void KEYBRD_Init (void)
+{
+ /* Call User Init*/
+ USR_KEYBRD_Init();
+}
+
+/**
+* @brief KEYBRD_ProcessData.
+* The function is to decode the pressed keys.
+* @param pbuf : Pointer to the HID IN report data buffer
+* @retval None
+*/
+
+static void KEYBRD_Decode(uint8_t *pbuf)
+{
+ static uint8_t shift;
+ static uint8_t keys[KBR_MAX_NBR_PRESSED];
+ static uint8_t keys_new[KBR_MAX_NBR_PRESSED];
+ static uint8_t keys_last[KBR_MAX_NBR_PRESSED];
+ static uint8_t key_newest;
+ static uint8_t nbr_keys;
+ static uint8_t nbr_keys_new;
+ static uint8_t nbr_keys_last;
+ uint8_t ix;
+ uint8_t jx;
+ uint8_t error;
+ uint8_t output;
+
+ nbr_keys = 0;
+ nbr_keys_new = 0;
+ nbr_keys_last = 0;
+ key_newest = 0x00;
+
+
+ /* Check if Shift key is pressed */
+ if ((pbuf[0] == KBD_LEFT_SHIFT) || (pbuf[0] == KBD_RIGHT_SHIFT)) {
+ shift = TRUE;
+ } else {
+ shift = FALSE;
+ }
+
+ error = FALSE;
+
+ /* Check for the value of pressed key */
+ for (ix = 2; ix < 2 + KBR_MAX_NBR_PRESSED; ix++) {
+ if ((pbuf[ix] == 0x01) ||
+ (pbuf[ix] == 0x02) ||
+ (pbuf[ix] == 0x03)) {
+ error = TRUE;
+ }
+ }
+
+ if (error == TRUE) {
+ return;
+ }
+
+ nbr_keys = 0;
+ nbr_keys_new = 0;
+ for (ix = 2; ix < 2 + KBR_MAX_NBR_PRESSED; ix++) {
+ if (pbuf[ix] != 0) {
+ keys[nbr_keys] = pbuf[ix];
+ nbr_keys++;
+ for (jx = 0; jx < nbr_keys_last; jx++) {
+ if (pbuf[ix] == keys_last[jx]) {
+ break;
+ }
+ }
+
+ if (jx == nbr_keys_last) {
+ keys_new[nbr_keys_new] = pbuf[ix];
+ nbr_keys_new++;
+ }
+ }
+ }
+
+ if (nbr_keys_new == 1) {
+ key_newest = keys_new[0];
+
+ if (shift == TRUE) {
+ output = HID_KEYBRD_ShiftKey[HID_KEYBRD_Codes[key_newest]];
+ } else {
+ output = HID_KEYBRD_Key[HID_KEYBRD_Codes[key_newest]];
+ }
+
+ /* call user process handle */
+ USR_KEYBRD_ProcessData(output);
+ } else {
+ key_newest = 0x00;
+ }
+
+
+ nbr_keys_last = nbr_keys;
+ for (ix = 0; ix < KBR_MAX_NBR_PRESSED; ix++) {
+ keys_last[ix] = keys[ix];
+ }
+}
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+
+/**
+* @}
+*/
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
--- /dev/null
+/**
+ ******************************************************************************
+ * @file usbh_hid_mouse.c
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 22-July-2011
+ * @brief This file is the application layer for USB Host HID Mouse Handling.
+ ******************************************************************************
+ * @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.
+ *
+ * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbh_hid_mouse.h"
+
+
+/** @addtogroup USBH_LIB
+ * @{
+ */
+
+/** @addtogroup USBH_CLASS
+ * @{
+ */
+
+/** @addtogroup USBH_HID_CLASS
+ * @{
+ */
+
+/** @defgroup USBH_HID_MOUSE
+ * @brief This file includes HID Layer Handlers for USB Host HID class.
+ * @{
+ */
+
+/** @defgroup USBH_HID_MOUSE_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_HID_MOUSE_Private_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_HID_MOUSE_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBH_HID_MOUSE_Private_FunctionPrototypes
+ * @{
+ */
+static void MOUSE_Init (void);
+static void MOUSE_Decode(uint8_t *data);
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_HID_MOUSE_Private_Variables
+ * @{
+ */
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+ #if defined (__CC_ARM) /*!< ARM Compiler */
+ __align(4)
+ #elif defined ( __ICCARM__ ) /*!< IAR Compiler */
+ #pragma data_alignment=4
+ #elif defined (__GNUC__) /*!< GNU Compiler */
+ #pragma pack(4)
+ #elif defined (__TASKING__) /*!< TASKING Compiler */
+ __align(4)
+ #endif /* __CC_ARM */
+#endif
+
+
+HID_MOUSE_Data_TypeDef HID_MOUSE_Data;
+HID_cb_TypeDef HID_MOUSE_cb =
+{
+ MOUSE_Init,
+ MOUSE_Decode,
+};
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_HID_MOUSE_Private_Functions
+ * @{
+ */
+
+/**
+* @brief MOUSE_Init
+* Init Mouse State.
+* @param None
+* @retval None
+*/
+static void MOUSE_Init ( void)
+{
+ /* Call User Init*/
+ USR_MOUSE_Init();
+}
+
+/**
+* @brief MOUSE_Decode
+* Decode Mouse data
+* @param data : Pointer to Mouse HID data buffer
+* @retval None
+*/
+static void MOUSE_Decode(uint8_t *data)
+{
+ HID_MOUSE_Data.button = data[0];
+
+ HID_MOUSE_Data.x = data[1];
+ HID_MOUSE_Data.y = data[2];
+
+ USR_MOUSE_ProcessData(&HID_MOUSE_Data);
+
+}
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
--- /dev/null
+/**
+ ******************************************************************************
+ * @file usbh_msc_bot.h
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 22-July-2011
+ * @brief Header file for usbh_msc_bot.c
+ ******************************************************************************
+ * @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.
+ *
+ * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive ----------------------------------------------*/
+#ifndef __USBH_MSC_BOT_H__
+#define __USBH_MSC_BOT_H__
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbh_stdreq.h"
+
+
+/** @addtogroup USBH_LIB
+ * @{
+ */
+
+/** @addtogroup USBH_CLASS
+ * @{
+ */
+
+/** @addtogroup USBH_MSC_CLASS
+ * @{
+ */
+
+/** @defgroup USBH_MSC_BOT
+ * @brief This file is the Header file for usbh_msc_core.c
+ * @{
+ */
+
+
+/** @defgroup USBH_MSC_BOT_Exported_Types
+ * @{
+ */
+
+typedef union _USBH_CBW_Block
+{
+ struct __CBW
+ {
+ uint32_t CBWSignature;
+ uint32_t CBWTag;
+ uint32_t CBWTransferLength;
+ uint8_t CBWFlags;
+ uint8_t CBWLUN;
+ uint8_t CBWLength;
+ uint8_t CBWCB[16];
+}field;
+ uint8_t CBWArray[31];
+}HostCBWPkt_TypeDef;
+
+typedef enum
+{
+ USBH_MSC_BOT_INIT_STATE = 0,
+ USBH_MSC_BOT_RESET,
+ USBH_MSC_GET_MAX_LUN,
+ USBH_MSC_TEST_UNIT_READY,
+ USBH_MSC_READ_CAPACITY10,
+ USBH_MSC_MODE_SENSE6,
+ USBH_MSC_REQUEST_SENSE,
+ USBH_MSC_BOT_USB_TRANSFERS,
+ USBH_MSC_DEFAULT_APPLI_STATE,
+ USBH_MSC_CTRL_ERROR_STATE,
+ USBH_MSC_UNRECOVERED_STATE
+}
+MSCState;
+
+
+typedef struct _BOTXfer
+{
+uint8_t MSCState;
+uint8_t MSCStateBkp;
+uint8_t MSCStateCurrent;
+uint8_t CmdStateMachine;
+uint8_t BOTState;
+uint8_t BOTStateBkp;
+uint8_t* pRxTxBuff;
+uint16_t DataLength;
+uint8_t BOTXferErrorCount;
+uint8_t BOTXferStatus;
+} USBH_BOTXfer_TypeDef;
+
+
+typedef union _USBH_CSW_Block
+{
+ struct __CSW
+ {
+ uint32_t CSWSignature;
+ uint32_t CSWTag;
+ uint32_t CSWDataResidue;
+ uint8_t CSWStatus;
+ }field;
+ uint8_t CSWArray[13];
+}HostCSWPkt_TypeDef;
+
+/**
+ * @}
+ */
+
+
+
+/** @defgroup USBH_MSC_BOT_Exported_Defines
+ * @{
+ */
+#define USBH_MSC_SEND_CBW 1
+#define USBH_MSC_SENT_CBW 2
+#define USBH_MSC_BOT_DATAIN_STATE 3
+#define USBH_MSC_BOT_DATAOUT_STATE 4
+#define USBH_MSC_RECEIVE_CSW_STATE 5
+#define USBH_MSC_DECODE_CSW 6
+#define USBH_MSC_BOT_ERROR_IN 7
+#define USBH_MSC_BOT_ERROR_OUT 8
+
+
+#define USBH_MSC_BOT_CBW_SIGNATURE 0x43425355
+#define USBH_MSC_BOT_CBW_TAG 0x20304050
+#define USBH_MSC_BOT_CSW_SIGNATURE 0x53425355
+#define USBH_MSC_CSW_DATA_LENGTH 0x000D
+#define USBH_MSC_BOT_CBW_PACKET_LENGTH 31
+#define USBH_MSC_CSW_LENGTH 13
+#define USBH_MSC_CSW_MAX_LENGTH 63
+
+/* CSW Status Definitions */
+#define USBH_MSC_CSW_CMD_PASSED 0x00
+#define USBH_MSC_CSW_CMD_FAILED 0x01
+#define USBH_MSC_CSW_PHASE_ERROR 0x02
+
+#define USBH_MSC_SEND_CSW_DISABLE 0
+#define USBH_MSC_SEND_CSW_ENABLE 1
+
+#define USBH_MSC_DIR_IN 0
+#define USBH_MSC_DIR_OUT 1
+#define USBH_MSC_BOTH_DIR 2
+
+//#define USBH_MSC_PAGE_LENGTH 0x40
+#define USBH_MSC_PAGE_LENGTH 512
+
+
+#define CBW_CB_LENGTH 16
+#define CBW_LENGTH 10
+#define CBW_LENGTH_TEST_UNIT_READY 6
+
+#define USB_REQ_BOT_RESET 0xFF
+#define USB_REQ_GET_MAX_LUN 0xFE
+
+#define MAX_BULK_STALL_COUNT_LIMIT 0x04 /* If STALL is seen on Bulk
+ Endpoint continously, this means
+ that device and Host has phase error
+ Hence a Reset is needed */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBH_MSC_BOT_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBH_MSC_BOT_Exported_Variables
+ * @{
+ */
+extern USBH_BOTXfer_TypeDef USBH_MSC_BOTXferParam;
+extern HostCBWPkt_TypeDef USBH_MSC_CBWData;
+extern HostCSWPkt_TypeDef USBH_MSC_CSWData;
+/**
+ * @}
+ */
+
+/** @defgroup USBH_MSC_BOT_Exported_FunctionsPrototype
+ * @{
+ */
+void USBH_MSC_HandleBOTXfer(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost);
+uint8_t USBH_MSC_DecodeCSW(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost);
+void USBH_MSC_Init(USB_OTG_CORE_HANDLE *pdev);
+USBH_Status USBH_MSC_BOT_Abort(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t direction);
+/**
+ * @}
+ */
+
+#endif //__USBH_MSC_BOT_H__
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
--- /dev/null
+/**
+ ******************************************************************************
+ * @file usbh_msc_core.h
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 22-July-2011
+ * @brief This file contains all the prototypes for the usbh_msc_core.c
+ ******************************************************************************
+ * @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.
+ *
+ * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive ----------------------------------------------*/
+#ifndef __USBH_MSC_CORE_H
+#define __USBH_MSC_CORE_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbh_core.h"
+#include "usbh_stdreq.h"
+#include "usb_bsp.h"
+#include "usbh_ioreq.h"
+#include "usbh_hcs.h"
+#include "usbh_msc_core.h"
+#include "usbh_msc_scsi.h"
+#include "usbh_msc_bot.h"
+
+/** @addtogroup USBH_LIB
+ * @{
+ */
+
+/** @addtogroup USBH_CLASS
+ * @{
+ */
+
+/** @addtogroup USBH_MSC_CLASS
+ * @{
+ */
+
+/** @defgroup USBH_MSC_CORE
+ * @brief This file is the Header file for usbh_msc_core.c
+ * @{
+ */
+
+
+/** @defgroup USBH_MSC_CORE_Exported_Types
+ * @{
+ */
+
+
+/* Structure for MSC process */
+typedef struct _MSC_Process
+{
+ uint8_t hc_num_in;
+ uint8_t hc_num_out;
+ uint8_t MSBulkOutEp;
+ uint8_t MSBulkInEp;
+ uint16_t MSBulkInEpSize;
+ uint16_t MSBulkOutEpSize;
+ uint8_t buff[USBH_MSC_MPS_SIZE];
+ uint8_t maxLun;
+}
+MSC_Machine_TypeDef;
+
+
+/**
+ * @}
+ */
+
+
+
+/** @defgroup USBH_MSC_CORE_Exported_Defines
+ * @{
+ */
+
+#define USB_REQ_BOT_RESET 0xFF
+#define USB_REQ_GET_MAX_LUN 0xFE
+
+
+/**
+ * @}
+ */
+
+/** @defgroup USBH_MSC_CORE_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBH_MSC_CORE_Exported_Variables
+ * @{
+ */
+extern USBH_Class_cb_TypeDef USBH_MSC_cb;
+extern MSC_Machine_TypeDef MSC_Machine;
+extern uint8_t MSCErrorCount;
+
+/**
+ * @}
+ */
+
+/** @defgroup USBH_MSC_CORE_Exported_FunctionsPrototype
+ * @{
+ */
+
+
+
+/**
+ * @}
+ */
+
+#endif /* __USBH_MSC_CORE_H */
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
+
+
--- /dev/null
+/**
+ ******************************************************************************
+ * @file usbh_msc_scsi.h
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 22-July-2011
+ * @brief Header file for usbh_msc_scsi.c
+ ******************************************************************************
+ * @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.
+ *
+ * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive ----------------------------------------------*/
+#ifndef __USBH_MSC_SCSI_H__
+#define __USBH_MSC_SCSI_H__
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbh_stdreq.h"
+
+
+/** @addtogroup USBH_LIB
+ * @{
+ */
+
+/** @addtogroup USBH_CLASS
+ * @{
+ */
+
+/** @addtogroup USBH_MSC_CLASS
+ * @{
+ */
+
+/** @defgroup USBH_MSC_SCSI
+ * @brief This file is the Header file for usbh_msc_scsi.c
+ * @{
+ */
+
+
+/** @defgroup USBH_MSC_SCSI_Exported_Types
+ * @{
+ */
+typedef enum {
+ USBH_MSC_OK = 0,
+ USBH_MSC_FAIL = 1,
+ USBH_MSC_PHASE_ERROR = 2,
+ USBH_MSC_BUSY = 3
+}USBH_MSC_Status_TypeDef;
+
+typedef enum {
+ CMD_UNINITIALIZED_STATE =0,
+ CMD_SEND_STATE,
+ CMD_WAIT_STATUS
+} CMD_STATES_TypeDef;
+
+
+
+typedef struct __MassStorageParameter
+{
+ uint32_t MSCapacity;
+ uint32_t MSSenseKey;
+ uint16_t MSPageLength;
+ uint8_t MSBulkOutEp;
+ uint8_t MSBulkInEp;
+ uint8_t MSWriteProtect;
+} MassStorageParameter_TypeDef;
+/**
+ * @}
+ */
+
+
+
+/** @defgroup USBH_MSC_SCSI_Exported_Defines
+ * @{
+ */
+
+
+
+#define OPCODE_TEST_UNIT_READY 0X00
+#define OPCODE_READ_CAPACITY10 0x25
+#define OPCODE_MODE_SENSE6 0x1A
+#define OPCODE_READ10 0x28
+#define OPCODE_WRITE10 0x2A
+#define OPCODE_REQUEST_SENSE 0x03
+
+#define DESC_REQUEST_SENSE 0X00
+#define ALLOCATION_LENGTH_REQUEST_SENSE 63
+#define XFER_LEN_READ_CAPACITY10 8
+#define XFER_LEN_MODE_SENSE6 63
+
+#define MASK_MODE_SENSE_WRITE_PROTECT 0x80
+#define MODE_SENSE_PAGE_CONTROL_FIELD 0x00
+#define MODE_SENSE_PAGE_CODE 0x3F
+#define DISK_WRITE_PROTECTED 0x01
+/**
+ * @}
+ */
+
+/** @defgroup USBH_MSC_SCSI_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup _Exported_Variables
+ * @{
+ */
+extern MassStorageParameter_TypeDef USBH_MSC_Param;
+/**
+ * @}
+ */
+
+/** @defgroup USBH_MSC_SCSI_Exported_FunctionsPrototype
+ * @{
+ */
+uint8_t USBH_MSC_TestUnitReady(USB_OTG_CORE_HANDLE *pdev);
+uint8_t USBH_MSC_ReadCapacity10(USB_OTG_CORE_HANDLE *pdev);
+uint8_t USBH_MSC_ModeSense6(USB_OTG_CORE_HANDLE *pdev);
+uint8_t USBH_MSC_RequestSense(USB_OTG_CORE_HANDLE *pdev);
+uint8_t USBH_MSC_Write10(USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *,
+ uint32_t ,
+ uint32_t );
+uint8_t USBH_MSC_Read10(USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *,
+ uint32_t ,
+ uint32_t );
+void USBH_MSC_StateMachine(USB_OTG_CORE_HANDLE *pdev);
+
+/**
+ * @}
+ */
+
+#endif //__USBH_MSC_SCSI_H__
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
--- /dev/null
+/**
+ ******************************************************************************
+ * @file usbh_msc_bot.c
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 22-July-2011
+ * @brief This file includes the mass storage related functions
+ ******************************************************************************
+ * @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.
+ *
+ * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbh_msc_core.h"
+#include "usbh_msc_scsi.h"
+#include "usbh_msc_bot.h"
+#include "usbh_ioreq.h"
+#include "usbh_def.h"
+#include "usb_hcd_int.h"
+
+
+/** @addtogroup USBH_LIB
+* @{
+*/
+
+/** @addtogroup USBH_CLASS
+* @{
+*/
+
+/** @addtogroup USBH_MSC_CLASS
+* @{
+*/
+
+/** @defgroup USBH_MSC_BOT
+* @brief This file includes the mass storage related functions
+* @{
+*/
+
+
+/** @defgroup USBH_MSC_BOT_Private_TypesDefinitions
+* @{
+*/
+/**
+* @}
+*/
+
+/** @defgroup USBH_MSC_BOT_Private_Defines
+* @{
+*/
+/**
+* @}
+*/
+
+/** @defgroup USBH_MSC_BOT_Private_Macros
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_MSC_BOT_Private_Variables
+* @{
+*/
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+ #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+ #pragma data_alignment=4
+ #endif
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+__ALIGN_BEGIN HostCBWPkt_TypeDef USBH_MSC_CBWData __ALIGN_END ;
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+ #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+ #pragma data_alignment=4
+ #endif
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+__ALIGN_BEGIN HostCSWPkt_TypeDef USBH_MSC_CSWData __ALIGN_END ;
+
+
+static uint32_t BOTStallErrorCount; /* Keeps count of STALL Error Cases*/
+
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_MSC_BOT_Private_FunctionPrototypes
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_MSC_BOT_Exported_Variables
+* @{
+*/
+USBH_BOTXfer_TypeDef USBH_MSC_BOTXferParam;
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_MSC_BOT_Private_Functions
+* @{
+*/
+
+
+/**
+* @brief USBH_MSC_Init
+* Initializes the mass storage parameters
+* @param None
+* @retval None
+*/
+void USBH_MSC_Init(USB_OTG_CORE_HANDLE *pdev )
+{
+ if(HCD_IsDeviceConnected(pdev))
+ {
+ USBH_MSC_CBWData.field.CBWSignature = USBH_MSC_BOT_CBW_SIGNATURE;
+ USBH_MSC_CBWData.field.CBWTag = USBH_MSC_BOT_CBW_TAG;
+ USBH_MSC_CBWData.field.CBWLUN = 0; /*Only one LUN is supported*/
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+ }
+
+ BOTStallErrorCount = 0;
+ MSCErrorCount = 0;
+}
+
+/**
+* @brief USBH_MSC_HandleBOTXfer
+* This function manages the different states of BOT transfer and
+* updates the status to upper layer.
+* @param None
+* @retval None
+*
+*/
+void USBH_MSC_HandleBOTXfer (USB_OTG_CORE_HANDLE *pdev ,USBH_HOST *phost)
+{
+ uint8_t xferDirection, index;
+ static uint32_t remainingDataLength;
+ static uint8_t *datapointer;
+ static uint8_t error_direction;
+ USBH_Status status;
+
+ URB_STATE URB_Status = URB_IDLE;
+
+ if(HCD_IsDeviceConnected(pdev))
+ {
+
+ switch (USBH_MSC_BOTXferParam.BOTState)
+ {
+ case USBH_MSC_SEND_CBW:
+ /* send CBW */
+ USBH_BulkSendData (pdev,
+ &USBH_MSC_CBWData.CBWArray[0],
+ USBH_MSC_BOT_CBW_PACKET_LENGTH ,
+ MSC_Machine.hc_num_out);
+
+ USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_SEND_CBW;
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SENT_CBW;
+
+ break;
+
+ case USBH_MSC_SENT_CBW:
+ URB_Status = HCD_GetURB_State(pdev , MSC_Machine.hc_num_out);
+
+ if(URB_Status == URB_DONE)
+ {
+ BOTStallErrorCount = 0;
+ USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_SENT_CBW;
+
+ /* If the CBW Pkt is sent successful, then change the state */
+ xferDirection = (USBH_MSC_CBWData.field.CBWFlags & USB_REQ_DIR_MASK);
+
+ if ( USBH_MSC_CBWData.field.CBWTransferLength != 0 )
+ {
+ remainingDataLength = USBH_MSC_CBWData.field.CBWTransferLength ;
+ datapointer = USBH_MSC_BOTXferParam.pRxTxBuff;
+
+ /* If there is Data Transfer Stage */
+ if (xferDirection == USB_D2H)
+ {
+ /* Data Direction is IN */
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOT_DATAIN_STATE;
+ }
+ else
+ {
+ /* Data Direction is OUT */
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOT_DATAOUT_STATE;
+ }
+ }
+
+ else
+ {/* If there is NO Data Transfer Stage */
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_RECEIVE_CSW_STATE;
+ }
+
+ }
+ else if(URB_Status == URB_NOTREADY)
+ {
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOTXferParam.BOTStateBkp;
+ }
+ else if(URB_Status == URB_STALL)
+ {
+ error_direction = USBH_MSC_DIR_OUT;
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOT_ERROR_OUT;
+ }
+ break;
+
+ case USBH_MSC_BOT_DATAIN_STATE:
+
+ URB_Status = HCD_GetURB_State(pdev , MSC_Machine.hc_num_in);
+ /* BOT DATA IN stage */
+ if((URB_Status == URB_DONE) ||(USBH_MSC_BOTXferParam.BOTStateBkp != USBH_MSC_BOT_DATAIN_STATE))
+ {
+ BOTStallErrorCount = 0;
+ USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_BOT_DATAIN_STATE;
+
+ if(remainingDataLength > USBH_MSC_MPS_SIZE)
+ {
+ USBH_BulkReceiveData (pdev,
+ datapointer,
+ USBH_MSC_MPS_SIZE ,
+ MSC_Machine.hc_num_in);
+
+ remainingDataLength -= USBH_MSC_MPS_SIZE;
+ datapointer = datapointer + USBH_MSC_MPS_SIZE;
+ }
+ else if ( remainingDataLength == 0)
+ {
+ /* If value was 0, and successful transfer, then change the state */
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_RECEIVE_CSW_STATE;
+ }
+ else
+ {
+ USBH_BulkReceiveData (pdev,
+ datapointer,
+ remainingDataLength ,
+ MSC_Machine.hc_num_in);
+
+ remainingDataLength = 0; /* Reset this value and keep in same state */
+ }
+ }
+ else if(URB_Status == URB_STALL)
+ {
+ /* This is Data Stage STALL Condition */
+
+ error_direction = USBH_MSC_DIR_IN;
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOT_ERROR_IN;
+
+ /* Refer to USB Mass-Storage Class : BOT (www.usb.org)
+ 6.7.2 Host expects to receive data from the device
+ 3. On a STALL condition receiving data, then:
+ The host shall accept the data received.
+ The host shall clear the Bulk-In pipe.
+ 4. The host shall attempt to receive a CSW.
+
+ USBH_MSC_BOTXferParam.BOTStateBkp is used to switch to the Original
+ state after the ClearFeature Command is issued.
+ */
+ USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_RECEIVE_CSW_STATE;
+
+ }
+ break;
+
+
+ case USBH_MSC_BOT_DATAOUT_STATE:
+ /* BOT DATA OUT stage */
+ URB_Status = HCD_GetURB_State(pdev , MSC_Machine.hc_num_out);
+ if(URB_Status == URB_DONE)
+ {
+ BOTStallErrorCount = 0;
+ USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_BOT_DATAOUT_STATE;
+ if(remainingDataLength > USBH_MSC_MPS_SIZE)
+ {
+ USBH_BulkSendData (pdev,
+ datapointer,
+ USBH_MSC_MPS_SIZE ,
+ MSC_Machine.hc_num_out);
+ datapointer = datapointer + USBH_MSC_MPS_SIZE;
+ remainingDataLength = remainingDataLength - USBH_MSC_MPS_SIZE;
+ }
+ else if ( remainingDataLength == 0)
+ {
+ /* If value was 0, and successful transfer, then change the state */
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_RECEIVE_CSW_STATE;
+ }
+ else
+ {
+ USBH_BulkSendData (pdev,
+ datapointer,
+ remainingDataLength ,
+ MSC_Machine.hc_num_out);
+
+ remainingDataLength = 0; /* Reset this value and keep in same state */
+ }
+ }
+
+ else if(URB_Status == URB_NOTREADY)
+ {
+ USBH_BulkSendData (pdev,
+ (datapointer - USBH_MSC_MPS_SIZE),
+ USBH_MSC_MPS_SIZE ,
+ MSC_Machine.hc_num_out);
+ }
+
+ else if(URB_Status == URB_STALL)
+ {
+ error_direction = USBH_MSC_DIR_OUT;
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOT_ERROR_OUT;
+
+ /* Refer to USB Mass-Storage Class : BOT (www.usb.org)
+ 6.7.3 Ho - Host expects to send data to the device
+ 3. On a STALL condition sending data, then:
+ " The host shall clear the Bulk-Out pipe.
+ 4. The host shall attempt to receive a CSW.
+
+ The Above statement will do the clear the Bulk-Out pipe.
+ The Below statement will help in Getting the CSW.
+
+ USBH_MSC_BOTXferParam.BOTStateBkp is used to switch to the Original
+ state after the ClearFeature Command is issued.
+ */
+
+ USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_RECEIVE_CSW_STATE;
+
+ }
+ break;
+
+ case USBH_MSC_RECEIVE_CSW_STATE:
+ /* BOT CSW stage */
+ /* NOTE: We cannot reset the BOTStallErrorCount here as it may come from
+ the clearFeature from previous command */
+
+ USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_RECEIVE_CSW_STATE;
+
+ USBH_MSC_BOTXferParam.pRxTxBuff = USBH_MSC_CSWData.CSWArray;
+ USBH_MSC_BOTXferParam.DataLength = USBH_MSC_CSW_MAX_LENGTH;
+
+ for(index = USBH_MSC_CSW_LENGTH; index != 0; index--)
+ {
+ USBH_MSC_CSWData.CSWArray[index] = 0;
+ }
+
+ USBH_MSC_CSWData.CSWArray[0] = 0;
+
+ USBH_BulkReceiveData (pdev,
+ USBH_MSC_BOTXferParam.pRxTxBuff,
+ USBH_MSC_CSW_MAX_LENGTH ,
+ MSC_Machine.hc_num_in);
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_DECODE_CSW;
+
+ break;
+
+ case USBH_MSC_DECODE_CSW:
+ URB_Status = HCD_GetURB_State(pdev , MSC_Machine.hc_num_in);
+ /* Decode CSW */
+ if(URB_Status == URB_DONE)
+ {
+ BOTStallErrorCount = 0;
+ USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_RECEIVE_CSW_STATE;
+
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOTXferParam.MSCStateCurrent ;
+
+ USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_DecodeCSW(pdev , phost);
+ }
+ else if(URB_Status == URB_STALL)
+ {
+ error_direction = USBH_MSC_DIR_IN;
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOT_ERROR_IN;
+ }
+ break;
+
+ case USBH_MSC_BOT_ERROR_IN:
+ status = USBH_MSC_BOT_Abort(pdev, phost, USBH_MSC_DIR_IN);
+ if (status == USBH_OK)
+ {
+ /* Check if the error was due in Both the directions */
+ if (error_direction == USBH_MSC_BOTH_DIR)
+ {/* If Both directions are Needed, Switch to OUT Direction */
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOT_ERROR_OUT;
+ }
+ else
+ {
+ /* Switch Back to the Original State, In many cases this will be
+ USBH_MSC_RECEIVE_CSW_STATE state */
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOTXferParam.BOTStateBkp;
+ }
+ }
+ else if (status == USBH_UNRECOVERED_ERROR)
+ {
+ /* This means that there is a STALL Error limit, Do Reset Recovery */
+ USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_PHASE_ERROR;
+ }
+ break;
+
+ case USBH_MSC_BOT_ERROR_OUT:
+ status = USBH_MSC_BOT_Abort(pdev, phost, USBH_MSC_DIR_OUT);
+ if ( status == USBH_OK)
+ { /* Switch Back to the Original State */
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOTXferParam.BOTStateBkp;
+ }
+ else if (status == USBH_UNRECOVERED_ERROR)
+ {
+ /* This means that there is a STALL Error limit, Do Reset Recovery */
+ USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_PHASE_ERROR;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+/**
+* @brief USBH_MSC_BOT_Abort
+* This function manages the different Error handling for STALL
+* @param direction : IN / OUT
+* @retval None
+*/
+USBH_Status USBH_MSC_BOT_Abort(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t direction)
+{
+ USBH_Status status;
+
+ status = USBH_BUSY;
+
+ switch (direction)
+ {
+ case USBH_MSC_DIR_IN :
+ /* send ClrFeture on Bulk IN endpoint */
+ status = USBH_ClrFeature(pdev,
+ phost,
+ MSC_Machine.MSBulkInEp,
+ MSC_Machine.hc_num_in);
+
+ break;
+
+ case USBH_MSC_DIR_OUT :
+ /*send ClrFeature on Bulk OUT endpoint */
+ status = USBH_ClrFeature(pdev,
+ phost,
+ MSC_Machine.MSBulkOutEp,
+ MSC_Machine.hc_num_out);
+ break;
+
+ default:
+ break;
+ }
+
+ BOTStallErrorCount++; /* Check Continous Number of times, STALL has Occured */
+ if (BOTStallErrorCount > MAX_BULK_STALL_COUNT_LIMIT )
+ {
+ status = USBH_UNRECOVERED_ERROR;
+ }
+
+ return status;
+}
+
+/**
+* @brief USBH_MSC_DecodeCSW
+* This function decodes the CSW received by the device and updates the
+* same to upper layer.
+* @param None
+* @retval On success USBH_MSC_OK, on failure USBH_MSC_FAIL
+* @notes
+* Refer to USB Mass-Storage Class : BOT (www.usb.org)
+* 6.3.1 Valid CSW Conditions :
+* The host shall consider the CSW valid when:
+* 1. dCSWSignature is equal to 53425355h
+* 2. the CSW is 13 (Dh) bytes in length,
+* 3. dCSWTag matches the dCBWTag from the corresponding CBW.
+*/
+
+uint8_t USBH_MSC_DecodeCSW(USB_OTG_CORE_HANDLE *pdev , USBH_HOST *phost)
+{
+ uint8_t status;
+ uint32_t dataXferCount = 0;
+ status = USBH_MSC_FAIL;
+
+ if(HCD_IsDeviceConnected(pdev))
+ {
+ /*Checking if the transfer length is diffrent than 13*/
+ dataXferCount = HCD_GetXferCnt(pdev, MSC_Machine.hc_num_in);
+
+ if(dataXferCount != USBH_MSC_CSW_LENGTH)
+ {
+ /*(4) Hi > Dn (Host expects to receive data from the device,
+ Device intends to transfer no data)
+ (5) Hi > Di (Host expects to receive data from the device,
+ Device intends to send data to the host)
+ (9) Ho > Dn (Host expects to send data to the device,
+ Device intends to transfer no data)
+ (11) Ho > Do (Host expects to send data to the device,
+ Device intends to receive data from the host)*/
+
+
+ status = USBH_MSC_PHASE_ERROR;
+ }
+ else
+ { /* CSW length is Correct */
+
+ /* Check validity of the CSW Signature and CSWStatus */
+ if(USBH_MSC_CSWData.field.CSWSignature == USBH_MSC_BOT_CSW_SIGNATURE)
+ {/* Check Condition 1. dCSWSignature is equal to 53425355h */
+
+ if(USBH_MSC_CSWData.field.CSWTag == USBH_MSC_CBWData.field.CBWTag)
+ {
+ /* Check Condition 3. dCSWTag matches the dCBWTag from the
+ corresponding CBW */
+
+ if(USBH_MSC_CSWData.field.CSWStatus == USBH_MSC_OK)
+ {
+ /* Refer to USB Mass-Storage Class : BOT (www.usb.org)
+
+ Hn Host expects no data transfers
+ Hi Host expects to receive data from the device
+ Ho Host expects to send data to the device
+
+ Dn Device intends to transfer no data
+ Di Device intends to send data to the host
+ Do Device intends to receive data from the host
+
+ Section 6.7
+ (1) Hn = Dn (Host expects no data transfers,
+ Device intends to transfer no data)
+ (6) Hi = Di (Host expects to receive data from the device,
+ Device intends to send data to the host)
+ (12) Ho = Do (Host expects to send data to the device,
+ Device intends to receive data from the host)
+
+ */
+
+ status = USBH_MSC_OK;
+ }
+ else if(USBH_MSC_CSWData.field.CSWStatus == USBH_MSC_FAIL)
+ {
+ status = USBH_MSC_FAIL;
+ }
+
+ else if(USBH_MSC_CSWData.field.CSWStatus == USBH_MSC_PHASE_ERROR)
+ {
+ /* Refer to USB Mass-Storage Class : BOT (www.usb.org)
+ Section 6.7
+ (2) Hn < Di ( Host expects no data transfers,
+ Device intends to send data to the host)
+ (3) Hn < Do ( Host expects no data transfers,
+ Device intends to receive data from the host)
+ (7) Hi < Di ( Host expects to receive data from the device,
+ Device intends to send data to the host)
+ (8) Hi <> Do ( Host expects to receive data from the device,
+ Device intends to receive data from the host)
+ (10) Ho <> Di (Host expects to send data to the device,
+ Di Device intends to send data to the host)
+ (13) Ho < Do (Host expects to send data to the device,
+ Device intends to receive data from the host)
+ */
+
+ status = USBH_MSC_PHASE_ERROR;
+ }
+ } /* CSW Tag Matching is Checked */
+ } /* CSW Signature Correct Checking */
+ else
+ {
+ /* If the CSW Signature is not valid, We sall return the Phase Error to
+ Upper Layers for Reset Recovery */
+
+ status = USBH_MSC_PHASE_ERROR;
+ }
+ } /* CSW Length Check*/
+ }
+
+ USBH_MSC_BOTXferParam.BOTXferStatus = status;
+ return status;
+}
+
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
+
+
--- /dev/null
+/**
+ ******************************************************************************
+ * @file usbh_msc_core.c
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 22-July-2011
+ * @brief This file implements the MSC class driver functions
+ * ===================================================================
+ * MSC Class Description
+ * ===================================================================
+ * This module manages the MSC class V1.0 following the "Universal
+ * Serial Bus Mass Storage Class (MSC) Bulk-Only Transport (BOT) Version 1.0
+ * Sep. 31, 1999".
+ * This driver implements the following aspects of the specification:
+ * - Bulk-Only Transport protocol
+ * - Subclass : SCSI transparent command set (ref. SCSI Primary Commands - 3 (SPC-3))
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @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.
+ *
+ * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
+*/
+
+/* Includes ------------------------------------------------------------------*/
+
+#include "usbh_msc_core.h"
+#include "usbh_msc_scsi.h"
+#include "usbh_msc_bot.h"
+#include "usbh_core.h"
+
+
+/** @addtogroup USBH_LIB
+ * @{
+ */
+
+/** @addtogroup USBH_CLASS
+ * @{
+ */
+
+/** @addtogroup USBH_MSC_CLASS
+ * @{
+ */
+
+/** @defgroup USBH_MSC_CORE
+ * @brief This file includes the mass storage related functions
+ * @{
+ */
+
+
+/** @defgroup USBH_MSC_CORE_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBH_MSC_CORE_Private_Defines
+ * @{
+ */
+#define USBH_MSC_ERROR_RETRY_LIMIT 10
+/**
+ * @}
+ */
+
+/** @defgroup USBH_MSC_CORE_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_MSC_CORE_Private_Variables
+ * @{
+ */
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+ #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+ #pragma data_alignment=4
+ #endif
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+__ALIGN_BEGIN MSC_Machine_TypeDef MSC_Machine __ALIGN_END ;
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+ #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+ #pragma data_alignment=4
+ #endif
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+__ALIGN_BEGIN USB_Setup_TypeDef MSC_Setup __ALIGN_END ;
+uint8_t MSCErrorCount = 0;
+
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_MSC_CORE_Private_FunctionPrototypes
+ * @{
+ */
+
+static USBH_Status USBH_MSC_InterfaceInit (USB_OTG_CORE_HANDLE *pdev ,
+ void *phost);
+
+static void USBH_MSC_InterfaceDeInit (USB_OTG_CORE_HANDLE *pdev ,
+ void *phost);
+
+static USBH_Status USBH_MSC_Handle(USB_OTG_CORE_HANDLE *pdev ,
+ void *phost);
+
+static USBH_Status USBH_MSC_ClassRequest(USB_OTG_CORE_HANDLE *pdev ,
+ void *phost);
+
+static USBH_Status USBH_MSC_BOTReset(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost);
+static USBH_Status USBH_MSC_GETMaxLUN(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost);
+
+
+USBH_Class_cb_TypeDef USBH_MSC_cb =
+{
+ USBH_MSC_InterfaceInit,
+ USBH_MSC_InterfaceDeInit,
+ USBH_MSC_ClassRequest,
+ USBH_MSC_Handle,
+};
+
+void USBH_MSC_ErrorHandle(uint8_t status);
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_MSC_CORE_Exported_Variables
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_MSC_CORE_Private_Functions
+ * @{
+ */
+
+
+/**
+ * @brief USBH_MSC_InterfaceInit
+ * Interface initialization for MSC class.
+ * @param pdev: Selected device
+ * @param hdev: Selected device property
+ * @retval USBH_Status : Status of class request handled.
+ */
+static USBH_Status USBH_MSC_InterfaceInit ( USB_OTG_CORE_HANDLE *pdev,
+ void *phost)
+{
+ USBH_HOST *pphost = phost;
+
+ if((pphost->device_prop.Itf_Desc[0].bInterfaceClass == MSC_CLASS) && \
+ (pphost->device_prop.Itf_Desc[0].bInterfaceProtocol == MSC_PROTOCOL))
+ {
+ if(pphost->device_prop.Ep_Desc[0][0].bEndpointAddress & 0x80)
+ {
+ MSC_Machine.MSBulkInEp = (pphost->device_prop.Ep_Desc[0][0].bEndpointAddress);
+ MSC_Machine.MSBulkInEpSize = pphost->device_prop.Ep_Desc[0][0].wMaxPacketSize;
+ }
+ else
+ {
+ MSC_Machine.MSBulkOutEp = (pphost->device_prop.Ep_Desc[0][0].bEndpointAddress);
+ MSC_Machine.MSBulkOutEpSize = pphost->device_prop.Ep_Desc[0] [0].wMaxPacketSize;
+ }
+
+ if(pphost->device_prop.Ep_Desc[0][1].bEndpointAddress & 0x80)
+ {
+ MSC_Machine.MSBulkInEp = (pphost->device_prop.Ep_Desc[0][1].bEndpointAddress);
+ MSC_Machine.MSBulkInEpSize = pphost->device_prop.Ep_Desc[0][1].wMaxPacketSize;
+ }
+ else
+ {
+ MSC_Machine.MSBulkOutEp = (pphost->device_prop.Ep_Desc[0][1].bEndpointAddress);
+ MSC_Machine.MSBulkOutEpSize = pphost->device_prop.Ep_Desc[0][1].wMaxPacketSize;
+ }
+
+ MSC_Machine.hc_num_out = USBH_Alloc_Channel(pdev,
+ MSC_Machine.MSBulkOutEp);
+ MSC_Machine.hc_num_in = USBH_Alloc_Channel(pdev,
+ MSC_Machine.MSBulkInEp);
+
+ /* Open the new channels */
+ USBH_Open_Channel (pdev,
+ MSC_Machine.hc_num_out,
+ pphost->device_prop.address,
+ pphost->device_prop.speed,
+ EP_TYPE_BULK,
+ MSC_Machine.MSBulkOutEpSize);
+
+ USBH_Open_Channel (pdev,
+ MSC_Machine.hc_num_in,
+ pphost->device_prop.address,
+ pphost->device_prop.speed,
+ EP_TYPE_BULK,
+ MSC_Machine.MSBulkInEpSize);
+
+ }
+
+ else
+ {
+ pphost->usr_cb->USBH_USR_DeviceNotSupported();
+ }
+
+ return USBH_OK ;
+
+}
+
+
+/**
+ * @brief USBH_MSC_InterfaceDeInit
+ * De-Initialize interface by freeing host channels allocated to interface
+ * @param pdev: Selected device
+ * @param hdev: Selected device property
+ * @retval None
+ */
+void USBH_MSC_InterfaceDeInit ( USB_OTG_CORE_HANDLE *pdev,
+ void *phost)
+{
+ if ( MSC_Machine.hc_num_out)
+ {
+ USB_OTG_HC_Halt(pdev, MSC_Machine.hc_num_out);
+ USBH_Free_Channel (pdev, MSC_Machine.hc_num_out);
+ MSC_Machine.hc_num_out = 0; /* Reset the Channel as Free */
+ }
+
+ if ( MSC_Machine.hc_num_in)
+ {
+ USB_OTG_HC_Halt(pdev, MSC_Machine.hc_num_in);
+ USBH_Free_Channel (pdev, MSC_Machine.hc_num_in);
+ MSC_Machine.hc_num_in = 0; /* Reset the Channel as Free */
+ }
+}
+
+/**
+ * @brief USBH_MSC_ClassRequest
+ * This function will only initialize the MSC state machine
+ * @param pdev: Selected device
+ * @param hdev: Selected device property
+ * @retval USBH_Status : Status of class request handled.
+ */
+
+static USBH_Status USBH_MSC_ClassRequest(USB_OTG_CORE_HANDLE *pdev ,
+ void *phost)
+{
+
+ USBH_Status status = USBH_OK ;
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_INIT_STATE;
+
+ return status;
+}
+
+
+/**
+ * @brief USBH_MSC_Handle
+ * MSC state machine handler
+ * @param pdev: Selected device
+ * @param hdev: Selected device property
+ * @retval USBH_Status
+ */
+
+static USBH_Status USBH_MSC_Handle(USB_OTG_CORE_HANDLE *pdev ,
+ void *phost)
+{
+ USBH_HOST *pphost = phost;
+
+ USBH_Status status = USBH_BUSY;
+ uint8_t mscStatus = USBH_MSC_BUSY;
+ uint8_t appliStatus = 0;
+
+ static uint8_t maxLunExceed = FALSE;
+
+
+ if(HCD_IsDeviceConnected(pdev))
+ {
+ switch(USBH_MSC_BOTXferParam.MSCState)
+ {
+ case USBH_MSC_BOT_INIT_STATE:
+ USBH_MSC_Init(pdev);
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_RESET;
+ break;
+
+ case USBH_MSC_BOT_RESET:
+ /* Issue BOT RESET request */
+ status = USBH_MSC_BOTReset(pdev, phost);
+ if(status == USBH_OK )
+ {
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_GET_MAX_LUN;
+ }
+
+ if(status == USBH_NOT_SUPPORTED )
+ {
+ /* If the Command has failed, then we need to move to Next State, after
+ STALL condition is cleared by Control-Transfer */
+ USBH_MSC_BOTXferParam.MSCStateBkp = USBH_MSC_GET_MAX_LUN;
+
+ /* a Clear Feature should be issued here */
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_CTRL_ERROR_STATE;
+ }
+ break;
+
+ case USBH_MSC_GET_MAX_LUN:
+ /* Issue GetMaxLUN request */
+ status = USBH_MSC_GETMaxLUN(pdev, phost);
+
+ if(status == USBH_OK )
+ {
+ MSC_Machine.maxLun = *(MSC_Machine.buff) ;
+
+ /* If device has more that one logical unit then it is not supported */
+ if((MSC_Machine.maxLun > 0) && (maxLunExceed == FALSE))
+ {
+ maxLunExceed = TRUE;
+ pphost->usr_cb->USBH_USR_DeviceNotSupported();
+
+ break;
+ }
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_TEST_UNIT_READY;
+ }
+
+ if(status == USBH_NOT_SUPPORTED )
+ {
+ /* If the Command has failed, then we need to move to Next State, after
+ STALL condition is cleared by Control-Transfer */
+ USBH_MSC_BOTXferParam.MSCStateBkp = USBH_MSC_TEST_UNIT_READY;
+
+ /* a Clear Feature should be issued here */
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_CTRL_ERROR_STATE;
+ }
+ break;
+
+ case USBH_MSC_CTRL_ERROR_STATE:
+ /* Issue Clearfeature request */
+ status = USBH_ClrFeature(pdev,
+ phost,
+ 0x00,
+ pphost->Control.hc_num_out);
+ if(status == USBH_OK )
+ {
+ /* If GetMaxLun Request not support, assume Single LUN configuration */
+ MSC_Machine.maxLun = 0;
+
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOTXferParam.MSCStateBkp;
+ }
+ break;
+
+ case USBH_MSC_TEST_UNIT_READY:
+ /* Issue SCSI command TestUnitReady */
+ mscStatus = USBH_MSC_TestUnitReady(pdev);
+
+ if(mscStatus == USBH_MSC_OK )
+ {
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_READ_CAPACITY10;
+ MSCErrorCount = 0;
+ status = USBH_OK;
+ }
+ else
+ {
+ USBH_MSC_ErrorHandle(mscStatus);
+ }
+ break;
+
+ case USBH_MSC_READ_CAPACITY10:
+ /* Issue READ_CAPACITY10 SCSI command */
+ mscStatus = USBH_MSC_ReadCapacity10(pdev);
+ if(mscStatus == USBH_MSC_OK )
+ {
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_MODE_SENSE6;
+ MSCErrorCount = 0;
+ status = USBH_OK;
+ }
+ else
+ {
+ USBH_MSC_ErrorHandle(mscStatus);
+ }
+ break;
+
+ case USBH_MSC_MODE_SENSE6:
+ /* Issue ModeSense6 SCSI command for detecting if device is write-protected */
+ mscStatus = USBH_MSC_ModeSense6(pdev);
+ if(mscStatus == USBH_MSC_OK )
+ {
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_DEFAULT_APPLI_STATE;
+ MSCErrorCount = 0;
+ status = USBH_OK;
+ }
+ else
+ {
+ USBH_MSC_ErrorHandle(mscStatus);
+ }
+ break;
+
+ case USBH_MSC_REQUEST_SENSE:
+ /* Issue RequestSense SCSI command for retreiving error code */
+ mscStatus = USBH_MSC_RequestSense(pdev);
+ if(mscStatus == USBH_MSC_OK )
+ {
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOTXferParam.MSCStateBkp;
+ status = USBH_OK;
+ }
+ else
+ {
+ USBH_MSC_ErrorHandle(mscStatus);
+ }
+ break;
+
+ case USBH_MSC_BOT_USB_TRANSFERS:
+ /* Process the BOT state machine */
+ USBH_MSC_HandleBOTXfer(pdev , phost);
+ break;
+
+ case USBH_MSC_DEFAULT_APPLI_STATE:
+ /* Process Application callback for MSC */
+ appliStatus = pphost->usr_cb->USBH_USR_MSC_Application();
+ if(appliStatus == 0)
+ {
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_DEFAULT_APPLI_STATE;
+ }
+ else if (appliStatus == 1)
+ {
+ /* De-init requested from application layer */
+ status = USBH_APPLY_DEINIT;
+ }
+ break;
+
+ case USBH_MSC_UNRECOVERED_STATE:
+
+ status = USBH_UNRECOVERED_ERROR;
+
+ break;
+
+ default:
+ break;
+
+ }
+ }
+ return status;
+}
+
+
+
+/**
+ * @brief USBH_MSC_BOTReset
+ * This request is used to reset the mass storage device and its
+ * associated interface. This class-specific request shall ready the
+ * device for the next CBW from the host.
+ * @param pdev: Selected device
+ * @retval USBH_Status : Status of class request handled.
+ */
+static USBH_Status USBH_MSC_BOTReset(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost)
+{
+
+ phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_TYPE_CLASS | \
+ USB_REQ_RECIPIENT_INTERFACE;
+
+ phost->Control.setup.b.bRequest = USB_REQ_BOT_RESET;
+ phost->Control.setup.b.wValue.w = 0;
+ phost->Control.setup.b.wIndex.w = 0;
+ phost->Control.setup.b.wLength.w = 0;
+
+ return USBH_CtlReq(pdev, phost, 0 , 0 );
+}
+
+
+/**
+ * @brief USBH_MSC_GETMaxLUN
+ * This request is used to reset the mass storage device and its
+ * associated interface. This class-specific request shall ready the
+ * device for the next CBW from the host.
+ * @param pdev: Selected device
+ * @retval USBH_Status : USB ctl xfer status
+ */
+static USBH_Status USBH_MSC_GETMaxLUN(USB_OTG_CORE_HANDLE *pdev , USBH_HOST *phost)
+{
+ phost->Control.setup.b.bmRequestType = USB_D2H | USB_REQ_TYPE_CLASS | \
+ USB_REQ_RECIPIENT_INTERFACE;
+
+ phost->Control.setup.b.bRequest = USB_REQ_GET_MAX_LUN;
+ phost->Control.setup.b.wValue.w = 0;
+ phost->Control.setup.b.wIndex.w = 0;
+ phost->Control.setup.b.wLength.w = 1;
+
+ return USBH_CtlReq(pdev, phost, MSC_Machine.buff , 1 );
+}
+
+/**
+ * @brief USBH_MSC_ErrorHandle
+ * The function is for handling errors occuring during the MSC
+ * state machine
+ * @param status
+ * @retval None
+ */
+
+void USBH_MSC_ErrorHandle(uint8_t status)
+{
+ if(status == USBH_MSC_FAIL)
+ {
+ MSCErrorCount++;
+ if(MSCErrorCount < USBH_MSC_ERROR_RETRY_LIMIT)
+ { /* Try MSC level error recovery, Issue the request Sense to get
+ Drive error reason */
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_REQUEST_SENSE;
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+ }
+ else
+ {
+ /* Error trials exceeded the limit, go to unrecovered state */
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_UNRECOVERED_STATE;
+ }
+ }
+ else if(status == USBH_MSC_PHASE_ERROR)
+ {
+ /* Phase error, Go to Unrecoovered state */
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_UNRECOVERED_STATE;
+ }
+ else if(status == USBH_MSC_BUSY)
+ {
+ /*No change in state*/
+ }
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
--- /dev/null
+
+#include "usb_conf.h"
+#include "diskio.h"
+#include "usbh_msc_core.h"
+/*--------------------------------------------------------------------------
+
+Module Private Functions and Variables
+
+---------------------------------------------------------------------------*/
+
+static volatile DSTATUS Stat = STA_NOINIT; /* Disk status */
+
+extern USB_OTG_CORE_HANDLE USB_OTG_Core;
+extern USBH_HOST USB_Host;
+
+/*-----------------------------------------------------------------------*/
+/* Initialize Disk Drive */
+/*-----------------------------------------------------------------------*/
+
+DSTATUS disk_initialize (
+ BYTE drv /* Physical drive number (0) */
+ )
+{
+
+ if(HCD_IsDeviceConnected(&USB_OTG_Core))
+ {
+ Stat &= ~STA_NOINIT;
+ }
+
+ return Stat;
+
+
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Get Disk Status */
+/*-----------------------------------------------------------------------*/
+
+DSTATUS disk_status (
+ BYTE drv /* Physical drive number (0) */
+ )
+{
+ if (drv) return STA_NOINIT; /* Supports only single drive */
+ return Stat;
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Read Sector(s) */
+/*-----------------------------------------------------------------------*/
+
+DRESULT disk_read (
+ BYTE drv, /* Physical drive number (0) */
+ BYTE *buff, /* Pointer to the data buffer to store read data */
+ DWORD sector, /* Start sector number (LBA) */
+ BYTE count /* Sector count (1..255) */
+ )
+{
+ BYTE status = USBH_MSC_OK;
+
+ if (drv || !count) return RES_PARERR;
+ if (Stat & STA_NOINIT) return RES_NOTRDY;
+
+
+ if(HCD_IsDeviceConnected(&USB_OTG_Core))
+ {
+
+ do
+ {
+ status = USBH_MSC_Read10(&USB_OTG_Core, buff,sector,512);
+ USBH_MSC_HandleBOTXfer(&USB_OTG_Core ,&USB_Host);
+
+ if(!HCD_IsDeviceConnected(&USB_OTG_Core))
+ {
+ return RES_ERROR;
+ }
+ }
+ while(status == USBH_MSC_BUSY );
+ }
+
+ if(status == USBH_MSC_OK)
+ return RES_OK;
+ return RES_ERROR;
+
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Write Sector(s) */
+/*-----------------------------------------------------------------------*/
+
+#if _READONLY == 0
+DRESULT disk_write (
+ BYTE drv, /* Physical drive number (0) */
+ const BYTE *buff, /* Pointer to the data to be written */
+ DWORD sector, /* Start sector number (LBA) */
+ BYTE count /* Sector count (1..255) */
+ )
+{
+ BYTE status = USBH_MSC_OK;
+ if (drv || !count) return RES_PARERR;
+ if (Stat & STA_NOINIT) return RES_NOTRDY;
+ if (Stat & STA_PROTECT) return RES_WRPRT;
+
+
+ if(HCD_IsDeviceConnected(&USB_OTG_Core))
+ {
+ do
+ {
+ status = USBH_MSC_Write10(&USB_OTG_Core,(BYTE*)buff,sector,512);
+ USBH_MSC_HandleBOTXfer(&USB_OTG_Core, &USB_Host);
+
+ if(!HCD_IsDeviceConnected(&USB_OTG_Core))
+ {
+ return RES_ERROR;
+ }
+ }
+
+ while(status == USBH_MSC_BUSY );
+
+ }
+
+ if(status == USBH_MSC_OK)
+ return RES_OK;
+ return RES_ERROR;
+}
+#endif /* _READONLY == 0 */
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Miscellaneous Functions */
+/*-----------------------------------------------------------------------*/
+
+#if _USE_IOCTL != 0
+DRESULT disk_ioctl (
+ BYTE drv, /* Physical drive number (0) */
+ BYTE ctrl, /* Control code */
+ void *buff /* Buffer to send/receive control data */
+ )
+{
+ DRESULT res = RES_OK;
+
+ if (drv) return RES_PARERR;
+
+ res = RES_ERROR;
+
+ if (Stat & STA_NOINIT) return RES_NOTRDY;
+
+ switch (ctrl) {
+ case CTRL_SYNC : /* Make sure that no pending write process */
+
+ res = RES_OK;
+ break;
+
+ case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */
+
+ *(DWORD*)buff = (DWORD) USBH_MSC_Param.MSCapacity;
+ res = RES_OK;
+ break;
+
+ case GET_SECTOR_SIZE : /* Get R/W sector size (WORD) */
+ *(WORD*)buff = 512;
+ res = RES_OK;
+ break;
+
+ case GET_BLOCK_SIZE : /* Get erase block size in unit of sector (DWORD) */
+
+ *(DWORD*)buff = 512;
+
+ break;
+
+
+ default:
+ res = RES_PARERR;
+ }
+
+
+
+ return res;
+}
+#endif /* _USE_IOCTL != 0 */
--- /dev/null
+/**
+ ******************************************************************************
+ * @file usbh_msc_scsi.c
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 22-July-2011
+ * @brief This file implements the SCSI commands
+ ******************************************************************************
+ * @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.
+ *
+ * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbh_msc_core.h"
+#include "usbh_msc_scsi.h"
+#include "usbh_msc_bot.h"
+#include "usbh_ioreq.h"
+#include "usbh_def.h"
+
+
+/** @addtogroup USBH_LIB
+ * @{
+ */
+
+/** @addtogroup USBH_CLASS
+ * @{
+ */
+
+/** @addtogroup USBH_MSC_CLASS
+ * @{
+ */
+
+/** @defgroup USBH_MSC_SCSI
+ * @brief This file includes the mass storage related functions
+ * @{
+ */
+
+
+/** @defgroup USBH_MSC_SCSI_Private_TypesDefinitions
+ * @{
+ */
+
+MassStorageParameter_TypeDef USBH_MSC_Param;
+/**
+ * @}
+ */
+
+/** @defgroup USBH_MSC_SCSI_Private_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBH_MSC_SCSI_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_MSC_SCSI_Private_Variables
+ * @{
+ */
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+ #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+ #pragma data_alignment=4
+ #endif
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+__ALIGN_BEGIN uint8_t USBH_DataInBuffer[512] __ALIGN_END ;
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+ #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+ #pragma data_alignment=4
+ #endif
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+__ALIGN_BEGIN uint8_t USBH_DataOutBuffer[512] __ALIGN_END ;
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_MSC_SCSI_Private_FunctionPrototypes
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_MSC_SCSI_Exported_Variables
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_MSC_SCSI_Private_Functions
+ * @{
+ */
+
+
+
+
+/**
+ * @brief USBH_MSC_TestUnitReady
+ * Issues 'Test unit ready' command to the device. Once the response
+ * received, it updates the status to upper layer.
+ * @param None
+ * @retval Status
+ */
+uint8_t USBH_MSC_TestUnitReady (USB_OTG_CORE_HANDLE *pdev)
+{
+ uint8_t index;
+ USBH_MSC_Status_TypeDef status = USBH_MSC_BUSY;
+
+ if(HCD_IsDeviceConnected(pdev))
+ {
+ switch(USBH_MSC_BOTXferParam.CmdStateMachine)
+ {
+ case CMD_SEND_STATE:
+ /*Prepare the CBW and relevent field*/
+ USBH_MSC_CBWData.field.CBWTransferLength = 0; /* No Data Transfer */
+ USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_OUT;
+ USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH_TEST_UNIT_READY;
+ USBH_MSC_BOTXferParam.pRxTxBuff = USBH_MSC_CSWData.CSWArray;
+ USBH_MSC_BOTXferParam.DataLength = USBH_MSC_CSW_MAX_LENGTH;
+ USBH_MSC_BOTXferParam.MSCStateCurrent = USBH_MSC_TEST_UNIT_READY;
+
+ for(index = CBW_CB_LENGTH; index != 0; index--)
+ {
+ USBH_MSC_CBWData.field.CBWCB[index] = 0x00;
+ }
+
+ USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_TEST_UNIT_READY;
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SEND_CBW;
+ /* Start the transfer, then let the state
+ machine magage the other transactions */
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_USB_TRANSFERS;
+ USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_BUSY;
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_WAIT_STATUS;
+
+ status = USBH_MSC_BUSY;
+ break;
+
+ case CMD_WAIT_STATUS:
+ if(USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_OK)
+ {
+ /* Commands successfully sent and Response Received */
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+
+ status = USBH_MSC_OK;
+ }
+ else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_FAIL )
+ {
+ /* Failure Mode */
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+ status = USBH_MSC_FAIL;
+ }
+
+ else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_PHASE_ERROR )
+ {
+ /* Failure Mode */
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+ status = USBH_MSC_PHASE_ERROR;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ return status;
+}
+
+
+/**
+ * @brief USBH_MSC_ReadCapacity10
+ * Issue the read capacity command to the device. Once the response
+ * received, it updates the status to upper layer
+ * @param None
+ * @retval Status
+ */
+uint8_t USBH_MSC_ReadCapacity10(USB_OTG_CORE_HANDLE *pdev)
+{
+ uint8_t index;
+ USBH_MSC_Status_TypeDef status = USBH_MSC_BUSY;
+
+ if(HCD_IsDeviceConnected(pdev))
+ {
+ switch(USBH_MSC_BOTXferParam.CmdStateMachine)
+ {
+ case CMD_SEND_STATE:
+ /*Prepare the CBW and relevent field*/
+ USBH_MSC_CBWData.field.CBWTransferLength = XFER_LEN_READ_CAPACITY10;
+ USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_IN;
+ USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH;
+
+ USBH_MSC_BOTXferParam.pRxTxBuff = USBH_DataInBuffer;
+ USBH_MSC_BOTXferParam.MSCStateCurrent = USBH_MSC_READ_CAPACITY10;
+
+ for(index = CBW_CB_LENGTH; index != 0; index--)
+ {
+ USBH_MSC_CBWData.field.CBWCB[index] = 0x00;
+ }
+
+ USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_READ_CAPACITY10;
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SEND_CBW;
+
+ /* Start the transfer, then let the state machine manage the other
+ transactions */
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_USB_TRANSFERS;
+ USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_BUSY;
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_WAIT_STATUS;
+
+ status = USBH_MSC_BUSY;
+ break;
+
+ case CMD_WAIT_STATUS:
+ if(USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_OK)
+ {
+ /*assign the capacity*/
+ (((uint8_t*)&USBH_MSC_Param.MSCapacity )[3]) = USBH_DataInBuffer[0];
+ (((uint8_t*)&USBH_MSC_Param.MSCapacity )[2]) = USBH_DataInBuffer[1];
+ (((uint8_t*)&USBH_MSC_Param.MSCapacity )[1]) = USBH_DataInBuffer[2];
+ (((uint8_t*)&USBH_MSC_Param.MSCapacity )[0]) = USBH_DataInBuffer[3];
+
+ /*assign the page length*/
+ (((uint8_t*)&USBH_MSC_Param.MSPageLength )[1]) = USBH_DataInBuffer[6];
+ (((uint8_t*)&USBH_MSC_Param.MSPageLength )[0]) = USBH_DataInBuffer[7];
+
+ /* Commands successfully sent and Response Received */
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+ status = USBH_MSC_OK;
+ }
+ else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_FAIL )
+ {
+ /* Failure Mode */
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+ status = USBH_MSC_FAIL;
+ }
+ else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_PHASE_ERROR )
+ {
+ /* Failure Mode */
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+ status = USBH_MSC_PHASE_ERROR;
+ }
+ else
+ {
+ /* Wait for the Commands to get Completed */
+ /* NO Change in state Machine */
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ return status;
+}
+
+
+/**
+ * @brief USBH_MSC_ModeSense6
+ * Issue the Mode Sense6 Command to the device. This function is used
+ * for reading the WriteProtect Status of the Mass-Storage device.
+ * @param None
+ * @retval Status
+ */
+uint8_t USBH_MSC_ModeSense6(USB_OTG_CORE_HANDLE *pdev)
+{
+ uint8_t index;
+ USBH_MSC_Status_TypeDef status = USBH_MSC_BUSY;
+
+ if(HCD_IsDeviceConnected(pdev))
+ {
+ switch(USBH_MSC_BOTXferParam.CmdStateMachine)
+ {
+ case CMD_SEND_STATE:
+ /*Prepare the CBW and relevent field*/
+ USBH_MSC_CBWData.field.CBWTransferLength = XFER_LEN_MODE_SENSE6;
+ USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_IN;
+ USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH;
+
+ USBH_MSC_BOTXferParam.pRxTxBuff = USBH_DataInBuffer;
+ USBH_MSC_BOTXferParam.MSCStateCurrent = USBH_MSC_MODE_SENSE6;
+
+ for(index = CBW_CB_LENGTH; index != 0; index--)
+ {
+ USBH_MSC_CBWData.field.CBWCB[index] = 0x00;
+ }
+
+ USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_MODE_SENSE6;
+ USBH_MSC_CBWData.field.CBWCB[2] = MODE_SENSE_PAGE_CONTROL_FIELD | \
+ MODE_SENSE_PAGE_CODE;
+
+ USBH_MSC_CBWData.field.CBWCB[4] = XFER_LEN_MODE_SENSE6;
+
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SEND_CBW;
+
+ /* Start the transfer, then let the state machine manage the other
+ transactions */
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_USB_TRANSFERS;
+ USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_BUSY;
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_WAIT_STATUS;
+
+ status = USBH_MSC_BUSY;
+ break;
+
+ case CMD_WAIT_STATUS:
+ if(USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_OK)
+ {
+ /* Assign the Write Protect status */
+ /* If WriteProtect = 0, Writing is allowed
+ If WriteProtect != 0, Disk is Write Protected */
+ if ( USBH_DataInBuffer[2] & MASK_MODE_SENSE_WRITE_PROTECT)
+ {
+ USBH_MSC_Param.MSWriteProtect = DISK_WRITE_PROTECTED;
+ }
+ else
+ {
+ USBH_MSC_Param.MSWriteProtect = 0;
+ }
+
+ /* Commands successfully sent and Response Received */
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+ status = USBH_MSC_OK;
+ }
+ else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_FAIL )
+ {
+ /* Failure Mode */
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+ status = USBH_MSC_FAIL;
+ }
+ else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_PHASE_ERROR )
+ {
+ /* Failure Mode */
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+ status = USBH_MSC_PHASE_ERROR;
+ }
+ else
+ {
+ /* Wait for the Commands to get Completed */
+ /* NO Change in state Machine */
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ return status;
+}
+
+/**
+ * @brief USBH_MSC_RequestSense
+ * Issues the Request Sense command to the device. Once the response
+ * received, it updates the status to upper layer
+ * @param None
+ * @retval Status
+ */
+uint8_t USBH_MSC_RequestSense(USB_OTG_CORE_HANDLE *pdev)
+{
+ USBH_MSC_Status_TypeDef status = USBH_MSC_BUSY;
+
+ uint8_t index;
+
+
+ if(HCD_IsDeviceConnected(pdev))
+ {
+ switch(USBH_MSC_BOTXferParam.CmdStateMachine)
+ {
+ case CMD_SEND_STATE:
+
+ /*Prepare the CBW and relevent field*/
+ USBH_MSC_CBWData.field.CBWTransferLength = \
+ ALLOCATION_LENGTH_REQUEST_SENSE;
+ USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_IN;
+ USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH;
+
+ USBH_MSC_BOTXferParam.pRxTxBuff = USBH_DataInBuffer;
+ USBH_MSC_BOTXferParam.MSCStateBkp = USBH_MSC_BOTXferParam.MSCStateCurrent;
+ USBH_MSC_BOTXferParam.MSCStateCurrent = USBH_MSC_REQUEST_SENSE;
+
+
+ for(index = CBW_CB_LENGTH; index != 0; index--)
+ {
+ USBH_MSC_CBWData.field.CBWCB[index] = 0x00;
+ }
+
+ USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_REQUEST_SENSE;
+ USBH_MSC_CBWData.field.CBWCB[1] = DESC_REQUEST_SENSE;
+ USBH_MSC_CBWData.field.CBWCB[4] = ALLOCATION_LENGTH_REQUEST_SENSE;
+
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SEND_CBW;
+ /* Start the transfer, then let the state machine magage
+ the other transactions */
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_USB_TRANSFERS;
+ USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_BUSY;
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_WAIT_STATUS;
+
+ status = USBH_MSC_BUSY;
+
+ break;
+
+ case CMD_WAIT_STATUS:
+
+ if(USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_OK)
+ {
+ /* Get Sense data*/
+ (((uint8_t*)&USBH_MSC_Param.MSSenseKey )[3]) = USBH_DataInBuffer[0];
+ (((uint8_t*)&USBH_MSC_Param.MSSenseKey )[2]) = USBH_DataInBuffer[1];
+ (((uint8_t*)&USBH_MSC_Param.MSSenseKey )[1]) = USBH_DataInBuffer[2];
+ (((uint8_t*)&USBH_MSC_Param.MSSenseKey )[0]) = USBH_DataInBuffer[3];
+
+ /* Commands successfully sent and Response Received */
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+ status = USBH_MSC_OK;
+ }
+ else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_FAIL )
+ {
+ /* Failure Mode */
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+ status = USBH_MSC_FAIL;
+ }
+
+ else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_PHASE_ERROR )
+ {
+ /* Failure Mode */
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+ status = USBH_MSC_PHASE_ERROR;
+ }
+
+ else
+ {
+ /* Wait for the Commands to get Completed */
+ /* NO Change in state Machine */
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ return status;
+}
+
+
+/**
+ * @brief USBH_MSC_Write10
+ * Issue the write command to the device. Once the response received,
+ * it updates the status to upper layer
+ * @param dataBuffer : DataBuffer contains the data to write
+ * @param address : Address to which the data will be written
+ * @param nbOfbytes : NbOfbytes to be written
+ * @retval Status
+ */
+uint8_t USBH_MSC_Write10(USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *dataBuffer,
+ uint32_t address,
+ uint32_t nbOfbytes)
+{
+ uint8_t index;
+ USBH_MSC_Status_TypeDef status = USBH_MSC_BUSY;
+ uint16_t nbOfPages;
+
+ if(HCD_IsDeviceConnected(pdev))
+ {
+ switch(USBH_MSC_BOTXferParam.CmdStateMachine)
+ {
+ case CMD_SEND_STATE:
+ USBH_MSC_CBWData.field.CBWTransferLength = nbOfbytes;
+ USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_OUT;
+ USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH;
+ USBH_MSC_BOTXferParam.pRxTxBuff = dataBuffer;
+
+
+ for(index = CBW_CB_LENGTH; index != 0; index--)
+ {
+ USBH_MSC_CBWData.field.CBWCB[index] = 0x00;
+ }
+
+ USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_WRITE10;
+
+ /*logical block address*/
+ USBH_MSC_CBWData.field.CBWCB[2] = (((uint8_t*)&address)[3]) ;
+ USBH_MSC_CBWData.field.CBWCB[3] = (((uint8_t*)&address)[2]);
+ USBH_MSC_CBWData.field.CBWCB[4] = (((uint8_t*)&address)[1]);
+ USBH_MSC_CBWData.field.CBWCB[5] = (((uint8_t*)&address)[0]);
+
+ /*USBH_MSC_PAGE_LENGTH = 512*/
+ nbOfPages = nbOfbytes/ USBH_MSC_PAGE_LENGTH;
+
+ /*Tranfer length */
+ USBH_MSC_CBWData.field.CBWCB[7] = (((uint8_t *)&nbOfPages)[1]) ;
+ USBH_MSC_CBWData.field.CBWCB[8] = (((uint8_t *)&nbOfPages)[0]) ;
+
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SEND_CBW;
+ /* Start the transfer, then let the state machine
+ magage the other transactions */
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_USB_TRANSFERS;
+ USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_BUSY;
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_WAIT_STATUS;
+
+ status = USBH_MSC_BUSY;
+
+ break;
+
+ case CMD_WAIT_STATUS:
+ if(USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_OK)
+ {
+ /* Commands successfully sent and Response Received */
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+ status = USBH_MSC_OK;
+ }
+ else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_FAIL )
+ {
+ /* Failure Mode */
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+ }
+
+ else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_PHASE_ERROR )
+ {
+ /* Failure Mode */
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+ status = USBH_MSC_PHASE_ERROR;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ return status;
+}
+
+/**
+ * @brief USBH_MSC_Read10
+ * Issue the read command to the device. Once the response received,
+ * it updates the status to upper layer
+ * @param dataBuffer : DataBuffer will contain the data to be read
+ * @param address : Address from which the data will be read
+ * @param nbOfbytes : NbOfbytes to be read
+ * @retval Status
+ */
+uint8_t USBH_MSC_Read10(USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *dataBuffer,
+ uint32_t address,
+ uint32_t nbOfbytes)
+{
+ uint8_t index;
+ static USBH_MSC_Status_TypeDef status = USBH_MSC_BUSY;
+ uint16_t nbOfPages;
+ status = USBH_MSC_BUSY;
+
+ if(HCD_IsDeviceConnected(pdev))
+ {
+ switch(USBH_MSC_BOTXferParam.CmdStateMachine)
+ {
+ case CMD_SEND_STATE:
+ /*Prepare the CBW and relevent field*/
+ USBH_MSC_CBWData.field.CBWTransferLength = nbOfbytes;
+ USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_IN;
+ USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH;
+
+ USBH_MSC_BOTXferParam.pRxTxBuff = dataBuffer;
+
+ for(index = CBW_CB_LENGTH; index != 0; index--)
+ {
+ USBH_MSC_CBWData.field.CBWCB[index] = 0x00;
+ }
+
+ USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_READ10;
+
+ /*logical block address*/
+
+ USBH_MSC_CBWData.field.CBWCB[2] = (((uint8_t*)&address)[3]);
+ USBH_MSC_CBWData.field.CBWCB[3] = (((uint8_t*)&address)[2]);
+ USBH_MSC_CBWData.field.CBWCB[4] = (((uint8_t*)&address)[1]);
+ USBH_MSC_CBWData.field.CBWCB[5] = (((uint8_t*)&address)[0]);
+
+ /*USBH_MSC_PAGE_LENGTH = 512*/
+ nbOfPages = nbOfbytes/ USBH_MSC_PAGE_LENGTH;
+
+ /*Tranfer length */
+ USBH_MSC_CBWData.field.CBWCB[7] = (((uint8_t *)&nbOfPages)[1]) ;
+ USBH_MSC_CBWData.field.CBWCB[8] = (((uint8_t *)&nbOfPages)[0]) ;
+
+
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SEND_CBW;
+ /* Start the transfer, then let the state machine
+ magage the other transactions */
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_USB_TRANSFERS;
+ USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_BUSY;
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_WAIT_STATUS;
+
+ status = USBH_MSC_BUSY;
+
+ break;
+
+ case CMD_WAIT_STATUS:
+
+ if((USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_OK) && \
+ (HCD_IsDeviceConnected(pdev)))
+ {
+ /* Commands successfully sent and Response Received */
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+ status = USBH_MSC_OK;
+ }
+ else if (( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_FAIL ) && \
+ (HCD_IsDeviceConnected(pdev)))
+ {
+ /* Failure Mode */
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+ }
+
+ else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_PHASE_ERROR )
+ {
+ /* Failure Mode */
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+ status = USBH_MSC_PHASE_ERROR;
+ }
+ else
+ {
+ /* Wait for the Commands to get Completed */
+ /* NO Change in state Machine */
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ return status;
+}
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
+
+
--- /dev/null
+/**
+ ******************************************************************************
+ * @file usbh_conf_template
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 22-July-2011
+ * @brief General USB Host library 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.
+ *
+ * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USBH_CONF__H__
+#define __USBH_CONF__H__
+
+/* Includes ------------------------------------------------------------------*/
+/** @addtogroup USBH_OTG_DRIVER
+ * @{
+ */
+
+/** @defgroup USBH_CONF
+ * @brief usb otg low level driver configuration file
+ * @{
+ */
+
+/** @defgroup USBH_CONF_Exported_Defines
+ * @{
+ */
+
+#define USBH_MAX_NUM_ENDPOINTS 2
+#define USBH_MAX_NUM_INTERFACES 2
+#ifdef USE_USB_OTG_FS
+#define USBH_MSC_MPS_SIZE 0x40
+#else
+#define USBH_MSC_MPS_SIZE 0x200
+#endif
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_CONF_Exported_Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_CONF_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBH_CONF_Exported_Variables
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBH_CONF_Exported_FunctionsPrototype
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+#endif //__USBH_CONF__H__
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
--- /dev/null
+/**
+ ******************************************************************************
+ * @file usbh_core.h
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 22-July-2011
+ * @brief Header file for usbh_core.c
+ ******************************************************************************
+ * @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.
+ *
+ * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive ----------------------------------------------*/
+#ifndef __USBH_CORE_H
+#define __USBH_CORE_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_hcd.h"
+#include "usbh_def.h"
+#include "usbh_conf.h"
+
+/** @addtogroup USBH_LIB
+ * @{
+ */
+
+/** @addtogroup USBH_LIB_CORE
+* @{
+*/
+
+/** @defgroup USBH_CORE
+ * @brief This file is the Header file for usbh_core.c
+ * @{
+ */
+
+
+/** @defgroup USBH_CORE_Exported_Defines
+ * @{
+ */
+
+#define MSC_CLASS 0x08
+#define HID_CLASS 0x03
+#define MSC_PROTOCOL 0x50
+#define CBI_PROTOCOL 0x01
+
+
+#define USBH_MAX_ERROR_COUNT 2
+#define USBH_DEVICE_ADDRESS_DEFAULT 0
+#define USBH_DEVICE_ADDRESS 1
+
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_CORE_Exported_Types
+ * @{
+ */
+
+typedef enum {
+ USBH_OK = 0,
+ USBH_BUSY,
+ USBH_FAIL,
+ USBH_NOT_SUPPORTED,
+ USBH_UNRECOVERED_ERROR,
+ USBH_ERROR_SPEED_UNKNOWN,
+ USBH_APPLY_DEINIT
+}USBH_Status;
+
+/* Following states are used for gState */
+typedef enum {
+ HOST_IDLE =0,
+ HOST_ISSUE_CORE_RESET,
+ HOST_DEV_ATTACHED,
+ HOST_DEV_DISCONNECTED,
+ HOST_ISSUE_RESET,
+ HOST_DETECT_DEVICE_SPEED,
+ HOST_ENUMERATION,
+ HOST_CLASS_REQUEST,
+ HOST_CLASS,
+ HOST_CTRL_XFER,
+ HOST_USR_INPUT,
+ HOST_SUSPENDED,
+ HOST_ERROR_STATE
+}HOST_State;
+
+/* Following states are used for EnumerationState */
+typedef enum {
+ ENUM_IDLE = 0,
+ ENUM_GET_FULL_DEV_DESC,
+ ENUM_SET_ADDR,
+ ENUM_GET_CFG_DESC,
+ ENUM_GET_FULL_CFG_DESC,
+ ENUM_GET_MFC_STRING_DESC,
+ ENUM_GET_PRODUCT_STRING_DESC,
+ ENUM_GET_SERIALNUM_STRING_DESC,
+ ENUM_SET_CONFIGURATION,
+ ENUM_DEV_CONFIGURED
+} ENUM_State;
+
+
+
+/* Following states are used for CtrlXferStateMachine */
+typedef enum {
+ CTRL_IDLE =0,
+ CTRL_SETUP,
+ CTRL_SETUP_WAIT,
+ CTRL_DATA_IN,
+ CTRL_DATA_IN_WAIT,
+ CTRL_DATA_OUT,
+ CTRL_DATA_OUT_WAIT,
+ CTRL_STATUS_IN,
+ CTRL_STATUS_IN_WAIT,
+ CTRL_STATUS_OUT,
+ CTRL_STATUS_OUT_WAIT,
+ CTRL_ERROR
+}
+CTRL_State;
+
+typedef enum {
+ USBH_USR_NO_RESP = 0,
+ USBH_USR_RESP_OK = 1,
+}
+USBH_USR_Status;
+
+/* Following states are used for RequestState */
+typedef enum {
+ CMD_IDLE =0,
+ CMD_SEND,
+ CMD_WAIT
+} CMD_State;
+
+
+
+typedef struct _Ctrl
+{
+ uint8_t hc_num_in;
+ uint8_t hc_num_out;
+ uint8_t ep0size;
+ uint8_t *buff;
+ uint16_t length;
+ uint8_t errorcount;
+ uint16_t timer;
+ CTRL_STATUS status;
+ USB_Setup_TypeDef setup;
+ CTRL_State state;
+
+} USBH_Ctrl_TypeDef;
+
+
+
+typedef struct _DeviceProp
+{
+
+ uint8_t address;
+ uint8_t speed;
+ USBH_DevDesc_TypeDef Dev_Desc;
+ USBH_CfgDesc_TypeDef Cfg_Desc;
+ USBH_InterfaceDesc_TypeDef Itf_Desc[USBH_MAX_NUM_INTERFACES];
+ USBH_EpDesc_TypeDef Ep_Desc[USBH_MAX_NUM_INTERFACES][USBH_MAX_NUM_ENDPOINTS];
+ USBH_HIDDesc_TypeDef HID_Desc;
+
+}USBH_Device_TypeDef;
+
+typedef struct _USBH_Class_cb
+{
+ USBH_Status (*Init)\
+ (USB_OTG_CORE_HANDLE *pdev , void *phost);
+ void (*DeInit)\
+ (USB_OTG_CORE_HANDLE *pdev , void *phost);
+ USBH_Status (*Requests)\
+ (USB_OTG_CORE_HANDLE *pdev , void *phost);
+ USBH_Status (*Machine)\
+ (USB_OTG_CORE_HANDLE *pdev , void *phost);
+
+} USBH_Class_cb_TypeDef;
+
+
+typedef struct _USBH_USR_PROP
+{
+ void (*Init)(void); /* HostLibInitialized */
+ void (*DeInit)(void); /* HostLibInitialized */
+ void (*DeviceAttached)(void); /* DeviceAttached */
+ void (*ResetDevice)(void);
+ void (*DeviceDisconnected)(void);
+ void (*OverCurrentDetected)(void);
+ void (*DeviceSpeedDetected)(uint8_t DeviceSpeed); /* DeviceSpeed */
+ void (*DeviceDescAvailable)(void *); /* DeviceDescriptor is available */
+ void (*DeviceAddressAssigned)(void); /* Address is assigned to USB Device */
+ void (*ConfigurationDescAvailable)(USBH_CfgDesc_TypeDef *,
+ USBH_InterfaceDesc_TypeDef *,
+ USBH_EpDesc_TypeDef *);
+ /* Configuration Descriptor available */
+ void (*ManufacturerString)(void *); /* ManufacturerString*/
+ void (*ProductString)(void *); /* ProductString*/
+ void (*SerialNumString)(void *); /* SerialNubString*/
+ void (*EnumerationDone)(void); /* Enumeration finished */
+ USBH_USR_Status (*UserInput)(void);
+ int (*USBH_USR_MSC_Application) (void);
+ void (*USBH_USR_DeviceNotSupported)(void); /* Device is not supported*/
+ void (*UnrecoveredError)(void);
+
+}
+USBH_Usr_cb_TypeDef;
+
+typedef struct _Host_TypeDef
+{
+ HOST_State gState; /* Host State Machine Value */
+ HOST_State gStateBkp; /* backup of previous State machine value */
+ ENUM_State EnumState; /* Enumeration state Machine */
+ CMD_State RequestState;
+ USBH_Ctrl_TypeDef Control;
+
+ USBH_Device_TypeDef device_prop;
+
+ USBH_Class_cb_TypeDef *class_cb;
+ USBH_Usr_cb_TypeDef *usr_cb;
+
+
+} USBH_HOST, *pUSBH_HOST;
+
+/**
+ * @}
+ */
+
+
+
+/** @defgroup USBH_CORE_Exported_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBH_CORE_Exported_Variables
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBH_CORE_Exported_FunctionsPrototype
+ * @{
+ */
+void USBH_Init(USB_OTG_CORE_HANDLE *pdev,
+ USB_OTG_CORE_ID_TypeDef coreID,
+ USBH_HOST *phost,
+ USBH_Class_cb_TypeDef *class_cb,
+ USBH_Usr_cb_TypeDef *usr_cb);
+
+USBH_Status USBH_DeInit(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost);
+void USBH_Process(USB_OTG_CORE_HANDLE *pdev ,
+ USBH_HOST *phost);
+void USBH_ErrorHandle(USBH_HOST *phost,
+ USBH_Status errType);
+
+/**
+ * @}
+ */
+
+#endif /* __USBH_CORE_H */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+* @}
+*/
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
+
+
--- /dev/null
+/**
+ ******************************************************************************
+ * @file usbh_def.h
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 22-July-2011
+ * @brief Definitions used in the USB host library
+ ******************************************************************************
+ * @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.
+ *
+ * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
+ ******************************************************************************
+ */
+/** @addtogroup USBH_LIB
+ * @{
+ */
+
+/** @addtogroup USBH_LIB_CORE
+* @{
+*/
+
+/** @defgroup USBH_DEF
+ * @brief This file is includes USB descriptors
+ * @{
+ */
+
+#ifndef USBH_DEF_H
+#define USBH_DEF_H
+
+#ifndef USBH_NULL
+#define USBH_NULL ((void *)0)
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+
+#define ValBit(VAR,POS) (VAR & (1 << POS))
+#define SetBit(VAR,POS) (VAR |= (1 << POS))
+#define ClrBit(VAR,POS) (VAR &= ((1 << POS)^255))
+
+#define LE16(addr) (((u16)(*((u8 *)(addr))))\
+ + (((u16)(*(((u8 *)(addr)) + 1))) << 8))
+
+#define USB_LEN_DESC_HDR 0x02
+#define USB_LEN_DEV_DESC 0x12
+#define USB_LEN_CFG_DESC 0x09
+#define USB_LEN_IF_DESC 0x09
+#define USB_LEN_EP_DESC 0x07
+#define USB_LEN_OTG_DESC 0x03
+#define USB_LEN_SETUP_PKT 0x08
+
+/* bmRequestType :D7 Data Phase Transfer Direction */
+#define USB_REQ_DIR_MASK 0x80
+#define USB_H2D 0x00
+#define USB_D2H 0x80
+
+/* bmRequestType D6..5 Type */
+#define USB_REQ_TYPE_STANDARD 0x00
+#define USB_REQ_TYPE_CLASS 0x20
+#define USB_REQ_TYPE_VENDOR 0x40
+#define USB_REQ_TYPE_RESERVED 0x60
+
+/* bmRequestType D4..0 Recipient */
+#define USB_REQ_RECIPIENT_DEVICE 0x00
+#define USB_REQ_RECIPIENT_INTERFACE 0x01
+#define USB_REQ_RECIPIENT_ENDPOINT 0x02
+#define USB_REQ_RECIPIENT_OTHER 0x03
+
+/* Table 9-4. Standard Request Codes */
+/* bRequest , Value */
+#define USB_REQ_GET_STATUS 0x00
+#define USB_REQ_CLEAR_FEATURE 0x01
+#define USB_REQ_SET_FEATURE 0x03
+#define USB_REQ_SET_ADDRESS 0x05
+#define USB_REQ_GET_DESCRIPTOR 0x06
+#define USB_REQ_SET_DESCRIPTOR 0x07
+#define USB_REQ_GET_CONFIGURATION 0x08
+#define USB_REQ_SET_CONFIGURATION 0x09
+#define USB_REQ_GET_INTERFACE 0x0A
+#define USB_REQ_SET_INTERFACE 0x0B
+#define USB_REQ_SYNCH_FRAME 0x0C
+
+/* Table 9-5. Descriptor Types of USB Specifications */
+#define USB_DESC_TYPE_DEVICE 1
+#define USB_DESC_TYPE_CONFIGURATION 2
+#define USB_DESC_TYPE_STRING 3
+#define USB_DESC_TYPE_INTERFACE 4
+#define USB_DESC_TYPE_ENDPOINT 5
+#define USB_DESC_TYPE_DEVICE_QUALIFIER 6
+#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 7
+#define USB_DESC_TYPE_INTERFACE_POWER 8
+#define USB_DESC_TYPE_HID 0x21
+#define USB_DESC_TYPE_HID_REPORT 0x22
+
+
+#define USB_DEVICE_DESC_SIZE 18
+#define USB_CONFIGURATION_DESC_SIZE 9
+#define USB_HID_DESC_SIZE 9
+#define USB_INTERFACE_DESC_SIZE 9
+#define USB_ENDPOINT_DESC_SIZE 7
+
+/* Descriptor Type and Descriptor Index */
+/* Use the following values when calling the function USBH_GetDescriptor */
+#define USB_DESC_DEVICE ((USB_DESC_TYPE_DEVICE << 8) & 0xFF00)
+#define USB_DESC_CONFIGURATION ((USB_DESC_TYPE_CONFIGURATION << 8) & 0xFF00)
+#define USB_DESC_STRING ((USB_DESC_TYPE_STRING << 8) & 0xFF00)
+#define USB_DESC_INTERFACE ((USB_DESC_TYPE_INTERFACE << 8) & 0xFF00)
+#define USB_DESC_ENDPOINT ((USB_DESC_TYPE_INTERFACE << 8) & 0xFF00)
+#define USB_DESC_DEVICE_QUALIFIER ((USB_DESC_TYPE_DEVICE_QUALIFIER << 8) & 0xFF00)
+#define USB_DESC_OTHER_SPEED_CONFIGURATION ((USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION << 8) & 0xFF00)
+#define USB_DESC_INTERFACE_POWER ((USB_DESC_TYPE_INTERFACE_POWER << 8) & 0xFF00)
+#define USB_DESC_HID_REPORT ((USB_DESC_TYPE_HID_REPORT << 8) & 0xFF00)
+#define USB_DESC_HID ((USB_DESC_TYPE_HID << 8) & 0xFF00)
+
+
+#define USB_EP_TYPE_CTRL 0x00
+#define USB_EP_TYPE_ISOC 0x01
+#define USB_EP_TYPE_BULK 0x02
+#define USB_EP_TYPE_INTR 0x03
+
+#define USB_EP_DIR_OUT 0x00
+#define USB_EP_DIR_IN 0x80
+#define USB_EP_DIR_MSK 0x80
+
+/* supported classes */
+#define USB_MSC_CLASS 0x08
+#define USB_HID_CLASS 0x03
+
+/* Interface Descriptor field values for HID Boot Protocol */
+#define HID_BOOT_CODE 0x01
+#define HID_KEYBRD_BOOT_CODE 0x01
+#define HID_MOUSE_BOOT_CODE 0x02
+
+/* As per USB specs 9.2.6.4 :Standard request with data request timeout: 5sec
+ Standard request with no data stage timeout : 50ms */
+#define DATA_STAGE_TIMEOUT 5000
+#define NODATA_STAGE_TIMEOUT 50
+
+/**
+ * @}
+ */
+
+
+#define USBH_CONFIGURATION_DESCRIPTOR_SIZE (USB_CONFIGURATION_DESC_SIZE \
+ + USB_INTERFACE_DESC_SIZE\
+ + (USBH_MAX_NUM_ENDPOINTS * USB_ENDPOINT_DESC_SIZE))
+
+
+#define CONFIG_DESC_wTOTAL_LENGTH (ConfigurationDescriptorData.ConfigDescfield.\
+ ConfigurationDescriptor.wTotalLength)
+
+
+/* This Union is copied from usb_core.h */
+typedef union
+{
+ uint16_t w;
+ struct BW
+ {
+ uint8_t msb;
+ uint8_t lsb;
+ }
+ bw;
+}
+uint16_t_uint8_t;
+
+
+typedef union _USB_Setup
+{
+ uint8_t d8[8];
+
+ struct _SetupPkt_Struc
+ {
+ uint8_t bmRequestType;
+ uint8_t bRequest;
+ uint16_t_uint8_t wValue;
+ uint16_t_uint8_t wIndex;
+ uint16_t_uint8_t wLength;
+ } b;
+}
+USB_Setup_TypeDef;
+
+typedef struct _DescHeader
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+}
+USBH_DescHeader_t;
+
+typedef struct _DeviceDescriptor
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint16_t bcdUSB; /* USB Specification Number which device complies too */
+ uint8_t bDeviceClass;
+ uint8_t bDeviceSubClass;
+ uint8_t bDeviceProtocol;
+ /* If equal to Zero, each interface specifies its own class
+ code if equal to 0xFF, the class code is vendor specified.
+ Otherwise field is valid Class Code.*/
+ uint8_t bMaxPacketSize;
+ uint16_t idVendor; /* Vendor ID (Assigned by USB Org) */
+ uint16_t idProduct; /* Product ID (Assigned by Manufacturer) */
+ uint16_t bcdDevice; /* Device Release Number */
+ uint8_t iManufacturer; /* Index of Manufacturer String Descriptor */
+ uint8_t iProduct; /* Index of Product String Descriptor */
+ uint8_t iSerialNumber; /* Index of Serial Number String Descriptor */
+ uint8_t bNumConfigurations; /* Number of Possible Configurations */
+}
+USBH_DevDesc_TypeDef;
+
+
+typedef struct _ConfigurationDescriptor
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint16_t wTotalLength; /* Total Length of Data Returned */
+ uint8_t bNumInterfaces; /* Number of Interfaces */
+ uint8_t bConfigurationValue; /* Value to use as an argument to select this configuration*/
+ uint8_t iConfiguration; /*Index of String Descriptor Describing this configuration */
+ uint8_t bmAttributes; /* D7 Bus Powered , D6 Self Powered, D5 Remote Wakeup , D4..0 Reserved (0)*/
+ uint8_t bMaxPower; /*Maximum Power Consumption */
+}
+USBH_CfgDesc_TypeDef;
+
+
+typedef struct _HIDDescriptor
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint16_t bcdHID; /* indicates what endpoint this descriptor is describing */
+ uint8_t bCountryCode; /* specifies the transfer type. */
+ uint8_t bNumDescriptors; /* specifies the transfer type. */
+ uint8_t bReportDescriptorType; /* Maximum Packet Size this endpoint is capable of sending or receiving */
+ uint16_t wItemLength; /* is used to specify the polling interval of certain transfers. */
+}
+USBH_HIDDesc_TypeDef;
+
+
+typedef struct _InterfaceDescriptor
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint8_t bInterfaceNumber;
+ uint8_t bAlternateSetting; /* Value used to select alternative setting */
+ uint8_t bNumEndpoints; /* Number of Endpoints used for this interface */
+ uint8_t bInterfaceClass; /* Class Code (Assigned by USB Org) */
+ uint8_t bInterfaceSubClass; /* Subclass Code (Assigned by USB Org) */
+ uint8_t bInterfaceProtocol; /* Protocol Code */
+ uint8_t iInterface; /* Index of String Descriptor Describing this interface */
+
+}
+USBH_InterfaceDesc_TypeDef;
+
+
+typedef struct _EndpointDescriptor
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint8_t bEndpointAddress; /* indicates what endpoint this descriptor is describing */
+ uint8_t bmAttributes; /* specifies the transfer type. */
+ uint16_t wMaxPacketSize; /* Maximum Packet Size this endpoint is capable of sending or receiving */
+ uint8_t bInterval; /* is used to specify the polling interval of certain transfers. */
+}
+USBH_EpDesc_TypeDef;
+#endif
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
--- /dev/null
+/**
+ ******************************************************************************
+ * @file usbh_hcs.h
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 22-July-2011
+ * @brief Header file for usbh_hcs.c
+ ******************************************************************************
+ * @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.
+ *
+ * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive ----------------------------------------------*/
+#ifndef __USBH_HCS_H
+#define __USBH_HCS_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbh_core.h"
+
+
+
+/** @addtogroup USBH_LIB
+ * @{
+ */
+
+/** @addtogroup USBH_LIB_CORE
+* @{
+*/
+
+/** @defgroup USBH_HCS
+ * @brief This file is the header file for usbh_hcs.c
+ * @{
+ */
+
+/** @defgroup USBH_HCS_Exported_Defines
+ * @{
+ */
+#define HC_MAX 8
+
+#define HC_OK 0x0000
+#define HC_USED 0x8000
+#define HC_ERROR 0xFFFF
+#define HC_USED_MASK 0x7FFF
+/**
+ * @}
+ */
+
+/** @defgroup USBH_HCS_Exported_Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_HCS_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBH_HCS_Exported_Variables
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBH_HCS_Exported_FunctionsPrototype
+ * @{
+ */
+
+uint8_t USBH_Alloc_Channel(USB_OTG_CORE_HANDLE *pdev, uint8_t ep_addr);
+
+uint8_t USBH_Free_Channel (USB_OTG_CORE_HANDLE *pdev, uint8_t idx);
+
+uint8_t USBH_DeAllocate_AllChannel (USB_OTG_CORE_HANDLE *pdev);
+
+uint8_t USBH_Open_Channel (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t ch_num,
+ uint8_t dev_address,
+ uint8_t speed,
+ uint8_t ep_type,
+ uint16_t mps);
+
+uint8_t USBH_Modify_Channel (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t hc_num,
+ uint8_t dev_address,
+ uint8_t speed,
+ uint8_t ep_type,
+ uint16_t mps);
+/**
+ * @}
+ */
+
+
+
+#endif /* __USBH_HCS_H */
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+* @}
+*/
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
+
--- /dev/null
+/**
+ ******************************************************************************
+ * @file usbh_ioreq.h
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 22-July-2011
+ * @brief Header file for usbh_ioreq.c
+ ******************************************************************************
+ * @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.
+ *
+ * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive ----------------------------------------------*/
+#ifndef __USBH_IOREQ_H
+#define __USBH_IOREQ_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_conf.h"
+#include "usbh_core.h"
+#include "usbh_def.h"
+
+
+/** @addtogroup USBH_LIB
+ * @{
+ */
+
+/** @addtogroup USBH_LIB_CORE
+* @{
+*/
+
+/** @defgroup USBH_IOREQ
+ * @brief This file is the header file for usbh_ioreq.c
+ * @{
+ */
+
+
+/** @defgroup USBH_IOREQ_Exported_Defines
+ * @{
+ */
+#define USBH_SETUP_PKT_SIZE 8
+#define USBH_EP0_EP_NUM 0
+#define USBH_MAX_PACKET_SIZE 0x40
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_IOREQ_Exported_Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_IOREQ_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBH_IOREQ_Exported_Variables
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBH_IOREQ_Exported_FunctionsPrototype
+ * @{
+ */
+USBH_Status USBH_CtlSendSetup ( USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *buff,
+ uint8_t hc_num);
+
+USBH_Status USBH_CtlSendData ( USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *buff,
+ uint8_t length,
+ uint8_t hc_num);
+
+USBH_Status USBH_CtlReceiveData( USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *buff,
+ uint8_t length,
+ uint8_t hc_num);
+
+USBH_Status USBH_BulkReceiveData( USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *buff,
+ uint16_t length,
+ uint8_t hc_num);
+
+USBH_Status USBH_BulkSendData ( USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *buff,
+ uint16_t length,
+ uint8_t hc_num);
+
+USBH_Status USBH_InterruptReceiveData( USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *buff,
+ uint8_t length,
+ uint8_t hc_num);
+
+USBH_Status USBH_InterruptSendData( USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *buff,
+ uint8_t length,
+ uint8_t hc_num);
+
+USBH_Status USBH_CtlReq (USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t *buff,
+ uint16_t length);
+/**
+ * @}
+ */
+
+#endif /* __USBH_IOREQ_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+* @}
+*/
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
+
--- /dev/null
+/**
+ ******************************************************************************
+ * @file usbh_stdreq.h
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 22-July-2011
+ * @brief Header file for usbh_stdreq.c
+ ******************************************************************************
+ * @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.
+ *
+ * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive ----------------------------------------------*/
+#ifndef __USBH_STDREQ_H
+#define __USBH_STDREQ_H
+
+/* Includes ------------------------------------------------------------------*/
+
+#include "usb_conf.h"
+#include "usb_hcd.h"
+#include "usbh_core.h"
+#include "usbh_def.h"
+
+/** @addtogroup USBH_LIB
+ * @{
+ */
+
+/** @addtogroup USBH_LIB_CORE
+* @{
+*/
+
+/** @defgroup USBH_STDREQ
+ * @brief This file is the
+ * @{
+ */
+
+
+/** @defgroup USBH_STDREQ_Exported_Defines
+ * @{
+ */
+/*Standard Feature Selector for clear feature command*/
+#define FEATURE_SELECTOR_ENDPOINT 0X00
+#define FEATURE_SELECTOR_DEVICE 0X01
+
+
+#define INTERFACE_DESC_TYPE 0x04
+#define ENDPOINT_DESC_TYPE 0x05
+#define INTERFACE_DESC_SIZE 0x09
+
+
+#define USBH_HID_CLASS 0x03
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_STDREQ_Exported_Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_STDREQ_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBH_STDREQ_Exported_Variables
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBH_STDREQ_Exported_FunctionsPrototype
+ * @{
+ */
+USBH_Status USBH_GetDescriptor(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t req_type,
+ uint16_t value_idx,
+ uint8_t* buff,
+ uint16_t length );
+
+USBH_Status USBH_Get_DevDesc(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t length);
+
+USBH_Status USBH_Get_StringDesc(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t string_index,
+ uint8_t *buff,
+ uint16_t length);
+
+USBH_Status USBH_SetCfg(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint16_t configuration_value);
+
+USBH_Status USBH_Get_CfgDesc(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint16_t length);
+
+USBH_Status USBH_SetAddress(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t DeviceAddress);
+
+USBH_Status USBH_ClrFeature(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t ep_num, uint8_t hc_num);
+
+USBH_Status USBH_Issue_ClrFeature(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t ep_num);
+/**
+ * @}
+ */
+
+#endif /* __USBH_STDREQ_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+* @}
+*/
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
+
--- /dev/null
+/**
+ ******************************************************************************
+ * @file usbh_core.c
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 22-July-2011
+ * @brief This file implements the functions for the core state machine process
+ * the enumeration and the control transfer process
+ ******************************************************************************
+ * @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.
+ *
+ * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
+ ******************************************************************************
+ */
+/* Includes ------------------------------------------------------------------*/
+
+#include "usbh_ioreq.h"
+#include "usb_bsp.h"
+#include "usbh_hcs.h"
+#include "usbh_stdreq.h"
+#include "usbh_core.h"
+
+
+/** @addtogroup USBH_LIB
+ * @{
+ */
+
+/** @addtogroup USBH_LIB_CORE
+* @{
+*/
+
+/** @defgroup USBH_CORE
+ * @brief TThis file handles the basic enumaration when a device is connected
+ * to the host.
+ * @{
+ */
+
+/** @defgroup USBH_CORE_Private_TypesDefinitions
+ * @{
+ */
+void USBH_Disconnect (void *pdev);
+void USBH_Connect (void *pdev);
+
+USB_OTG_hPort_TypeDef USBH_DeviceConnStatus_cb =
+{
+ USBH_Disconnect,
+ USBH_Connect,
+ 0,
+ 0,
+ 0,
+ 0
+};
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_CORE_Private_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_CORE_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_CORE_Private_Variables
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_CORE_Private_FunctionPrototypes
+ * @{
+ */
+static USBH_Status USBH_HandleEnum(USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost);
+USBH_Status USBH_HandleControl (USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost);
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_CORE_Private_Functions
+ * @{
+ */
+
+
+/**
+ * @brief USBH_Connect
+ * USB Connect callback function from the Interrupt.
+ * @param selected device
+ * @retval none
+ */
+void USBH_Connect (void *pdev)
+{
+ USB_OTG_CORE_HANDLE *ppdev = pdev;
+ ppdev->host.port_cb->ConnStatus = 1;
+ ppdev->host.port_cb->ConnHandled = 0;
+}
+
+/**
+ * @brief USBH_Disconnect
+ * USB Disconnect callback function from the Interrupt.
+ * @param selected device
+ * @retval none
+ */
+
+void USBH_Disconnect (void *pdev)
+{
+
+ USB_OTG_CORE_HANDLE *ppdev = pdev;
+
+ /* Make device Not connected flag true */
+ ppdev->host.port_cb->DisconnStatus = 1;
+ ppdev->host.port_cb->DisconnHandled = 0;
+}
+
+/**
+ * @brief USBH_Init
+ * Host hardware and stack initializations
+ * @param class_cb: Class callback structure address
+ * @param usr_cb: User callback structure address
+ * @retval None
+ */
+void USBH_Init(USB_OTG_CORE_HANDLE *pdev,
+ USB_OTG_CORE_ID_TypeDef coreID,
+ USBH_HOST *phost,
+ USBH_Class_cb_TypeDef *class_cb,
+ USBH_Usr_cb_TypeDef *usr_cb)
+{
+
+ /* Hardware Init */
+ USB_OTG_BSP_Init(pdev);
+
+ /* configure GPIO pin used for switching VBUS power */
+ USB_OTG_BSP_ConfigVBUS(0);
+
+
+ /* Host de-initializations */
+ USBH_DeInit(pdev, phost);
+
+ /*Register class and user callbacks */
+ phost->class_cb = class_cb;
+ phost->usr_cb = usr_cb;
+ pdev->host.port_cb = &USBH_DeviceConnStatus_cb;
+
+ pdev->host.port_cb->ConnStatus = 0;
+ pdev->host.port_cb->DisconnStatus = 0;
+
+
+ /* Start the USB OTG core */
+ HCD_Init(pdev , coreID);
+
+ /* Upon Init call usr call back */
+ phost->usr_cb->Init();
+
+ /* Enable Interrupts */
+ USB_OTG_BSP_EnableInterrupt(pdev);
+}
+
+/**
+ * @brief USBH_DeInit
+ * Re-Initialize Host
+ * @param None
+ * @retval status: USBH_Status
+ */
+USBH_Status USBH_DeInit(USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost)
+{
+ /* Software Init */
+
+ phost->gState = HOST_IDLE;
+ phost->gStateBkp = HOST_IDLE;
+ phost->EnumState = ENUM_IDLE;
+ phost->RequestState = CMD_SEND;
+
+ phost->Control.state = CTRL_SETUP;
+ phost->Control.ep0size = USB_OTG_MAX_EP0_SIZE;
+
+ phost->device_prop.address = USBH_DEVICE_ADDRESS_DEFAULT;
+ phost->device_prop.speed = HPRT0_PRTSPD_FULL_SPEED;
+
+ USBH_Free_Channel (pdev, phost->Control.hc_num_in);
+ USBH_Free_Channel (pdev, phost->Control.hc_num_out);
+ return USBH_OK;
+}
+
+/**
+* @brief USBH_Process
+* USB Host core main state machine process
+* @param None
+* @retval None
+*/
+void USBH_Process(USB_OTG_CORE_HANDLE *pdev , USBH_HOST *phost)
+{
+ volatile USBH_Status status = USBH_FAIL;
+
+ switch (phost->gState)
+ {
+ case HOST_ISSUE_CORE_RESET :
+
+ if ( HCD_ResetPort(pdev) == 0)
+ {
+ phost->gState = HOST_IDLE;
+ }
+ break;
+
+ case HOST_IDLE :
+
+ if (HCD_IsDeviceConnected(pdev))
+ {
+ /* Wait for USB Connect Interrupt void USBH_ISR_Connected(void) */
+ USBH_DeAllocate_AllChannel(pdev);
+ phost->gState = HOST_DEV_ATTACHED;
+ }
+ break;
+
+ case HOST_DEV_ATTACHED :
+
+ phost->usr_cb->DeviceAttached();
+ pdev->host.port_cb->DisconnStatus = 0;
+ pdev->host.port_cb->ConnHandled = 1;
+
+ phost->Control.hc_num_out = USBH_Alloc_Channel(pdev, 0x00);
+ phost->Control.hc_num_in = USBH_Alloc_Channel(pdev, 0x80);
+
+ /* Reset USB Device */
+ if ( HCD_ResetPort(pdev) == 0)
+ {
+ phost->usr_cb->ResetDevice();
+ /* Wait for USB USBH_ISR_PrtEnDisableChange()
+ Host is Now ready to start the Enumeration
+ */
+
+ phost->device_prop.speed = HCD_GetCurrentSpeed(pdev);
+
+ phost->gState = HOST_ENUMERATION;
+ phost->usr_cb->DeviceSpeedDetected(phost->device_prop.speed);
+
+ /* Open Control pipes */
+ USBH_Open_Channel (pdev,
+ phost->Control.hc_num_in,
+ phost->device_prop.address,
+ phost->device_prop.speed,
+ EP_TYPE_CTRL,
+ phost->Control.ep0size);
+
+ /* Open Control pipes */
+ USBH_Open_Channel (pdev,
+ phost->Control.hc_num_out,
+ phost->device_prop.address,
+ phost->device_prop.speed,
+ EP_TYPE_CTRL,
+ phost->Control.ep0size);
+ }
+ break;
+
+ case HOST_ENUMERATION:
+ /* Check for enumeration status */
+ if ( USBH_HandleEnum(pdev , phost) == USBH_OK)
+ {
+ /* The function shall return USBH_OK when full enumeration is complete */
+
+ /* user callback for end of device basic enumeration */
+ phost->usr_cb->EnumerationDone();
+
+ phost->gState = HOST_USR_INPUT;
+ }
+ break;
+
+ case HOST_USR_INPUT:
+ /*The function should return user response true to move to class state */
+ if ( phost->usr_cb->UserInput() == USBH_USR_RESP_OK)
+ {
+ if((phost->class_cb->Init(pdev, phost))\
+ == USBH_OK)
+ {
+ phost->gState = HOST_CLASS_REQUEST;
+ }
+ }
+ break;
+
+ case HOST_CLASS_REQUEST:
+ /* process class standard contol requests state machine */
+ status = phost->class_cb->Requests(pdev, phost);
+
+ if(status == USBH_OK)
+ {
+ phost->gState = HOST_CLASS;
+ }
+
+ else
+ {
+ USBH_ErrorHandle(phost, status);
+ }
+
+
+ break;
+ case HOST_CLASS:
+ /* process class state machine */
+ status = phost->class_cb->Machine(pdev, phost);
+ USBH_ErrorHandle(phost, status);
+ break;
+
+ case HOST_CTRL_XFER:
+ /* process control transfer state machine */
+ USBH_HandleControl(pdev, phost);
+ break;
+
+ case HOST_SUSPENDED:
+ break;
+
+ case HOST_ERROR_STATE:
+ /* Re-Initilaize Host for new Enumeration */
+ USBH_DeInit(pdev, phost);
+ phost->usr_cb->DeInit();
+ phost->class_cb->DeInit(pdev, &phost->device_prop);
+ break;
+
+ default :
+ break;
+ }
+
+ /* check device disconnection event */
+ if (!(HCD_IsDeviceConnected(pdev)) &&
+ (pdev->host.port_cb->DisconnHandled == 0))
+ {
+ /* Manage User disconnect operations*/
+ phost->usr_cb->DeviceDisconnected();
+
+ pdev->host.port_cb->DisconnHandled = 1; /* Handle to avoid the Re-entry*/
+
+ /* Re-Initilaize Host for new Enumeration */
+ USBH_DeInit(pdev, phost);
+ phost->usr_cb->DeInit();
+ phost->class_cb->DeInit(pdev, &phost->device_prop);
+ }
+}
+
+
+/**
+ * @brief USBH_ErrorHandle
+ * This function handles the Error on Host side.
+ * @param errType : Type of Error or Busy/OK state
+ * @retval None
+ */
+void USBH_ErrorHandle(USBH_HOST *phost, USBH_Status errType)
+{
+ /* Error unrecovered or not supported device speed */
+ if ( (errType == USBH_ERROR_SPEED_UNKNOWN) ||
+ (errType == USBH_UNRECOVERED_ERROR) )
+ {
+ phost->usr_cb->UnrecoveredError();
+ phost->gState = HOST_ERROR_STATE;
+ }
+ /* USB host restart requested from application layer */
+ else if(errType == USBH_APPLY_DEINIT)
+ {
+ phost->gState = HOST_ERROR_STATE;
+ /* user callback for initalization */
+ phost->usr_cb->Init();
+ }
+}
+
+
+/**
+ * @brief USBH_HandleEnum
+ * This function includes the complete enumeration process
+ * @param pdev: Selected device
+ * @retval USBH_Status
+ */
+static USBH_Status USBH_HandleEnum(USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost)
+{
+ USBH_Status Status = USBH_BUSY;
+ uint8_t Local_Buffer[64];
+
+ switch (phost->EnumState)
+ {
+ case ENUM_IDLE:
+ /* Get Device Desc for only 1st 8 bytes : To get EP0 MaxPacketSize */
+ if ( USBH_Get_DevDesc(pdev , phost, 8) == USBH_OK)
+ {
+ phost->Control.ep0size = phost->device_prop.Dev_Desc.bMaxPacketSize;
+
+ /* Issue Reset */
+ HCD_ResetPort(pdev);
+ phost->EnumState = ENUM_GET_FULL_DEV_DESC;
+
+ /* modify control channels configuration for MaxPacket size */
+ USBH_Modify_Channel (pdev,
+ phost->Control.hc_num_out,
+ 0,
+ 0,
+ 0,
+ phost->Control.ep0size);
+
+ USBH_Modify_Channel (pdev,
+ phost->Control.hc_num_in,
+ 0,
+ 0,
+ 0,
+ phost->Control.ep0size);
+ }
+ break;
+
+ case ENUM_GET_FULL_DEV_DESC:
+ /* Get FULL Device Desc */
+ if ( USBH_Get_DevDesc(pdev, phost, USB_DEVICE_DESC_SIZE)\
+ == USBH_OK)
+ {
+ /* user callback for device descriptor available */
+ phost->usr_cb->DeviceDescAvailable(&phost->device_prop.Dev_Desc);
+ phost->EnumState = ENUM_SET_ADDR;
+ }
+ break;
+
+ case ENUM_SET_ADDR:
+ /* set address */
+ if ( USBH_SetAddress(pdev, phost, USBH_DEVICE_ADDRESS) == USBH_OK)
+ {
+ phost->device_prop.address = USBH_DEVICE_ADDRESS;
+
+ /* user callback for device address assigned */
+ phost->usr_cb->DeviceAddressAssigned();
+ phost->EnumState = ENUM_GET_CFG_DESC;
+
+ /* modify control channels to update device address */
+ USBH_Modify_Channel (pdev,
+ phost->Control.hc_num_in,
+ phost->device_prop.address,
+ 0,
+ 0,
+ 0);
+
+ USBH_Modify_Channel (pdev,
+ phost->Control.hc_num_out,
+ phost->device_prop.address,
+ 0,
+ 0,
+ 0);
+ }
+ break;
+
+ case ENUM_GET_CFG_DESC:
+ /* get standard configuration descriptor */
+ if ( USBH_Get_CfgDesc(pdev,
+ phost,
+ USB_CONFIGURATION_DESC_SIZE) == USBH_OK)
+ {
+ phost->EnumState = ENUM_GET_FULL_CFG_DESC;
+ }
+ break;
+
+ case ENUM_GET_FULL_CFG_DESC:
+ /* get FULL config descriptor (config, interface, endpoints) */
+ if (USBH_Get_CfgDesc(pdev,
+ phost,
+ phost->device_prop.Cfg_Desc.wTotalLength) == USBH_OK)
+ {
+ /* User callback for configuration descriptors available */
+ phost->usr_cb->ConfigurationDescAvailable(&phost->device_prop.Cfg_Desc,
+ phost->device_prop.Itf_Desc,
+ phost->device_prop.Ep_Desc[0]);
+
+ phost->EnumState = ENUM_GET_MFC_STRING_DESC;
+ }
+ break;
+
+ case ENUM_GET_MFC_STRING_DESC:
+ if (phost->device_prop.Dev_Desc.iManufacturer != 0)
+ { /* Check that Manufacturer String is available */
+
+ if ( USBH_Get_StringDesc(pdev,
+ phost,
+ phost->device_prop.Dev_Desc.iManufacturer,
+ Local_Buffer ,
+ 0xff) == USBH_OK)
+ {
+ /* User callback for Manufacturing string */
+ phost->usr_cb->ManufacturerString(Local_Buffer);
+ phost->EnumState = ENUM_GET_PRODUCT_STRING_DESC;
+ }
+ }
+ else
+ {
+ phost->usr_cb->ManufacturerString("N/A");
+ phost->EnumState = ENUM_GET_PRODUCT_STRING_DESC;
+ }
+ break;
+
+ case ENUM_GET_PRODUCT_STRING_DESC:
+ if (phost->device_prop.Dev_Desc.iProduct != 0)
+ { /* Check that Product string is available */
+ if ( USBH_Get_StringDesc(pdev,
+ phost,
+ phost->device_prop.Dev_Desc.iProduct,
+ Local_Buffer,
+ 0xff) == USBH_OK)
+ {
+ /* User callback for Product string */
+ phost->usr_cb->ProductString(Local_Buffer);
+ phost->EnumState = ENUM_GET_SERIALNUM_STRING_DESC;
+ }
+ }
+ else
+ {
+ phost->usr_cb->ProductString("N/A");
+ phost->EnumState = ENUM_GET_SERIALNUM_STRING_DESC;
+ }
+ break;
+
+ case ENUM_GET_SERIALNUM_STRING_DESC:
+ if (phost->device_prop.Dev_Desc.iSerialNumber != 0)
+ { /* Check that Serial number string is available */
+ if ( USBH_Get_StringDesc(pdev,
+ phost,
+ phost->device_prop.Dev_Desc.iSerialNumber,
+ Local_Buffer,
+ 0xff) == USBH_OK)
+ {
+ /* User callback for Serial number string */
+ phost->usr_cb->SerialNumString(Local_Buffer);
+ phost->EnumState = ENUM_SET_CONFIGURATION;
+ }
+ }
+ else
+ {
+ phost->usr_cb->SerialNumString("N/A");
+ phost->EnumState = ENUM_SET_CONFIGURATION;
+ }
+ break;
+
+ case ENUM_SET_CONFIGURATION:
+ /* set configuration (default config) */
+ if (USBH_SetCfg(pdev,
+ phost,
+ phost->device_prop.Cfg_Desc.bConfigurationValue) == USBH_OK)
+ {
+ phost->EnumState = ENUM_DEV_CONFIGURED;
+ }
+ break;
+
+
+ case ENUM_DEV_CONFIGURED:
+ /* user callback for enumeration done */
+ Status = USBH_OK;
+ break;
+
+ default:
+ break;
+ }
+ return Status;
+}
+
+
+/**
+ * @brief USBH_HandleControl
+ * Handles the USB control transfer state machine
+ * @param pdev: Selected device
+ * @retval Status
+ */
+USBH_Status USBH_HandleControl (USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost)
+{
+ uint8_t direction;
+ static uint16_t timeout = 0;
+ USBH_Status status = USBH_OK;
+ URB_STATE URB_Status = URB_IDLE;
+
+ phost->Control.status = CTRL_START;
+
+
+ switch (phost->Control.state)
+ {
+ case CTRL_SETUP:
+ /* send a SETUP packet */
+ USBH_CtlSendSetup (pdev,
+ phost->Control.setup.d8 ,
+ phost->Control.hc_num_out);
+ phost->Control.state = CTRL_SETUP_WAIT;
+ break;
+
+ case CTRL_SETUP_WAIT:
+
+ URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_out);
+ /* case SETUP packet sent successfully */
+ if(URB_Status == URB_DONE)
+ {
+ direction = (phost->Control.setup.b.bmRequestType & USB_REQ_DIR_MASK);
+
+ /* check if there is a data stage */
+ if (phost->Control.setup.b.wLength.w != 0 )
+ {
+ timeout = DATA_STAGE_TIMEOUT;
+ if (direction == USB_D2H)
+ {
+ /* Data Direction is IN */
+ phost->Control.state = CTRL_DATA_IN;
+ }
+ else
+ {
+ /* Data Direction is OUT */
+ phost->Control.state = CTRL_DATA_OUT;
+ }
+ }
+ /* No DATA stage */
+ else
+ {
+ timeout = NODATA_STAGE_TIMEOUT;
+
+ /* If there is No Data Transfer Stage */
+ if (direction == USB_D2H)
+ {
+ /* Data Direction is IN */
+ phost->Control.state = CTRL_STATUS_OUT;
+ }
+ else
+ {
+ /* Data Direction is OUT */
+ phost->Control.state = CTRL_STATUS_IN;
+ }
+ }
+ /* Set the delay timer to enable timeout for data stage completion */
+ phost->Control.timer = HCD_GetCurrentFrame(pdev);
+ }
+ else if(URB_Status == URB_ERROR)
+ {
+ phost->Control.state = CTRL_ERROR;
+ phost->Control.status = CTRL_XACTERR;
+ }
+ break;
+
+ case CTRL_DATA_IN:
+ /* Issue an IN token */
+ USBH_CtlReceiveData(pdev,
+ phost->Control.buff,
+ phost->Control.length,
+ phost->Control.hc_num_in);
+
+ phost->Control.state = CTRL_DATA_IN_WAIT;
+ break;
+
+ case CTRL_DATA_IN_WAIT:
+
+ URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_in);
+
+ /* check is DATA packet transfered successfully */
+ if (URB_Status == URB_DONE)
+ {
+ phost->Control.state = CTRL_STATUS_OUT;
+ }
+
+ /* manage error cases*/
+ if (URB_Status == URB_STALL)
+ {
+ /* In stall case, return to previous machine state*/
+ phost->gState = phost->gStateBkp;
+ }
+ else if (URB_Status == URB_ERROR)
+ {
+ /* Device error */
+ phost->Control.state = CTRL_ERROR;
+ }
+ else if ((HCD_GetCurrentFrame(pdev)- phost->Control.timer) > timeout)
+ {
+ /* timeout for IN transfer */
+ phost->Control.state = CTRL_ERROR;
+ }
+ break;
+
+ case CTRL_DATA_OUT:
+ /* Start DATA out transfer (only one DATA packet)*/
+
+ pdev->host.hc[phost->Control.hc_num_out].toggle_out ^= 1;
+
+ USBH_CtlSendData (pdev,
+ phost->Control.buff,
+ phost->Control.length ,
+ phost->Control.hc_num_out);
+
+ phost->Control.state = CTRL_DATA_OUT_WAIT;
+ break;
+
+ case CTRL_DATA_OUT_WAIT:
+
+ URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_out);
+ if (URB_Status == URB_DONE)
+ { /* If the Setup Pkt is sent successful, then change the state */
+ phost->Control.state = CTRL_STATUS_IN;
+ }
+
+ /* handle error cases */
+ else if (URB_Status == URB_STALL)
+ {
+ /* In stall case, return to previous machine state*/
+ phost->gState = phost->gStateBkp;
+ }
+ else if (URB_Status == URB_NOTREADY)
+ {
+ /* Nack received from device */
+ phost->Control.state = CTRL_DATA_OUT;
+ }
+ else if (URB_Status == URB_ERROR)
+ {
+ /* device error */
+ phost->Control.state = CTRL_ERROR;
+ }
+ break;
+
+
+ case CTRL_STATUS_IN:
+ /* Send 0 bytes out packet */
+ USBH_CtlReceiveData (pdev,
+ 0,
+ 0,
+ phost->Control.hc_num_in);
+
+ phost->Control.state = CTRL_STATUS_IN_WAIT;
+
+ break;
+
+ case CTRL_STATUS_IN_WAIT:
+
+ URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_in);
+
+ if ( URB_Status == URB_DONE)
+ { /* Control transfers completed, Exit the State Machine */
+ phost->gState = phost->gStateBkp;
+ }
+
+ else if (URB_Status == URB_ERROR)
+ {
+ phost->Control.state = CTRL_ERROR;
+ }
+
+ else if((HCD_GetCurrentFrame(pdev)\
+ - phost->Control.timer) > timeout)
+ {
+ phost->Control.state = CTRL_ERROR;
+ }
+ else if(URB_Status == URB_STALL)
+ {
+ /* Control transfers completed, Exit the State Machine */
+ phost->gState = phost->gStateBkp;
+ phost->Control.status = CTRL_STALL;
+ status = USBH_NOT_SUPPORTED;
+ }
+ break;
+
+ case CTRL_STATUS_OUT:
+ pdev->host.hc[phost->Control.hc_num_out].toggle_out ^= 1;
+ USBH_CtlSendData (pdev,
+ 0,
+ 0,
+ phost->Control.hc_num_out);
+
+ phost->Control.state = CTRL_STATUS_OUT_WAIT;
+ break;
+
+ case CTRL_STATUS_OUT_WAIT:
+
+ URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_out);
+ if (URB_Status == URB_DONE)
+ {
+ phost->gState = phost->gStateBkp;
+ }
+ else if (URB_Status == URB_NOTREADY)
+ {
+ phost->Control.state = CTRL_STATUS_OUT;
+ }
+ else if (URB_Status == URB_ERROR)
+ {
+ phost->Control.state = CTRL_ERROR;
+ }
+ break;
+
+ case CTRL_ERROR:
+ /*
+ After a halt condition is encountered or an error is detected by the
+ host, a control endpoint is allowed to recover by accepting the next Setup
+ PID; i.e., recovery actions via some other pipe are not required for control
+ endpoints. For the Default Control Pipe, a device reset will ultimately be
+ required to clear the halt or error condition if the next Setup PID is not
+ accepted.
+ */
+ if (++ phost->Control.errorcount <= USBH_MAX_ERROR_COUNT)
+ {
+ /* Do the transmission again, starting from SETUP Packet */
+ phost->Control.state = CTRL_SETUP;
+ }
+ else
+ {
+ phost->Control.status = CTRL_FAIL;
+ phost->gState = phost->gStateBkp;
+
+ status = USBH_FAIL;
+ }
+ break;
+
+ default:
+ break;
+ }
+ return status;
+}
+
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
+
+
+
--- /dev/null
+/**
+ ******************************************************************************
+ * @file usbh_hcs.c
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 22-July-2011
+ * @brief This file implements functions for opening and closing host channels
+ ******************************************************************************
+ * @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.
+ *
+ * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbh_hcs.h"
+
+/** @addtogroup USBH_LIB
+ * @{
+ */
+
+/** @addtogroup USBH_LIB_CORE
+* @{
+*/
+
+/** @defgroup USBH_HCS
+ * @brief This file includes opening and closing host channels
+ * @{
+ */
+
+/** @defgroup USBH_HCS_Private_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBH_HCS_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_HCS_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_HCS_Private_Variables
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_HCS_Private_FunctionPrototypes
+ * @{
+ */
+static uint16_t USBH_GetFreeChannel (USB_OTG_CORE_HANDLE *pdev);
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_HCS_Private_Functions
+ * @{
+ */
+
+
+
+/**
+ * @brief USBH_Open_Channel
+ * Open a pipe
+ * @param pdev : Selected device
+ * @param hc_num: Host channel Number
+ * @param dev_address: USB Device address allocated to attached device
+ * @param speed : USB device speed (Full/Low)
+ * @param ep_type: end point type (Bulk/int/ctl)
+ * @param mps: max pkt size
+ * @retval Status
+ */
+uint8_t USBH_Open_Channel (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t hc_num,
+ uint8_t dev_address,
+ uint8_t speed,
+ uint8_t ep_type,
+ uint16_t mps)
+{
+
+ pdev->host.hc[hc_num].ep_num = pdev->host.channel[hc_num]& 0x7F;
+ pdev->host.hc[hc_num].ep_is_in = (pdev->host.channel[hc_num] & 0x80 ) == 0x80;
+ pdev->host.hc[hc_num].dev_addr = dev_address;
+ pdev->host.hc[hc_num].ep_type = ep_type;
+ pdev->host.hc[hc_num].max_packet = mps;
+ pdev->host.hc[hc_num].speed = speed;
+ pdev->host.hc[hc_num].toggle_in = 0;
+ pdev->host.hc[hc_num].toggle_out = 0;
+ if(speed == HPRT0_PRTSPD_HIGH_SPEED)
+ {
+ pdev->host.hc[hc_num].do_ping = 1;
+ }
+
+ USB_OTG_HC_Init(pdev, hc_num) ;
+
+ return HC_OK;
+
+}
+
+/**
+ * @brief USBH_Modify_Channel
+ * Modify a pipe
+ * @param pdev : Selected device
+ * @param hc_num: Host channel Number
+ * @param dev_address: USB Device address allocated to attached device
+ * @param speed : USB device speed (Full/Low)
+ * @param ep_type: end point type (Bulk/int/ctl)
+ * @param mps: max pkt size
+ * @retval Status
+ */
+uint8_t USBH_Modify_Channel (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t hc_num,
+ uint8_t dev_address,
+ uint8_t speed,
+ uint8_t ep_type,
+ uint16_t mps)
+{
+
+ if(dev_address != 0)
+ {
+ pdev->host.hc[hc_num].dev_addr = dev_address;
+ }
+
+ if((pdev->host.hc[hc_num].max_packet != mps) && (mps != 0))
+ {
+ pdev->host.hc[hc_num].max_packet = mps;
+ }
+
+ if((pdev->host.hc[hc_num].speed != speed ) && (speed != 0 ))
+ {
+ pdev->host.hc[hc_num].speed = speed;
+ }
+
+ USB_OTG_HC_Init(pdev, hc_num);
+ return HC_OK;
+
+}
+
+/**
+ * @brief USBH_Alloc_Channel
+ * Allocate a new channel for the pipe
+ * @param ep_addr: End point for which the channel to be allocated
+ * @retval hc_num: Host channel number
+ */
+uint8_t USBH_Alloc_Channel (USB_OTG_CORE_HANDLE *pdev, uint8_t ep_addr)
+{
+ uint16_t hc_num;
+
+ hc_num = USBH_GetFreeChannel(pdev);
+
+ if (hc_num != HC_ERROR)
+ {
+ pdev->host.channel[hc_num] = HC_USED | ep_addr;
+ }
+ return hc_num;
+}
+
+/**
+ * @brief USBH_Free_Pipe
+ * Free the USB host channel
+ * @param idx: Channel number to be freed
+ * @retval Status
+ */
+uint8_t USBH_Free_Channel (USB_OTG_CORE_HANDLE *pdev, uint8_t idx)
+{
+ if(idx < HC_MAX)
+ {
+ pdev->host.channel[idx] &= HC_USED_MASK;
+ }
+ return USBH_OK;
+}
+
+
+/**
+ * @brief USBH_DeAllocate_AllChannel
+ * Free all USB host channel
+* @param pdev : core instance
+ * @retval Status
+ */
+uint8_t USBH_DeAllocate_AllChannel (USB_OTG_CORE_HANDLE *pdev)
+{
+ uint8_t idx;
+
+ for (idx = 2; idx < HC_MAX ; idx ++)
+ {
+ pdev->host.channel[idx] = 0;
+ }
+ return USBH_OK;
+}
+
+/**
+ * @brief USBH_GetFreeChannel
+ * Get a free channel number for allocation to a device endpoint
+ * @param None
+ * @retval idx: Free Channel number
+ */
+static uint16_t USBH_GetFreeChannel (USB_OTG_CORE_HANDLE *pdev)
+{
+ uint8_t idx = 0;
+
+ for (idx = 0 ; idx < HC_MAX ; idx++)
+ {
+ if ((pdev->host.channel[idx] & HC_USED) == 0)
+ {
+ return idx;
+ }
+ }
+ return HC_ERROR;
+}
+
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
+
--- /dev/null
+/**
+ ******************************************************************************
+ * @file usbh_ioreq.c
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 22-July-2011
+ * @brief This file handles the issuing of the USB transactions
+ ******************************************************************************
+ * @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.
+ *
+ * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
+ ******************************************************************************
+ */
+/* Includes ------------------------------------------------------------------*/
+
+#include "usbh_ioreq.h"
+
+/** @addtogroup USBH_LIB
+ * @{
+ */
+
+/** @addtogroup USBH_LIB_CORE
+* @{
+*/
+
+/** @defgroup USBH_IOREQ
+ * @brief This file handles the standard protocol processing (USB v2.0)
+ * @{
+ */
+
+
+/** @defgroup USBH_IOREQ_Private_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_IOREQ_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+
+/** @defgroup USBH_IOREQ_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_IOREQ_Private_Variables
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_IOREQ_Private_FunctionPrototypes
+ * @{
+ */
+static USBH_Status USBH_SubmitSetupRequest(USBH_HOST *phost,
+ uint8_t* buff,
+ uint16_t length);
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_IOREQ_Private_Functions
+ * @{
+ */
+
+
+/**
+ * @brief USBH_CtlReq
+ * USBH_CtlReq sends a control request and provide the status after
+ * completion of the request
+ * @param pdev: Selected device
+ * @param req: Setup Request Structure
+ * @param buff: data buffer address to store the response
+ * @param length: length of the response
+ * @retval Status
+ */
+USBH_Status USBH_CtlReq (USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t *buff,
+ uint16_t length)
+{
+ USBH_Status status;
+ URB_STATE URB_Status = URB_IDLE;
+
+ URB_Status = HCD_GetURB_State(pdev, phost->Control.hc_num_out);
+
+ status = USBH_BUSY;
+
+ switch (phost->RequestState)
+ {
+ case CMD_SEND:
+ /* Start a SETUP transfer */
+ USBH_SubmitSetupRequest(phost, buff, length);
+ phost->RequestState = CMD_WAIT;
+ status = USBH_BUSY;
+ break;
+
+ case CMD_WAIT:
+ if (URB_Status == URB_DONE)
+ {
+ /* Commands successfully sent and Response Received */
+ phost->RequestState = CMD_SEND;
+ status = USBH_OK;
+ }
+ else if (URB_Status == URB_ERROR)
+ {
+ /* Failure Mode */
+ phost->RequestState = CMD_SEND;
+ status = USBH_FAIL;
+ }
+ else if (URB_Status == URB_STALL)
+ {
+ /* Commands successfully sent and Response Received */
+ phost->RequestState = CMD_SEND;
+ status = USBH_NOT_SUPPORTED;
+ }
+ break;
+
+ default:
+ break;
+ }
+ return status;
+}
+
+/**
+ * @brief USBH_CtlSendSetup
+ * Sends the Setup Packet to the Device
+ * @param pdev: Selected device
+ * @param buff: Buffer pointer from which the Data will be send to Device
+ * @param hc_num: Host channel Number
+ * @retval Status
+ */
+USBH_Status USBH_CtlSendSetup ( USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *buff,
+ uint8_t hc_num){
+ pdev->host.hc[hc_num].ep_is_in = 0;
+ pdev->host.hc[hc_num].data_pid = HC_PID_SETUP;
+ pdev->host.hc[hc_num].xfer_buff = buff;
+ pdev->host.hc[hc_num].xfer_len = USBH_SETUP_PKT_SIZE;
+
+ return (USBH_Status)HCD_SubmitRequest (pdev , hc_num);
+}
+
+
+/**
+ * @brief USBH_CtlSendData
+ * Sends a data Packet to the Device
+ * @param pdev: Selected device
+ * @param buff: Buffer pointer from which the Data will be sent to Device
+ * @param length: Length of the data to be sent
+ * @param hc_num: Host channel Number
+ * @retval Status
+ */
+USBH_Status USBH_CtlSendData ( USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *buff,
+ uint8_t length,
+ uint8_t hc_num)
+{
+ pdev->host.hc[hc_num].ep_is_in = 0;
+ pdev->host.hc[hc_num].xfer_buff = buff;
+ pdev->host.hc[hc_num].xfer_len = length;
+
+ if ( length == 0 )
+ { /* For Status OUT stage, Length==0, Status Out PID = 1 */
+ pdev->host.hc[hc_num].toggle_out = 1;
+ }
+
+ /* Set the Data Toggle bit as per the Flag */
+ if ( pdev->host.hc[hc_num].toggle_out == 0)
+ { /* Put the PID 0 */
+ pdev->host.hc[hc_num].data_pid = HC_PID_DATA0;
+ }
+ else
+ { /* Put the PID 1 */
+ pdev->host.hc[hc_num].data_pid = HC_PID_DATA1 ;
+ }
+
+ HCD_SubmitRequest (pdev , hc_num);
+
+ return USBH_OK;
+}
+
+
+/**
+ * @brief USBH_CtlReceiveData
+ * Receives the Device Response to the Setup Packet
+ * @param pdev: Selected device
+ * @param buff: Buffer pointer in which the response needs to be copied
+ * @param length: Length of the data to be received
+ * @param hc_num: Host channel Number
+ * @retval Status.
+ */
+USBH_Status USBH_CtlReceiveData(USB_OTG_CORE_HANDLE *pdev,
+ uint8_t* buff,
+ uint8_t length,
+ uint8_t hc_num)
+{
+
+ pdev->host.hc[hc_num].ep_is_in = 1;
+ pdev->host.hc[hc_num].data_pid = HC_PID_DATA1;
+ pdev->host.hc[hc_num].xfer_buff = buff;
+ pdev->host.hc[hc_num].xfer_len = length;
+
+ HCD_SubmitRequest (pdev , hc_num);
+
+ return USBH_OK;
+
+}
+
+
+/**
+ * @brief USBH_BulkSendData
+ * Sends the Bulk Packet to the device
+ * @param pdev: Selected device
+ * @param buff: Buffer pointer from which the Data will be sent to Device
+ * @param length: Length of the data to be sent
+ * @param hc_num: Host channel Number
+ * @retval Status
+ */
+USBH_Status USBH_BulkSendData ( USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *buff,
+ uint16_t length,
+ uint8_t hc_num)
+{
+ pdev->host.hc[hc_num].ep_is_in = 0;
+ pdev->host.hc[hc_num].xfer_buff = buff;
+ pdev->host.hc[hc_num].xfer_len = length;
+
+ /* Set the Data Toggle bit as per the Flag */
+ if ( pdev->host.hc[hc_num].toggle_out == 0)
+ { /* Put the PID 0 */
+ pdev->host.hc[hc_num].data_pid = HC_PID_DATA0;
+ }
+ else
+ { /* Put the PID 1 */
+ pdev->host.hc[hc_num].data_pid = HC_PID_DATA1 ;
+ }
+
+ HCD_SubmitRequest (pdev , hc_num);
+ return USBH_OK;
+}
+
+
+/**
+ * @brief USBH_BulkReceiveData
+ * Receives IN bulk packet from device
+ * @param pdev: Selected device
+ * @param buff: Buffer pointer in which the received data packet to be copied
+ * @param length: Length of the data to be received
+ * @param hc_num: Host channel Number
+ * @retval Status.
+ */
+USBH_Status USBH_BulkReceiveData( USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *buff,
+ uint16_t length,
+ uint8_t hc_num)
+{
+ pdev->host.hc[hc_num].ep_is_in = 1;
+ pdev->host.hc[hc_num].xfer_buff = buff;
+ pdev->host.hc[hc_num].xfer_len = length;
+
+
+ if( pdev->host.hc[hc_num].toggle_in == 0)
+ {
+ pdev->host.hc[hc_num].data_pid = HC_PID_DATA0;
+ }
+ else
+ {
+ pdev->host.hc[hc_num].data_pid = HC_PID_DATA1;
+ }
+
+ HCD_SubmitRequest (pdev , hc_num);
+ return USBH_OK;
+}
+
+
+/**
+ * @brief USBH_InterruptReceiveData
+ * Receives the Device Response to the Interrupt IN token
+ * @param pdev: Selected device
+ * @param buff: Buffer pointer in which the response needs to be copied
+ * @param length: Length of the data to be received
+ * @param hc_num: Host channel Number
+ * @retval Status.
+ */
+USBH_Status USBH_InterruptReceiveData( USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *buff,
+ uint8_t length,
+ uint8_t hc_num)
+{
+
+ pdev->host.hc[hc_num].ep_is_in = 1;
+ pdev->host.hc[hc_num].xfer_buff = buff;
+ pdev->host.hc[hc_num].xfer_len = length;
+
+
+
+ if(pdev->host.hc[hc_num].toggle_in == 0)
+ {
+ pdev->host.hc[hc_num].data_pid = HC_PID_DATA0;
+ }
+ else
+ {
+ pdev->host.hc[hc_num].data_pid = HC_PID_DATA1;
+ }
+
+ /* toggle DATA PID */
+ pdev->host.hc[hc_num].toggle_in ^= 1;
+
+ HCD_SubmitRequest (pdev , hc_num);
+
+ return USBH_OK;
+}
+
+/**
+ * @brief USBH_InterruptSendData
+ * Sends the data on Interrupt OUT Endpoint
+ * @param pdev: Selected device
+ * @param buff: Buffer pointer from where the data needs to be copied
+ * @param length: Length of the data to be sent
+ * @param hc_num: Host channel Number
+ * @retval Status.
+ */
+USBH_Status USBH_InterruptSendData( USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *buff,
+ uint8_t length,
+ uint8_t hc_num)
+{
+
+ pdev->host.hc[hc_num].ep_is_in = 0;
+ pdev->host.hc[hc_num].xfer_buff = buff;
+ pdev->host.hc[hc_num].xfer_len = length;
+
+ if(pdev->host.hc[hc_num].toggle_in == 0)
+ {
+ pdev->host.hc[hc_num].data_pid = HC_PID_DATA0;
+ }
+ else
+ {
+ pdev->host.hc[hc_num].data_pid = HC_PID_DATA1;
+ }
+
+ pdev->host.hc[hc_num].toggle_in ^= 1;
+
+ HCD_SubmitRequest (pdev , hc_num);
+
+ return USBH_OK;
+}
+
+
+/**
+ * @brief USBH_SubmitSetupRequest
+ * Start a setup transfer by changing the state-machine and
+ * initializing the required variables needed for the Control Transfer
+ * @param pdev: Selected device
+ * @param setup: Setup Request Structure
+ * @param buff: Buffer used for setup request
+ * @param length: Length of the data
+ * @retval Status.
+*/
+static USBH_Status USBH_SubmitSetupRequest(USBH_HOST *phost,
+ uint8_t* buff,
+ uint16_t length)
+{
+
+ /* Save Global State */
+ phost->gStateBkp = phost->gState;
+
+ /* Prepare the Transactions */
+ phost->gState = HOST_CTRL_XFER;
+ phost->Control.buff = buff;
+ phost->Control.length = length;
+ phost->Control.state = CTRL_SETUP;
+
+ return USBH_OK;
+}
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
+
+
--- /dev/null
+/**
+ ******************************************************************************
+ * @file usbh_stdreq.c
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 22-July-2011
+ * @brief This file implements the standard requests for device enumeration
+ ******************************************************************************
+ * @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.
+ *
+ * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
+ ******************************************************************************
+ */
+/* Includes ------------------------------------------------------------------*/
+
+#include "usbh_ioreq.h"
+#include "usbh_stdreq.h"
+
+/** @addtogroup USBH_LIB
+* @{
+*/
+
+/** @addtogroup USBH_LIB_CORE
+* @{
+*/
+
+/** @defgroup USBH_STDREQ
+* @brief This file implements the standard requests for device enumeration
+* @{
+*/
+
+
+/** @defgroup USBH_STDREQ_Private_Defines
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_STDREQ_Private_TypesDefinitions
+* @{
+*/
+/**
+* @}
+*/
+
+
+
+/** @defgroup USBH_STDREQ_Private_Macros
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_STDREQ_Private_Variables
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_STDREQ_Private_FunctionPrototypes
+* @{
+*/
+static void USBH_ParseDevDesc (USBH_DevDesc_TypeDef* , uint8_t *buf, uint16_t length);
+
+static void USBH_ParseCfgDesc (USBH_CfgDesc_TypeDef* cfg_desc,
+ USBH_InterfaceDesc_TypeDef* itf_desc,
+ USBH_EpDesc_TypeDef* ep_desc,
+ uint8_t *buf,
+ uint16_t length);
+static USBH_DescHeader_t *USBH_GetNextDesc (uint8_t *pbuf,
+ uint16_t *ptr);
+
+static void USBH_ParseInterfaceDesc (USBH_InterfaceDesc_TypeDef *if_descriptor, uint8_t *buf);
+static void USBH_ParseEPDesc (USBH_EpDesc_TypeDef *ep_descriptor, uint8_t *buf);
+
+static void USBH_ParseStringDesc (uint8_t* psrc, uint8_t* pdest, uint16_t length);
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_STDREQ_Private_Functions
+* @{
+*/
+
+
+/**
+* @brief USBH_Get_DevDesc
+* Issue Get Device Descriptor command to the device. Once the response
+* received, it parses the device descriptor and updates the status.
+* @param pdev: Selected device
+* @param dev_desc: Device Descriptor buffer address
+* @param pdev->host.Rx_Buffer: Receive Buffer address
+* @param length: Length of the descriptor
+* @retval Status
+*/
+USBH_Status USBH_Get_DevDesc(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t length)
+{
+
+ USBH_Status status;
+
+ if((status = USBH_GetDescriptor(pdev,
+ phost,
+ USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD,
+ USB_DESC_DEVICE,
+ pdev->host.Rx_Buffer,
+ length)) == USBH_OK)
+ {
+ /* Commands successfully sent and Response Received */
+ USBH_ParseDevDesc(&phost->device_prop.Dev_Desc, pdev->host.Rx_Buffer, length);
+ }
+ return status;
+}
+
+/**
+* @brief USBH_Get_CfgDesc
+* Issues Configuration Descriptor to the device. Once the response
+* received, it parses the configuartion descriptor and updates the
+* status.
+* @param pdev: Selected device
+* @param cfg_desc: Configuration Descriptor address
+* @param itf_desc: Interface Descriptor address
+* @param ep_desc: Endpoint Descriptor address
+* @param length: Length of the descriptor
+* @retval Status
+*/
+USBH_Status USBH_Get_CfgDesc(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint16_t length)
+
+{
+ USBH_Status status;
+
+ if((status = USBH_GetDescriptor(pdev,
+ phost,
+ USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD,
+ USB_DESC_CONFIGURATION,
+ pdev->host.Rx_Buffer,
+ length)) == USBH_OK)
+ {
+ /* Commands successfully sent and Response Received */
+ USBH_ParseCfgDesc (&phost->device_prop.Cfg_Desc,
+ phost->device_prop.Itf_Desc,
+ phost->device_prop.Ep_Desc[0],
+ pdev->host.Rx_Buffer,
+ length);
+
+ }
+ return status;
+}
+
+
+/**
+* @brief USBH_Get_StringDesc
+* Issues string Descriptor command to the device. Once the response
+* received, it parses the string descriptor and updates the status.
+* @param pdev: Selected device
+* @param string_index: String index for the descriptor
+* @param buff: Buffer address for the descriptor
+* @param length: Length of the descriptor
+* @retval Status
+*/
+USBH_Status USBH_Get_StringDesc(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t string_index,
+ uint8_t *buff,
+ uint16_t length)
+{
+ USBH_Status status;
+
+ if((status = USBH_GetDescriptor(pdev,
+ phost,
+ USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD,
+ USB_DESC_STRING | string_index,
+ pdev->host.Rx_Buffer,
+ length)) == USBH_OK)
+ {
+ /* Commands successfully sent and Response Received */
+ USBH_ParseStringDesc(pdev->host.Rx_Buffer,buff, length);
+ }
+ return status;
+}
+
+/**
+* @brief USBH_GetDescriptor
+* Issues Descriptor command to the device. Once the response received,
+* it parses the descriptor and updates the status.
+* @param pdev: Selected device
+* @param req_type: Descriptor type
+* @param value_idx: wValue for the GetDescriptr request
+* @param buff: Buffer to store the descriptor
+* @param length: Length of the descriptor
+* @retval Status
+*/
+USBH_Status USBH_GetDescriptor(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t req_type,
+ uint16_t value_idx,
+ uint8_t* buff,
+ uint16_t length )
+{
+ phost->Control.setup.b.bmRequestType = USB_D2H | req_type;
+ phost->Control.setup.b.bRequest = USB_REQ_GET_DESCRIPTOR;
+ phost->Control.setup.b.wValue.w = value_idx;
+
+ if ((value_idx & 0xff00) == USB_DESC_STRING)
+ {
+ phost->Control.setup.b.wIndex.w = 0x0409;
+ }
+ else
+ {
+ phost->Control.setup.b.wIndex.w = 0;
+ }
+ phost->Control.setup.b.wLength.w = length;
+ return USBH_CtlReq(pdev, phost, buff , length );
+}
+
+/**
+* @brief USBH_SetAddress
+* This command sets the address to the connected device
+* @param pdev: Selected device
+* @param DeviceAddress: Device address to assign
+* @retval Status
+*/
+USBH_Status USBH_SetAddress(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t DeviceAddress)
+{
+ phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_DEVICE | \
+ USB_REQ_TYPE_STANDARD;
+
+ phost->Control.setup.b.bRequest = USB_REQ_SET_ADDRESS;
+
+ phost->Control.setup.b.wValue.w = (uint16_t)DeviceAddress;
+ phost->Control.setup.b.wIndex.w = 0;
+ phost->Control.setup.b.wLength.w = 0;
+
+ return USBH_CtlReq(pdev, phost, 0 , 0 );
+}
+
+/**
+* @brief USBH_SetCfg
+* The command sets the configuration value to the connected device
+* @param pdev: Selected device
+* @param cfg_idx: Configuration value
+* @retval Status
+*/
+USBH_Status USBH_SetCfg(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint16_t cfg_idx)
+{
+
+ phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_DEVICE |\
+ USB_REQ_TYPE_STANDARD;
+ phost->Control.setup.b.bRequest = USB_REQ_SET_CONFIGURATION;
+ phost->Control.setup.b.wValue.w = cfg_idx;
+ phost->Control.setup.b.wIndex.w = 0;
+ phost->Control.setup.b.wLength.w = 0;
+
+ return USBH_CtlReq(pdev, phost, 0 , 0 );
+}
+
+/**
+* @brief USBH_ClrFeature
+* This request is used to clear or disable a specific feature.
+
+* @param pdev: Selected device
+* @param ep_num: endpoint number
+* @param hc_num: Host channel number
+* @retval Status
+*/
+USBH_Status USBH_ClrFeature(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t ep_num,
+ uint8_t hc_num)
+{
+
+ phost->Control.setup.b.bmRequestType = USB_H2D |
+ USB_REQ_RECIPIENT_ENDPOINT |
+ USB_REQ_TYPE_STANDARD;
+
+ phost->Control.setup.b.bRequest = USB_REQ_CLEAR_FEATURE;
+ phost->Control.setup.b.wValue.w = FEATURE_SELECTOR_ENDPOINT;
+ phost->Control.setup.b.wIndex.w = ep_num;
+ phost->Control.setup.b.wLength.w = 0;
+
+ if ((ep_num & USB_REQ_DIR_MASK ) == USB_D2H)
+ { /* EP Type is IN */
+ pdev->host.hc[hc_num].toggle_in = 0;
+ }
+ else
+ {/* EP Type is OUT */
+ pdev->host.hc[hc_num].toggle_out = 0;
+ }
+
+ return USBH_CtlReq(pdev, phost, 0 , 0 );
+}
+
+/**
+* @brief USBH_ParseDevDesc
+* This function Parses the device descriptor
+* @param dev_desc: device_descriptor destinaton address
+* @param buf: Buffer where the source descriptor is available
+* @param length: Length of the descriptor
+* @retval None
+*/
+static void USBH_ParseDevDesc (USBH_DevDesc_TypeDef* dev_desc,
+ uint8_t *buf,
+ uint16_t length)
+{
+ dev_desc->bLength = *(uint8_t *) (buf + 0);
+ dev_desc->bDescriptorType = *(uint8_t *) (buf + 1);
+ dev_desc->bcdUSB = LE16 (buf + 2);
+ dev_desc->bDeviceClass = *(uint8_t *) (buf + 4);
+ dev_desc->bDeviceSubClass = *(uint8_t *) (buf + 5);
+ dev_desc->bDeviceProtocol = *(uint8_t *) (buf + 6);
+ dev_desc->bMaxPacketSize = *(uint8_t *) (buf + 7);
+
+ if (length > 8)
+ { /* For 1st time after device connection, Host may issue only 8 bytes for
+ Device Descriptor Length */
+ dev_desc->idVendor = LE16 (buf + 8);
+ dev_desc->idProduct = LE16 (buf + 10);
+ dev_desc->bcdDevice = LE16 (buf + 12);
+ dev_desc->iManufacturer = *(uint8_t *) (buf + 14);
+ dev_desc->iProduct = *(uint8_t *) (buf + 15);
+ dev_desc->iSerialNumber = *(uint8_t *) (buf + 16);
+ dev_desc->bNumConfigurations = *(uint8_t *) (buf + 17);
+ }
+}
+
+/**
+* @brief USBH_ParseCfgDesc
+* This function Parses the configuration descriptor
+* @param cfg_desc: Configuration Descriptor address
+* @param itf_desc: Interface Descriptor address
+* @param ep_desc: Endpoint Descriptor address
+* @param buf: Buffer where the source descriptor is available
+* @param length: Length of the descriptor
+* @retval None
+*/
+static void USBH_ParseCfgDesc (USBH_CfgDesc_TypeDef* cfg_desc,
+ USBH_InterfaceDesc_TypeDef* itf_desc,
+ USBH_EpDesc_TypeDef* ep_desc,
+ uint8_t *buf,
+ uint16_t length)
+{
+ USBH_InterfaceDesc_TypeDef *pif ;
+ USBH_EpDesc_TypeDef *pep;
+ USBH_DescHeader_t *pdesc = (USBH_DescHeader_t *)buf;
+ uint16_t ptr;
+ int8_t if_ix;
+ int8_t ep_ix;
+
+ pdesc = (USBH_DescHeader_t *)buf;
+
+ /* Parse configuration descriptor */
+ cfg_desc->bLength = *(uint8_t *) (buf + 0);
+ cfg_desc->bDescriptorType = *(uint8_t *) (buf + 1);
+ cfg_desc->wTotalLength = LE16 (buf + 2);
+ cfg_desc->bNumInterfaces = *(uint8_t *) (buf + 4);
+ cfg_desc->bConfigurationValue = *(uint8_t *) (buf + 5);
+ cfg_desc->iConfiguration = *(uint8_t *) (buf + 6);
+ cfg_desc->bmAttributes = *(uint8_t *) (buf + 7);
+ cfg_desc->bMaxPower = *(uint8_t *) (buf + 8);
+
+
+ if (length > USB_CONFIGURATION_DESC_SIZE)
+ {
+ ptr = USB_LEN_CFG_DESC;
+
+ if ( cfg_desc->bNumInterfaces <= USBH_MAX_NUM_INTERFACES)
+ {
+ if_ix = 0;
+ pif = (USBH_InterfaceDesc_TypeDef *)0;
+
+ /* Parse Interface descriptor relative to the current configuration */
+ if(cfg_desc->bNumInterfaces <= USBH_MAX_NUM_INTERFACES)
+ {
+ while (if_ix < cfg_desc->bNumInterfaces)
+ {
+ pdesc = USBH_GetNextDesc((uint8_t *)pdesc, &ptr);
+ if (pdesc->bDescriptorType == USB_DESC_TYPE_INTERFACE)
+ {
+ pif = &itf_desc[if_ix];
+ USBH_ParseInterfaceDesc (pif, (uint8_t *)pdesc);
+ ep_ix = 0;
+
+ /* Parse Ep descriptors relative to the current interface */
+ if(pif->bNumEndpoints <= USBH_MAX_NUM_ENDPOINTS)
+ {
+ while (ep_ix < pif->bNumEndpoints)
+ {
+ pdesc = USBH_GetNextDesc((void* )pdesc, &ptr);
+ if (pdesc->bDescriptorType == USB_DESC_TYPE_ENDPOINT)
+ {
+ pep = &ep_desc[ep_ix];
+ USBH_ParseEPDesc (pep, (uint8_t *)pdesc);
+ ep_ix++;
+ }
+ else
+ {
+ ptr += pdesc->bLength;
+ }
+ }
+ }
+ if_ix++;
+ }
+ else
+ {
+ ptr += pdesc->bLength;
+ }
+ }
+ }
+ }
+ }
+}
+
+
+/**
+* @brief USBH_ParseInterfaceDesc
+* This function Parses the interface descriptor
+* @param if_descriptor : Interface descriptor destination
+* @param buf: Buffer where the descriptor data is available
+* @retval None
+*/
+static void USBH_ParseInterfaceDesc (USBH_InterfaceDesc_TypeDef *if_descriptor,
+ uint8_t *buf)
+{
+ if_descriptor->bLength = *(uint8_t *) (buf + 0);
+ if_descriptor->bDescriptorType = *(uint8_t *) (buf + 1);
+ if_descriptor->bInterfaceNumber = *(uint8_t *) (buf + 2);
+ if_descriptor->bAlternateSetting = *(uint8_t *) (buf + 3);
+ if_descriptor->bNumEndpoints = *(uint8_t *) (buf + 4);
+ if_descriptor->bInterfaceClass = *(uint8_t *) (buf + 5);
+ if_descriptor->bInterfaceSubClass = *(uint8_t *) (buf + 6);
+ if_descriptor->bInterfaceProtocol = *(uint8_t *) (buf + 7);
+ if_descriptor->iInterface = *(uint8_t *) (buf + 8);
+}
+
+/**
+* @brief USBH_ParseEPDesc
+* This function Parses the endpoint descriptor
+* @param ep_descriptor: Endpoint descriptor destination address
+* @param buf: Buffer where the parsed descriptor stored
+* @retval None
+*/
+static void USBH_ParseEPDesc (USBH_EpDesc_TypeDef *ep_descriptor,
+ uint8_t *buf)
+{
+
+ ep_descriptor->bLength = *(uint8_t *) (buf + 0);
+ ep_descriptor->bDescriptorType = *(uint8_t *) (buf + 1);
+ ep_descriptor->bEndpointAddress = *(uint8_t *) (buf + 2);
+ ep_descriptor->bmAttributes = *(uint8_t *) (buf + 3);
+ ep_descriptor->wMaxPacketSize = LE16 (buf + 4);
+ ep_descriptor->bInterval = *(uint8_t *) (buf + 6);
+}
+
+/**
+* @brief USBH_ParseStringDesc
+* This function Parses the string descriptor
+* @param psrc: Source pointer containing the descriptor data
+* @param pdest: Destination address pointer
+* @param length: Length of the descriptor
+* @retval None
+*/
+static void USBH_ParseStringDesc (uint8_t* psrc,
+ uint8_t* pdest,
+ uint16_t length)
+{
+ uint16_t strlength;
+ uint16_t idx;
+
+ /* The UNICODE string descriptor is not NULL-terminated. The string length is
+ computed by substracting two from the value of the first byte of the descriptor.
+ */
+
+ /* Check which is lower size, the Size of string or the length of bytes read
+ from the device */
+
+ if ( psrc[1] == USB_DESC_TYPE_STRING)
+ { /* Make sure the Descriptor is String Type */
+
+ /* psrc[0] contains Size of Descriptor, subtract 2 to get the length of string */
+ strlength = ( ( (psrc[0]-2) <= length) ? (psrc[0]-2) :length);
+ psrc += 2; /* Adjust the offset ignoring the String Len and Descriptor type */
+
+ for (idx = 0; idx < strlength; idx+=2 )
+ {/* Copy Only the string and ignore the UNICODE ID, hence add the src */
+ *pdest = psrc[idx];
+ pdest++;
+ }
+ *pdest = 0; /* mark end of string */
+ }
+}
+
+/**
+* @brief USBH_GetNextDesc
+* This function return the next descriptor header
+* @param buf: Buffer where the cfg descriptor is available
+* @param ptr: data popinter inside the cfg descriptor
+* @retval next header
+*/
+static USBH_DescHeader_t *USBH_GetNextDesc (uint8_t *pbuf, uint16_t *ptr)
+{
+ USBH_DescHeader_t *pnext;
+
+ *ptr += ((USBH_DescHeader_t *)pbuf)->bLength;
+ pnext = (USBH_DescHeader_t *)((uint8_t *)pbuf + \
+ ((USBH_DescHeader_t *)pbuf)->bLength);
+
+ return(pnext);
+}
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
+
+
+