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

📄 usbrx.c

📁 一个USB的驱动驱动
💻 C
字号:
/*==================================================
 		Include head files 
 ==================================================*/
#include "USBdisk_main.h"
#include "types.h"
#include "melody.h"
#include "bsp_gpio_cfg.h"

#define USB_DISK_START		0x0A000000
/*==================================================
 		External variables and function declatrtion
 ==================================================*/

/*==================================================
 		Globle Variables
 ==================================================*/
UINT8   _gUsbDevReq_8[2];     			//device request from host
UINT16  _gUsbDevReq_16[3];     			//device request from host

UINT32  _gUsbNumSector;         		//number of sector to read/write
UINT32  _gUsbCurSector;         		//current sector being read/write
UINT8	_gCBW[32];						//ommand block wrapper

int USB_Index = 0;
int USB_TxEn = 0;
int USB_RxEn = 0;
int USB_Power = 0;

//device descriptors								
const UINT8  _gUsbDevDscptr[18] = 	{	
										0x12,0x01,0x00,0x02,
    									0x00,0x00,0x00,0x40,
    									0xFB,0x07,0x00,0x00,
    									0x00,0x13,0x00,0x00,
    									0x00,0x01
                     				};
                     				
//configutation descriptors
const UINT8 _gUsbConfDscptr[32] = 	{	
                    					0x09,0x02,0x20,0x00,
                    					0x01,0x01,0x00,0xc0,
                                        0x64,0x09,0x04,0x00,
                                        0x00,0x02,0x08,0x06,
                                     	0x50,0x00,0x07,0x05,
                                      	0x81,0x02,0x00,0x02,
                  						0x00,0x07,0x05,0x02,
                    					0x02,0x20,0x00,0x00
                    					
    								};	

const UINT8 BulkonlyInquiry[36] =   {									
										0x00,0x80,0x00,0x01,
										0x1F,0x00,0x00,0x00,		
										0x50,0x4d,0x50,0x20,
										0x53,0x54,0x41,0x52,
										0x44,0x41,0x4e,0x44,
										0x78,0x20,0x55,0x45,
										0x44,0x49,0x53,0x4b,
										0x20,0x20,0x20,0x20,							
										0x30,0x31,0x30,0x30		 
								    };
const UINT8 FAT16[64] = {
							 0xeb,0x3c,0x90, // Jump Code
							 0x4d,0x53,0x57,0x49,0x4e,0x34,0x2e,0x31, // OEM Name
							 0x00,0x02, // 512 bytes per sector
							 0x10,	// 16 sectors per cluster
							 0x01,0x00, // Reserved Sector        
	       					 0x02,  // 2 FAT
	       					 0x00,0x02, // 512 max root dir entry
	       					 0x00,0x00, 
	       					 0xf8,  // Media type
	       					 0x18,0x00, // Sectors Per FAT
	       					 0x3f,0x00,	// Sectors Per Track
	       					 0xff,0x00, // Num of Head
	       					 0x00,0x00,0x00,0x00, // Number of Hidden Sectors in Partition     
	       					 0xAF,0xFF,0x00,0x00, // Number of Sectors in Partition
	       					 0x00,0x00, // Logical Drive Number of Partition
	       					 0x29,
	       					 0x00,0x00,0x00,0x00, // Serial Number of Partition
	       					 0x20,0x20,0x20,0x20,0x20,      
	      					 0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x41,0x54,0x31,0x36,0x20,0x20,0x20,0x00,0x00,
						};
/*==================================================
 		Functions define
 ==================================================*/
PGPIO_REGS pGPIORegs = (PGPIO_REGS)GPIO_REGS_PA_BASE;
/*---------------------------------------
 		USB Inition
 ---------------------------------------*/
void USBInit(void)
{
	UINT32 tmpGPIO;
	
	GPIOInit(pGPIORegs, USB_PW, GPIO_USE, GPIO_OUTPUT, GPIO_HIGH);

	_reg_PLL_GPCR = 0x000003ff;	
	_reg_PLL_CSCR = 0x27004002;	                            
	_reg_PLL_PCDR = 0x00000000;				
	_reg_PLL_PCTL = 0xa8010046;
	
	_reg_PLL_GCCR = 0x00000009;	
							 
	tmpGPIO = _reg_GPIO_USB_GIUS;	
	tmpGPIO = tmpGPIO & 0xfffffBff;	
	_reg_GPIO_USB_GIUS = tmpGPIO;
	
	tmpGPIO = _reg_GPIO_USB_GIUS;
	tmpGPIO = tmpGPIO | 0x40080000;	
	_reg_GPIO_USB_GIUS = tmpGPIO;
	
	tmpGPIO = _reg_GPIO_USB_DDIR;
	tmpGPIO = tmpGPIO & 0xbfffffff;
	_reg_GPIO_USB_DDIR = tmpGPIO;
	
	tmpGPIO = _reg_GPIO_USB_DDIR;
	tmpGPIO |= 0x00080000;
	_reg_GPIO_USB_DDIR = tmpGPIO;
	
}


