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

📄 usbd_ep0.c

📁 usb drivers based on s3c2410
💻 C
字号:
#include "usbd.h"
#include "usb.h"

#ifdef _DEBUG
#include <stdio.h>
#endif /* _DEBUG */

struct USB_SETUP_DATA                 setup_data;
struct USB_DEVICE_DESCRIPTOR          device_desc;
struct USB_CONFIGURATION_DESCRIPTOR   config_desc;
struct USB_INTERFACE_DESCRIPTOR       interface_desc;
struct USB_ENDPOINT_DESCRIPTOR        ep_in_desc,ep_out_desc;
struct USB_CONFIGURATION_SET          config_set;
struct USB_INTERFACE_GET              interface_get;
struct USB_GET_STATUS                 get_status;  

/*Clear EP0 Out Packet Ready*/
#define CLR_EP0_OUT_PKT_RDY() 		    EP0_CSR = ( ep0_csr & (~EP0_WR_BITS) | \
						EP0_SERVICED_OUT_PKT_RDY )
/*Clear EP0 Packet 0*/	 
#define CLR_EP0_OUTPKTRDY_DATAEND() 	EP0_CSR = ( ep0_csr & (~EP0_WR_BITS) | \
						(EP0_SERVICED_OUT_PKT_RDY|EP0_DATA_END) )	 
/*Set EP0 IN Packet Ready*/					
#define SET_EP0_IN_PKT_RDY() 		      EP0_CSR = ( ep0_csr & (~EP0_WR_BITS) | \
						(EP0_IN_PKT_READY) )
/*Send Packet 0*/	 
#define SET_EP0_INPKTRDY_DATAEND() 	  EP0_CSR = ( ep0_csr & (~EP0_WR_BITS) | \
						(EP0_IN_PKT_READY|EP0_DATA_END) )	 
/*Clear EP0 Setup End Tag*/					
#define CLR_EP0_SETUP_END() 		      EP0_CSR = ( ep0_csr & (~EP0_WR_BITS) | \
						(EP0_SERVICED_SETUP_END) )
/*Clear EP0 Sent Stall Tag(host ---->mcu)*/
#define CLR_EP0_SENT_STALL() 		      EP0_CSR = ( ep0_csr & (~EP0_WR_BITS) & \
						(~EP0_SENT_STALL) )
/*Flush EP0 Fifo*/
#define FLUSH_EP0_FIFO() 		{while(OUT_FIFO_CNT1_REG) EP0_FIFO;}

void init_descriptor(void)
{	
  /*standard device descriptor*/
  device_desc.bLength              =0x12;	
  device_desc.bDescriptorType      =DEVICE_TYPE;         
  device_desc.bcdUSBL              =0x10;    
  device_desc.bcdUSBH              =0x01; 
  device_desc.bDeviceClass         =0xFF;          
  device_desc.bDeviceSubClass      =0x0;          
  device_desc.bDeviceProtocol      =0x0;          
  device_desc.bMaxPacketSize0      =0x8;         
  device_desc.idVendorL            =0x45;//C0;//5c;//51;//9f;//45;
  device_desc.idVendorH            =0x53;//16;//05;//09;//04;//53;
  device_desc.idProductL           =0x34;//Dc;//00;//03;//50;//34;
  device_desc.idProductH           =0x12;//05;//21;//16;//52;//12;
  device_desc.bcdDeviceL           =0x00;
  device_desc.bcdDeviceH           =0x01;
  device_desc.iManufacturer        =0x0;  
  device_desc.iProduct             =0x0;	
  device_desc.iSerialNumber        =0x0;
  device_desc.bNumConfigurations   =0x1;

  /*standard configuration descriptor*/
  config_desc.bLength              =0x9;    
  config_desc.bDescriptorType      =CONFIGURATION_TYPE;         
  config_desc.wTotalLengthL        =0x20; 
  config_desc.wTotalLengthH        =0;
  config_desc.bNumInterfaces       =1;
  config_desc.bConfigurationValue  =1;  
  config_desc.iConfiguration       =0;
  config_desc.bmAttributes         =CONF_ATTR_DEFAULT|CONF_ATTR_SELFPOWERED;  
  config_desc.maxPower             =25;           

  /*standard interface descriptor*/
  interface_desc.bLength           =0x9;    
  interface_desc.bDescriptorType   =INTERFACE_TYPE;         
  interface_desc.bInterfaceNumber  =0x0;
  interface_desc.bAlternateSetting =0x0; 
  interface_desc.bNumEndpoints     =0x0;	
  interface_desc.bInterfaceClass   =0xFF; 
  interface_desc.bInterfaceSubClass=0x0;  
  interface_desc.bInterfaceProtocol=0x0;
  interface_desc.iInterface        =0x0;
   
  /*standard endpoint mode_in descriptor*/
  ep_in_desc.bLength=0x7;    
  ep_in_desc.bDescriptorType=ENDPOINT_TYPE;         
  ep_in_desc.bEndpointAddress=1|EP_MODE_IN;   
  ep_in_desc.bmAttributes=EP_ATTR_BULK;
  ep_in_desc.wMaxPacketSizeL=EP1_PKT_SIZE; 
  ep_in_desc.wMaxPacketSizeH=0x0;
  ep_in_desc.bInterval=0x0; //not used

  /*standard endpoint mode_out descriptor*/
  ep_out_desc.bLength=0x7;    
  ep_out_desc.bDescriptorType=ENDPOINT_TYPE;         
  ep_out_desc.bEndpointAddress=3|EP_MODE_OUT;   
  ep_out_desc.bmAttributes=EP_ATTR_BULK;
  ep_out_desc.wMaxPacketSizeL=EP3_PKT_SIZE; 
  ep_out_desc.wMaxPacketSizeH=0x0;
  ep_out_desc.bInterval=0x0; //not used 

}

void
ep0_handler()
{
  unsigned char ep0_csr;

  INDEX_REG = 0;
  ep0_csr = EP0_CSR;
  
  if(ep0_csr & EP0_SETUP_END)					
  {   
  	CLR_EP0_SETUP_END();
	  if(ep0_csr & EP0_OUT_PKT_READY) 			
	  {
	    FLUSH_EP0_FIFO(); 
	    CLR_EP0_OUT_PKT_RDY();
	  }
	  return;
  }	

  if(ep0_csr & EP0_SENT_STALL)				
  {   
   	CLR_EP0_SENT_STALL();
	  if(ep0_csr & EP0_OUT_PKT_READY) 
	  {
	    CLR_EP0_OUT_PKT_RDY();
	  }
	  return;
  }	
  
  /*deal with setup packet*/
  if(ep0_csr & EP0_OUT_PKT_READY) 
  {	
	  read_pkt_ep0(( unsigned char *) &setup_data, EP0_PKT_SIZE);
	  
#ifdef _DEBUG
	  printf("%x  %x  %x  %x  %x  %x  %x  %x\n", setup_data.bLengthH, setup_data.bLengthL,
	                                             setup_data.bIndexH, setup_data.bIndexL,
	                                             setup_data.bValueH, setup_data.bValueL,
	                                             setup_data.bRequest, setup_data.bmRequestType);
#endif /* _DEBUG */	  
	  
	  switch(setup_data.bRequest)
	  {
	  	case GET_DESCRIPTOR:
	   	   
	   	   //printf("GET_DESCRIPTOR\n");       
	  		
	  	   switch(setup_data.bValueH)        
         {
           case DEVICE_TYPE:				//device descriptor
           	
     	       //printf("DEVICE_TYPE\n"); 
 	 	         CLR_EP0_OUT_PKT_RDY();
 	 	   
		 	 	     if(setup_data.bLengthL == 0x40)
		 	 	     {
			         write_pkt_ep0((unsigned char *) &device_desc + 0, 8); 
			         SET_EP0_IN_PKT_RDY();
			         		           
	           }
			       /*after we get the new address, we should response to GET_DESCRIPTOR with the whole device_desc.*/ 
			       else if(setup_data.bLengthL == 0x12)
			       {
		           write_pkt_ep0((unsigned char *) &device_desc + 0, 8); 
			         SET_EP0_IN_PKT_RDY();
			         delay(1);
			         write_pkt_ep0((unsigned char *) &device_desc + 0x8, 8); 
		           SET_EP0_IN_PKT_RDY();
		           delay(1);
		           write_pkt_ep0((unsigned char *) &device_desc + 0x10, 2);
 		           SET_EP0_IN_PKT_RDY();
   	           SET_EP0_INPKTRDY_DATAEND();
		         }
		         else
		         {
		           printf("setup_data.bLengthL error\n");
		         }
		                 	        
	           break;	
	     
	         case CONFIGURATION_TYPE:			//configuration descriptor
	   	       
	   	       CLR_EP0_OUT_PKT_RDY();
	   	       if((setup_data.bLengthL + (setup_data.bLengthH << 8)) > 0x9)
	   	       {
	   	       	 printf("win98\n");
 	    	       write_pkt_ep0((unsigned char *) &config_desc + 0, 8); //EP0_PKT_SIZE
               SET_EP0_IN_PKT_RDY();
               delay(1);
               write_pkt_ep0((unsigned char *) &config_desc + 8, 1); 
               write_pkt_ep0((unsigned char *) &interface_desc + 0, 7); 
               SET_EP0_IN_PKT_RDY();
               delay(1);
               write_pkt_ep0((unsigned char *) &interface_desc + 7, 2);
               write_pkt_ep0((unsigned char *) &ep_in_desc + 0, 6); 
               SET_EP0_IN_PKT_RDY();
               delay(1);
               write_pkt_ep0((unsigned char *) &ep_in_desc + 6, 1); 
               write_pkt_ep0((unsigned char *) &ep_out_desc + 0, 7);
               SET_EP0_IN_PKT_RDY();
               delay(1);//如果在这里不delay一下,是要出错的
               SET_EP0_INPKTRDY_DATAEND();
             }
             else
             {
               printf("win2000\n");
             	 write_pkt_ep0((unsigned char *) &config_desc + 0, 8); //EP0_PKT_SIZE
               SET_EP0_IN_PKT_RDY();
               delay(1);
               write_pkt_ep0((unsigned char *) &config_desc + 8, 1); 
               SET_EP0_IN_PKT_RDY();
               SET_EP0_INPKTRDY_DATAEND();
                             
             }	  
	   	       
	   	       //printf("CONFIGURATION_TYPE\n");       
  		       break;
	     
   	       case STRING_TYPE:				//string descriptor    /*XXX*/
   	         printf("STRING_TYPE\n"); 
   	         CLR_EP0_OUTPKTRDY_DATAEND();  
   	         break;
   	         
 	 	       case INTERFACE_TYPE:	
 	 	       	 printf("INTERFACE_TYPE\n");    	 	       	
 	 	       	 break;
 	 	       	
 	 	       case ENDPOINT_TYPE:
 	 	       	 printf("ENDPOINT_TYPE\n");    	 	       	
 	 	       	 break;
 	 	       	 
 	 	       default:
 	 	       	 break;
	      }
	  		break;
	  		 
	  	case SET_ADDRESS:
	   	  
	   	  //printf("SET_ADDRESS\n");       
	  		
	  		CLR_EP0_OUT_PKT_RDY();
	  		FUNC_ADDR_REG=setup_data.bValueL | 0x80;
	  		//printf("SET_ADDRESS  %x\n", setup_data.bValueL | 0x80); 
	      CLR_EP0_OUTPKTRDY_DATAEND(); //Because of no data control transfers.
	  		break;
	  		
	  	case SET_CONFIGURATION:
	  		
	  		config_set.bConfigurationValue=setup_data.bValueL;
        CLR_EP0_OUTPKTRDY_DATAEND(); //Because of no data control transfers.
	  		printf("SET_CONFIGURATION\n");   
	  		break;
	  		
	  	case CLEAR_FEATURE:
	  		
	  		printf("CLEAR_FEATURE\n");   
	  		break;
	  		
	  	case GET_CONFIGURATION:
	  	
	  	  printf("GET_CONFIGURATION\n");   
	  		break;
	  		
	  	case GET_INTERFACE:
	  		
	  		printf("GET_INTERFACE\n");   
	  		break;
	  		
	  	case GET_STATUS:
	  		
	  		printf("GET_STATUS\n");   
	  		break;
	  		
	  	case SET_DESCRIPTOR:
	  		printf("SET_DESCRIPTOR\n");   
	  		break;
	  		
	  	case SET_FEATURE:
	  		printf("SET_FEATURE\n");   
	  		break;
	  		
	  	case SET_INTERFACE:
	  		
	  		printf("SET_INTERFACE\n");   
	  		break;
	  		
	  	case SYNCH_FRAME:
	  		
	  		printf("SYNCH_FRAME\n");   
	  		break;
	  		
	  	default:
	  		break;
	  	
	  }
	}

	
}


⌨️ 快捷键说明

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