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

📄 mass_stg.c

📁 基于c8051F320的优盘制作代码及原理图
💻 C
📖 第 1 页 / 共 3 页
字号:
/*******************************************************************************************
USB	MASS STORAGE Source Code
Create	By:		Sen	Xu
Date:			09/10/2007
Version:		V1.0
Note:			Only for Study and not for cometial use
*******************************************************************************************/
#include		"c8051f320.h"
#include		"intrins.h"
#include		"USB.h"
#include 		"UFI.h"
#include		"flash.c"


#define			MaxSize		0x40
#define			BIT0		0x01
#define			BIT1		0x02
#define			BIT2		0x04
#define			BIT3		0x08
#define			BIT4		0x10
#define			BIT5		0x20
#define			BIT6		0x40
#define			BIT7		0x80
///////////////////////////////////////////////////////////////////////////////////////////
//Descriptors
#define			DEVICE		0x01
#define			CONFIG		0x02
#define			STRING		0x03
#define			INTERFACE	0x04
#define			ENDPOINT	0x05

///////////////////////////////////////////////////////////////////////////////////////////
//Host Requst Report
#define			Set_Addr		0x05
#define			Get_Descriptor	0x06
#define			Set_Config		0x09
#define			Set_Interface	0x11
///////////////////////////////////////////////////////////////////////////////////////////
//Mass Storage class Specitial Requst
#define			Get_Max_Lun			0xFE
#define			Mass_Storage_Reset	0xFF
///////////////////////////////////////////////////////////////////////////////////////////



extern	void	Oscillator_Init(void);
extern	void	System_Config(void);
extern	void	USB_Config(void);
extern	void	SFR_WR(uchar,uchar);
extern	uchar	SFR_RD(uchar);
extern	void	Delay_uS(uint);
extern	void	Delay_mS(uchar);
extern	void	Analysis_Requst(Requst *);
extern	uint	Swap(uint);
extern	void	FIFO_WR(uchar *, uchar, uint)	reentrant;
extern	void	FIFO_RD(uchar,uchar);
extern	void	CLR_Flags(void);
extern	void	Analysis_UFI(void);
extern	void	BulkOut_Process(void);
extern	ulong	exchange(ulong);
extern	void	Read_ID(void);
extern	void	write_cmd(uchar);
extern	void	write_addr(uchar);
extern	void	write_addr_2byte(uchar, uchar);
extern	void	write_addr_3byte(uchar, uchar, uchar);
extern	uchar	read_dat(void);
extern	void	write_dat(uchar);
extern	uchar	read_status(void);
extern	uchar	block_erase(uchar,uchar);
extern	uchar	page_program(uchar *,uchar, uchar, uchar, uint);
extern	uchar	copy_back(uchar	,uchar , uchar , uchar , uchar , uchar);
extern	void	page_read(uchar	,uchar , uchar)	;	
extern	void	check_invalid(void);
extern	void	test_flash(void);
extern	void	fill_DBR(void);
extern	void	block_buffer(uint);


/*****************************************************************************************
Interrupt Flag Data Structure for Program jump
******************************************************************************************/
typedef	struct	Flag
{
	uchar	epin1;
	uchar	epout1;

}Flags;


/****************************************************************************************
UFI CBW DATA STRUCTURE
*****************************************************************************************/
code	uchar	Return_Inquiry[36] =
{
	0x00,			//Device Type
	0x80,			//Removable media
	0x00,
	0x01,
	0x1F,
	'x','u','s','e','n','C','H','F',	//VID
	0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
	0x38,0x39,0x30,0x31,0x32,0x33,0x34,0x35,
	'V','1','.','0'
	

};

code	uchar	Return_Read_Format[20] =
{
	0x00,0x00,0x00,0x10,			//Capacity List Header
	0x00,0x00,0xFA,0x00,			//Block number
	0x01,0x00,0x02,0x00,			//sector length 512byte
	0x00,0x00,0xFA,0x00,
	0x00,0x00,0x02,0x00
};

code	uchar	Return_Read_Cap [8] =
{
	0x00,0x00,0xFA,0x00,			//Mediu Capacity
	0x00,0x00,0x02,0x00				
};

code	uchar	Sense[8] =
{
	0x45,	0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00
};

code	uchar	DBR[512] = 
{
	0xeb,	0x58,	0x90,
	0x4d, 	0x53,   0x44, 0x4f, 0x53, 0x35, 0x2e, 0x30, 
	0x00,	0x02,
	0x01,
	0x01,	0x00,
	0x02,
	0xB0,	0x00,
	0x00,	0xfa,
	0xf8,
	0xFA,	0x00,
	0x3F,	0x00,
	0xFF,	0x00,
	0x00,	0x00,	0x00,	0x00,
	0x00,	0x00,	0x00,	0x00,
	0x80,
	0x00,
	0x029,
	0xA8, 0x8B, 0x36, 0x52,
	0x4E, 0x4F, 0x20, 0x4E, 0x41, 0x4D, 0x45, 0x20, 0x20, 0x20, 0x20,
	0x46, 0x41, 0x54, 0x31, 0x36, 0x20,  0x20, 0x20,
	0xf1, 0x7d,
 0xfa, 0x33, 0xc9, 0x8e,  0xd1, 0xbc, 0xfc, 0x7b,  0x16, 0x07, 0xbd, 0x78,  0x00, 0xc5, 0x76, 0x00,
 0x1e, 0x56, 0x16, 0x55,  0xbf, 0x22, 0x05, 0x89,  0x7e, 0x00, 0x89, 0x4e,  0x02, 0xb1, 0x0b, 0xfc,
 0xf3, 0xa4, 0x06, 0x1f,  0xbd, 0x00, 0x7c, 0xc6,  0x45, 0xfe, 0x0f, 0x8b,  0x46, 0x18, 0x88, 0x45,
 0xf9, 0xfb, 0x38, 0x66,  0x24, 0x7c, 0x04, 0xcd,  0x13, 0x72, 0x3c, 0x8a,  0x46, 0x10, 0x98, 0xf7,
 0x66, 0x16, 0x03, 0x46,  0x1c, 0x13, 0x56, 0x1e,  0x03, 0x46, 0x0e, 0x13,  0xd1, 0x50, 0x52, 0x89,
 0x46, 0xfc, 0x89, 0x56,  0xfe, 0xb8, 0x20, 0x00,  0x8b, 0x76, 0x11, 0xf7,  0xe6, 0x8b, 0x5e, 0x0b,
 0x03, 0xc3, 0x48, 0xf7,  0xf3, 0x01, 0x46, 0xfc,  0x11, 0x4e, 0xfe, 0x5a,  0x58, 0xbb, 0x00, 0x07,
 0x8b, 0xfb, 0xb1, 0x01,  0xe8, 0x94, 0x00, 0x72,  0x47, 0x38, 0x2d, 0x74,  0x19, 0xb1, 0x0b, 0x56,
 0x8b, 0x76, 0x3e, 0xf3,  0xa6, 0x5e, 0x74, 0x4a,  0x4e, 0x74, 0x0b, 0x03,  0xf9, 0x83, 0xc7, 0x15,
 0x3b, 0xfb, 0x72, 0xe5,  0xeb, 0xd7, 0x2b, 0xc9,  0xb8, 0xd8, 0x7d, 0x87,  0x46, 0x3e, 0x3c, 0xd8,
 0x75, 0x99, 0xbe, 0x80,  0x7d, 0xac, 0x98, 0x03,  0xf0, 0xac, 0x84, 0xc0,  0x74, 0x17, 0x3c, 0xff,
 0x74, 0x09, 0xb4, 0x0e,  0xbb, 0x07, 0x00, 0xcd,  0x10, 0xeb, 0xee, 0xbe,  0x83, 0x7d, 0xeb, 0xe5,
 0xbe, 0x81, 0x7d, 0xeb,  0xe0, 0x33, 0xc0, 0xcd,  0x16, 0x5e, 0x1f, 0x8f,  0x04, 0x8f, 0x44, 0x02,
 0xcd, 0x19, 0xbe, 0x82,  0x7d, 0x8b, 0x7d, 0x0f,  0x83, 0xff, 0x02, 0x72,  0xc8, 0x8b, 0xc7, 0x48,
 0x48, 0x8a, 0x4e, 0x0d,  0xf7, 0xe1, 0x03, 0x46,  0xfc, 0x13, 0x56, 0xfe,  0xbb, 0x00, 0x07, 0x53,
 0xb1, 0x04, 0xe8, 0x16,  0x00, 0x5b, 0x72, 0xc8,  0x81, 0x3f, 0x4d, 0x5a,  0x75, 0xa7, 0x81, 0xbf,
 0x00, 0x02, 0x42, 0x4a,  0x75, 0x9f, 0xea, 0x00,  0x02, 0x70, 0x00, 0x50,  0x52, 0x51, 0x91, 0x92,
 0x33, 0xd2, 0xf7, 0x76,  0x18, 0x91, 0xf7, 0x76,  0x18, 0x42, 0x87, 0xca,  0xf7, 0x76, 0x1a, 0x8a,
 0xf2, 0x8a, 0x56, 0x24,  0x8a, 0xe8, 0xd0, 0xcc,  0xd0, 0xcc, 0x0a, 0xcc,  0xb8, 0x01, 0x02, 0xcd,
 0x13, 0x59, 0x5a, 0x58,  0x72, 0x09, 0x40, 0x75,  0x01, 0x42, 0x03, 0x5e,  0x0b, 0xe2, 0xcc, 0xc3,
 0x03, 0x18, 0x01, 0x27,  0x0d, 0x0a, 0x49, 0x6e,  0x76, 0x61, 0x6c, 0x69,  0x64, 0x20, 0x73, 0x79,
 0x73, 0x74, 0x65, 0x6d,  0x20, 0x64, 0x69, 0x73,  0x6b, 0xff, 0x0d, 0x0a,  0x44, 0x69, 0x73, 0x6b,
 0x20, 0x49, 0x2f, 0x4f,  0x20, 0x65, 0x72, 0x72,  0x6f, 0x72, 0xff, 0x0d,  0x0a, 0x52, 0x65, 0x70,
 0x6c, 0x61, 0x63, 0x65,  0x20, 0x74, 0x68, 0x65,  0x20, 0x64, 0x69, 0x73,  0x6b, 0x2c, 0x20, 0x61,
 0x6e, 0x64, 0x20, 0x74,  0x68, 0x65, 0x6e, 0x20,  0x70, 0x72, 0x65, 0x73,  0x73, 0x20, 0x61, 0x6e,
 0x79, 0x20, 0x6b, 0x65,  0x79, 0x0d, 0x0a, 0x00,  0x49, 0x4f, 0x20, 0x20,  0x20, 0x20, 0x20, 0x20,
 0x53, 0x59, 0x53, 0x4d,  0x53, 0x44, 0x4f, 0x53,  0x20, 0x20, 0x20, 0x53,  0x59, 0x53, 0x80, 0x01,
 0x00, 0x57, 0x49, 0x4e,  0x42, 0x4f, 0x4f, 0x54,  0x20, 0x53, 0x59, 0x53,  0x00, 0x00, 0x55, 0xaa
};
/****************************************************************************************
Descriptor	Fullfill Blocks
*****************************************************************************************/
code	Device_Descriptor	device_descriptor = 
{
	0x12,			//Descriptor Length
	0x01,			//Descriptor Type
	0x0002,			//bcdUSB USB2.0 Protocal
	//0x1001,
	0x00,			//Device Class: Mass Storage
	0x00,			//Sub Device Class
	0x00,			//Device Protocal
	0x40,			//Max Packet size
	0x1234,			//ID Vendor
	0x5678,			//Product ID
	0x0000,			//BCD Device
	0x00,
	0x00,
	0x00,
	0x01			//Number of Configurations
		
} ;	
//////////////////////////////////////////////////////////////////////////////////////////////		
code	Config_Descriptor	config_descriptor = 
{
	0x09,			//Descriptor Length
	0x02,			//Descriptor type
	0x3C00,			//config + interface + 6*endpoint
	0x01,			//Number of interface
	0x01,			//config value for Set_config and Get_config		
	0x00,			//index of Config Descriptor
	0x80,			//Device is Self Powered, don't surpport Remote Wakeup
	0xFA			//Maximum Bus Current is 500mA

};	
//////////////////////////////////////////////////////////////////////////////////////////////
code	Interface_Descriptor	interface_descriptor =
{
	0x09,			//Length
	0x04,			//Type
	0x00,			//interface Number
	0x00,			//default value
	0x02,			//Endpoint Number
	0x08,			//interface Class
	0x06,			//Interface Sub Class
	0x50,			//Use Mass Storage Bulk Only Transfer 
	0x00			//Index of the Descriptor

};
//////////////////////////////////////////////////////////////////////////////////////////////
code	Endpoint_Descriptor		endpointIN1_descriptor = 
{
	0x07,			//Length
	0x05,			//Type
	0x81,			//Endpoint	Address
	0x02,			//Endpoint Surpport Bulk Transfer
	0x4000,			//Max Packet Size
	0x00			//not Related

};
///////////////////////////////////////////////////////////////////////////////////////////////
code	Endpoint_Descriptor		endpointOUT1_descriptor = 
{
	0x07,			//Length
	0x05,			//Type
	0x01,			//Endpoint	Address
	0x02,			//Endpoint Surpport Bulk Transfer
	0x4000,			//Max Packet Size
	0x00			//not Related

};
//////////////////////////////////////////////////////////////////////////////////////////////
code	Endpoint_Descriptor		endpointIN2_descriptor = 
{
	0x07,			//Length
	0x05,			//Type
	0x82,			//Endpoint	Address
	0x02,			//Endpoint Surpport Bulk Transfer
	0x4000,			//Max Packet Size
	0x00			//not Related

};
/////////////////////////////////////////////////////////////////////////////////////////////
code	Endpoint_Descriptor		endpointOUT2_descriptor = 
{
	0x07,			//Length
	0x05,			//Type
	0x02,			//Endpoint	Address
	0x02,			//Endpoint Surpport Bulk Transfer
	0x4000,			//Max Packet Size
	0x00			//not Related

};

////////////////////////////////////////////////////////////////////////////////////////////
code	Endpoint_Descriptor		endpointIN3_descriptor = 
{
	0x07,			//Length
	0x05,			//Type
	0x83,			//Endpoint	Address
	0x02,			//Endpoint Surpport Bulk Transfer
	0x4000,			//Max Packet Size
	0x00			//not Related

};

///////////////////////////////////////////////////////////////////////////////////////////
code	Endpoint_Descriptor		endpointOUT3_descriptor = 
{
	0x07,			//Length
	0x05,			//Type
	0x03,			//Endpoint	Address
	0x02,			//Endpoint Surpport Bulk Transfer
	0x4000,			//Max Packet Size
	0x00			//not Related

};
/////////////////////////////////////////////////////////////////////////////////////////
code	Config_Long		config_long = 
{
//Configure Descriptor
	{
	0x09,			//Descriptor Length
	0x02,			//Descriptor type
	0x2000,			//config + interface + 6*endpoint
	0x01,			//Number of interface
	0x01,			//config value for Set_config and Get_config		
	0x00,			//index of Config Descriptor
	0x80,			//Device is Self Powered, don't surpport Remote Wakeup
	0xFA			//Maximum Bus Current is 500mA

	},	

//Interface Descriptor
	{
	0x09,			//Length
	0x04,			//Type
	0x00,			//interface Number
	0x00,			//default value
	0x02,			//Endpoint Number
	0x08,			//interface Class
	0x06,			//Interface Sub Class
	0x50,			//Use Mass Storage Bulk Only Transfer 
	0x00			//Index of the Descriptor

	},

//Six Endpoint1-3 Descriptor
{
//Endpoint 1 IN description	
	{
	0x07,			//Length
	0x05,			//Type
	0x81,			//Endpoint	Address
	0x02,			//Endpoint Surpport Bulk Transfer
	0x4000,			//Max Packet Size
	0x00			//not Related

	},
//Endpoint 1 OUT Description
	{
	0x07,			//Length
	0x05,			//Type
	0x01,			//Endpoint	Address
	0x02,			//Endpoint Surpport Bulk Transfer
	0x4000,			//Max Packet Size
	0x00			//not Related

	},

//Endpoint 2 IN Description
/*	{
	0x07,			//Length
	0x05,			//Type
	0x82,			//Endpoint	Address
	0x02,			//Endpoint Surpport Bulk Transfer
	0x4000,			//Max Packet Size
	0x00			//not Related

	},
//Endpoint 2 OUT Description
	{
	0x07,			//Length
	0x05,			//Type
	0x02,			//Endpoint	Address
	0x02,			//Endpoint Surpport Bulk Transfer
	0x4000,			//Max Packet Size
	0x00			//not Related

	},
//Endpoint 3 IN Description
	{
	0x07,			//Length
	0x05,			//Type
	0x81,			//Endpoint	Address
	0x02,			//Endpoint Surpport Bulk Transfer
	0x4000,			//Max Packet Size
	0x00			//not Related

	},

//Endpoint 3 OUT Description
	{
	0x07,			//Length
	0x05,			//Type
	0x01,			//Endpoint	Address
	0x02,			//Endpoint Surpport Bulk Transfer
	0x4000,			//Max Packet Size
	0x00			//not Related

	},*/


}

};
/*****************************************************************************************
Global Variables Define Area
******************************************************************************************/
xdata	Flags	flags;							//Bulk in and Bulk out endPoint interrupt flags
CSW		*pCS;
bit		csw;
xdata	uchar		buf[512];

/****************************************************************************************
MAIN ROUTINE FOR USB TRANSFER
*****************************************************************************************/
void	main(void)
{
//variables define	area

	Oscillator_Init();
	System_Config();
	CLR_Flags();
	Read_ID();
	//page_read(0,0, 0);
	fill_DBR();
	//block_buffer(0);
	//check_invalid();
	//test_flash();
	USB_Config();
	

	while(1)
	{
		if(flags.epin1 | flags.epout1)
			Analysis_UFI();
																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																								
	}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               	

}

/****************************************************************************************
name:		USB_ISR
function:	USB Interrupt Service Routine
pars:		no
returns:	no
******************************************************************************************/
void	USB_ISR(void)	interrupt 8		
{
	uchar	CMINT_FLAG,IN_FLAG,	OUT_FLAG;				//Interrupt flags,IN,OUT and Common
	xdata	uchar	RevBuf[8];							//Save the host Requst Command
	Requst	*pReq;
	uchar	cmd,	number, i;	

	
//read interrupt status	
	CMINT_FLAG = SFR_RD(CMINT);							//save the Interrupt flags for 
														//Subroutine Entry
	IN_FLAG = SFR_RD(IN1INT);
	OUT_FLAG = SFR_RD(OUT1INT);


//interrupt subroutine process
	if(CMINT_FLAG & BIT2)								//Reset procedure
	{
		while(SFR_RD(POWER) & 0x08);
		USB_Config();
		
	}
	else if(IN_FLAG & BIT0)								//Endpoint 0 affairs procedure
	{
		SFR_WR(INDEX,	0x00);		
		cmd = SFR_RD(E0CSR);
		if(cmd & BIT0)
		{
			number = SFR_RD(E0CNT);
			for(i=0;i<number;i++)					    //Receive the host Requst
				RevBuf[i] = SFR_RD(FIFO0);
			cmd |= 0x48;								//Clear the Receive Interrupt Flag
														//and indicate Receive Data is END
			SFR_WR(E0CSR,	cmd);
			pReq = (pRequst)RevBuf;
			Analysis_Requst(pReq);
				

		}
		
		else if(cmd & BIT2)								//Stall procedure
		{
			cmd &= ~BIT2;
			SFR_WR(E0CSR,	cmd);
			//LED = 1;
		}		


	}
	 if(IN_FLAG & BIT1)
		flags.epin1 = 1;
    if(OUT_FLAG & BIT1)
		flags.epout1 = 1;
	  	
}
/*****************************************************************************************
Delay 1mS Subroutine
******************************************************************************************/
void	Delay_mS(uchar t)
{
	uint	i;
	uchar	j;
    for(j=0;j<t;j++)
	for(i=0;i<20000;i++);

}

void	Delay_uS(uint	t)
{
	do
	{
		_nop_();_nop_();
		_nop_();_nop_();
		_nop_();_nop_();
		_nop_();_nop_();
	}while(t--);
	

}

/*****************************************************************************************
name:		Oscillator_Init
function:	initial the system clock and 48MHz USB clock
pars:		no
returns:	no
******************************************************************************************/
void	Oscillator_Init(void)
{
    int i = 0;
    CLKMUL    = 0x80;
    for (i = 0; i < 20; i++);    			// Wait 5us for initialization
    CLKMUL    |= 0xC0;
    while ((CLKMUL & 0x20) == 0);
    CLKSEL    = 0x02;
    OSCICN    = 0x83;
}

/******************************************************************************************

⌨️ 快捷键说明

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