📄 usb.c
字号:
UWORD StartSector;
UHWORD FATSz16,FSInfo;
if(!SPC_Inquiry())
return false;
if(!SPC_TestUnit())
return false;
if(!SPC_RequestSense())
return false;
DelayMs(50);
if(!SPC_TestUnit())
return false;
if(!SPC_LockMedia())
return false;
if(!RBC_ReadCapacity())
return false;
pMBR = (PMBR_BLOCK)DBUF;
DeviceInfo.BPB_BytesPerSec=512; //暂假设为512
if(!RBC_Read(0x0,1,DBUF))
return false;
if(DBUF[0]==0xeb||DBUF[0]==0xe9)
StartSector=0;
else
StartSector=SwapINT32(pMBR->StartSector);
pBPB=(PBPB_BLOCK)DBUF;
if(!RBC_Read(StartSector,1,DBUF))
return false;
DeviceInfo.BPB_BytesPerSec=SwapINT16(pBPB->BPB_BytesPerSec);
DeviceInfo.BPB_SecPerClus=pBPB->BPB_SecPerClus;
DeviceInfo.BPB_RootEntCnt=SwapINT16(pBPB->BPB_RootEntCnt);
FATSz16=SwapINT16(pBPB->BPB_FATSz16);
if(FATSz16>0) // 表明是FAT16系统
{
DeviceInfo.FATSz=SwapINT16(pBPB->BPB_FATSz16);
DiskFlags.bIsFat32=0;
DeviceInfo.FatStartSector=StartSector+SwapINT16(pBPB->BPB_RsvdSecCn);
DeviceInfo.RootStartSector=DeviceInfo.FatStartSector+2*DeviceInfo.FATSz;
DeviceInfo.FirstDataSector=DeviceInfo.RootStartSector+(DeviceInfo.BPB_RootEntCnt>>4);
DeviceInfo.FSI_Nxt_Free=2;
ThisDir.DepthIndex=0;
ThisDir.bRootDir=1;
ThisDir.Link[0]=DeviceInfo.RootStartSector;
ThisDir.ParentStartCluster=0;
ThisDir.StartCluster=0;
ThisDir.StartSector=DeviceInfo.RootStartSector;
}
else //说明是FAT32系统
{
DeviceInfo.FATSz=SwapINT32(pBPB->fat16_32.fat32.BPB_FATSz32);
DiskFlags.bIsFat32=1;
FSInfo=SwapINT16(pBPB->fat16_32.fat32.BPB_FSInfo);
DeviceInfo.FatStartSector=StartSector+SwapINT16(pBPB->BPB_RsvdSecCn);
DeviceInfo.RootClusterNum=SwapINT32(pBPB->fat16_32.fat32.BPB_RootClus);
DeviceInfo.FirstDataSector=DeviceInfo.FatStartSector+2*DeviceInfo.FATSz;
ThisDir.DepthIndex=0;
ThisDir.bRootDir=1;
ThisDir.Link[0]=DeviceInfo.RootClusterNum;
ThisDir.ParentStartCluster=0;
ThisDir.StartCluster=DeviceInfo.RootClusterNum;
if(!RBC_Read(FSInfo,1,DBUF))
return false;
pFSInfo=(PFSINFO_BLOCK)DBUF;
DeviceInfo.FSI_Free_Count=SwapINT32(pFSInfo->FSI_Free_Count);
if(DeviceInfo.FSI_Free_Count==0xFFFFFFFF)
DeviceInfo.FSI_Free_Count=0;
DeviceInfo.FSI_Nxt_Free=SwapINT32(pFSInfo->FSI_Nxt_Free);
if(DeviceInfo.FSI_Nxt_Free==0xFFFFFFFF)
DeviceInfo.FSI_Nxt_Free=0;
}
ThisFile.bFileOpen=0;
ThisFile.FatSectorPointer=0;
return true;
}
UBYTE SPC_Inquiry(void)
{
#define cdbInquirySPC RBC_CDB.SpcCdb_Inquiry
TPBulk_CBW.dCBW_Signature=CBW_SIGNATURE;
TPBulk_CBW.dCBW_Tag=0x60a624de;
TPBulk_CBW.dCBW_DataXferLen=0x24000000;
TPBulk_CBW.bCBW_Flag=0x80;
TPBulk_CBW.bCBW_LUN=opLun;
TPBulk_CBW.bCBW_CDBLen=sizeof(INQUIRY_SPC);
cdbInquirySPC.OperationCode=SPC_CMD_INQUIRY;
cdbInquirySPC.Lun5to7=opLun<<5;
cdbInquirySPC.PageCode=0;
cdbInquirySPC.Reserved=0;
cdbInquirySPC.AllocationLen=0x24;
cdbInquirySPC.Control=0;
if(!epBulkSend((UBYTE *)&TPBulk_CBW,31))
return false;
if(!epBulkRcv(DBUF,36))
return false;
if(!epBulkRcv((UBYTE *)&TPBulk_CSW,13))
return false;
return true;
#undef cdbInquirySPC
}
UBYTE SPC_RequestSense(void)
{
#define cdbRequestSenseSPC RBC_CDB.SpcCdb_RequestSense
TPBulk_CBW.dCBW_Signature=CBW_SIGNATURE;
TPBulk_CBW.dCBW_Tag=0x60a624de;
TPBulk_CBW.dCBW_DataXferLen=0x0e000000;
TPBulk_CBW.bCBW_Flag=0x80;
TPBulk_CBW.bCBW_LUN=opLun;
TPBulk_CBW.bCBW_CDBLen=0x0c;//sizeof(REQUEST_SENSE_SPC);
cdbRequestSenseSPC.OperationCode=SPC_CMD_REQUESTSENSE;
cdbRequestSenseSPC.Lun5to7=opLun<<5;
cdbRequestSenseSPC.Reserved[0]=0;
cdbRequestSenseSPC.Reserved[1]=0;
cdbRequestSenseSPC.AllocationLen=0x0e;
if(!epBulkSend((UBYTE *)&TPBulk_CBW,31))
return false;
if(!epBulkRcv(DBUF,18))
return false;
if(!epBulkRcv((UBYTE *)&TPBulk_CSW,13))
return false;
return true;
#undef cdbRequestSenseSPC
}
UBYTE SPC_TestUnit(void)
{
#define cdbTestUnit RBC_CDB.SpcCdb_TestUnit
TPBulk_CBW.dCBW_Signature=CBW_SIGNATURE;
TPBulk_CBW.dCBW_Tag=0x60a624de;
TPBulk_CBW.dCBW_DataXferLen=0x00000000;
TPBulk_CBW.bCBW_Flag=0x00;
TPBulk_CBW.bCBW_LUN=opLun;
TPBulk_CBW.bCBW_CDBLen=sizeof(TEST_UNIT_SPC);
cdbTestUnit.OperationCode=SPC_CMD_TESTUNITREADY;
cdbTestUnit.Lun5to7=opLun<<5;
if(!epBulkSend((UBYTE *)&TPBulk_CBW,31))
return false;
if(!epBulkRcv((UBYTE *)&TPBulk_CSW,13))
return false;
#undef cdbTestUnit
return true;
}
UBYTE SPC_LockMedia(void)
{
#define cdbLockSPC RBC_CDB.SpcCdb_Remove
TPBulk_CBW.dCBW_Signature=CBW_SIGNATURE;
TPBulk_CBW.dCBW_Tag=0x60a624de;
TPBulk_CBW.dCBW_DataXferLen=0x00000000;
TPBulk_CBW.bCBW_Flag=0x00;
TPBulk_CBW.bCBW_LUN=opLun;
TPBulk_CBW.bCBW_CDBLen=sizeof(MEDIA_REMOVAL_SPC);
cdbLockSPC.OperationCode=SPC_CMD_PRVENTALLOWMEDIUMREMOVAL;
cdbLockSPC.Lun5to7=opLun<<5;
cdbLockSPC.Prevent=1;
if(!epBulkSend((UBYTE *)&TPBulk_CBW,31))
return false;
if(!epBulkRcv((UBYTE *)&TPBulk_CSW,13))
return false;
#undef cdbLockSPC
return true;
}
UBYTE RBC_ReadCapacity(void)
{
#define cdbReadCap RBC_CDB.RbcCdb_ReadCapacity
TPBulk_CBW.dCBW_Signature=CBW_SIGNATURE;
TPBulk_CBW.dCBW_Tag=0x60a624de;
TPBulk_CBW.bCBW_LUN=opLun;
TPBulk_CBW.dCBW_DataXferLen=0x08000000;
TPBulk_CBW.bCBW_Flag=0x80;
TPBulk_CBW.bCBW_CDBLen=sizeof(READ_CAPACITY_RBC);
cdbReadCap.OperationCode=RBC_CMD_READCAPACITY;
cdbReadCap.Lun5to7=opLun<<5;
cdbReadCap.Reserved[0]=0;
cdbReadCap.Reserved[1]=0;
cdbReadCap.Reserved[2]=0;
cdbReadCap.Reserved[3]=0;
cdbReadCap.PMI=0;
if(!epBulkSend((UBYTE *)&TPBulk_CBW,31))
return false;
if(!epBulkRcv(DBUF,8))
return false;
if(!epBulkRcv((UBYTE *)&TPBulk_CSW,13))
return false;
#undef cdbReadCap
return true;
}
UBYTE RBC_Read(UWORD lba,UBYTE len,UBYTE *pBuffer)
{
#define cdbRead RBC_CDB.RbcCdb_Read
TPBulk_CBW.dCBW_Signature=CBW_SIGNATURE;
TPBulk_CBW.dCBW_Tag=0x60a624de;
TPBulk_CBW.dCBW_DataXferLen=SwapINT32(len*512);
TPBulk_CBW.bCBW_Flag=0x80;
TPBulk_CBW.bCBW_LUN=opLun;
TPBulk_CBW.bCBW_CDBLen=sizeof(READ_RBC);
cdbRead.OperationCode=RBC_CMD_READ10;
cdbRead.VendorSpecific=opLun<<5;
cdbRead.LBA.LBA_W32=lba;
cdbRead.XferLength=len;
if(!epBulkSend((UBYTE *)&TPBulk_CBW,31))
return false;
if(!epBulkRcv(pBuffer,len*512))
return false;
if(!epBulkRcv((UBYTE *)&TPBulk_CSW,13))
return false;
#undef cdbRead
return true;
}
UBYTE RBC_Write(UWORD lba,UBYTE len,UBYTE *pBuffer)
{
#define cdbWrite RBC_CDB.RbcCdb_Write
TPBulk_CBW.dCBW_Signature=CBW_SIGNATURE;
TPBulk_CBW.dCBW_Tag=0xb4D977c1;
TPBulk_CBW.dCBW_DataXferLen=SwapINT32(len*512);
TPBulk_CBW.bCBW_Flag=0x0;
TPBulk_CBW.bCBW_LUN=opLun;
TPBulk_CBW.bCBW_CDBLen=sizeof(WRITE_RBC);
cdbWrite.OperationCode=RBC_CMD_WRITE10;
cdbWrite.VendorSpecific=opLun<<5;
cdbWrite.LBA.LBA_W32=lba;
cdbWrite.XferLength=len;
cdbWrite.Reserved2=0;
cdbWrite.Control=0;
if(!epBulkSend((UBYTE *)&TPBulk_CBW,31))
return false;
if(!epBulkSend(pBuffer,len*512))
return false;
if(!epBulkRcv((UBYTE *)&TPBulk_CSW,13))
return false;
#undef cdbWrite
return true;
}
UWORD FirstSectorofCluster(UWORD clusterNum)
{
return (clusterNum-2)*DeviceInfo.BPB_SecPerClus+DeviceInfo.FirstDataSector;
}
UWORD ThisFatSecNum(UWORD clusterNum)
{
UWORD temp;
if(DiskFlags.bIsFat32==0)
temp=DeviceInfo.BPB_BytesPerSec/2;
else
temp=DeviceInfo.BPB_BytesPerSec/4;
temp=clusterNum/temp;
temp=temp+DeviceInfo.FatStartSector;
return temp;
}
UHWORD ThisFatEntOffset(UWORD clusterNum)
{
UHWORD temp;
UWORD temp1;
if(DiskFlags.bIsFat32==0)
temp1=2*clusterNum;
else
temp1=4*clusterNum;
temp=temp1/DeviceInfo.BPB_BytesPerSec;
temp1=temp1-temp*DeviceInfo.BPB_BytesPerSec;
return temp1;
}
UWORD GetNextClusterNum(UWORD clusterNum)
{
UWORD UseFatSecNum;
UHWORD UseFatEntOffset;
UseFatSecNum=ThisFatSecNum(clusterNum);
UseFatEntOffset=ThisFatEntOffset(clusterNum);
if(ThisFile.FatSectorPointer!=UseFatSecNum)
{
if(!RBC_Read(UseFatSecNum,1,FatBuf))
return 0x0;
ThisFile.FatSectorPointer=UseFatSecNum;
}
if(DiskFlags.bIsFat32==0)
clusterNum=MakeWord(0,0,FatBuf[UseFatEntOffset+1],FatBuf[UseFatEntOffset]);
else
clusterNum=MakeWord(FatBuf[UseFatEntOffset+3],FatBuf[UseFatEntOffset+2],FatBuf[UseFatEntOffset+1],FatBuf[UseFatEntOffset]);
return clusterNum;
}
UBYTE DeleteClusterLink(UWORD clusterNum)
{
UBYTE bChanged;
UWORD UseFatSecNum,maxClusterNum;
UHWORD UseFatEntOffset;
UWORD ThisSector;
ThisSector=0;
bChanged=0;
if(DiskFlags.bIsFat32==0)
maxClusterNum=0xfff8;
else
maxClusterNum=0x0ffffff8;
while((clusterNum>1)&&(clusterNum<maxClusterNum))
{
UseFatSecNum=ThisFatSecNum(clusterNum);
UseFatEntOffset=ThisFatEntOffset(clusterNum);
if(ThisSector!=UseFatSecNum)
{
if(bChanged)
{
if(!RBC_Write(ThisSector,1,DBUF))
return false;
if(!RBC_Write(ThisSector+DeviceInfo.FATSz,1,DBUF))
return false;
bChanged=0;
}
if(!RBC_Read(UseFatSecNum,1,DBUF))
{
return false;
}
ThisSector=UseFatSecNum;
}
if(DiskFlags.bIsFat32==0)
{
clusterNum=MakeWord(0,0,DBUF[UseFatEntOffset+1],DBUF[UseFatEntOffset]);
DBUF[UseFatEntOffset]=0x00;
DBUF[UseFatEntOffset+1]=0x00;
bChanged=1;
}
else
{
clusterNum=MakeWord(DBUF[UseFatEntOffset+3],DBUF[UseFatEntOffset+2],DBUF[UseFatEntOffset+1],DBUF[UseFatEntOffset]);
DBUF[UseFatEntOffset]=0x00;
DBUF[UseFatEntOffset+1]=0x00;
DBUF[UseFatEntOffset+2]=0x00;
DBUF[UseFatEntOffset+3]=0x00;
bChanged=1;
}
}
if(bChanged)
{
if(!RBC_Write(ThisSector,1,DBUF))
return false;
if(!RBC_Write(ThisSector+DeviceInfo.FATSz,1,DBUF))
return false;
bChanged=0;
}
return true;
}
UWORD CreateClusterLink(UWORD currentCluster)
{
UBYTE bFound;
UHWORD UseFatEntOffset;
UWORD UseFatSecNum,maxClusterCnt;
bFound=0;
if(DiskFlags.bIsFat32==0)
maxClusterCnt=DeviceInfo.FATSz*(DeviceInfo.BPB_BytesPerSec/2);
else
maxClusterCnt=DeviceInfo.FATSz*(DeviceInfo.BPB_BytesPerSec/4);
while(FreeClusterNum<maxClusterCnt)
{
UseFatSecNum=ThisFatSecNum(FreeClusterNum);
UseFatEntOffset=ThisFatEntOffset(FreeClusterNum);
if(UseFatSecNum!=FreeSecNum)
{
if(DiskFlags.bFatChanged==1)
{
if(!RBC_Write(FreeSecNum,1,CurFatSector))
return 0;
if(!RBC_Write(FreeSecNum+DeviceInfo.FATSz,1,CurFatSector))
return 0;
DiskFlags.bFatChanged=0;
}
FreeSecNum=UseFatSecNum;
if(!RBC_Read(FreeSecNum,1,CurFatSector))
return 0x0;
}
if(DiskFlags.bIsFat32==0)
{
if((CurFatSector[UseFatEntOffset]==0)&&(CurFatSector[UseFatEntOffset+1]==0))
{
CurFatSector[UseFatEntOffset]=0xff;
CurFatSector[UseFatEntOffset+1]=0xff;
DiskFlags.bFatChanged=1;
bFound=1;
}
}
else
{
if((CurFatSector[UseFatEntOffset]==0)&&(CurFatSector[UseFatEntOffset+1]==0)&&(CurFatSector[UseFatEntOffset+2]==0)&&(CurFatSector[UseFatEntOffset+3]==0))
{
CurFatSector[UseFatEntOffset]=0xff;
CurFatSector[UseFatEntOffset+1]=0xff;
CurFatSector[UseFatEntOffset+2]=0xff;
CurFatSector[UseFatEntOffset+3]=0x0f;
DiskFlags.bFatChanged=1;
bFound=1;
}
}
if(bFound==1)
break;
else
FreeClusterNum++;
}
if(bFound==0)
return 0x00;
if(currentCluster==0x00)
return FreeClusterNum++;
UseFatSecNum=ThisFatSecNum(currentCluster);
UseFatEntOffset=ThisFatEntOffset(currentCluster);
if(UseFatSecNum!=FreeSecNum)
{
RBC_Read(UseFatSecNum,1,DBUF);
if(DiskFlags.bIsFat32==0)
{
DBUF[UseFatEntOffset]=FreeClusterNum;
DBUF[UseFatEntOffset+1]=FreeClusterNum>>8;
}
else
{
DBUF[UseFatEntOffset]=FreeClusterNum;
DBUF[UseFatEntOffset+1]=FreeClusterNum>>8;
DBUF[UseFatEntOffset+2]=FreeClusterNum>>16;
DBUF[UseFatEntOffset+3]=FreeClusterNum>>24;
}
if(!RBC_Write(UseFatSecNum,1,DBUF))
return 0x00;
if(!RBC_Write(UseFatSecNum+DeviceInfo.FATSz,1,DBUF))
return 0x00;
}
else
{
if(DiskFlags.bIsFat32==0)
{
CurFatSector[UseFatEntOffset]=FreeClusterNum;
CurFatSector[UseFatEntOffset+1]=FreeClusterNum>>8;
}
else
{
CurFatSector[UseFatEntOffset]=FreeClusterNum;
CurFatSector[UseFatEntOffset+1]=FreeClusterNum>>8;
CurFatSector[UseFatEntOffset+2]=FreeClusterNum>>16;
CurFatSector[UseFatEntOffset+3]=FreeClusterNum>>24;
}
DiskFlags.bFatChanged=1;
}
return FreeClusterNum++;
}
UBYTE SeekSectorToRead(UWORD * pClusterNum,UHWORD *pSector,UWORD *pSectorToRead)
{
UWORD idata clusterNum,sectorToRead;
UBYTE idata sector;
clusterNum=*pClusterNum;
sectorToRead=*pSectorToRead;
sector=*pSector;
if(DiskFlags.bIsFat32==0)
{
if(ThisDir.bRootDir)
{
if(sector>DeviceInfo.BPB_RootEntCnt>>4)
{
return false;
}
sectorToRead=ThisDir.StartSector+sector++;
}
else
{
if(sector>DeviceInfo.BPB_SecPerClus-1)
{
clusterNum=GetNextClusterNum(clusterNum);
if(clusterNum>0xfff8)
return false;
sector=0;
}
sectorToRead=FirstSectorofCluster(clusterNum)+sector++;
}
}
else
{
if(sector>DeviceInfo.BPB_SecPerClus-1)
{
clusterNum=GetNextClusterNum(clusterNum);
if(clusterNum>0x0ffffff8)
return false;
sector=0;
}
sectorToRead=FirstSectorofCluster(clusterNum)+sector++;
}
*pClusterNum=clusterNum;
*pSectorToRead=sectorToRead;
*pSector=sector;
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -