www.pudn.com > UDISK.rar > UFI.C


//************************************************************************ 
//author:dragon 
//web:8dragon.com 
//2004.2.5完成于桃龙源 
//************************************************************************* 
#include "AT89X52.h" 
#include "host_811.h" 
#include "ufi.h" 
BLOCK  idata BlockCommand; 
extern idata USBDEV uDev; 
extern BYTE bBUF[256]; 
//********************************************************************* 
//*底层的批量传输函数 
//********************************************************************* 
BYTE BulkOut(BYTE *pbBuffer,UINT len,UINT lba) 
{ 
	WORD j; 
	//////////////////////////////////////////////////////////////////////// 
	while(len>0) 
	{ 
		if (len >64) 
			j = 64; 
		else				 
			j= len; 
		if(!usbXfer(0x01,uDev.bEpOut,PID_OUT,64,j,pbBuffer))  
			return FALSE; 
		len-=j; 
		pbBuffer=pbBuffer+j; 
	} 
	return TRUE; 
} 
BYTE BulkIn(BYTE *pbBuffer,UINT len) 
{ 
	BYTE i; 
	//////////////////////////////////////////////////////////////////////// 
	if(len) 
	{ 
		i=100; 
		while(!usbXfer(0x01,uDev.bEpin,PID_IN,64,len,pbBuffer)) 
		{ 
			 i--; 
		 } 
		if(i<=0) 
		  return FALSE; 
	} 
	return TRUE; 
} 
//********************************************************************** 
//获取U盘的硬件信息 
//********************************************************************** 
BYTE Inquiry(void) 
{ 
	BlockCommand.CbwBlock.dCBW_Signature=CBW_SIGNATURE; 
	BlockCommand.CbwBlock.dCBW_Tag=0x60a624de; 
	BlockCommand.CbwBlock.dCBW_DataXferLen=0x24000000; 
	BlockCommand.CbwBlock.bCBW_Flag=0x80; 
	BlockCommand.CbwBlock.bCBW_LUN=0; 
	BlockCommand.CbwBlock.bCBW_CDBLen=sizeof(INQUIRY); 
	//----------------------------------------------------------------- 
	//包含在CBWCB中的Inquiry命令 
	//------------------------------------------------------------------ 
	BlockCommand.CbwBlock.CBWCommand.Ufi_Inquiry.OperationCode=UFI_CMD_INQUIRY; 
	BlockCommand.CbwBlock.CBWCommand.Ufi_Inquiry.Reserved0=0; 
	BlockCommand.CbwBlock.CBWCommand.Ufi_Inquiry.PageCode=0; 
	BlockCommand.CbwBlock.CBWCommand.Ufi_Inquiry.AllocationLen=0x24; 
	DelayMs(20); 
	if(!BulkOut((BYTE *)&BlockCommand.CbwBlock,sizeof(BlockCommand.CbwBlock))) 
		return FALSE;	 
	DelayMs(20); 
	if(!BulkIn(bBUF,38)) 
		return FALSE; 
	if(!BulkIn((BYTE *)&BlockCommand.CswBlock,13)) 
		return FALSE; 
	return TRUE;	 
} 
//********************************************************************** 
//测试U盘是否可用www.8dragon.com 
//********************************************************************** 
BYTE TestUnit(void) 
{ 
	BlockCommand.CbwBlock.dCBW_Signature=CBW_SIGNATURE; 
	BlockCommand.CbwBlock.dCBW_Tag=0x60a624de; 
	BlockCommand.CbwBlock.dCBW_DataXferLen=0x00000000; 
	BlockCommand.CbwBlock.bCBW_Flag=0x00; 
	BlockCommand.CbwBlock.bCBW_LUN=0; 
	BlockCommand.CbwBlock.bCBW_CDBLen=sizeof(TEST_UNIT); 
	//----------------------------------------------------------------- 
	//包含在CBWCB中的TestUnit命令 
	//------------------------------------------------------------------ 
	BlockCommand.CbwBlock.CBWCommand.Ufi_TestUnit.OperationCode=UFI_CMD_TESTUNITREADY; 
	DelayMs(70); 
	if(!BulkOut((BYTE *)&BlockCommand.CbwBlock,sizeof(BlockCommand.CbwBlock))) 
		return FALSE; 
	DelayMs(150); 
	if(!BulkIn((BYTE *)&BlockCommand.CswBlock,13)) 
		return FALSE; 
	return TRUE; 
} 
//********************************************************************** 
//让U盘传回必要数据 
//********************************************************************** 
BYTE RequestSense(void) 
{ 
	BlockCommand.CbwBlock.dCBW_Signature=CBW_SIGNATURE; 
	BlockCommand.CbwBlock.dCBW_Tag=0x60a624de; 
	BlockCommand.CbwBlock.dCBW_DataXferLen=0x0e000000; 
	BlockCommand.CbwBlock.bCBW_Flag=0x80; 
	BlockCommand.CbwBlock.bCBW_LUN=0; 
	BlockCommand.CbwBlock.bCBW_CDBLen=sizeof(REQUEST_SENSE); 
	//----------------------------------------------------------------- 
	//包含在CBWCB中的RSEQUESTSENS命令 
	//------------------------------------------------------------------	 
	BlockCommand.CbwBlock.CBWCommand.Ufi_RequestSense.OperationCode=UFI_CMD_REQUESTSENSE; 
	BlockCommand.CbwBlock.CBWCommand.Ufi_RequestSense.AllocationLen=0x0e; 
	DelayMs(45); 
	if(!BulkOut((BYTE *)&BlockCommand.CbwBlock,sizeof(BlockCommand.CbwBlock),0)) 
		return FALSE; 
	DelayMs(45); 
	if(!BulkIn((BYTE *)bBUF,18)) 
		return FALSE; 
	DelayMs(45); 
	if(!BulkIn((BYTE *)&BlockCommand.CswBlock,13)) 
		return FALSE; 
	return TRUE;	 
} 
//********************************************************************** 
//读取已格U盘的容量 
//********************************************************************** 
BYTE ReadCapacity(void) 
{ 
	BlockCommand.CbwBlock.dCBW_Signature=CBW_SIGNATURE; 
	BlockCommand.CbwBlock.dCBW_Tag=0x60a624de; 
	BlockCommand.CbwBlock.dCBW_DataXferLen=0x08000000; 
	BlockCommand.CbwBlock.bCBW_Flag=0x80; 
	BlockCommand.CbwBlock.bCBW_LUN=0;	 
	//BlockCommand.CbwBlock.CBW_CDBLen=sizeof(READ_CAPACITY); 
	BlockCommand.CbwBlock.bCBW_CDBLen=sizeof(READ_CAPACITY); 
	//----------------------------------------------------------------- 
	//包含在CBWCB中的READCAPACITY命令 
	//------------------------------------------------------------------	 
	BlockCommand.CbwBlock.CBWCommand.Ufi_ReadCapacity.OperationCode=UFI_CMD_READCAPACITY; 
	DelayMs(45); 
	if(!BulkOut((BYTE *)&BlockCommand.CbwBlock,sizeof(BlockCommand.CbwBlock),0)) 
		return FALSE; 
	DelayMs(45); 
	if(!BulkIn((BYTE *)bBUF,8)) 
		return FALSE; 
	DelayMs(45); 
	if(!BulkIn((BYTE *)&BlockCommand.CswBlock,13)) 
		return FALSE;	 
	return TRUE; 
} 
//********************************************************************** 
//读取U盘中的数据 
//********************************************************************** 
BYTE Read(DWORD dlba,BYTE blen,BYTE *pbBuffer) 
{	BYTE i; 
	//////////////////////////////////////////////////////////////////////// 
	BlockCommand.CbwBlock.dCBW_Signature=CBW_SIGNATURE; 
	BlockCommand.CbwBlock.dCBW_Tag=0x60a624de; 
	BlockCommand.CbwBlock.dCBW_DataXferLen=DWordSwap(blen*512); 
	BlockCommand.CbwBlock.bCBW_Flag=0x80; 
	BlockCommand.CbwBlock.bCBW_LUN=0; 
	BlockCommand.CbwBlock.bCBW_CDBLen=sizeof(READ); 
	//----------------------------------------------------------------- 
	//包含在CBWCB中的READ命令 
	//------------------------------------------------------------------ 
	BlockCommand.CbwBlock.CBWCommand.Ufi_Read.OperationCode=UFI_CMD_READ; 
	BlockCommand.CbwBlock.CBWCommand.Ufi_Read.Reserved1=0; 
	BlockCommand.CbwBlock.CBWCommand.Ufi_Read.LBA=dlba; 
	BlockCommand.CbwBlock.CBWCommand.Ufi_Read.ReadLength=blen; 
	DelayMs(100); 
	if(!BulkOut((BYTE *)&BlockCommand.CbwBlock,sizeof(BlockCommand.CbwBlock),0)) 
		return FALSE; 
	i=100; 
	while(i--) 
	{ 
		DelayMs(1); 
		if(BulkIn(pbBuffer,blen*512)) 
			break; 
	}	 
	if(i==0) 
		return FALSE; 
	DelayMs(2); 
	if(!BulkIn((BYTE *)&BlockCommand.CswBlock,13)) 
		return FALSE; 
	return TRUE; 
} 
//********************************************************************** 
//写数据到U盘 
//********************************************************************** 
BYTE Write(DWORD dlba,BYTE blen,BYTE *pbBuffer,BYTE bWaitTime) 
{ 
	BYTE i; 
	//////////////////////////////////////////////////////////////////////// 
	BlockCommand.CbwBlock.dCBW_Signature=CBW_SIGNATURE; 
	BlockCommand.CbwBlock.dCBW_Tag=0xb4d977c1; 
	BlockCommand.CbwBlock.dCBW_DataXferLen=DWordSwap(blen*512); 
	BlockCommand.CbwBlock.bCBW_Flag=0x0; 
	BlockCommand.CbwBlock.bCBW_LUN=0; 
	BlockCommand.CbwBlock.bCBW_CDBLen=sizeof(WRITE); 
	//----------------------------------------------------------------- 
	//包含在CBWCB中的WRITE命令 
	//------------------------------------------------------------------ 
	BlockCommand.CbwBlock.CBWCommand.Ufi_Write.OperationCode=UFI_CMD_WRITE; 
	BlockCommand.CbwBlock.CBWCommand.Ufi_Write.Reserved1=0; 
	BlockCommand.CbwBlock.CBWCommand.Ufi_Write.LBA=dlba; 
	BlockCommand.CbwBlock.CBWCommand.Ufi_Write.WriteLength=blen; 
	BlockCommand.CbwBlock.CBWCommand.Ufi_Write.Reserved2=0;	 
	if(!BulkOut((BYTE *)&BlockCommand.CbwBlock,sizeof(BlockCommand.CbwBlock),0))	 
		return FALSE; 
	//DelayMs(bwaittime);	 
	DelayMs(200); 
	if(!BulkOut(pbBuffer,512*blen,dlba)) 
		return FALSE;				 
	i=10; 
	while(i--) 
	{ 
		if(BulkIn((BYTE *)&BlockCommand.CswBlock,13)) 
			break; 
	} 
	if(i==0) 
		return FALSE; 
	return TRUE;	 
} 
BYTE PollDisk(void) 
{ 
	//也许需要延长一定的时间,在每个测试参数后面 
//	BYTE Cache[512]; 
//	BYTE i; 
	DelayMs(100); 
	if(!Inquiry()) 
		return FALSE; 
	if(!TestUnit()) 
		return FALSE; 
	if(!RequestSense()) 
		return FALSE; 
	if(!TestUnit()) 
		return FALSE; 
	if(!ReadCapacity()) 
		return FALSE;	 
	if(!RequestSense()) 
		return FALSE; 
	if(!TestUnit()) 
		return FALSE; 
	if(!ReadCapacity()) 
		return FALSE;	 
	if(!TestUnit()) 
        return FALSE; 
    if(!RequestSense()) 
		return FALSE; 
 
	return TRUE; 
} 
//************************************************************************ 
//author:dragon 
//web:8dragon.com 
//2004.2.5完成于桃龙源 
//*************************************************************************