ertfs文件系统里面既有完整ucos程序
源代码在线查看: tpbulk.c
/***********************************************************************
* $Workfile: tpbulk.c $
* $Revision: 1.3 $
* $Author: meterchen $
* $Date: 2003/08/25 14:03:12 $
*
* Project: TianGuang-udisk
*
* Description:
* USB Mass Storage
* Class Spec 1.0 Oct. 1998
* Bulk Only Transport 1.0 Jun.21 1999
* Notes:
* 3. Share Mem between CBW & CSW to minimize Operations as well as RAM
* 2. CSW structure size is 13[0xd] bytes
* 1. bInterfaceProtocol for Bulk-Only Transport
* 0x50 = 'P'
*
* Revision History:
*
***********************************************************************
*
* Copyright (c) 2003 CHENMENG
*
* All rights reserved
*
**********************************************************************/
#include "BasicTyp.h"
#include "def9603.h"
#include "macro.h"
#include "bitops.h"
extern UINT8 dtapid; /* PID related status */
#define TGL0PID BIT0 /* tracks NEXT data PID for endpoint0*/
#define TGL1PID BIT1 /* tracks NEXT data PID for endpoint1*/
#define TGL2PID BIT2 /* tracks NEXT data PID for endpoint2*/
#define TGL3PID BIT3 /* tracks NEXT data PID for endpoint3*/
#include "SCSI2Cmd.h"
#include "SCSI2.h"
#include "TPBulk.h"
// Bulk-Only TP Finite State Machine [One-Hot]
INT8 BOTFSMstate;
#define BOTFSM_CBWProc 0x0
#define BOTFSM_DataIn 0x1
#define BOTFSM_DataOut 0x2
#define BOTFSM_CSWProc 0x3
#define BOTFSM_CSW 0x4
#define BOTFSM_IDLE 0x5
#define BOTFSM_Stall 0x6
INT32 BOTXfer_wResidue;
INT8 * BOTXfer_pData;
// BOT FSM
// IDLE Stage -> CBW -> CBW Proc -> DATA OUT Stage -> CSW Proc -> CSW Stage -> IDLE
// IDLE Stage -> CBW -> CBW Proc -> DATA IN Stage -> CSW Proc -> CSW Stage -> IDLE
// STALL Stage -> IDLE
//
INT8 BOTBF_StallAtBulkOut;
INT8 BOTBF_StallAtBulkIn;
TPBLK_STRUC TPBulk_Block;
#define TPBulk_CBW TPBulk_Block.TPBulk_CommandBlock
#define SCSI2_CDB TPBulk_CBW.cdbSCSI2
#define SCSI2_LUN TPBulk_CBW.bCBW_LUN
#define TPBulk_CSW TPBulk_Block.TPBulk_CommandStatus
/*
* read from 9603's recv ep1
* it is not so necessary
*/
INT8 USB_ReadEndpoint(INT8 endp, INT8 len, INT8 * buf)
{
INT8 i;
if(endp == 1)
{
for(i=0; i *buf++ = read_usb(RXD1);
}
return i;
}
/*
*************************************************************************
Bulk-Only TP-Bulk Hanlder
*************************************************************************
*/
void TPBulk_CBWHandler( void )
{
/*
* Get CBW
*/
if( 64 == USB_ReadEndpoint(1,64,(PINT8)&(TPBulk_CBW)) )
{
if(TPBulksup_IsCBWValid())
{
/*
* for Valid CBW
*/
SCSI2_Handler();
return;
}
}
/*
* for Invalid CBW
* Stall Both Bulk Endpoints
* Let host goto reset recovery sequence
*/
TPBulksup_ErrorHandler(CASECBW,0);
SCSI2_BuildSenseData(SCSI_SENSE_ILLEGAL_REQUEST,SCSI_ADSENSE_ILLEGAL_COMMAND,0);
TPBulk_CSWHandler();// Goto USBFSM4BOT_CSWPROC;
}
void TPBulksup_ErrorHandler(INT8 HostDevCase,INT16 wByteCounterDevWillXfer)
{
TPBulk_CSW.dCSW_DataResidue = TPBulk_CBW.dCBW_DataXferLen - wByteCounterDevWillXfer;
switch(HostDevCase)
{
case CASEOK:
case CASE1: /* Hn=Dn*/
case CASE6: /* Hi=Di*/
TPBulk_CSW.bCSW_Status = CSW_GOOD;
break;
case CASE12: /* Ho=Do*/
TPBulk_CSW.bCSW_Status = CSW_GOOD;
break;
case CASE2: /* Hn case CASE3: /* Hn
//BOTBF_StallAtBulkIn = 1; // may or may-not
TPBulk_CSW.bCSW_Status = CSW_PHASE_ERROR;
break;
case CASE4: /* Hi>Dn*/
case CASE5: /* Hi>Di*/
//BOTBF_StallAtBulkIn = 1;
TPBulk_CSW.bCSW_Status = CSW_FAIL;//CSW_GOOD or CSW_FAIL
break;
case CASE7: /* Hi case CASE8: /* HiDo */
//BOTBF_StallAtBulkIn = 1; // may or may-not
TPBulk_CSW.bCSW_Status = CSW_PHASE_ERROR;
break;
case CASE9: /* Ho>Dn*/
case CASE11: /* Ho>Do*/
//BOTBF_StallAtBulkOut = 1; // may or may-not
TPBulk_CSW.bCSW_Status = CSW_FAIL;//CSW_GOOD or CSW_FAIL
break;
case CASE10: /* HoDi */
case CASE13: /* Ho
//TBF_StallAtBulkIn = 1;// may or may-not
//TBF_StallAtBulkOut = 1;// may or may-not
TPBulk_CSW.bCSW_Status = CSW_PHASE_ERROR;
break;
case CASECBW: /* invalid CBW */
//BOTBF_StallAtBulkIn = 1;
//BOTBF_StallAtBulkOut = 1;
TPBulk_CSW.bCSW_Status = CSW_PHASE_ERROR;
break;
case CASECMDFAIL:
//BOTBF_StallAtBulkIn = 1;
TPBulk_CSW.bCSW_Status = CSW_FAIL;
break;
default:
break;
}
TPBulk_CSW.dCSW_Signature = CSW_SIGNATURE;
// TPBulk_CSW.dCSW_Tag = TPBulk_CBW.dCBW_Tag;
}
void TPBulk_CSWHandler( void )
{
INT8 i;
if(BOTBF_StallAtBulkIn)
{
//Hal4D12_SetEndpointStatus(5,1);//Bulk-In
// BOTFSMstate = USBFSM4BOT_STALL;
// BOTFSMstate =USBFSM4BOT_CSWPROC; //USBFSM4BOT_CSWPROC=0x10
TPBulk_CSW.dCSW_DataResidue += BOTXfer_wResidue;
//Xfer_Space &= BOTXFERSPACE_MASK;
//BOTXfer_atRAM = 1;
BOTXfer_pData = (PINT8) &TPBulk_CSW;
BOTXfer_wResidue = sizeof(CSW);
}
else if(BOTBF_StallAtBulkOut)
{
//Hal4D12_SetEndpointStatus(4,1);//Bulk-Out
BOTFSMstate = BOTFSM_Stall;
}
else
{
//TPBulk_CSW.dCSW_DataResidue += BOTXfer_wResidue;
//Xfer_Space &= BOTXFERSPACE_MASK;
//BOTXfer_atRAM = 1;
//BOTXfer_pData = (PINT8) &TPBulk_CSW;
//BOTXfer_wResidue = sizeof(CSW);
BOTFSMstate = BOTFSM_CSW;
}
if(BOTFSMstate == BOTFSM_CSW)
{
//Hal4Sys_D12CmdPortOutB( 0x05);// SelectEP BulkIn
//FlexByte = Hal4Sys_D12DataPortInB();
//if(FlexByte_b0 == 0) // BulkIn is empty
//{
// FlexByte = MLsup_XferPktFrMEM2USB();
// BOTXfer_pdata += FlexByte;
// BOTXfer_wResidue -= FlexByte;
// if(BOTXfer_wResidue == 0)
// BOTFSMstate = USBFSM4BOT_IDLE; // Goto BOTFSMstate_IDLE
//}
for(i=0; i write_usb(TXD1,((INT8 *)&TPBulk_CSW)[i]); /*send data to the tx1 FIFO */
TXEN1_PID; //enable TX, choose PID, and flip the data toggle
}
}
/*
*************************************************************************
Bulk Only Transport support functions
*************************************************************************
*/
BOOLEAN TPBulksup_IsCBWValid( void)
{
#ifdef BIG_ENDIAN
//TPBulk_CBW.dCBW_DataXferLen = Hal4Sys_SwapINT32(TPBulk_CBW.dCBW_DataXferLen);
#endif
if( TPBulk_CBW.dCBW_Signature == CBW_SIGNATURE \
&& TPBulk_CBW.bCBW_LUN && TPBulk_CBW.bCBW_CDBLen return(1);
else
return(0);
}