?? bulk_only.c
字號:
#include "c8051F320.h"
#include "stdio.h"
#include "intrins.h"
/////////////////////////////
#include "Usb_FunDec.h"
#include "Usb_Parameter.h"
#include "Usb_Register.h"
#include "Usb_Request.h"
#include "Usb_SCSI_Descreptor.h"
///////////////////////////////////////////////////////////////////////////////////////////
sbit LED = P0^0; //LED控制腳
// Bulk傳輸處理函數
void Interpret_CBW(void); // 解釋CBW命令
void TransDataGoOn(void); // 繼續傳輸
void TransCSW(void); // 發送CSW
void Bulk_Receive_Data(void); // 接收數據
void Copy(unsigned char *PEnd,unsigned char *PSource,unsigned int num); // 在Bulk_Out過程中將Bulk_Buffer中的數據拷貝到Bulk_PACKET中
// 外部函數調用
extern void Flash_Read_Page(unsigned int BLockNum,unsigned char BlockPageNum,unsigned char *P,unsigned int Data_Length);
extern unsigned char Flash_Write_Page(unsigned int BLockNum,unsigned char BlockPageNum,unsigned char *P,unsigned int Data_Length);
extern unsigned char Flash_Erase_Block(unsigned int BlockNum);
// 外部變量
extern unsigned char Ep_Status[3];
// BUlk傳輸變量
unsigned char Bulk_Status = BULK_IDLE; // Bulk傳輸狀態
unsigned char Bulk_CSW[13]={0x55,0x53,0x42,0x53,};
xdata struct CBW
{
unsigned char dCBWstagnature[4];
unsigned char dCBWTag[4];
unsigned char dCBWDataTransLength[4];
unsigned char bmCBWFlags;
unsigned char dCBWLun;
unsigned char dCBWCBLength;
unsigned char CBWCB[16];
}Bulk_CBW;
xdata unsigned char Bulk_PACKET[512]; // 讀寫FLASH時的數據緩沖區
xdata unsigned char Bulk_Buffer[64]; // FIFO緩沖區
unsigned int LBA=0; // LBA
unsigned int Transfer_Length=0; // 要傳輸的長度,單位為扇區
unsigned int nCurrentBlock=0; // 當前的Block地址
unsigned int nCurrentPage=0; // 當前的Page地址
unsigned char *pCurrentBuf; // Bulk傳輸中的指針
unsigned int nBufCount=0; // FIFO讀寫過程中傳輸的數據量
unsigned int nBegainPage=0; // Bulk_Out傳輸中的開始Page地址
/////////////////////////////////////////////////////////////////////////////////////////////
void Handle_In1()
{
unsigned char ControlReg;
UWrite_Byte(INDEX, 1);
URead_Byte(EINCSRL, ControlReg);
if (Ep_Status[1] == EP_HALT)
{
UWrite_Byte(EINCSRL, rbInSDSTL);
}
else
{
if (ControlReg & rbInSTSTL)
{
UWrite_Byte(EINCSRL, rbInCLRDT);//清除SDSTL和STSTL,并將CLRDT寫1使toggle復位為0
}
if (ControlReg & rbInUNDRUN)
{
UWrite_Byte(EINCSRL, 0x00); // 清除UNDRUN,注意toggle位不復位
}
if(!(ControlReg & rbInINPRDY))
{
switch(Bulk_Status)
{
case BULK_DATA_TRANS: TransDataGoOn(); break;
case BULK_DATA_END: TransCSW(); break;
default: break;
}
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////////
// Handle_Out2
void Handle_Out2()
{
unsigned int Count=0;
unsigned char ControlReg;
UWrite_Byte(INDEX, 2); // Set index to endpoint 2 registers
URead_Byte(EOUTCSRL, ControlReg);
if (Ep_Status[2] == EP_HALT) // If endpoint is halted, send a stall
{
UWrite_Byte(EOUTCSRL, rbOutSDSTL);
}
else
{
if (ControlReg & rbOutSTSTL)
{
UWrite_Byte(EOUTCSRL, rbOutCLRDT); //清除SDSTL和STSTL,并將CLRDT寫1使toggle復位為0
}
////////////////////////////////////////////////////////////////
if(ControlReg & rbOutOPRDY)
{
UWrite_Byte(INDEX, 2);
URead_Byte(EOUTCNTL, Count);
Fifo_Read(FIFO_EP2, Count, Bulk_Buffer);
UWrite_Byte(INDEX, 2);
UWrite_Byte(EOUTCSRL, 0); // Clear Out Packet ready bit
if((Bulk_Status !=BULK_DATA_RECIEVE) && (Bulk_Buffer[0]==0x55))
{
Interpret_CBW();
}
else
{
Bulk_Receive_Data();
}
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
void Interpret_CBW()
{
unsigned char i=0;
Bulk_CSW[4] = Bulk_Buffer[4];
Bulk_CSW[5] = Bulk_Buffer[5];
Bulk_CSW[6] = Bulk_Buffer[6];
Bulk_CSW[7] = Bulk_Buffer[7];
for(i=0;i<12;i++) //提取SCSI命令字
{
Bulk_CBW.CBWCB[i] = Bulk_Buffer[15+i];
}
switch(Bulk_CBW.CBWCB[0])
{
case INQUIRY: SCSI_Inquiry(); break;
case MODE_SENSE: SCSI_Mode_Sense(); break;
case READ10: SCSI_Read10(); break;
case READ_CAPACITY: SCSI_Read_Capacity(); break;
case TEST_UNIT_READY: SCSI_Test_Unit_Ready(); break;
case VERIFY: SCSI_Verify(); break;
case WRITE10: SCSI_Write10(); break;
case MEDIUM_REMOVAL: SCSI_Medium_Removal(); break;
case Vender_Order: SCSI_Vender_Order(); break;
default: SCSI_Reserved(); break;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
void SCSI_Inquiry(void)
{
if(Bulk_CBW.CBWCB[4]!=0)
{
Bulk_Status=BULK_DATA_END;
Fifo_Write(FIFO_EP1,sizeof(Device_InquiryData),Device_InquiryData);
UWrite_Byte(INDEX, 1);
UWrite_Byte(EINCSRL, rbInINPRDY);
}
else
{}
}
void SCSI_Mode_Sense(void)
{
Bulk_Status=BULK_DATA_END;
Fifo_Write(FIFO_EP1,sizeof(Device_ModeSense),Device_ModeSense);
UWrite_Byte(INDEX, 1);
UWrite_Byte(EINCSRL, rbInINPRDY);
}
void SCSI_Read_Capacity(void)
{
Bulk_Status=BULK_DATA_END;
Fifo_Write(FIFO_EP1,sizeof(Device_Capacity),Device_Capacity);
UWrite_Byte(INDEX, 1);
UWrite_Byte(EINCSRL, rbInINPRDY);
}
void SCSI_Vender_Order()
{
Bulk_Status=BULK_DATA_END;
Fifo_Write(FIFO_EP1,sizeof(Vender_Order),Vender_Order);
UWrite_Byte(INDEX, 1);
UWrite_Byte(EINCSRL, rbInINPRDY);
}
void SCSI_Test_Unit_Ready(void)
{
TransCSW();
}
void SCSI_Medium_Removal(void)
{
TransCSW();
}
void SCSI_Verify(void)
{
TransCSW();
}
void SCSI_Reserved(void)
{
}
void TransCSW()
{
Fifo_Write(FIFO_EP1, 13, Bulk_CSW);
UWrite_Byte(INDEX, 1);
UWrite_Byte(EINCSRL, rbInINPRDY);
Bulk_Status=BULK_IDLE;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
void SCSI_Read10()
{
unsigned int i=0;
LED=~LED;
for(i=0;i<4;i++) // 計算LBA,CBWCB的第2、3、4和5位代表LBA
{
LBA=(LBA<<8)+Bulk_CBW.CBWCB[2+i];
}
Transfer_Length = Bulk_CBW.CBWCB[7]*256 + Bulk_CBW.CBWCB[8]; //傳輸的長度,CBWCB的第7和8位代表傳輸長度
nCurrentBlock = LBA / 32; //計算FLASH的物理地址
nCurrentPage = LBA % 32;
Flash_Read_Page(nCurrentBlock,nCurrentPage,Bulk_PACKET,512); //向頁緩沖區讀1頁
Transfer_Length--; //待傳輸的扇區數減1
nCurrentPage++; //當前頁序號加1
Bulk_Status = BULK_DATA_TRANS; //Bulk在傳輸狀態
pCurrentBuf = Bulk_PACKET; //指針指向頁緩沖區
nBufCount=0;
Fifo_Write(FIFO_EP1,EP1_PACKET_SIZE,pCurrentBuf+nBufCount); //在雙緩沖方式,一次可以向FIFO寫兩個數據包
UWrite_Byte(INDEX, 1);
UWrite_Byte(EINCSRL, rbInINPRDY);
nBufCount+=EP1_PACKET_SIZE;
Fifo_Write(FIFO_EP1,EP1_PACKET_SIZE,pCurrentBuf+nBufCount);
UWrite_Byte(INDEX, 1);
UWrite_Byte(EINCSRL, rbInINPRDY);
}
void TransDataGoOn()
{
unsigned int i=0;
if(nBufCount<384)
{
nBufCount+=EP1_PACKET_SIZE;
Fifo_Write(FIFO_EP1,EP1_PACKET_SIZE,pCurrentBuf+nBufCount); //在雙緩沖方式,一次可以向FIFO寫兩個數據包
UWrite_Byte(INDEX, 1);
UWrite_Byte(EINCSRL, rbInINPRDY);
nBufCount+=EP1_PACKET_SIZE;
Fifo_Write(FIFO_EP1,EP1_PACKET_SIZE,pCurrentBuf+nBufCount);
UWrite_Byte(INDEX, 1);
UWrite_Byte(EINCSRL, rbInINPRDY);
}
else if(Transfer_Length>0)
{
if(nCurrentPage==32)
{
nCurrentBlock++;
nCurrentPage=0;
}
else
{}
Flash_Read_Page(nCurrentBlock,nCurrentPage,Bulk_PACKET,512);
nCurrentPage++;
Transfer_Length--;
nBufCount=0;
pCurrentBuf=Bulk_PACKET;
Bulk_Status=BULK_DATA_TRANS;
Fifo_Write(FIFO_EP1,EP1_PACKET_SIZE,pCurrentBuf+nBufCount);//在雙緩沖方式,一次可以向FIFO寫兩個數據包
UWrite_Byte(INDEX, 1);
UWrite_Byte(EINCSRL, rbInINPRDY);
nBufCount+=EP1_PACKET_SIZE;
Fifo_Write(FIFO_EP1,EP1_PACKET_SIZE,pCurrentBuf+nBufCount);
UWrite_Byte(INDEX, 1);
UWrite_Byte(EINCSRL, rbInINPRDY);
}
else
{
Bulk_Status=BULK_DATA_END;
nBufCount=0;
TransCSW();
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////
void SCSI_Write10(void)
{
unsigned int i=0;
LED=~LED;
for(i=0;i<4;i++)
{
LBA=(LBA<<8)+Bulk_CBW.CBWCB[2+i];
}
Transfer_Length = Bulk_CBW.CBWCB[7]*256 + Bulk_CBW.CBWCB[8];
nCurrentBlock=LBA/32;
nCurrentPage =LBA%32;
nBegainPage = nCurrentPage;
Bulk_Status = BULK_DATA_RECIEVE;
pCurrentBuf = Bulk_PACKET;
nBufCount = 0;
Flash_Erase_Block(Bufer_Block); //擦除緩沖區BLOCK
}
void Bulk_Receive_Data()
{
unsigned int i=0;
Copy(pCurrentBuf+nBufCount,Bulk_Buffer,EP2_PACKET_SIZE);
nBufCount+=EP2_PACKET_SIZE;
if(nBufCount==512) //如果一扇區內容接收完畢
{
Flash_Write_Page(Bufer_Block,nCurrentPage,Bulk_PACKET,512); //將數據暫時寫到緩沖區BLOCK
nCurrentPage++; //頁指針加1
Transfer_Length--; //待傳輸數據長度減1
nBufCount=0;
}
if((Transfer_Length>0)&&(nCurrentPage == 32)) //如果一個BLOCK寫完畢
{
for(i=0;i<nBegainPage;i++)
{
Flash_Read_Page(nCurrentBlock,i,Bulk_PACKET,512);
Flash_Write_Page(Bufer_Block,i,Bulk_PACKET,512);
}
Flash_Erase_Block(nCurrentBlock);
for(i=0;i<32;i++)
{
Flash_Read_Page(Bufer_Block,i,Bulk_PACKET,512);
Flash_Write_Page(nCurrentBlock,i,Bulk_PACKET,512);
}
nCurrentBlock++;
nCurrentPage=0;
nBufCount=0;
nBegainPage=0;
Flash_Erase_Block(Bufer_Block);
}
if(Transfer_Length==0)
{
for(i=0;i<nBegainPage;i++)
{
Flash_Read_Page(nCurrentBlock,i,Bulk_PACKET,512);
Flash_Write_Page(Bufer_Block,i,Bulk_PACKET,512);
}
for(i=nCurrentPage;i<32;i++)
{
Flash_Read_Page(nCurrentBlock,i,Bulk_PACKET,512);
Flash_Write_Page(Bufer_Block,i,Bulk_PACKET,512);
}
Flash_Erase_Block(nCurrentBlock);
for(i=0;i<32;i++)
{
Flash_Read_Page(Bufer_Block,i,Bulk_PACKET,512);
Flash_Write_Page(nCurrentBlock,i,Bulk_PACKET,512);
}
TransCSW();
}
}
void Copy(unsigned char *PEnd,unsigned char *PSource,unsigned int num)
{
unsigned int i=0;
for(i=0;i<num;i++)
{
*(PEnd+i)=*(PSource+i);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -