?? tpbulk.c
字號:
#include "SL811.H"
#include "TPBULK.H"
//#include "HAL.H"
//#include "HPI.H"
//#include "common.h"
//////////////////////////////////
extern BYTE DBUF[BUFFER_LENGTH];
extern XXGPKG usbstack;
extern SYS_INFO_BLOCK DeviceInfo;
extern FILE_INFO ThisFile;
TPBLK_STRUC TPBulk_Block;
BYTE MAXLUN;
#define TPBulk_CBW TPBulk_Block.TPBulk_CommandBlock
#define CBW_wXferLen TPBulk_CBW.dCBW_DataXferLen
#define RBC_CDB TPBulk_CBW.cdbRBC
#define RBC_LUN TPBulk_CBW.bCBW_LUN
#define TPBulk_CSW TPBulk_Block.TPBulk_CommandStatus
///////////////////////////////////////////////////////////////////////////
unsigned char EnumMassDev(void)
{
PMBR_BLOCK pMBR;
PBPB_BLOCK pBPB;
Uart_Printf("Enumerate MASS Device ...\n");
TPBulk_GetMaxLUN();
MAXLUN = DBUF[0];
////////////////////////////////////////////////////
if(!SPC_Inquiry())
return FALSE;
//if(!SPC_READLONG())
// return FALSE;
if(!SPC_TestUnit())
return FALSE;
if(!SPC_LockMedia())
return FALSE;
if(!SPC_RequestSense())
return FALSE;
/* if(!SPC_TestUnit())
return FALSE;*/
if(!RBC_ReadCapacity())
return FALSE;
////////////////////////////////////////////////////
DeviceInfo.BPB_BytesPerSec = DBUF[6]<<8+DBUF[7]; //每扇區字節數
Uart_Printf("BytesPerSec is %d\n",DeviceInfo.BPB_BytesPerSec);
/* if(!SPC_RequestSense())
return FALSE;
if(!SPC_TestUnit())
return FALSE;
if(!RBC_ReadCapacity())
return FALSE;*/
if(!RBC_Read(0x0,1,DBUF))//讀取MBR內容(主引導記錄)
return FALSE;
//////////////////////////////////
if(DBUF[0]==0xeb||DBUF[0]==0xe9)
{
DeviceInfo.StartSector=0;
//DeviceInfo.TotalSector=SwapINT32(pMBR->TotalSector);
}
else
{
//////////////////////////////////
DeviceInfo.StartSector=DBUF[455]<<8 | DBUF[454];//開始扇區
DeviceInfo.TotalSector=DBUF[461]<<24 | DBUF[460]<<16 | DBUF[459]<<8 | DBUF[458];//扇區總數
}
Uart_Printf("TotalSector is %d\n",DeviceInfo.TotalSector);
///////////////////////////////////////////////////////
// *pBPB=0xc0144a0;//(PBPB_BLOCK)DBUF;
if(!RBC_Read(DeviceInfo.StartSector,1,DBUF))//讀取DBR內容(系統引導記錄)
return FALSE;
DeviceInfo.BPB_BytesPerSec = DBUF[12]<<8 | DBUF[11];
DeviceInfo.BPB_SecPerClus = DBUF[13];//每簇扇區數
DeviceInfo.BPB_RsvdSecCn = DBUF[15]<<8 | DBUF[14];//從DBR到FAT的保留扇區數
DeviceInfo.BPB_NumFATs = DBUF[16];//FAT個數;
DeviceInfo.BPB_RootEntCnt = DBUF[45]<<8 | DBUF[44];//根目錄項數,FAT32為0
DeviceInfo.BPB_TotSec16 = DBUF[20]<<8 | DBUF[19];//小扇區數,FAT32為0;
DeviceInfo.BPB_FATSz16 = DBUF[39]<<24| DBUF[38]<<16 | DBUF[37]<<8 | DBUF[36];//每FAT扇區數;
DeviceInfo.BPB_HiddSec = DBUF[31]<<24 | DBUF[30]<<16 | DBUF[29]<<8 | DBUF[28];//隱藏扇區數
DeviceInfo.BPB_TotSec32 = DBUF[35]<<24 | DBUF[34]<<16 | DBUF[33]<<8 | DBUF[32];//總扇區數
DeviceInfo.BS_DrvNum = DBUF[36];
DeviceInfo.FatStartSector = DeviceInfo.StartSector + DeviceInfo.BPB_RsvdSecCn;//0619 +1
DeviceInfo.RootStartSector = DeviceInfo.FatStartSector + DeviceInfo.BPB_NumFATs * DeviceInfo.BPB_FATSz16;
//DeviceInfo.StartSector+2*DeviceInfo.BPB_FATSz16+1;
DeviceInfo.DataStartSector = DeviceInfo.FatStartSector + DeviceInfo.BPB_NumFATs * DeviceInfo.BPB_FATSz16;
//DeviceInfo.RootStartSector + (DeviceInfo.BPB_RootEntCnt>>4);
DeviceInfo.FirstDataSector = DeviceInfo.DataStartSector + 32;
//DeviceInfo.FirstSectorofCluster=;
Uart_Printf("TotalCapacity is %d KB\n",DeviceInfo.TotalSector * DeviceInfo.BPB_BytesPerSec / 1024);
Uart_Printf("DataCapacity is %d KB\n",(DeviceInfo.TotalSector - DeviceInfo.DataStartSector) * DeviceInfo.BPB_BytesPerSec / 1024);
///////////////////////////////////////////////////////
ThisFile.bFileOpen=0;
///////////////////////////////////////////////////////
return TRUE;
}
unsigned char TPBulk_GetMaxLUN(void)
{
usbstack.setup.bmRequest=0xa1;
usbstack.setup.bRequest=0xfe;
usbstack.setup.wValue=0;
usbstack.setup.wIndex=0;
usbstack.setup.wLength=1;
usbstack.buffer=DBUF;
return ep0Xfer();
}
unsigned char SPC_Inquiry(void)
{
#define cdbInquirySPC RBC_CDB.SpcCdb_Inquiry
BYTE i;
// RBC_CDB.SpcCdb_Inquiry.OperationCode = 0x12;
//unsigned char len;
//unsigned char retStatus=FALSE;
TPBulk_CBW.dCBW_Signature = CBW_SIGNATURE;
TPBulk_CBW.dCBW_Tag = 0x878bfa28;//0x60a624de;
TPBulk_CBW.dCBW_DataXferLen = 0x00000024;
TPBulk_CBW.bCBW_Flag = 0x80;
TPBulk_CBW.bCBW_LUN = MAXLUN;//0;
TPBulk_CBW.bCBW_CDBLen = 0x0C;//sizeof(INQUIRY_SPC);
for(i = 0;i<16;i++)
TPBulk_CBW.cdbRBC1[i]=0;
TPBulk_CBW.cdbRBC1[0]=0x12;
TPBulk_CBW.cdbRBC1[4]=0x24;
/////////////////////////////////
/* cdbInquirySPC.OperationCode=SPC_CMD_INQUIRY;
cdbInquirySPC.EnableVPD=0;
cdbInquirySPC.CmdSupportData=0;
cdbInquirySPC.PageCode=0;
cdbInquirySPC.AllocationLen=0x24;
cdbInquirySPC.Control=0;*/
////////////////////////////////
//if(!epBulkRcv(DBUF,5))
// return FALSE;
if(!epBulkSend((unsigned char *)&TPBulk_CBW,31))//sizeof(TPBulk_CBW)))
return FALSE;
DelayMs(150);
//len=36;
if(!epBulkRcv(DBUF,36))
return FALSE;
if(!epBulkRcv((unsigned char *)&TPBulk_CSW,13))
return FALSE;
////////////////////////////////
return TRUE;
#undef cdbInquirySPC
}
unsigned char SPC_READLONG(void)//讀格式化容量
{
BYTE i;
#define cdbReadLong RBC_CDB.SpcCdb_ReadLong
//nsigned char retStatus=FALSE;
TPBulk_CBW.dCBW_Signature=CBW_SIGNATURE;
TPBulk_CBW.dCBW_Tag=0x878bfa28;
TPBulk_CBW.dCBW_DataXferLen=0xfc000000;
TPBulk_CBW.bCBW_Flag=0x80;
TPBulk_CBW.bCBW_LUN=MAXLUN;//0;
TPBulk_CBW.bCBW_CDBLen=0x0C;//sizeof(READ_LONG_CMD);
/////////////////////////////////////
for(i = 0;i<16;i++)
TPBulk_CBW.cdbRBC1[i]=0;
TPBulk_CBW.cdbRBC1[0]=SPC_CMD_READLONG;
TPBulk_CBW.cdbRBC1[9]=0xfc;
// cdbReadLong.OperationCode=SPC_CMD_READLONG;
// cdbReadLong.LogicalUnitNum=0;
// cdbReadLong.AllocationLen=0xfc;
//////////////////////////////////////
if(!epBulkSend((unsigned char *)&TPBulk_CBW,31))
return FALSE;
DelayMs(5);
//len=36;
if(!epBulkRcv(DBUF,0xfc))
return FALSE;
if(!epBulkRcv((unsigned char *)&TPBulk_CSW,13))
return FALSE;
////////////////////////////
return TRUE;
#undef cdbReadLong
}
unsigned char SPC_RequestSense(void)
{
BYTE i;
#define cdbRequestSenseSPC RBC_CDB.SpcCdb_RequestSense
//unsigned char retStatus=FALSE;
TPBulk_CBW.dCBW_Signature=CBW_SIGNATURE;
TPBulk_CBW.dCBW_Tag=0x878bfa28;
TPBulk_CBW.dCBW_DataXferLen=0x00000012;//0x0e000000;
TPBulk_CBW.bCBW_Flag=0x80;
TPBulk_CBW.bCBW_LUN=MAXLUN;//0;
TPBulk_CBW.bCBW_CDBLen=0x0C;//sizeof(REQUEST_SENSE_SPC);
/////////////////////////////////////
for(i = 0;i<16;i++)
TPBulk_CBW.cdbRBC1[i]=0;
TPBulk_CBW.cdbRBC1[0]=SPC_CMD_REQUESTSENSE;
TPBulk_CBW.cdbRBC1[4]=0x12;
// cdbRequestSenseSPC.OperationCode=SPC_CMD_REQUESTSENSE;
// cdbRequestSenseSPC.AllocationLen=0x0e;
//////////////////////////////////////
if(!epBulkSend((unsigned char *)&TPBulk_CBW,31))
return FALSE;
DelayMs(5);
//len=36;
if(!epBulkRcv(DBUF,18))
return FALSE;
if(!epBulkRcv((unsigned char *)&TPBulk_CSW,13))
return FALSE;
/////////////////////////////
return TRUE;
#undef cdbRequestSenseSPC
}
unsigned char SPC_TestUnit(void)
{
BYTE i;
#define cdbTestUnit RBC_CDB.SpcCdb_TestUnit
//unsigned char retStatus=FALSE;
TPBulk_CBW.dCBW_Signature=CBW_SIGNATURE;
TPBulk_CBW.dCBW_Tag=0x878bfa28;
TPBulk_CBW.dCBW_DataXferLen=0x00000000;
TPBulk_CBW.bCBW_Flag=0x00;
TPBulk_CBW.bCBW_LUN=MAXLUN;//0;
TPBulk_CBW.bCBW_CDBLen=0x0C;//sizeof(TEST_UNIT_SPC);
for(i = 0;i<16;i++)
TPBulk_CBW.cdbRBC1[i]=0;
TPBulk_CBW.cdbRBC1[0]=SPC_CMD_TESTUNITREADY; //操作碼
/////////////////////////////////////
//cdbTestUnit.OperationCode=SPC_CMD_TESTUNITREADY;
//////////////////////////////////////
if(!epBulkSend((unsigned char *)&TPBulk_CBW,31))
return FALSE;
DelayMs(5);
if(!epBulkRcv((unsigned char *)&TPBulk_CSW,13))
return FALSE;
#undef cdbTestUnit
////////////////////////////
return TRUE;
}
unsigned char SPC_LockMedia(void)
{
BYTE i;
#define cdbLockSPC RBC_CDB.SpcCdb_Remove
//unsigned char retStatus=FALSE;
TPBulk_CBW.dCBW_Signature=CBW_SIGNATURE;
TPBulk_CBW.dCBW_Tag=0x878bfa28;
TPBulk_CBW.dCBW_DataXferLen=0x00000000;
TPBulk_CBW.bCBW_Flag=0x00;
TPBulk_CBW.bCBW_LUN=MAXLUN;//0;
TPBulk_CBW.bCBW_CDBLen=0x0C;//sizeof(MEDIA_REMOVAL_SPC);
///////////////////////////////////////////
for(i = 0;i<16;i++)
TPBulk_CBW.cdbRBC1[i]=0;
TPBulk_CBW.cdbRBC1[0]=SPC_CMD_PRVENTALLOWMEDIUMREMOVAL; //操作碼
TPBulk_CBW.cdbRBC1[4]=1;
// cdbLockSPC.OperationCode=SPC_CMD_PRVENTALLOWMEDIUMREMOVAL;
// cdbLockSPC.Prevent=1;
///////////////////////////////////////////
if(!epBulkSend((unsigned char *)&TPBulk_CBW,31))
return FALSE;
DelayMs(5);
if(!epBulkRcv((unsigned char *)&TPBulk_CSW,13))
return FALSE;
#undef cdbLockSPC
/////////////////////////////
return TRUE;
}
unsigned char RBC_ReadCapacity(void)
{
BYTE i;
#define cdbReadCap RBC_CDB.RbcCdb_ReadCapacity
//unsigned char retStatus=FALSE;
TPBulk_CBW.dCBW_Signature=CBW_SIGNATURE;
TPBulk_CBW.dCBW_Tag=0x878bfa28;
TPBulk_CBW.bCBW_LUN=MAXLUN;//0;
TPBulk_CBW.dCBW_DataXferLen=0x00000008;
TPBulk_CBW.bCBW_Flag=0x80;
TPBulk_CBW.bCBW_CDBLen=0x0C;//sizeof(READ_CAPACITY_RBC);
/////////////////////////////////////
for(i = 0;i<16;i++)
TPBulk_CBW.cdbRBC1[i]=0;
TPBulk_CBW.cdbRBC1[0]=RBC_CMD_READCAPACITY;
// cdbReadCap.OperationCode=RBC_CMD_READCAPACITY;
/////////////////////////////////////
if(!epBulkSend((unsigned char *)&TPBulk_CBW,31))
return FALSE;
DelayMs(10);
//len=36;
if(!epBulkRcv(DBUF,8))
return FALSE;
if(!epBulkRcv((unsigned char *)&TPBulk_CSW,13))
return FALSE;
#undef cdbReadCap
/////////////////////////////
return TRUE;
}
unsigned char RBC_Read(unsigned long lba,unsigned char len,unsigned char *pBuffer)
{
BYTE i;
#define cdbRead RBC_CDB.RbcCdb_Read
//unsigned char retStatus=FALSE;
TPBulk_CBW.dCBW_Signature=CBW_SIGNATURE;
TPBulk_CBW.dCBW_Tag=0x878bfa28;
TPBulk_CBW.dCBW_DataXferLen=0x0200;//SwapINT32(len*DeviceInfo.BPB_BytesPerSec);
TPBulk_CBW.bCBW_Flag=0x80;
TPBulk_CBW.bCBW_LUN=MAXLUN;//0;
TPBulk_CBW.bCBW_CDBLen=0x0C;//sizeof(READ_RBC);
/////////////////////////////////////
for(i = 0;i<16;i++)
TPBulk_CBW.cdbRBC1[i]=0;
TPBulk_CBW.cdbRBC1[0]=RBC_CMD_READ10;
TPBulk_CBW.cdbRBC1[2]=(lba>>24)&0xff;
TPBulk_CBW.cdbRBC1[3]=(lba>>16)&0xff;
TPBulk_CBW.cdbRBC1[4]=(lba>>8)&0xff;
TPBulk_CBW.cdbRBC1[5]=lba&0xff;
TPBulk_CBW.cdbRBC1[8]=len;
// cdbRead.OperationCode=RBC_CMD_READ10;
// cdbRead.VendorSpecific=0;
// cdbRead.LBA.LBA_W32=lba;
// cdbRead.XferLength=len;
//////////////////////////////////////
if(!epBulkSend((unsigned char *)&TPBulk_CBW,31))
return FALSE;
DelayMs(5);
//len=36;
if(!epBulkRcv(pBuffer,len*DeviceInfo.BPB_BytesPerSec))
return FALSE;
DelayMs(1);
if(!epBulkRcv((unsigned char *)&TPBulk_CSW,13))
return FALSE;
#undef cdbRead
/////////////////////////////
return TRUE;
}
unsigned char RBC_Write(unsigned long lba,unsigned char len,unsigned char *pBuffer)
{
BYTE i;
#define cdbWrite RBC_CDB.RbcCdb_Write
//len=2;
//unsigned int idata temp;
//unsigned char i;
//len=1;
//SPC_TestUnit();
//unsigned char retStatus=FALSE;
TPBulk_CBW.dCBW_Signature=CBW_SIGNATURE;
TPBulk_CBW.dCBW_Tag=0x878bfa28;
TPBulk_CBW.dCBW_DataXferLen=0x0200;//SwapINT32(len*DeviceInfo.BPB_BytesPerSec);
TPBulk_CBW.bCBW_Flag=0x0;
TPBulk_CBW.bCBW_LUN=MAXLUN;//0;
TPBulk_CBW.bCBW_CDBLen=0x0C;//sizeof(WRITE_RBC);
/////////////////////////////////////
for(i = 0;i<16;i++)
TPBulk_CBW.cdbRBC1[i]=0;
TPBulk_CBW.cdbRBC1[0]=RBC_CMD_WRITE10;
TPBulk_CBW.cdbRBC1[2]=(lba>>24)&0xff;
TPBulk_CBW.cdbRBC1[3]=(lba>>16)&0xff;
TPBulk_CBW.cdbRBC1[4]=(lba>>8)&0xff;
TPBulk_CBW.cdbRBC1[5]=lba&0xff;
TPBulk_CBW.cdbRBC1[8]=len;
// cdbWrite.OperationCode=RBC_CMD_WRITE10;
// cdbWrite.VendorSpecific=0;
// cdbWrite.LBA.LBA_W32=lba;
// cdbWrite.XferLength=len;
cdbWrite.Reserved2=0;
cdbWrite.Control=0;
//////////////////////////////////////
if(!epBulkSend((unsigned char *)&TPBulk_CBW,31))
return FALSE;
DelayMs(5);
if(!epBulkSend(pBuffer,DeviceInfo.BPB_BytesPerSec))
return FALSE;
DelayMs(5);
if(!epBulkRcv((unsigned char *)&TPBulk_CSW,13))
return FALSE;
#undef cdbWrite
/////////////////////////////
return TRUE;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -