⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bulk_only.#1

📁 源码 : KIEL C 单片机 : C8051F320 功能 : U盘 (64M) 关键字 : C8051F320,U盘,NANDFLASH,FAT,SCH 描述 : 源码完全可运行
💻 #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 + -