/*---------------------------------------
 		USB soft connect
 ---------------------------------------*/
void USBSoftConnect(void)
{
	_reg_USBD_IntrTxE  |= 0x0002;
	_reg_USBD_IntrRxE  |= 0x0004;
		
	_reg_USBD_Power |= 0x20;
	
	_reg_USBD_Power |= 0x40;
	
	while(!(_reg_USBD_Power & 0x08));
	
	while(!(_reg_USBD_Power & 0x10));
	
	_reg_USBD_Index  = 0x01;
	_reg_USBD_TxCSR  = 0x2048;
	_reg_USBD_Index  = 0x02;
	_reg_USBD_RxCSR  = 0x0090;
	USB_TxEn = _reg_USBD_IntrTxE;
	USB_RxEn = _reg_USBD_IntrRxE;
	USB_Index = _reg_USBD_Index;
	USB_Power = _reg_USBD_Power;
}

void readUSB()
{
	int i;
	unsigned char *p;

	for(;_gUsbNumSector>0;_gUsbNumSector--)
	{
		p = (unsigned char *)(USB_DISK_START + _gUsbCurSector * 512);
		for(i=0;i<512;i++) _reg_USBD_FIFO1_byte = p[i];
				
		_reg_USBD_Index = 0x01;
		_reg_USBD_TxCSR |= 0x2001;
		while(_reg_USBD_TxCSR & 0x0001);
			
		_gUsbCurSector++;
	}
}

void writeUSB()
{
	int i=0,j=0;
	int k;
	unsigned char *p;

	for(; _gUsbNumSector > 0; _gUsbNumSector--)
	{
		for(k=0;k<16;k++)
		{
			_reg_USBD_Index = 0x02;	
			while(!(_reg_USBD_RxCSR & 0x0001));
			p = (unsigned char *)(USB_DISK_START + _gUsbCurSector * 512);
			for(i=0;i<0x20;i++)
			{
				*p++ = _reg_USBD_FIFO2_byte;
			}
						
			_reg_USBD_RxCSR &= 0xfffe;
		}				
	
		_gUsbCurSector++;
	}
				
	_reg_USBD_Index = 0x02;	
	_reg_USBD_RxCSR &= 0xfffe;	
}

UINT16 RxCount;
UINT16 RxCount1;
UINT16 RxCount2;

