Starting to integrate usb branch.
Optimized Makefiles
This commit is contained in:
@@ -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>© 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****/
|
||||
|
||||
@@ -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>© 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****/
|
||||
|
||||
|
||||
|
||||
@@ -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>© 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****/
|
||||
|
||||
@@ -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>© 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****/
|
||||
|
||||
|
||||
|
||||
@@ -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>© 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****/
|
||||
@@ -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 */
|
||||
@@ -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>© 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****/
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user