📄 dobotmsclass.c
字号:
/*
****************************************************************************
H I T A C H I P R O P R I E T A R Y
COPYRIGHT (c) 2001 BY Semiconductor & Integrated Circuits,Hitachi,Ltd.
--- ALL RIGHTS RESERVED ---
File Name :DoBOTMSClass.c
Working :Executing MassStorageClass Bulk-Only transfer
Modified :Rev 2001_10_15 {Author : T.Ishikawa}
Modified :Rev 2001_09_28 {Author : T.Ishikawa}
Created :Rev 1.0 {Author : T.Ishikawa[2001.Jan.10]}
****************************************************************************
*/
#include <machine.h>
#include "CatProType.h"
#include "sci.h"
#include "flashdisk.h"
extern DATA_BUFF Cache[];
extern EpInfoType *epinfo_ptr[];
extern volatile unsigned char write_protect;
extern volatile unsigned char report_wp;
unsigned short Delaytime=50,OperateCode=0;
/* Prototype */
void DecStandardCommands(void);
enum DecControlCmdDoneType DecVenderCommands(void);
enum DecControlCmdDoneType DecBOTClassCommands(void);
void ActControl(unsigned long,unsigned char,unsigned char);
void ActControlIn(unsigned long,unsigned char);
void ActControlOut(unsigned long,unsigned char);
void ActControlInOut(unsigned long,unsigned char,unsigned char);
short ActBulkOut(unsigned long,unsigned char,unsigned char);
short ActBulkIn(unsigned long,unsigned char,unsigned char);
void ActBulkOnly(unsigned long ,unsigned char ,unsigned char );
void ActBulkOnlyCommand(unsigned long ,unsigned char );
void ActBulkOnlyIn(unsigned long ,unsigned char );
void ActBulkOnlyOut(unsigned long ,unsigned char );
// DMA transfer for RAM->FIFO
short ActBulkIn_DMA(unsigned long interruptBitStreamLVar ,unsigned char epInfoNumberLVar ,unsigned char dataBuffNumberLVar);
short ActBulkOut_DMA(unsigned long interruptBitStreamLVar ,unsigned char epInfoNumberLVar ,unsigned char dataBuffNumberLVar);
/* Contents */
/***************************************************************************
Function Name :ActBulkOnly(unsigned long ,unsigned char ,unsigned char )
Working :Executing Bulk-Only Transport State
Return Value :void
Modified :{Author : T.Ishikawa[2001.Oct.15]}
Modified :{Author : T.Ishikawa[2001.Aug.09]}
Created :{Author : T.Ishikawa[2001.Jan.10]}
***************************************************************************/
void ActBulkOnly(unsigned long interruptBitStreamLVar ,unsigned char epInfoNumberLVar ,unsigned char dataBuffNumberLVar)
{
register unsigned char PState = EpInfo[USE_OUT_EP].PresentState;
if (PState == TRANS_OUT)
{ /* BOT's data stage is TRANS_OUT */
ActBulkOnlyOut(interruptBitStreamLVar,USE_OUT_EP);
}
else if (PState == TRANS_IN)
{ /* BOT's data stage is TRANS_IN */
ActBulkOnlyIn(interruptBitStreamLVar,USE_IN_EP);
}
else if ((PState == WAIT) && (interruptBitStreamLVar & EP_BOT_FULL_BIT))
{ /* BOT's data stage is WAIT and occurring EP1_FULL interrupt */
ActBulkOnlyCommand(interruptBitStreamLVar,USE_OUT_EP);
}
else
{ /* not apply */
/* clear EP2_TR flag */
/* clear EP_BOT_IN_TR flag */
BULK_ITFF_CLEAR
}
}
/***************************************************************************
Function Name :ActBulkOnlyCommand(unsigned long ,unsigned char )
Working :Executing Bulk-Only Transport CBW
Return Value :void
Modified :{Author : T.Ishikawa[2001.Aug.09]}
Created :{Author : T.Ishikawa[2001.Jan.10]}
***************************************************************************/
void ActBulkOnlyCommand(unsigned long interruptBitStreamLVar ,unsigned char epInfoNumberLVar)
{
short byteLVar = 0;
if ((EpInfo[USE_OUT_EP].PresentState != WAIT) || !(interruptBitStreamLVar & EP1_FULL_BIT))
return;
/* clear interrupt flag */
BULK_OTSF_CLEAR
/* set up data buffer pointers */
BufPtr[CSWCBW_INFO].sPtr = &cbwDataGVar->byteVal[0];
BufPtr[CSWCBW_INFO].ePtr = &cbwDataGVar->byteVal[30] + 1;
/* read CBW */
byteLVar = ActBulkOut(interruptBitStreamLVar,epInfoNumberLVar,CSWCBW_INFO);
/* check CBW */
if ((byteLVar != 31) || (cbwDataGVar->cbwType.dCBWSignature != 0x55534243))
{ // (size isn't correct) or (CBW Header isn't correct)
BOT_IN_EP_STALL_ON
return;
}
/* make CSW */
cswDataGVar->cswMeaningType.dCSWSignature = 0x55534253;
cswDataGVar->cswMeaningType.dCSWTag = cbwDataGVar->cbwType.dCBWTag;
cswDataGVar->cswMeaningType.bCSWStatus = 0x00;
/* change CBW data transfer length from little endian to big endian */
/* becouse of recognizing HOST expectant data length */
cbwDataGVar->cbwType.dCBWDataTransferLength = ConvReflexn((unsigned char*)&cbwDataGVar->cbwType.dCBWDataTransferLength,4);
/* Control firmware state decoding CBW Data Transport direction */
if (cbwDataGVar->cbwType.bmCBWFlags == 0) {
/* Data direction is HOST to Function */
EpInfo[USE_OUT_EP].PresentState = TRANS_OUT;
/* mask EP_BOT_IN_EMPTY interrupt */
SET_BULK_IN_INTERRUPT2
/* enable EP_BOT_IN_TR interrupt */
SET_BULK_IN_INTERRUPT3
}
else {
/* Data direction is Function to HOST */
EpInfo[USE_OUT_EP].PresentState = TRANS_IN;
/* enable EP_BOT_IN_EMPTY interrupt */
SET_BULK_IN_INTERRUPT1
}
/* read Interrupt enable flag */
GET_INTERRUPT_ENABLE
/* decode to command and SCSI tansfer data length for HOST */
cswDataGVar->cswMeaningType.dCSWDataResidue = DecBotCmd();
if ((cbwDataGVar->cbwType.dCBWDataTransferLength == 0) && (cswDataGVar->cswMeaningType.dCSWDataResidue != 0)) {
/* HOST expectant data length = 0 and Function expectant data length != 0 */
cswDataGVar->cswMeaningType.bCSWStatus = 0x02;
}
/* clear EP_BOT_IN_TR interrupt flag */
BULK_ITFF_CLEAR
}
/***************************************************************************
Function Name :ActBulkOnlyIn(unsigned long ,unsigned char )
Working :Executing Data Transport and Status Transport
:in case data stage direction is IN
Return Value :void
Modified :{Author : T.Ishikawa[2001.Aug.09]}
Created :{Author : T.Ishikawa[2001.Jan.10]}
***************************************************************************/
void ActBulkOnlyIn(unsigned long interruptBitStreamLVar ,unsigned char epInfoNumberLVar)
{
short byteLVar = 0;
//SCI_Str("\r\nABOI-");
if (cbwDataGVar->cbwType.dCBWDataTransferLength != 0)
{ /* exist transfer data Data Transport */
if ((cswDataGVar->cswMeaningType.bCSWStatus == 0x00) && (cswDataGVar->cswMeaningType.dCSWDataResidue >= epinfo_ptr[epInfoNumberLVar]->MaxPacketSize))
{ /* status is 0x00 and transfer data size is over MaxPacketSize */
//*** transfer data from RAM->FIFO by DMA request
//*** remember the size must be modular of 512
if (Cache->ReadCache.Modified != 0)
byteLVar = ActBulkIn_DMA(interruptBitStreamLVar,USE_IN_EP,DATA_INFO);
else
//** for not Flash Memory Access and transfer data > max. end-point size
byteLVar = ActBulkIn(interruptBitStreamLVar,USE_IN_EP,DATA_INFO);
/* calculate data length */
cbwDataGVar->cbwType.dCBWDataTransferLength -= byteLVar;
cswDataGVar->cswMeaningType.dCSWDataResidue -= byteLVar;
}
else if (cswDataGVar->cswMeaningType.bCSWStatus != 0x00)
{ /* there is no transfer data , Function transfers data all 0 value up to HOST expectant data length */
/* set up data buffer pointers */
BufPtr[DATA_INFO].sPtr = &returnData->byteVal[0];
BufPtr[DATA_INFO].ePtr = &returnData->byteVal[cbwDataGVar->cbwType.dCBWDataTransferLength];
byteLVar = ActBulkIn(interruptBitStreamLVar,USE_IN_EP,DATA_INFO);
/* calculate data length */
cbwDataGVar->cbwType.dCBWDataTransferLength -= byteLVar;
cswDataGVar->cswMeaningType.dCSWDataResidue -= byteLVar;
}
else
{ /* another case */
/* copy transfer data to work area */
while (byteLVar < cswDataGVar->cswMeaningType.dCSWDataResidue)
{
returnData->byteVal[byteLVar] = *BufPtr[DATA_INFO].sPtr;
byteLVar++;
BufPtr[DATA_INFO].sPtr++;
}
/* set 0 redidue work area */
while ((byteLVar <= cbwDataGVar->cbwType.dCBWDataTransferLength) && (byteLVar <= EpInfo[epInfoNumberLVar].MaxPacketSize)) {
returnData->byteVal[byteLVar] = 0x00;
byteLVar++;
}
/* set up data buffer pointers */
BufPtr[DATA_INFO].sPtr = &returnData->byteVal[0];
BufPtr[DATA_INFO].ePtr = &returnData->byteVal[cbwDataGVar->cbwType.dCBWDataTransferLength];
if (cbwDataGVar->cbwType.dCBWDataTransferLength > 64)
BufPtr[DATA_INFO].ePtr = &returnData->byteVal[64];
byteLVar = ActBulkIn(interruptBitStreamLVar,USE_IN_EP,DATA_INFO);
/* calculate data length */
cbwDataGVar->cbwType.dCBWDataTransferLength -= byteLVar;
cswDataGVar->cswMeaningType.dCSWDataResidue -= byteLVar;
/* clear work area */
for(byteLVar=0; byteLVar<16; byteLVar++) // buffer size = 64
returnData->longVal[byteLVar] = 0x00000000;
}
}
else
{ /* not exist transfer data Status Transport */
/* mask EP_BOT_IN_EMPTY interrupt */
SET_BULK_IN_INTERRUPT2
/* get interrupt enable flag */
GET_INTERRUPT_ENABLE
/* set up data buffer pointers */
BufPtr[CSWCBW_INFO].sPtr = &cswDataGVar->byteVal[0];
BufPtr[CSWCBW_INFO].ePtr = &cswDataGVar->byteVal[13];
if ((cswDataGVar->cswMeaningType.bCSWStatus == 0x00) && (cswDataGVar->cswMeaningType.dCSWDataResidue > 0))
{ /* Transfered data is over Function expectant data length */
/* Status is set 0x02 */
cswDataGVar->cswMeaningType.bCSWStatus = 0x02;
}
if (cswDataGVar->cswMeaningType.dCSWDataResidue < 0){
cswDataGVar->cswMeaningType.dCSWDataResidue = ~cswDataGVar->cswMeaningType.dCSWDataResidue;
cswDataGVar->cswMeaningType.dCSWDataResidue++;
}
/* change CSWDataResidue to little endian */
cswDataGVar->cswMeaningType.dCSWDataResidue = ConvReflexn((unsigned char*)&cswDataGVar->cswMeaningType.dCSWDataResidue,4);
/* transfer CSW and complete BOT */
ActBulkIn(0,USE_IN_EP,CSWCBW_INFO);
/* state is set "WAIT" */
EpInfo[USE_OUT_EP].PresentState = WAIT;
}
//SCI_Str("RTS");
}
/***************************************************************************
Function Name :ActBulkOnlyOut(unsigned long ,unsigned char )
Working :Executing Data Transport and Status Transport
:in case data stage direction is OUT
Return Value :void
Modified :{Author : T.Ishikawa[2001.Aug.09]}
Created :{Author : T.Ishikawa[2001.Jan.10]}
***************************************************************************/
void ActBulkOnlyOut(unsigned long interruptBitStreamLVar ,unsigned char epInfoNumberLVar)
{
//SCI_Str("\r\nActBOO-");
//SCI_Str("\r\nABO");
unsigned int i,temp;
if ((interruptBitStreamLVar & EP_BOT_FULL_BIT) == EP_BOT_FULL_BIT)
{ /* EP_BOT_OUT_FULL interrupt ? Data Transport */
/* clear Bulk Out EP TS interrupt flag */
BULK_OTSF_CLEAR
short byteLVar = 0;
short receiveByteLVar = *EpInfo[epInfoNumberLVar].FifoSize;
if (cswDataGVar->cswMeaningType.bCSWStatus == 0x00)
{ /* can put away in data buffer ? */
//*** transfer data from FIFO->RAM by DMA request
//*** remember the size must be modular of 512
byteLVar = ActBulkOut_DMA(interruptBitStreamLVar,epInfoNumberLVar,DATA_INFO);
/* calculate data length */
cbwDataGVar->cbwType.dCBWDataTransferLength -= byteLVar;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -