⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tpbulk.c

📁 ertfs文件系统里面既有完整ucos程序
💻 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<len; 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<Di*/
	case CASE3:     /* Hn<Do*/

		//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<Di*/
	case CASE8:     /* Hi<>Do */

		//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:    /* Ho<>Di */
	case CASE13:    /* Ho<Do*/

		//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<13; 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 <= 10 \
        && TPBulk_CBW.bCBW_CDBLen <= MAX_CDBLEN )
		return(1);
	else
		return(0);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -