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

📄 usb.c

📁 一个简单的基于s3c2410的bootloader
💻 C
📖 第 1 页 / 共 2 页
字号:
//=========================================================================================
//usb.c
//=========================================================================================
#include "addr.h"
#include "usb.h"
#include "lib.h"
#include "libs.h"

struct USB_SETUP_DATA SetupData;
struct USB_DEVICE_DESCRIPTOR DescriptorDevice;
struct USB_CONFIGURATION_DESCRIPTOR DescriptorConfiguration;
struct USB_INTERFACE_DESCRIPTOR DescriptorInterface;
struct USB_ENDPOINT_DESCRIPTOR DescriptorEndpoint_0;
struct USB_ENDPOINT_DESCRIPTOR DescriptorEndpoint_1;
struct USB_GET_STATUS StatusGet;
U8 ConfiguratioSet;
U8 InterfaceSet;

static const U8 DescriptorString0[]={	//codes representing languages
	4,TYPE_STRING,LANGID_US_L,LANGID_US_H,  
    };
static const U8 DescriptorString1[]={	//Manufacturer  
        (0x14+2),TYPE_STRING, 
        'S',0x0,'y',0x0,'s',0x0,'t',0x0,'e',0x0,'m',0x0,' ',0x0,'M',0x0,
        'C',0x0,'U',0x0,
    };
static const U8 DescriptorString2[]={	//Product  
        (0x2a+2),TYPE_STRING, 
        'S',0x0,'E',0x0,'C',0x0,' ',0x0,'S',0x0,'3',0x0,'C',0x0,'2',0x0,
        '4',0x0,'1',0x0,'0',0x0,'X',0x0,' ',0x0,'T',0x0,'e',0x0,'s',0x0,
        't',0x0,' ',0x0,'B',0x0,'/',0x0,'D',0x0
    };
    
volatile U8 DownStatus;
volatile U32 uDownSize;
volatile U32 uDownAddr;
volatile U16 uCheckSum;
volatile U32 uTempDownSize;
U8 * pDownAddr;

void Handler_Ep0( void );
void Handler_Ep1( void );
void Handler_Ep3( void );
void ResetUsbdReg( void );
void __irq IsrDma2( void );
 
void USBD_ReadFIFO( U8 * buf, volatile U8 * pFIFO, U32 size )
{
	U32 i;
    	
	for( i = 0; i < size; i++ )
	{
		buf[i] = *pFIFO;	
	}
}
 
U16 USBD_ReadFIFO_WithChecksumReturn( U8 * buf, volatile U8 * pFIFO, U32 size )
{
	U32 i;
    U16 uChecksum = 0;
    
	for( i = 0; i < size; i++ )
	{
		buf[i] = *pFIFO;
		uChecksum += buf[i];
	}
	
	return uChecksum;
}

void USBD_WriteFIFO( U8 * buf, volatile U8 * pFIFO, U32 size )
{
	U32 i;
	for( i = 0; i < size; i++ )
	{
		*pFIFO = buf[i];	
	}
}

void ResetUsbdReg( void )
{
// *** End point information ***
//   EP0: control
//   EP1: bulk in end point
//   EP2: not used
//   EP3: bulk out end point
//   EP4: not used 
	rPWR_REG = 0x0;	//disable suspend mode

    rINDEX_REG = 0;	
    rMAXP_REG = FIFO_SIZE_8;
    rEP0_CSR = BIT_EP0_CSR_SERVICED_OUT_PKT_RDY | BIT_EP0_CSR_SERVICED_SETUP_END;
 				
    rINDEX_REG = 1;
    #if (EP1_PKT_SIZE == 32)
		rMAXP_REG = FIFO_SIZE_32;
    #else
		rMAXP_REG = FIFO_SIZE_64;
    #endif	
    rIN_CSR1_REG = BIT_EPIN1_FIFO_FLUSH | BIT_EPIN1_CLR_DATA_TOGGLE;	
    rIN_CSR2_REG = BIT_EPIN2_MODE_IN | BIT_EPIN2_IN_DMA_INT_MASK | BIT_EPIN2_BULK;   
    rOUT_CSR1_REG = BIT_EPOUT1_CLR_DATA_TOGGLE;   	
	//The data toggle bit should be cleared when initialization.
    rOUT_CSR2_REG = BIT_EPOUT2_BULK | BIT_EPOUT2_OUT_DMA_INT_MASK;   	

    rINDEX_REG = 2;
	#if (EP2_PKT_SIZE == 32)
		rMAXP_REG = FIFO_SIZE_32;
    #else
		rMAXP_REG = FIFO_SIZE_64;
	#endif	
    rIN_CSR1_REG = BIT_EPIN1_FIFO_FLUSH | BIT_EPIN1_CLR_DATA_TOGGLE;
    rIN_CSR2_REG = BIT_EPIN2_MODE_IN | BIT_EPIN2_IN_DMA_INT_MASK;  
    rOUT_CSR1_REG = BIT_EPOUT1_CLR_DATA_TOGGLE;   
	//The data toggle bit should be cleared when initialization.	
    rOUT_CSR2_REG = BIT_EPOUT2_BULK | BIT_EPOUT2_OUT_DMA_INT_MASK;   	

	rINDEX_REG = 3;
	#if (EP3_PKT_SIZE == 32)
		rMAXP_REG = FIFO_SIZE_32;
    #else
		rMAXP_REG = FIFO_SIZE_64;
	#endif	
    rIN_CSR1_REG = BIT_EPIN1_FIFO_FLUSH | BIT_EPIN1_CLR_DATA_TOGGLE;
    rIN_CSR2_REG = BIT_EPIN2_MODE_OUT | BIT_EPIN2_IN_DMA_INT_MASK;
    rOUT_CSR1_REG = BIT_EPOUT1_CLR_DATA_TOGGLE;   
	//The data toggle bit should be cleared when initialization.
    rOUT_CSR2_REG = BIT_EPOUT2_BULK | BIT_EPOUT2_OUT_DMA_INT_MASK;   	

    rINDEX_REG = 4;
	#if (EP4_PKT_SIZE == 32)
		rMAXP_REG = FIFO_SIZE_32;
    #else
		rMAXP_REG = FIFO_SIZE_64;
	#endif		
    rIN_CSR1_REG = BIT_EPIN1_FIFO_FLUSH | BIT_EPIN1_CLR_DATA_TOGGLE;
    rIN_CSR2_REG = BIT_EPIN2_MODE_OUT | BIT_EPIN2_IN_DMA_INT_MASK;   
    rOUT_CSR1_REG = BIT_EPOUT1_CLR_DATA_TOGGLE;
	//The data toggle bit should be cleared when initialization.
    rOUT_CSR2_REG = BIT_EPOUT2_BULK | BIT_EPOUT2_OUT_DMA_INT_MASK;  

    rEP_INT_REG = BIT_USBD_EP0_INT |  BIT_USBD_EP1_INT |  BIT_USBD_EP2_INT | 
    			 BIT_USBD_EP3_INT |  BIT_USBD_EP4_INT;
    rUSB_INT_REG = BIT_USBD_SUSPEND_INT | BIT_USBD_SUSPEND_INT | BIT_USBD_RESET_INT; 
    
    rEP_INT_EN_REG = BIT_USBD_EP0_INT |  BIT_USBD_EP1_INT | BIT_USBD_EP3_INT;
    rUSB_INT_EN_REG = BIT_USBD_RESET_INT;
    
	uDownSize = 0;
	uDownAddr = 0;
	uCheckSum = 0;
	DownStatus = 0;
}

void InitDescriptorTable(void)
{	
    //Standard device descriptor
    DescriptorDevice.bLength 			= 0x12;	//EP0_DEV_DESC_SIZE=0x12 bytes    
    DescriptorDevice.bDescriptorType 	= TYPE_DEVICE;         
    DescriptorDevice.bcdUSBL 			= 0x10;
    DescriptorDevice.bcdUSBH 			= 0x01; 	//Ver 1.10
    DescriptorDevice.bDeviceClass 		= 0xFF;	//0x0          
    DescriptorDevice.bDeviceSubClass 	= 0x0;          
    DescriptorDevice.bDeviceProtocol	= 0x0;          
    DescriptorDevice.bMaxPacketSize0	= 0x8;         
    DescriptorDevice.idVendorL			= 0x45;
    DescriptorDevice.idVendorH			= 0x53;
    DescriptorDevice.idProductL			= 0x34;
    DescriptorDevice.idProductH			= 0x12;
    DescriptorDevice.bcdDeviceL			= 0x00;
    DescriptorDevice.bcdDeviceH			= 0x01;
    DescriptorDevice.iManufacturer		= 0x1;	//index of string descriptor
    DescriptorDevice.iProduct			= 0x2;	//index of string descriptor 
    DescriptorDevice.iSerialNumber		= 0x0;
    DescriptorDevice.bNumConfigurations	= 0x1;

    //Standard configuration descriptor
    DescriptorConfiguration.bLength				= 0x9;    
    DescriptorConfiguration.bDescriptorType		= TYPE_CONFIGURATION;         
    DescriptorConfiguration.wTotalLengthL		= 0x20; //<cfg desc>+<if desc>+<endp0 desc>+<endp1 desc>
    DescriptorConfiguration.wTotalLengthH		= 0;
    DescriptorConfiguration.bNumInterfaces		= 1;
    DescriptorConfiguration.bConfigurationValue	= 1;  
    DescriptorConfiguration.iConfiguration		= 0;
    DescriptorConfiguration.bmAttributes		= CONF_ATTR_DEFAULT|CONF_ATTR_SELFPOWERED;  //bus powered only.
    DescriptorConfiguration.maxPower			= 25;	//draws 50mA current from the USB bus.          

    //Standard interface descriptor
    DescriptorInterface.bLength				= 0x9;    
    DescriptorInterface.bDescriptorType		= TYPE_INTERFACE;         
    DescriptorInterface.bInterfaceNumber	= 0x0;
    DescriptorInterface.bAlternateSetting	= 0x0; //?
    DescriptorInterface.bNumEndpoints		= 2;	//# of endpoints except EP0
    DescriptorInterface.bInterfaceClass		= 0xff; //0x0 ?
    DescriptorInterface.bInterfaceSubClass	= 0x0;  
    DescriptorInterface.bInterfaceProtocol	= 0x0;
    DescriptorInterface.iInterface			= 0x0;

    //Standard endpoint0 descriptor
    DescriptorEndpoint_0.bLength			= 0x7;    
    DescriptorEndpoint_0.bDescriptorType	= TYPE_ENDPOINT;         
    DescriptorEndpoint_0.bEndpointAddress	= 1|EP_ADDR_IN;   // 2400Xendpoint 1 is IN endpoint.
    DescriptorEndpoint_0.bmAttributes		= EP_ATTR_BULK;
    DescriptorEndpoint_0.wMaxPacketSizeL	= EP1_PKT_SIZE; //64
    DescriptorEndpoint_0.wMaxPacketSizeH	= 0x0;
    DescriptorEndpoint_0.bInterval			= 0x0; //not used

    //Standard endpoint1 descriptor
    DescriptorEndpoint_1.bLength			= 0x7;    
    DescriptorEndpoint_1.bDescriptorType	= TYPE_ENDPOINT;         
    DescriptorEndpoint_1.bEndpointAddress	= 3|EP_ADDR_OUT;   // 2400X endpoint 3 is OUT endpoint.
    DescriptorEndpoint_1.bmAttributes		= EP_ATTR_BULK;
    DescriptorEndpoint_1.wMaxPacketSizeL	= EP3_PKT_SIZE; //64
    DescriptorEndpoint_1.wMaxPacketSizeH	= 0x0;
    DescriptorEndpoint_1.bInterval			= 0x0; //not used 
    
}

void UsbTest( void )
{
    //rGPGUP &= ~(1<<9); /* Enable GPG9 */
    //rGPGDAT |= (1<<9); /* set GPG9 high */ 
    
	rGPHCON = rGPHCON & ~(0xf<<18) | (0x5<<18);  
	Delay(200);
	Irq_InstallHandler( BIT_USBD, USBDIsr );
	Irq_InstallHandler( BIT_DMA2, IsrDma2 );
    ClearPending( BIT_USBD ); 
    ClearPending( BIT_DMA2 ); 
    //To enhance the USB signal quality.
    //CLKOUT 0,1=OUTPUT to reduce the power consumption.
    rMISCCR=rMISCCR & ~(1<<3); // USBD is selected instead of USBH1 
    rMISCCR=rMISCCR & ~(1<<13); // USB port 1 is enabled.
    
    
//	MMU_EnableICache();
	
    InitDescriptorTable();
    ResetUsbdReg();
	Irq_Enable( BIT_USBD );
}

void Handler_Ep0( void )
{
    static U8* pBuffer;
    static U32 uSize;
    static U32 uPos;
    U8 ustatus_EP0_CSR;
    U8 ubakup_rINDEX_REG;
    
    ubakup_rINDEX_REG = rINDEX_REG;
    rINDEX_REG = 0;
	ustatus_EP0_CSR = rEP0_CSR;
	
	//	exception, host end the control transfer befor DATA_END is set
	if ( ustatus_EP0_CSR & BIT_EP0_SETUP_END )
	{
		rEP0_CSR = ( ustatus_EP0_CSR & ( BIT_EP0_WR_BITS ) 
				| BIT_EP0_CSR_SERVICED_SETUP_END );
		if ( ustatus_EP0_CSR & BIT_EP0_OUT_PKT_RDY )
		{
			rEP0_CSR = ( ustatus_EP0_CSR & ( BIT_EP0_WR_BITS ) 
					| BIT_EP0_CSR_SERVICED_OUT_PKT_RDY );
			DbgPrintf("ex if\n");	
		}
		else
		{
			DbgPrintf("ex else\n");	
		}
		pBuffer = 0;
	}
	
	//	exception, protocol violation.
	else if ( ustatus_EP0_CSR & BIT_EP0_SENT_STALL )
	{
		if ( ustatus_EP0_CSR & BIT_EP0_OUT_PKT_RDY )
			rEP0_CSR = ( ustatus_EP0_CSR & ( BIT_EP0_WR_BITS ) 
					| BIT_EP0_SENT_STALL | BIT_EP0_CSR_SERVICED_OUT_PKT_RDY );
		else
			rEP0_CSR = ( ustatus_EP0_CSR & ( BIT_EP0_WR_BITS ) 
					| BIT_EP0_SENT_STALL );
		DbgPrintf("exception, protocol violation\n");
	}
	
    else if( ( ustatus_EP0_CSR & BIT_EP0_OUT_PKT_RDY ) )
    {	
    	USBD_ReadFIFO((U8 *)&SetupData, &rEP0_FIFO, EP0_PKT_SIZE);
		
		switch( SetupData.bRequest )
    	{
			case GET_DESCRIPTOR:
				switch( SetupData.bValueH )
				{
				case TYPE_DEVICE:
					DbgPrintf( "GT_DE\n" );
					pBuffer = ( U8 * )&DescriptorDevice;
					uSize = sizeof( DescriptorDevice );
					uPos = 0;		
					rEP0_CSR = ( ustatus_EP0_CSR & ( BIT_EP0_WR_BITS ) 
							| BIT_EP0_CSR_SERVICED_OUT_PKT_RDY );
					break;
				case TYPE_CONFIGURATION:
					DbgPrintf( "GT_CF\n" );					
					pBuffer = ( U8 * )&DescriptorConfiguration;
					if ( ( SetupData.bLengthL + ( SetupData.bLengthH << 8 ) ) > 0x09 )
	 	    	  		//bLengthH should be used for bLength=0x209 at WIN2K.
	  		    		uSize = sizeof( DescriptorConfiguration )
	  		    				+ sizeof( DescriptorInterface ) 
	  		    				+ 2 * sizeof( DescriptorEndpoint_0 );
					else	    	    //for WIN2K
	  		    		uSize = sizeof( DescriptorConfiguration );
					uPos = 0;				
					rEP0_CSR = ( ustatus_EP0_CSR & ( BIT_EP0_WR_BITS ) 
							| BIT_EP0_CSR_SERVICED_OUT_PKT_RDY );
					break;
				case TYPE_INTERFACE:
					DbgPrintf( "GT_IF\n" );
					pBuffer = ( U8 * )&DescriptorInterface;
					uSize = sizeof( DescriptorInterface );
					uPos = 0;				
					rEP0_CSR = ( ustatus_EP0_CSR & ( BIT_EP0_WR_BITS ) 
							| BIT_EP0_CSR_SERVICED_OUT_PKT_RDY );
					break;
				case TYPE_ENDPOINT:
					DbgPrintf( "GT_EP\n" );
		 	    	switch( SetupData.bValueL & 0xf )
			    	{
			    	case 0:

⌨️ 快捷键说明

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