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

📄 mass_stg.c

📁 基于c8051F320的优盘制作代码及原理图
💻 C
📖 第 1 页 / 共 3 页
字号:
name:		System_Config
function:	Config the IO Port and Interrupt source
pars:		no
renturns:	no
*******************************************************************************************/
void	System_Config(void)
{
	PCA0MD    &= ~0x40;						 //Disable 	WDT	
    //PCA0MD    = 0x00;
	P0MDOUT   = 0x02;
	P1MDOUT	  = 0x00;						 //Open Drain mode
	P2MDOUT	  = 0xBF;						 //Push-pull output	
    XBR1      = 0x40;						 //Enable Weak Pull-up
	REG0CN	  = 0x10;						 //Enable internal LDO, Low Power mode
	GND	= 1;
	WP = 1;
	RE = 1;
	WE = 1;
	CE = 1;
	ALE = 0;
	CLE = 0;
	

}
	
/******************************************************************************************
name:		USB_Config
function:	USB SIE function Config
pars:		no
returns:	no
********************************************************************************************/
void	USB_Config(void)
{
	RSTSRC	  &= ~0x80;					  	  //Disable USB VBUS Reset 
	IE        = 0x80;
	EIE1      = 0x02;						  //Enable USB interrupt
	USB0XCN	= 0xE0;							  //Enable Tranceiver, Full Speed Mode
	SFR_WR(CLKREC,	0x89);					  //Enable	USB clock Recovery Ciruit
	SFR_WR(CMIE,	0x04);					  //Enable	Reset Interrupt
	SFR_WR(INIE,	0x0F);					  //Enable	EndPoint0-3 input Interrupt
	SFR_WR(OUTIE,	0x0F);					  //Enable	EndPoint0-3 output Interrupt
	SFR_WR(INDEX,	0x01);					  //Split the FIFO into two halfs for input 
	SFR_WR(EINCSRH, 0x4);					  //Endpoint and output Endpoint
	SFR_WR(EOUTCSRH,0x0);					  //Endpoint 1, 2, 3 are configured Double Buffer
	SFR_WR(INDEX,	0x02);
	SFR_WR(EINCSRH, 0x4);
	SFR_WR(EOUTCSRH,0x0);
	SFR_WR(INDEX,	0x03);
	SFR_WR(EINCSRH,	0x4);
	SFR_WR(EOUTCSRH,0x0);	
	SFR_WR(INDEX,	0x00);
	SFR_WR(POWER,	0x00);					  //Enable USB0
		


}
/*******************************************************************************************
name:		SFR_WR
function:	wirte the cmd or data to the desired USB FSR by USB0ADDR and USB0DAT
pars:		addr(SFR's address),	dat(cmd or data)
returns:	no
********************************************************************************************/
void	SFR_WR(uchar addr,	uchar dat)
{
	while(USB0ADR>>7);
	USB0ADR	= addr;
	USB0DAT = dat;

}

/********************************************************************************************
name:		SFR_RD
function:	read the content of the address in USB0ADR
pars:		addr
returns:	dat
*********************************************************************************************/
uchar	SFR_RD(uchar addr)
{
	uchar	dat;
	while(USB0ADR>>7);
	USB0ADR = 0x80 + addr;
	while(USB0ADR>>7);
	dat = USB0DAT;
	return	dat;

}

/**********************************************************************************************
name:		Swap		
function:	Swap the 8bit High and 8bit Low
pars:		dat
renturns:	Swap_dat
***********************************************************************************************/
uint	Swap(uint	dat)
{
	uint	Swap_dat;
	Swap_dat = dat>>8 | dat<<8;
	return	Swap_dat;

}

/**********************************************************************************************
name:		FIFO_WR
function:	write data to the output fifo
pars:		ptr(data pointer),	addr(fifo address), num(length)
returns:	no
***********************************************************************************************/
void	FIFO_WR(uchar *ptr,	uchar addr,	uint num)	reentrant
{	
	uint	i;
	USB0ADR	= addr;
	for(i=0;i<num;i++)
	{
			while(USB0ADR>>7);
			USB0DAT = *(ptr + i);
	}

}