static void processCommand()		//using SCSI command
{
	UINT32	i,j=0,k;
	UINT32 dCBWDataTransferLength;
	UINT8  dCSWSignature[4] = {	0x55,0x53,0x42,0x53	};
	
	while(1)
	{
		_reg_USBD_Index = 0x02;	
		while(!(_reg_USBD_RxCSR & 0x0001));	
		RxCount = _reg_USBD_RxCount;
		if(RxCount == 0x20)
		{
			for (i=0;i<0x20;i++) 
			{													
				_gCBW[j] = _reg_USBD_FIFO2_byte;
				j++;
			}
			_reg_USBD_RxCSR &= 0xfffe;		
		}
		else if((0x00 < RxCount) && (RxCount < 0x20))
		{
			for (i=0; i<RxCount; i++) 
			{													
				_gCBW[j] = _reg_USBD_FIFO2_byte;
				j++;
			}
			_reg_USBD_RxCSR &= 0xfffe;
			break;
		}
		else if(RxCount == 0x00)
		{
			_reg_USBD_RxCSR &= 0xfffe;
			break;
		}
		else
		{
			printf("error!the recieved packet size exceed the Max packet size");
			return;
		}
	}
	_reg_USBD_Index = 0x02;	
	_reg_USBD_RxCSR &= 0xfffe;
	
	switch(_gCBW[15])
	{
		case 0x12:	// INQUIRY,  return 36 bytes				
			for(i=0;i<36;i++) _reg_USBD_FIFO1_byte = BulkonlyInquiry[i];
			
			_reg_USBD_Index = 0x01;			
			_reg_USBD_TxCSR |= 0x2001;
			while(_reg_USBD_TxCSR & 0x0001);
			
			
			for(i=0;i<4;i++) _reg_USBD_FIFO1_byte = dCSWSignature[i];			
			for(i=4;i<8;i++) _reg_USBD_FIFO1_byte = _gCBW[i];			
			for(i=0;i<4;i++) _reg_USBD_FIFO1_byte = 0x00;			
			_reg_USBD_FIFO1_byte = 0x00;
									
			_reg_USBD_Index = 0x01;
			_reg_USBD_TxCSR |= 0x0001;
			while(_reg_USBD_TxCSR & 0x0001);
				
						
			break;
		case 0x23:	// READ FORMAT CAPACITIES, not supported, return STALL
		case 0x1A:	// MODE SENSE (6), not supported, return STALL
		case 0x5A:	// MODE SENSE (10), not supported, return STALL			
			for(i=0;i<4;i++) _reg_USBD_FIFO1_byte = dCSWSignature[i];
			for(i=4;i<12;i++) _reg_USBD_FIFO1_byte = _gCBW[i];
			_reg_USBD_FIFO1_byte = 0x01;
			
			_reg_USBD_Index = 0x01;
			_reg_USBD_TxCSR |= 0x2001;
			while(_reg_USBD_TxCSR & 0x0001);
			
			_reg_USBD_Index = 0x01;
			_reg_USBD_TxCSR |= 0x2010;
			while(_reg_USBD_TxCSR & 0x0020);	
		      
			break;
		case 0x1B:
			for(i=0;i<4;i++) _reg_USBD_FIFO1_byte = dCSWSignature[i];			
			for(i=4;i<8;i++) _reg_USBD_FIFO1_byte = _gCBW[i];			
			for(i=0;i<4;i++) _reg_USBD_FIFO1_byte = 0x00;			
			_reg_USBD_FIFO1_byte = 0x00;
									
			_reg_USBD_Index = 0x01;
			_reg_USBD_TxCSR |= 0x0001;
			while(_reg_USBD_TxCSR & 0x0001);
			
			break;			
		case 0x03:	// REQUEST SENSE, return error 
			_reg_USBD_FIFO1_byte = 0x70;
			_reg_USBD_FIFO1_byte = 0x00;
			_reg_USBD_FIFO1_byte = 0x05;
			_reg_USBD_FIFO1_byte = 0x00;
			_reg_USBD_FIFO1_byte = 0x00;
			_reg_USBD_FIFO1_byte = 0x00;
			_reg_USBD_FIFO1_byte = 0x00;
			_reg_USBD_FIFO1_byte = 0x0C;
			_reg_USBD_FIFO1_byte = 0x00;
			_reg_USBD_FIFO1_byte = 0x00;
			_reg_USBD_FIFO1_byte = 0x00;
			_reg_USBD_FIFO1_byte = 0x00;
			_reg_USBD_FIFO1_byte = 0x20;
			_reg_USBD_FIFO1_byte = 0x00;
			_reg_USBD_FIFO1_byte = 0x00;
			_reg_USBD_FIFO1_byte = 0x00;
			_reg_USBD_FIFO1_byte = 0x00;
			_reg_USBD_FIFO1_byte = 0x00;
			
			_reg_USBD_Index = 0x01;
			_reg_USBD_TxCSR |= 0x2001;
			while(_reg_USBD_TxCSR & 0x0001);
			
			
			for(i=0;i<4;i++)_reg_USBD_FIFO1_byte = dCSWSignature[i];
			for(i=4;i<8;i++)_reg_USBD_FIFO1_byte = _gCBW[i];
			for(i=0;i<4;i++)_reg_USBD_FIFO1_byte = 0x00;
			_reg_USBD_FIFO1_byte = 0x00;
			
			_reg_USBD_Index = 0x01;
			_reg_USBD_TxCSR |= 0x2001;
			while(_reg_USBD_TxCSR & 0x0001);
			
			break;		
		case 0x25:	// READ_CAPACITY
						
			_reg_USBD_FIFO1_byte = 0x00;
			_reg_USBD_FIFO1_byte = 0x00;
			_reg_USBD_FIFO1_byte = 0xff;
			_reg_USBD_FIFO1_byte = 0x7f;
			_reg_USBD_FIFO1_byte = 0x00;
			_reg_USBD_FIFO1_byte = 0x00;
			_reg_USBD_FIFO1_byte = 0x02;
			_reg_USBD_FIFO1_byte = 0x00;
			
			_reg_USBD_Index = 0x01;
			_reg_USBD_TxCSR |= 0x2001;
			while(_reg_USBD_TxCSR & 0x0001);
			
			for(i=0;i<4;i++)_reg_USBD_FIFO1_byte = dCSWSignature[i];
			for(i=4;i<8;i++)_reg_USBD_FIFO1_byte = _gCBW[i];
			for(i=0;i<4;i++)_reg_USBD_FIFO1_byte = 0x00;
			_reg_USBD_FIFO1_byte = 0x00;
			
			_reg_USBD_Index = 0x01;
			_reg_USBD_TxCSR |= 0x2001;
			while(_reg_USBD_TxCSR & 0x0001);
					
			break;
		case 0x00:
			for(i=0;i<4;i++)_reg_USBD_FIFO1_byte = dCSWSignature[i];
			for(i=4;i<8;i++)_reg_USBD_FIFO1_byte = _gCBW[i];
			for(i=0;i<4;i++)_reg_USBD_FIFO1_byte = 0x00;
			_reg_USBD_FIFO1_byte = 0x00;
			
			_reg_USBD_Index = 0x01;
			_reg_USBD_TxCSR |= 0x2001;
			while(_reg_USBD_TxCSR & 0x0001);
			
			break;
		case 0x1E:
			for(i=0;i<4;i++)_reg_USBD_FIFO1_byte = dCSWSignature[i];
			for(i=4;i<8;i++)_reg_USBD_FIFO1_byte = _gCBW[i];
			for(i=0;i<4;i++)_reg_USBD_FIFO1_byte = 0x00;
			_reg_USBD_FIFO1_byte = 0x00;
			
			_reg_USBD_Index = 0x01;
			_reg_USBD_TxCSR |= 0x2001;
			while(_reg_USBD_TxCSR & 0x0001);
					
			break;
		case 0x2F:
			for(i=0;i<4;i++)_reg_USBD_FIFO1_byte = dCSWSignature[i];
			for(i=4;i<8;i++)_reg_USBD_FIFO1_byte = _gCBW[i];
			for(i=0;i<4;i++)_reg_USBD_FIFO1_byte = 0x00;
			_reg_USBD_FIFO1_byte = 0x00;
			
			_reg_USBD_Index = 0x01;
			_reg_USBD_TxCSR |= 0x2001;
			while(_reg_USBD_TxCSR & 0x0001);
				
			break;
		case 0x28:	// READ(10)	
			
			_gUsbCurSector = 0;
			for (i=0; i<4; i++)
				_gUsbCurSector = (_gUsbCurSector << 8) | (UINT32)_gCBW[17+i];			
			_gUsbNumSector = (((UINT32)_gCBW[22]) << 8) | ((UINT32)_gCBW[23]);
			
			readUSB();
			
			for(i=0;i<4;i++)_reg_USBD_FIFO1_byte = dCSWSignature[i];
			for(i=4;i<8;i++)_reg_USBD_FIFO1_byte = _gCBW[i];
			for(i=0;i<4;i++)_reg_USBD_FIFO1_byte = 0x00;
			_reg_USBD_FIFO1_byte = 0x00;
			
			_reg_USBD_Index = 0x01;
			_reg_USBD_TxCSR |= 0x2001;
			while(_reg_USBD_TxCSR & 0x0001);
			
			break;
		case 0x2A:	// WRITE(10)			
			_gUsbCurSector = 0;
			_gUsbNumSector = 0;
			for (i=0; i<4; i++) 
			{
				_gUsbCurSector = (_gUsbCurSector << 8) | (UINT32)_gCBW[17+i];
			}			
			_gUsbNumSector = (((UINT32)_gCBW[22]) << 8) | ((UINT32)_gCBW[23]);
			
			writeUSB();
			
			for(i=0;i<4;i++)_reg_USBD_FIFO1_byte = dCSWSignature[i];
			for(i=4;i<8;i++)_reg_USBD_FIFO1_byte = _gCBW[i];
			for(i=0;i<4;i++)_reg_USBD_FIFO1_byte = 0x00;
			_reg_USBD_FIFO1_byte = 0x00;
			
			_reg_USBD_Index = 0x01;
			_reg_USBD_TxCSR |= 0x2001;
			while(_reg_USBD_TxCSR & 0x0001);
			
			break;

		default:
			break;
	}
}

static void handleGetDevDscptr(void)
{
	UINT32 i;
	
	for(i=0;i<8;i++)
	{
		_reg_USBD_FIFO0_byte = _gUsbDevDscptr[i];
	}
	if (_gUsbDevReq_16[2] >= 0x12) 
	{
		for(i=8;i<18;i++)
		{
			_reg_USBD_FIFO0_byte = _gUsbDevDscptr[i];
		}
	}
	
}

static void handleGetConfDscptr(void)
{
	UINT32 i;

	if (_gUsbDevReq_16[2] == 0x09) 
	{	
		for(i=0;i<9;i++)
		{
			_reg_USBD_FIFO0_byte = _gUsbConfDscptr[ i];
		}
	}
	else 
	{
		for(i=0;i<32;i++)
		{			
			_reg_USBD_FIFO0_byte = _gUsbConfDscptr[ i];
		}
	}
}

static void handleDevReq(void)
{
	UINT32 fifoWord;
	
	fifoWord = _reg_USBD_FIFO0_word;
	_gUsbDevReq_8[0] = (UINT8)(fifoWord );			//bmRequestType,1 byte	
	_gUsbDevReq_8[1] = (UINT8)(fifoWord >> 8);		//bRequest,1 byte	
	_gUsbDevReq_16[0] = (UINT16)(fifoWord >> 16);	//wValue,2 bytes	
	
	
	fifoWord = _reg_USBD_FIFO0_word;
	_gUsbDevReq_16[1] = (UINT16)(fifoWord); 		//wIndex,2 bytes	
	_gUsbDevReq_16[2] = (UINT16)(fifoWord >> 16); 	//wLength,2 bytes
		
	_reg_USBD_Index = 0x00;
	_reg_USBD_CSR0 |= 0x0040;
	
	switch(_gUsbDevReq_8[1])
	{
		case 0x05:
			_reg_USBD_FAddr = (UINT8)_gUsbDevReq_16[0];
			_reg_USBD_CSR0  |= 0x0048;
			{
				_reg_USBD_Index = 0x01;
				_reg_USBD_TxMaxP = 0x0200;
					
				_reg_USBD_Index  = 0x02;
				_reg_USBD_RxMaxP = 0x0020;
					
				_reg_USBD_Index = 0x00;
			}
			break;
	
		case 0x06:
			switch (_gUsbDevReq_16[0]) 
			{				
				case 0x0100: 			//1 for device descriptor																
					handleGetDevDscptr();

					_reg_USBD_Index = 0x00;
					_reg_USBD_CSR0  |= 0x000A;
					while(_reg_USBD_CSR0 & 0x0002);
								
					break;
				case 0x0200: 			//2 for configuration descriptor								
					handleGetConfDscptr();

					_reg_USBD_Index = 0x00;
					_reg_USBD_CSR0  |= 0x000A;
					while(_reg_USBD_CSR0 & 0x0002);

					break;
			}
			break;
			
		case 0xfe:
			_reg_USBD_FIFO0_byte = 0x00;

			_reg_USBD_Index = 0x00;
			_reg_USBD_CSR0  |= 0x000A;
			while(_reg_USBD_CSR0 & 0x0002);

			break;

		default:
			break;			
	}
}

void formatDrive()
{
	unsigned int i, j, k;
	unsigned char *p;

	p = (unsigned char *)USB_DISK_START;

	// write boot sector
	for (i=0; i<64; i++)
	{
		*(p++) = FAT16[i];
	}

	for(i = 64; i < 512; i++)
	{
		*(p++) = 0;
	}

	// write FAT (2 copies)
	for (i=0; i<2; i++)
	{
		*(p++) = 0xF8;
		*(p++) = 0xFF;
		*(p++) = 0xFF;
		for (j=3; j<512; j++)
			*(p++) = 0;
		for (j=1; j<24; j++)
			for (k=0; k<512; k++)
				*(p++) = 0;
	}

	// write directory entries
	for (i=0; i<32; i++)
		for (j=0; j<512; j++)
			*(p++) = 0;
}

/*----------------------------------------------------
 	USB main function
 ----------------------------------------------------*/
void usbrx(void)
{	
	_reg_USBD_Index = 0x00;
	if(_reg_USBD_CSR0 & 0x0001)
	{
		handleDevReq();				// handle DevRqs to EP0
	}
		
	_reg_USBD_Index = 0x02;	
	if(_reg_USBD_RxCSR & 0x0001)
	{
	    processCommand();			// handle Bulk-only protocol to EP2					
	}
}

⌨️ 快捷键说明

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