📄 bulk_only.#1
字号:
#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的第6和7位代表传输长度
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 + -