/*void	FIFO_RD(uchar	addr,	uchar num)
{
	uchar	i;
	while(USB0ADR>>7);
	USB0ADR = addr +  0xC0;
	for(i=0;i<num;i++)
	{
		while(USB0ADR>>7);
		buf[i] = USB0DAT;
	}
}*/
/**********************************************************************************************
name:		Analysis_Requst
function:	analysis the requst report and ackownlage the host
pars:		Requst pointer pReq
returns:	no
Note:		DATAEND is Stage shakehand signal,	INPRDY and OPRDY are Phase shakehand signal
EndPoint 0	Control Registor
----------------------------------------------------------------------
| SSUEND | SOPRDY |	SDSTL|	SUEND |	DATAEND | STSTL | INPRDY | OPRDY |
|		 |		  |		 |		  |			|		|		 |		 |
----------------------------------------------------------------------
***********************************************************************************************/
void	Analysis_Requst(Requst	* ptr)
{
	uchar	type, index;							//Variables must be defined in front of 
	uint	requst;	
	uint	value;
	uint	num;									//the Code Area
	

	Config_Descriptor	* pConfig;
	Interface_Descriptor	* pInterface;
	Config_Long			* pConfig_Long;
	Device_Descriptor	* pDevice;						//fore Convert the Structure Type to 
	pDevice	= & device_descriptor;						//unsigned character 
	pConfig = & config_descriptor;
	pInterface = & interface_descriptor;
	pConfig_Long = & config_long;


	value  = ptr->wValue;
	requst = ptr->bRequst;
	num	= Swap(ptr->wLength);
	type  =  (uchar)(ptr->wValue & 0x00FF);
	index =  (uchar)((ptr->wValue & 0xFF00)>>8);
	

	switch	(requst)
	{
		case	Set_Addr:
		{
		
//SFR_WR(FADDR,	index);						
//Must not Read Address first, should always return ZERO Length Packet First, then save the Address
//Otherwise the FADDR is always the Default Address 0x0, the Assigned Address is Random Between 0~127
			
			SFR_WR(E0CSR,	0x0A);						//Send ACK and indicate DATA END
			SFR_WR(FADDR,	index);
			while(SFR_RD(FADDR) & BIT7);
			break;

		}
		case	Get_Descriptor:

			switch	(type)
			{
				
				case	DEVICE:
				
					FIFO_WR((uchar *)pDevice,	FIFO0,	num);
					SFR_WR(E0CSR,	0x0A);

					break;

				case	CONFIG:										
					if(num<65)											//Requst Config Descriptor Only
					{
						FIFO_WR((uchar *)pConfig,	FIFO0,	num);
						SFR_WR(E0CSR,	0x0A);
					}
					else
					{
						FIFO_WR((uchar *)pConfig_Long,	FIFO0, 0x20);		//Requst Full Configuration
						SFR_WR(E0CSR,	0x0A);
					
						
					}
					break;

				case	STRING:


					break;

				case	INTERFACE:
					

					break;

				case	ENDPOINT:

					

					break;


			}


		case	Set_Config:


			break;

		case	Set_Interface:	


			break;
		
		case	Get_Max_Lun:								//Get the max Logic Unit Number of Device

			SFR_WR(FIFO0,	0x0);
			SFR_WR(E0CSR,	0x0A);
			break;

		case	Mass_Storage_Reset:							//Reset the Device
		
			USB_Config();
			break;

	}


}

/***************************************************************************************
name:			CLR_Flags
function:		clear the bulk endpoint interrupt flags
pars:			no
returns:		no
****************************************************************************************/
void	CLR_Flags(void)
{
	flags.epin1 = 0;
	flags.epout1 = 0;
}

