📄 usbd_protstorage.c
字号:
return retValue;
}
/* =============================================================================
// Function_Name: USBD_ProtStorageRegisterCBRStorageEvent
// description : Register the callback function for notifying StorageEvent
// argument : pfnCallback Address of callback function to be registered
// return : Finished normally STATUS_SUCCESS
// Finished abnormally STATUS_UNABLE_TO_REGISTER
// flag :
// global :
// =============================================================================
*/
LONG USBD_ProtStorageRegisterCBRStorageEvent(CALLBACK_PROC pfnCallback)
{
LONG retValue;
retValue = STATUS_SUCCESS;
while (1) {
/* Register the callback function */
if (PrvStorageEventCallback != NULL) {
/* Unable to register */
retValue = STATUS_UNABLE_TO_REGISTER;
break;
}
/* Register the callback function */
PrvStorageEventCallback = pfnCallback;
break;};
return retValue;
}
/* =============================================================================
// Function_Name: USBD_ProtStorageUnregisterCBRStorageEvent
// description : Delete callback function which is registered in USBD_ProtStorageRegisterCBRStorageEvent
// argument : pfnCallback Callback function to delete
// return : Finished normally STATUS_SUCCESS
// Finished abnormally STATUS_UNREGISTERD
// flag :
// global :
// =============================================================================
*/
LONG USBD_ProtStorageUnregisterCBRStorageEvent(CALLBACK_PROC pfnCallback)
{
LONG retValue;
retValue = STATUS_SUCCESS;
while (1) {
if (pfnCallback == PrvStorageEventCallback) {
/* Delete the callback function */
PrvStorageEventCallback = NULL;
} else {
/* Unable to delete */
retValue = STATUS_UNREGISTERED;
}
break;};
return retValue;
}
/* =============================================================================
// Function_Name: USBD_ProtStorageGetStatus
// description : Get status
// argument : type Type of status to get(unused)
// status Address used to return status
// return : Finished normally STATUS_SUCCESS
// flag :
// global :
// =============================================================================
*/
LONG USBD_ProtStorageGetStatus(UCHAR type,ULONG *status)
{
LONG retValue;
retValue = STATUS_SUCCESS;
while (1) {
/* Set Status */
*status = PrvBulkOnlyStatus; /* BulkOnly Status */
/* Call process of polling */
PrvPollingProc();
break;};
return retValue;
}
/* =============================================================================
// Function_Name: USBD_ProtStorageSetState
// description : Set state of USBD_ProtStorage
// argument : state USBD_PROT_STORAGE_START_STATE Start
// USBD_PROT_STORAGE_STOP_STATE Stop
// USBD_PROT_STORAGE_RESET_STATE Reset
// USBD_PROT_STORAGE_READYSUSPEND_STATE Preparation of Suspend
// return : Finished normally STATUS_SUCCESS
// flag :
// global :
// =============================================================================
*/
LONG USBD_ProtStorageSetState(ULONG state)
{
LONG retValue;
retValue = STATUS_SUCCESS;
while (1) {
/* Set State */
switch (state) {
case USBD_PROT_STORAGE_START_STATE: /* Start it */
SET_BIT(PrvInternalStatus,PRV_IR_CBW_READY);
CLR_BIT(PrvInternalStatus,PRV_IR_CSW_READY);
CLR_BIT(PrvInternalStatus,PRV_IR_RESET_RECOVERY);
CLR_BIT(PrvInternalStatus,PRV_IR_BULKIN_TRANSFER_END);
CLR_BIT(PrvInternalStatus,PRV_IR_BULKOUT_TRANSFER_END);
PrvBulkEPInfo[PRV_BULKIN].bState = PRV_IDLE_STATE;
PrvBulkEPInfo[PRV_BULKOUT].bState = PRV_IDLE_STATE;
PrvCSW[0] = 0x55;
PrvCSW[1] = 0x53;
PrvCSW[2] = 0x42;
PrvCSW[3] = 0x53;
/* Clear FIFO of Bulk-In,Bulk-Out */
USBD_FuncSetEPxControl(PrvBulkEPInfo[PRV_BULKIN].bEPNumber,USBD_FUNC_CE_FIFOCLEAR,USBD_FUNC_FLAG_CLR);
USBD_FuncSetEPxControl(PrvBulkEPInfo[PRV_BULKOUT].bEPNumber,USBD_FUNC_CE_NAKMODE,USBD_FUNC_FLAG_SET);
USBD_FuncSetEPxControl(PrvBulkEPInfo[PRV_BULKOUT].bEPNumber,USBD_FUNC_CE_FIFOCLEAR,USBD_FUNC_FLAG_CLR);
/* Event Off */
USBD_FuncSetEPxIntEvent(PrvAllocId,PrvBulkEPInfo[PRV_BULKIN].bEPNumber,0x00,0x00);
USBD_FuncSetEPxIntEvent(PrvAllocId,PrvBulkEPInfo[PRV_BULKOUT].bEPNumber,0x00,0x00);
break;
case USBD_PROT_STORAGE_STOP_STATE: /* Stop it */
/* Clear variables */
memset(PrvCBW,0x00,31);
PrvInternalStatus = 0x00;
/* Event Off */
USBD_FuncSetEPxIntEvent(PrvAllocId,PrvBulkEPInfo[PRV_BULKIN].bEPNumber,0x00,0x00);
USBD_FuncSetEPxIntEvent(PrvAllocId,PrvBulkEPInfo[PRV_BULKOUT].bEPNumber,0x00,0x00);
/* Stop CBW,CSW Mode */
retValue = USBD_IFSetBulkOnlyMode(USBD_IF_CBWMODE | USBD_IF_CSWMODE,USBD_IF_DISABLE);
/* Abort transfer */
if (PrvBulkEPInfo[PRV_BULKIN].bState != PRV_IDLE_STATE) {
PrvBulkEPInfo[PRV_BULKIN].bState = PRV_IDLE_STATE;
if (PrvBulkEPInfo[PRV_BULKIN].bUseDMA == 0) {
USBD_FuncEPxPIOSimpleTransferAbort(PrvAllocId,PrvBulkEPInfo[PRV_BULKIN].bEPNumber);
} else {
PrvBulkEPInfo[PRV_BULKIN].bUseDMA = 0;
USBD_FuncEndEPxDMATransfer(PrvBulkEPInfo[PRV_BULKIN].bEPNumber);
}
}
if (PrvBulkEPInfo[PRV_BULKOUT].bState != PRV_IDLE_STATE) {
PrvBulkEPInfo[PRV_BULKOUT].bState = PRV_IDLE_STATE;
if (PrvBulkEPInfo[PRV_BULKOUT].bUseDMA == 0) {
USBD_FuncEPxPIOSimpleTransferAbort(PrvAllocId,PrvBulkEPInfo[PRV_BULKOUT].bEPNumber);
} else {
PrvBulkEPInfo[PRV_BULKOUT].bUseDMA = 0;
USBD_FuncEndEPxDMATransfer(PrvBulkEPInfo[PRV_BULKOUT].bEPNumber);
}
}
/*------------------------------------------------------------------------------------------
* Because it is called while USB Reset, if FS/HS has been changed, MaxPacketSize may has been changed,
* so check the Descriptor again.
*/
PrvFindEndpointFromConfigDescriptor();
break;
case USBD_PROT_STORAGE_RESET_STATE: /* Process Mass Storage Reset */
/* Set CBW to enable state of receiving */
SET_BIT(PrvInternalStatus,PRV_IR_CBW_READY);
CLR_BIT(PrvInternalStatus,PRV_IR_CSW_READY);
CLR_BIT(PrvInternalStatus,PRV_IR_RESET_RECOVERY);
CLR_BIT(PrvInternalStatus,PRV_IR_BULKIN_TRANSFER_END);
CLR_BIT(PrvInternalStatus,PRV_IR_BULKOUT_TRANSFER_END);
/* Stop CBW,CSW Mode */
retValue = USBD_IFSetBulkOnlyMode(USBD_IF_CBWMODE | USBD_IF_CSWMODE,USBD_IF_DISABLE);
/* Event Off */
USBD_FuncSetEPxIntEvent(PrvAllocId,PrvBulkEPInfo[PRV_BULKIN].bEPNumber,0x00,0x00);
USBD_FuncSetEPxIntEvent(PrvAllocId,PrvBulkEPInfo[PRV_BULKOUT].bEPNumber,0x00,0x00);
if (PrvBulkEPInfo[PRV_BULKIN].bState != PRV_STALL_STATE) {
PrvBulkEPInfo[PRV_BULKIN].bState = PRV_IDLE_STATE;
if (PrvBulkEPInfo[PRV_BULKIN].bUseDMA == 0) {
USBD_FuncEPxPIOSimpleTransferAbort(PrvAllocId,PrvBulkEPInfo[PRV_BULKIN].bEPNumber);
} else {
PrvBulkEPInfo[PRV_BULKIN].bUseDMA = 0;
USBD_FuncEndEPxDMATransfer(PrvBulkEPInfo[PRV_BULKIN].bEPNumber);
}
USBD_FuncSetEPxControl(PrvBulkEPInfo[PRV_BULKIN].bEPNumber,USBD_FUNC_CE_NAKMODE,USBD_FUNC_FLAG_SET);
USBD_FuncSetEPxControl(PrvBulkEPInfo[PRV_BULKIN].bEPNumber,USBD_FUNC_CE_FIFOCLEAR|USBD_FUNC_CE_STALLMODE,USBD_FUNC_FLAG_CLR);
}
if (PrvBulkEPInfo[PRV_BULKOUT].bState != PRV_STALL_STATE) {
PrvBulkEPInfo[PRV_BULKOUT].bState = PRV_IDLE_STATE;
if (PrvBulkEPInfo[PRV_BULKOUT].bUseDMA == 0) {
USBD_FuncEPxPIOSimpleTransferAbort(PrvAllocId,PrvBulkEPInfo[PRV_BULKOUT].bEPNumber);
} else {
PrvBulkEPInfo[PRV_BULKOUT].bUseDMA = 0;
USBD_FuncEndEPxDMATransfer(PrvBulkEPInfo[PRV_BULKOUT].bEPNumber);
}
USBD_FuncSetEPxControl(PrvBulkEPInfo[PRV_BULKOUT].bEPNumber,USBD_FUNC_CE_NAKMODE,USBD_FUNC_FLAG_SET);
USBD_FuncSetEPxControl(PrvBulkEPInfo[PRV_BULKOUT].bEPNumber,USBD_FUNC_CE_FIFOCLEAR|USBD_FUNC_CE_STALLMODE,USBD_FUNC_FLAG_CLR);
}
break;
default:
/* It doesn't come here */
break;
}
break;};
return retValue;
}
/* =============================================================================
// Function_Name: USBD_ProtStorageGetCommand
// description : Get ATAPI command which has been received from the host
// argument : cmd Address used to save command which will be got
// return : Finished normally STATUS_SUCCESS
// flag :
// global :
// =============================================================================
*/
LONG USBD_ProtStorageGetCommand(USBD_PROT_STORAGE_CMD *cmd)
{
LONG retValue;
ULONG size;
retValue = STATUS_SUCCESS;
while (1) {
/* Get the Command */
if ((PrvCBW[12] & 0x80) != 0x00) {
/* Bulk IN */
cmd->bXferDir = USBD_PROT_STORAGE_BULKIN;
} else {
/* Bulk OUT */
cmd->bXferDir = USBD_PROT_STORAGE_BULKOUT;
}
size = PrvCBW[11];size <<= 8;
size += PrvCBW[10];size <<= 8;
size += PrvCBW[ 9];size <<= 8;
size += PrvCBW[ 8];
cmd->dwXferSize = size;
cmd->bLUN = PrvCBW[13] & 0x0F;
memset(cmd->pbCommand,0x00,PRV_MAX_CMD_LEN); /* Clear */
memcpy(cmd->pbCommand,PrvCBW + 15,(PrvCBW[14] & 0x1F)); // Mod for USBCV MSC Test
break;};
return retValue;
}
/* =============================================================================
// Function_Name: USBD_ProtStorageSetCommandStatus
// description : Set status of CSW command which will be sent to the host
// argument : xferedSize Number of bytes which has been sent
// : status USBD_PROT_STORAGE_COMMAND_SUCCESS Normal
// USBD_PROT_STORAGE_COMMAND_FAIL Error
// xferedSize Number of bytes which has been sent
// return : Finished normally STATUS_SUCCESS
// flag :
// global :
// =============================================================================
*/
LONG USBD_ProtStorageSetCommandStatus(ULONG xferedSize,UCHAR status)
{
LONG retValue;
UCHAR abortFlag;
UCHAR epx;
ULONG size;
retValue = STATUS_SUCCESS;
abortFlag = FALSE;
while (1) {
if ((PrvCBW[12] & 0x80) != 0x00) {
/* Bulk IN */
size = PrvBulkEPInfo[PRV_BULKIN].dwReqXferSize;
} else {
/* Bulk OUT */
size = PrvBulkEPInfo[PRV_BULKOUT].dwReqXferSize;
}
if (xferedSize > size) {
/* When Number of bytes which has been transferred is more than number of bytes which has been requested to transfer from the host */
retValue = STATUS_INVALID_PARAMETER;
break;
}
PrvCSWResidue = size - xferedSize;
/* Set status of CSW */
switch (status) {
case USBD_PROT_STORAGE_COMMAND_SUCCESS:
SET_BIT(PrvInternalStatus,PRV_IR_CSW_READY);
PrvCSW[12] = 0x00; /* Command Success */
break;
case USBD_PROT_STORAGE_COMMAND_FAIL:
case USBD_PROT_STORAGE_PHASE_ERR:
CLR_BIT(PrvInternalStatus,PRV_IR_CSW_READY);
if (PrvBulkEPInfo[PRV_BULKIN].bState == PRV_DATA_STATE) {
/* Abort the transfer if it is on transferring of Bulk IN data */
PrvBulkEPInfo[PRV_BULKIN].bState = PRV_ABORT_STATE;
USBD_FuncEPxPIOSimpleTransferAbort(PrvAllocId,PrvBulkEPInfo[PRV_BULKIN].bEPNumber);
abortFlag = TRUE;
}
if (PrvBulkEPInfo[PRV_BULKOUT].bState == PRV_DATA_STATE) {
/* Abort the transfer if it is on transferring of Bulk OUT data */
PrvBulkEPInfo[PRV_BULKOUT].bState = PRV_ABORT_STATE;
USBD_FuncEPxPIOSimpleTransferAbort(PrvAllocId,PrvBulkEPInfo[PRV_BULKOUT].bEPNumber);
abortFlag = TRUE;
}
if (abortFlag == FALSE) {
/* Before transfer of data */
if ((PrvCBW[12] & 0x80) != 0x00) {
epx = PRV_BULKIN;
} else {
epx = PRV_BULKOUT;
}
if (PrvBulkEPInfo[epx].dwReqXferSize > 0) {
/* If there are data to transfer */
PrvBulkEPInfo[epx].bState = PRV_ABORT_STATE;
/* (v) Set to TotalXferSize, in order to Stall */
PrvBulkEPInfo[epx].dwTotalXferSize = PrvBulkEPInfo[epx].dwReqXferSize;
if (epx == PRV_BULKIN) {
SET_BIT(PrvInternalStatus,PRV_IR_BULKIN_TRANSFER_END);
} else {
SET_BIT(PrvInternalStatus,PRV_IR_BULKOUT_TRANSFER_END);
}
}
}
/* Add for USBCV MSC Test */
if (status == USBD_PROT_STORAGE_COMMAND_FAIL) {
PrvCSW[12] = 0x01; /* Command Fail */
} else {
PrvCSW[12] = 0x02; /* Phase Error */
}
/* End of USBCV MSC Test */
SET_BIT(PrvInternalStatus,PRV_IR_CSW_READY);
break;
default:
/* It doesn't come here */
break;
}
break;};
return retValue;
}
/* =============================================================================
// Function_Name: USBD_ProtStorageRequestSuccess
// description : Be used when request of Mass Storage Class had been received
// argument : None
// return : Finished normally STATUS_SUCCESS
// Finished abnormally STATUS_UNSUCCESSFUL
// flag :
// global :
// =============================================================================
*/
LONG USBD_ProtStorageRequestSuccess(void)
{
LONG retValue,tempRet;
retValue = STATUS_UNSUCCESSFUL;
while (1) {
if (IS_BIT(PrvBulkOnlyStatus,USBD_PROT_STORAGE_BULKONLYRESET) == TRUE) {
CLR_BIT(PrvBulkOnlyStatus,USBD_PROT_STORAGE_BULKONLYRESET);
/* If Mass Storage Reset had been received, do Status Stage */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -