Starting to integrate usb branch.

Optimized Makefiles
This commit is contained in:
t-moe
2015-04-03 18:46:25 +02:00
parent 1f2af9f2fb
commit 21dd1e21f7
175 changed files with 88773 additions and 5 deletions

View File

@@ -0,0 +1,221 @@
/**
******************************************************************************
* @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>&copy; 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****/

View File

@@ -0,0 +1,141 @@
/**
******************************************************************************
* @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>&copy; 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****/

View File

@@ -0,0 +1,163 @@
/**
******************************************************************************
* @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>&copy; 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****/

View File

@@ -0,0 +1,613 @@
/**
******************************************************************************
* @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>&copy; 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****/

View File

@@ -0,0 +1,559 @@
/**
******************************************************************************
* @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>&copy; 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****/

View File

@@ -0,0 +1,186 @@
#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*count);
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*count);
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 */

View File

@@ -0,0 +1,674 @@
/**
******************************************************************************
* @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>&copy; 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****/