/****************************************************************************************
name:		Analysis_UFI
function:	analysis the SCSI-UFI commands
pars:		no
returns:	no
*****************************************************************************************/
void	Analysis_UFI(void)
{

	if(flags.epin1 && csw)							//Bulk in interrupt
	{
		flags.epin1 = 0;	
		SFR_WR(INDEX,	0x01);
		FIFO_WR((uchar *)pCS,	FIFO1, 0x0D);
		SFR_WR(EINCSRL,	0x01);
		//while(SFR_RD(EINCSRL) & BIT0);
		csw = 0;
	
	}

	if(flags.epout1)								//Bulk out interrupt
	{
		flags.epout1 = 0;	
		BulkOut_Process();
		
	}

}
/******************************************************************************************
name:		exchange
function:	exchange the Big Endian to the Little Endian
pars:		dat
returns:	temp
******************************************************************************************/
ulong	exchange(ulong dat)	
{
	uint	temp1,temp2;
	ulong	temp;
	temp1 = (uint)(dat>>16);
	temp2 = (uint)dat;
	temp1 = temp1>>8 | temp1<<8;
	temp2 = temp2>>8 | temp2<<8;
    temp = ((ulong)temp2<<16) | ((ulong)temp1);
	return	temp;


}
/*****************************************************************************************
name:		BulkOut_Process
function:	bulk out endpoint process
par:		no
returns:	no
******************************************************************************************/
void	BulkOut_Process()
{
		uchar	temp1,	temp2,temp3,temp4, status,	LBAL, LBAH,lbal,lbah,flag,  SaddrL, SaddrH;
		ulong	temp;
		uint	cnt,	i,	j,	t,	PageNum,	LBA,	lba;
xdata	uchar	CBWbuf[31];
		CBW		*pCB;
		CSW		CSW0;


		SFR_WR(INDEX,	1);
		status = SFR_RD(EOUTCSRL);
		if(status & BIT0)										//get the received data length
		{
			temp1 =  SFR_RD(EOUTCNTL);
			temp2 =  SFR_RD(EOUTCNTH);
			cnt = (((uint)temp2)<<8) | ((uint)temp1);
		}
		for(i=0;i<31;i++)
			CBWbuf[i] = SFR_RD(FIFO1);					//buffer the Bulk out data
																
		temp1 = SFR_RD(EOUTCSRL);
		temp1 &= ~BIT0;
		SFR_WR(EOUTCSRL,	temp1);
		pCB = (pCBW)CBWbuf;										//Converte to the CBW format

//make the CSW blok
		CSW0.CSWTag = pCB->CBWTag;	
		CSW0.CSWSignature = 0x55534253;
		temp = exchange(pCB->CBWDataLength);
		if(temp<MaxSize)
		{
			CSW0.CSWDataLength = 0;
		}
		else
		{
			CSW0.CSWDataLength = 0;
		}
		pCS = & CSW0;											//Send the address of CSW to the write FIFO
		
	
//analysis the CBWCB
		temp1 = pCB->CBWCB[0];
		LBAL = pCB->CBWCB[5];
		LBAH = pCB->CBWCB[4];
		SaddrH = 0xFF;
		if(LBAL & 0x20)
			SaddrL = 0xE0;
		else
			SaddrL = 0xC0;
		LBA  = (uint)LBAL	|	((uint)LBAH)<<8;
		PageNum = (0x00FF & (uint)(pCB->CBWCB[8])) | (0x00FF & (uint)(pCB->CBWCB[7])) << 8;

		switch	(temp1)
		{
			case	Format_Unit:
			
				break;
	
			case	Inquiry:									//SCSI Inquiry Command process
				
				FIFO_WR(Return_Inquiry,	FIFO1,	0x24);
				SFR_WR(EINCSRL,	1);	
				csw = 1;
				while(SFR_RD(EINCSRL) & BIT0);					//WAIT for send compelete
						
				break;
			
			case	Read_Format:								//SCSI Read Format Capacity process
				
				FIFO_WR(Return_Read_Format,FIFO1, 0x14);
				SFR_WR(EINCSRL,	1);	
				csw = 1;
				while(SFR_RD(EINCSRL) & BIT0);					//Wait for send compelete
				
				break;

			case	Read_Cap:
				
				FIFO_WR(Return_Read_Cap,	FIFO1, 0x8);	//SCSI Read Capacity process
				SFR_WR(EINCSRL,	1);
				CSW0.CSWStatus = 0;
				csw = 1;
				while(SFR_RD(EINCSRL) & BIT0);					//Wait for Send compelete
				
				break;
			
			case	Prevent_Allow:
				
				FIFO_WR((uchar *)pCS,	FIFO1, 0x0D);
				SFR_WR(EINCSRL,	1);	
				csw = 0;
				while(SFR_RD(EINCSRL) & BIT0);			
				break;

			case	Test_Ready:
			
				//FIFO_WR((uchar *)pCS,	FIFO1, 0x0D);
				//SFR_WR(EINCSRL,	1);	
				flags.epin1 = 1;
				csw = 1;					//Wait for send compelete
					
				break;

			case	Read_10:

				for(t=0;t<PageNum;t++)							//SCSI READ10 Process, read data from Flash and send to HOST
				{
					page_read(0x0,	LBAL+(uchar)t,	LBAH);
					for(i=0;i<8;i++)
					{
						FIFO_WR(buf + i*MaxSize,	FIFO1, MaxSize);
						SFR_WR(EINCSRL,	1);	
						while(SFR_RD(EINCSRL) & BIT0);
				
					}

				}					
				csw = 1;
				break;	
			
			case	Mode_Sense6:

				FIFO_WR(Sense,	FIFO1, 0x08);
				SFR_WR(EINCSRL,	1);
				csw = 1;	
				while(SFR_RD(EINCSRL) & BIT0);
				//csw = 1;
				break;
		
			case	Verify:

				flags.epin1 = 1;
				csw = 1;
				break;

			case	Write_10:									//SCSI WIRTE10 Process, write data to NandFlash
				
				lba = LBA;
				block_buffer(LBA);
				for(i=0;i<PageNum;i++)						 		//write Host send data to the 512B xdata buffer
				{
					
					lbal = (uchar)(lba & 0x00ff);
					lbah = (uchar)((lba & 0xff00)>>8);
					for(j=0;j<8;j++)
					{
						for(t=0;t<64;t++)
							buf[t+64*j] = SFR_RD(FIFO1);
						SFR_WR(EOUTCSRL,	0x0);
															
					}
					if(flag = page_program(buf,	0,	lbal,	lbah,	512))	//program one Sector data to NandFlash
						LED = 0;
					lba++;				
					
					if((i+1)%32==0)
					{
						LBA += 32;
						block_buffer(LBA);
					}

				}

				if(LBA%32)
					{
						LBAL = (uchar)(LBA & 0x00ff);
						LBAH = (uchar)((LBA & 0xff00)>>8);
						temp3 = LBAL & 0xE0;
						temp4 = LBAL & 0x1F;
						for(i=0;i<temp4;i++)												//Sector address before Write Sector address
							if(flag = copy_back(0, SaddrL+(uchar)i, SaddrH,  0, temp3+(uchar)i, LBAH))	//recover the Sector data before erase
								LED = 0;

							temp4 = temp4 + PageNum;			
						for(i=temp4;i<32;i++)												//Sector address after Write Sector address
							if(flag = copy_back(0, SaddrL+(uchar)i, SaddrH,  0, temp3+(uchar)i, LBAH))	//recover the Sector data before erase
								LED = 0;
					}


				flags.epin1 = 1;
				csw = 1;
				break;				

		}

}
/***************************************************************************************
name:		Read_ID
function:	Read Flash Device ID
pars:		no
returns:	no
****************************************************************************************/
void	Read_ID(void)
{
//Nandflash reset
	uchar	Data_in;
	CE = 0;
	CLE = 1;
    _nop_();
	_nop_();
	WE = 0;
	DIO = 0xFF;
	_nop_();
	_nop_();
	WE = 1;
	_nop_();
	_nop_();
	CLE =0;
	CE = 1;
	Delay_mS(10);
//read device ID
	CE = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -