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

📄 usb_drv.c

📁 这是一个用C语言在VC6.0环境下编写的用于USB驱动的代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "usb_cfg.h"
#include "usb_def.h"
#include "usb_reg.h"
#include "at89x52.h"
#include "stdio.h"
#include "disk_cfg.h"
#include "INTRINS.H"
#define nop _nop_()
#define uint unsigned int
#define uchar unsigned char
/*_____ M A C R O S ________________________________________________________*/
#define FLUSHTX0 {write_usb(TXC0,FLUSH);}
/* Flush and disable the USB TX1 **************************************/
#define FLUSHTX1 {write_usb(TXC1,FLUSH);}
/* Flush and disable the USB TX2 **************************************/
#define FLUSHTX2 {write_usb(TXC2,FLUSH);}
/* Flush and disable the USB TX3 **************************************/
#define FLUSHTX3 {write_usb(TXC3,FLUSH);}
/* Flush and disable the USB RX0 **************************************/
#define FLUSHRX0 {write_usb(RXC0,FLUSH);}
/* Flush and disable the USB RX1 **************************************/
#define FLUSHRX1 {write_usb(RXC1,FLUSH);}
/* Flush and disable the USB RX2 **************************************/
#define FLUSHRX2 {write_usb(RXC2,FLUSH);}
/* Flush and disable the USB RX3 **************************************/
#define FLUSHRX3 {write_usb(RXC3,FLUSH);}

/*  Send data to TXD0 ****************************/
#define send_desc_to_TXD0   \
	for(desc_idx=0;desc_idx<EP_CONTROL_LENGTH&&desc_idx<data_to_transfer;desc_idx++)   \
    {                                                                                  \
		TXD0=*pbuffer++;                                                               \
    }                                                                                  \
	if(data_to_transfer>EP_CONTROL_LENGTH)                                             \
	{                                                                                  \
	    data_to_transfer-=EP_CONTROL_LENGTH;                                           \
	}                                                                                  \
	else                                                                               \
	{                                                                                  \
	   data_to_transfer=0;                                                             \
	}                                                                                  \ 

/* store the status byte in FIFO0 for the chosen endpoint *************/
#define EPSTATUS(ep)                                                   \
	    case ep:                                                   \
	      if (stalled^(1<<ep)) write_usb(TXD0,1); else write_usb(TXD0,0);\     
	      break;  

/* enable TX0, using the appropriate DATA PID *************************/


#define TXEN0_PID    \
	  { if(dta_pid0) write_usb(TXC0,TX_TOGL+TX_EN);       /*DATA1*/\
	    else write_usb(TXC0,TX_EN);                       /*DATA0*/\
	    dta_pid0=!dta_pid0;} 

/* enable TX1, using the appropriate DATA PID, but not toggling it ****/
#define TXEN1_PID_NO_TGL  \
      { if(dta_pid1) write_usb(TXC1,TX_TOGL+TX_LAST+TX_EN);       /*DATA1*/\
	    else write_usb(TXC1,TX_LAST+TX_EN); }                      /*DATA0*/
#define TXEN1_PID        \
      { TXEN1_PID_NO_TGL;  \
	    dta_pid1=!dta_pid1;}


/* enable TX2, using the appropriate DATA PID, but not toggling it ****/
#define TXEN2_PID_NO_TGL  \
      { if(dta_pid2) write_usb(TXC2,TX_TOGL+TX_LAST+TX_EN);       /*DATA1*/\
	    else write_usb(TXC2,TX_LAST+TX_EN); }                      /*DATA0*/
#define TXEN2_PID        \
      { TXEN2_PID_NO_TGL;  \
	    dta_pid2=!dta_pid2;}

/* enable TX3, using the appropriate DATA PID, but not toggling it ****/
#define TXEN3_PID_NO_TGL  \
      { if(dta_pid3) write_usb(TXC3,TX_TOGL+TX_LAST+TX_EN);       /*DATA1*/\
	    else write_usb(TXC3,TX_LAST+TX_EN); }                      /*DATA0*/
#define TXEN3_PID        \
      { TXEN3_PID_NO_TGL;  \
	    dta_pid3=!dta_pid3;}

#define write_usb(USB_REG,i)   USB_REG=i
#define read_usb(USB_REG)    USB_REG
/*Fuction declare*******************************/
extern void DelaymS(uint i);
void rx_0();
void rx_1();
void rx_2();
void rx_3();
void tx_0();
void tx_1();
void tx_2();
void tx_3();
void usb_alt();
void nak0();
void nakO1();
void nakI1();
void nak2();
void nak3();
void usb_get_descriptor();
void usb_set_configuration();
void usb_clear_feature();
void usb_set_feature();
void usb_get_status();
void usb_mass_storage_get_lun();
void usb_mass_storage_reset();

/*global ver define *********************/
    uchar rxstat;
	uchar txstat;
	uchar desc_idx;
	uchar evnt;
	uchar usb_buf[64];
	char bdata dtapid;                  /* PID related status*/
    sbit dta_pid0= dtapid^0;
    sbit dta_pid1= dtapid^1;
    sbit dta_pid2= dtapid^2;
    sbit dta_pid3= dtapid^3;
	char bdata stalled;                 /* indicate the stall status of endpoints0-6 */
    sbit stall_ep0 = stalled^0;
    sbit stall_ep1 = stalled^1;
    sbit stall_ep2 = stalled^2;
    sbit stall_ep3 = stalled^3;
    sbit stall_ep4 = stalled^4;
    sbit stall_ep5 = stalled^5;
    sbit stall_ep6 = stalled^6;
	uchar bmRequestType;
	uchar bmRequest;
	uchar data_to_transfer;
    uchar code *pbuffer;
	uchar zero_packet_flag;
	uchar usb_cfg;
	uchar flag;
	



void usb_init()
{
     usb_cfg=0;
	 data_to_transfer=0;
	 pbuffer=NULL;
	 zero_packet_flag=FALSE;
     RST=0;
 	 DelaymS(100);
	 RST=1;
	 DelaymS(100);
     write_usb(MCNTRL,SRST);   //reset
     while( read_usb(MCNTRL) & SRST);//wait for reset finish
     write_usb(MCNTRL,INT_L_P + VGE );//power on 3.3V
     write_usb(MAMSK, 0);   // disable all ints
     /*set up interrupt masks ****************************************/
     write_usb(NAKMSK,NAK_O0+NAK_O1+NAK_I1);                          /*NAK evnts*/  
     write_usb(TXMSK,TXFIFO0+TXFIFO1+TXFIFO2+TXFIFO3);          /*TX events*/
     write_usb(RXMSK,RXFIFO0+RXFIFO1+RXFIFO2+RXFIFO3);          /*RX events*/
     //write_usb(ALTMSK,SD3+RESET_A);                     /*ALT evnts*/
     /*this is modified in the */
     /*suspend-resume routines */
     /*so if any change is made*/
     /*here it needs to be ref-*/
     /*lected there too.       */
     write_usb(MAMSK,(INTR_E+RX_EV+NAK+TX_EV+ALT));
     write_usb(DMAMASK, 0);
      /*set default address, enable EP0 only **************************/
      write_usb(FAR,AD_EN+0);
      write_usb(EPC0, 0x00); 
      /*enable the receiver and go operational ************************/  
      FLUSHTX0;                           /*flush TX0 and disable   */  
      write_usb(RXC0,RX_EN);              /*enable the receiver     */
      write_usb(NFSR,OPR_ST);             /*go operational          */   
      write_usb(MCNTRL,INT_L_P+NAT+VGE);      /*set NODE ATTACH         */
}

void usb_isr()interrupt 0
{
     
     evnt=read_usb(MAEV);
	 if (evnt & RX_EV) 
     {
          evnt=read_usb(RXEV);            /*check the RX events     */  
          if      (evnt&RXFIFO0) rx_0();  /*endpoint 0              */   
          else if (evnt&RXFIFO1) rx_1();  /*endpoint 2              */ 
          else if (evnt&RXFIFO2) rx_2();  /*endpoint 4              */  
          else if (evnt&RXFIFO3) rx_3();  /*endpoint 6              */  
          else                            /*some other RX event     */
          { 
          }
     }
     else if (evnt & TX_EV) 
    {
          evnt=read_usb(TXEV);            /*check the TX events     */  
          if      (evnt&TXFIFO0) tx_0();  /*endpoint 0              */   
          else if (evnt&TXFIFO1) tx_1();  /*endpoint 1              */ 
          else if (evnt&TXFIFO2) tx_2();  /*endpoint 3              */  
          else if (evnt&TXFIFO3) tx_3();  /*endpoint 5              */  
          else                            /*some other TX event     */
          { 
          }
    }
    else if (evnt & ALT) usb_alt();     /*alternate event?        */   
    else if (evnt & NAK) 
    {
          evnt=read_usb(NAKEV);           /*check the NAK events    */ 
          if      (evnt & NAK_O0) nak0();   /*endpoint 0              */   
          else if (evnt & NAK_O1) nakO1();   /*endpoint 2              */
          else if (evnt & NAK_I1) nakI1(); 
          else if (evnt & NAK_O2) nak2();   /*endpoint 4              */  
          else if (evnt & NAK_O3) nak3();   /*endpoint 6              */  
          else                            /*some other TX event     */
          { 
          }
    }
    else                                /*spurious event!         */
    {
    }
}

void rx_0()
{
    rxstat=read_usb(RXS0);              /*get receiver status     */
	/*is this a setup packet? ***************************************/  
    if(rxstat & SETUP_R)                   
    { 
        data_to_transfer=0;
	    pbuffer=NULL;
	    zero_packet_flag=FALSE;
        /*read data payload into buffer then flush/disble the RX ****/
		
        for(desc_idx=0; desc_idx<8; desc_idx++)
        {
             usb_buf[desc_idx] = read_usb(RXD0);
        }
		FLUSHRX0;                     /*make sure the RX is off */
        FLUSHTX0;                     /*make sure the TX is off */ 
		TI=1;printf("\n");
		for(desc_idx=0; desc_idx<8; desc_idx++)
        {
             printf("%2.2X,", (uint)usb_buf[desc_idx]);

        }
        bmRequestType=usb_buf[0];
		bmRequest=usb_buf[1];        
        if ((usb_buf[0]&0x60)==0x00)    /*if a standard request   */
		{
	        switch (usb_buf[1])           /*find request target     */
	        {
			    case GET_STATUS:
                     usb_get_status();
                     break;
				case CLEAR_FEATURE:
                     usb_clear_feature();
                     break;
				case SET_FEATURE:
                     usb_set_feature();
                     break;
				case SET_ADDRESS:
                     /*set and enable new address for endpoint 0, but set*/
		             /*DEF too, so new address doesn't take effect until */
		             /*the handshake completes                           */
                     write_usb(EPC0,DEF);   
	                 write_usb(FAR,usb_buf[2] | AD_EN);  
					 break;
			    case GET_DESCRIPTOR:
                     usb_get_descriptor();
                     break;				
                case GET_CONFIGURATION:
                     write_usb(TXD0,usb_cfg);/*load the config value   */ 
					 break;
                
                case SET_CONFIGURATION:
                     usb_set_configuration();
					 break;
                
               
                
                case GET_MAX_LUN:
                     write_usb(TXD0,MS_MAX_LUN);
                     break;
                case MASS_STORAGE_RESET:
                     usb_mass_storage_reset();
                     break;
 		        default:                  /*unsupported standard req*/ 
 			         //write_usb(EPC0,STALL);
				break;
      	    }
        }
        else                            /*if a non-standard req.  */   
        {
		    //write_usb(EPC0,STALL);
        }

	    /*the following is done for all setup packets.  Note that if*/  
	    /*no data was stuffed into the FIFO, the result of the fol- */  
	    /*lowing will be a zero-length response.                    */ 
        dta_pid0=1;  /*enable the TX (DATA1) */ 
 	    TXEN0_PID;
    }
    /*if not a setup packet, it must be an OUT packet ***************/ 
    else   
    {
	    
	    if (data_to_transfer>0||zero_packet_flag==TRUE)             /*get_descr status stage? */
        {
            /*test for errors (zero length, correct PID)            */
            if ((rxstat& 0x5F)!=0x10)   /*length error??          */
            {
            }
		    data_to_transfer=0;           /*exit get_descr mode     */
            zero_packet_flag=FALSE;
			FLUSHTX0;                   /*flush TX0 and disable   */ 
        }
		FLUSHRX0;                     /*make sure the RX is off */
		write_usb(RXC0,RX_EN);          /*re-enable the receiver  */   
    }
    //test_b= 0;
    /*we do this stuff for all rx_0 events **************************/  

}

void usb_get_descriptor()
{
    uchar string_type;
	uchar descriptor_type;
	uchar  wLength;
    data_to_transfer=0;
	pbuffer=NULL;
	zero_packet_flag=FALSE;
	string_type = usb_buf[2];            /* read LSB of wValue */
    descriptor_type = usb_buf[3];        /* read MSB of wValue */ 
	wLength=usb_buf[6];
	switch (descriptor_type)
    {
         case DEVICE:
              data_to_transfer = sizeof (usb_device_descriptor);
              pbuffer = &(usb_device_descriptor.bLength);
			  break;
    
        case CONFIGURATION:
             data_to_transfer = sizeof (usb_configuration);
             pbuffer = &(usb_configuration.cfg.bLength);
			 break;
        case STRING:
             switch (string_type)
             {
                  case LANG_ID:
                       data_to_transfer = sizeof (usb_language);
                       pbuffer = &(usb_language.bLength);
					   break;

                  case MAN_INDEX:
                       data_to_transfer = sizeof (usb_manufacturer);
                       pbuffer = &(usb_manufacturer.bLength);
					   break;
        
                 case PROD_INDEX:
                      data_to_transfer = sizeof (usb_product);
                      pbuffer = &(usb_product.bLength);
                      break;
        
                case SN_INDEX:
                     data_to_transfer = sizeof (usb_serial_number);
                     pbuffer = &(usb_serial_number.bLength);
					 break;
        
               default:
			        //write_usb(EPC0,STALL);
			        break;
		     }
	   default:
	         //write_usb(EPC0,STALL);
	         break;
	}
    if(wLength>data_to_transfer)
	{
	    if((data_to_transfer % EP_CONTROL_LENGTH) == 0)
		{
		    zero_packet_flag=TRUE;
		}
		else
		{
		    zero_packet_flag=FALSE;
		}
	}
	else
	{
	    data_to_transfer=wLength;
	}	
    send_desc_to_TXD0;

}

void usb_set_configuration()
{   
    usb_cfg = usb_buf[2];               /*set the configuration # */  
	if (usb_cfg>0)                  /*set the configuration   */   
	{
	    dtapid = 0;                     /*FIRST PID is DATA0      */   
	    stalled = 0;                     /*nothing stalled         */
		dta_pid1=1;
	    FLUSHTX1;                       /*flush  TX1 and disable  */   
	    write_usb(EPC1,EP_EN+01);       /*enable EP1 at adr 1     */

	    FLUSHRX1;                       /*flush  RX1 and disable  */ 
	    write_usb(EPC2,EP_EN+02);       /*enable EP2 at adr 2     */   
	    write_usb(RXC1,RX_EN);          /*enable RX1              */  
   
		FLUSHTX2;                       /*flush  TX1 and disable  */   
	    write_usb(EPC3,EP_EN+03);       /*enable EP1 at adr 1     */

		FLUSHRX2;                       /*flush  RX1 and disable  */ 
	    write_usb(EPC4,EP_EN+04);       /*enable EP2 at adr 2     */   
	    write_usb(RXC2,RX_EN);          /*enable RX1              */  

		FLUSHTX3;                       /*flush  TX1 and disable  */   
	    write_usb(EPC5,EP_EN+05);       /*enable EP1 at adr 1     */

		FLUSHRX3;                       /*flush  RX1 and disable  */ 
	    write_usb(EPC6,EP_EN+06);       /*enable EP2 at adr 2     */   
	    write_usb(RXC3,RX_EN);          /*enable RX1              */  
		
	    
	  }
	else                                /*unconfigure the device  */

⌨️ 快捷键说明

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