usbsetup.c
上传用户:hank9955
上传日期:2022-08-05
资源大小:14k
文件大小:21k
源码类别:

USB编程

开发平台:

C/C++

  1. /**************************************************************
  2.  NAME: usbsetup.c
  3.  DESC: process the USB setup stage operations.
  4.  HISTORY:
  5.  MAR.25.2002:purnnamu: S3C2400X usbsetup.c is ported for S3C2410X.
  6.  AUG.20.2002:purnnamu: rEP0_CSR should be used instead of rOUT_CSR1_REG for EP0 macros.
  7.  **************************************************************/
  8. #include <string.h>
  9. #include "option.h"
  10. #include "2410addr.h"
  11. #include "2410lib.h"
  12. #include "def.h"
  13. #include "2410usb.h"
  14. #include "usbmain.h"
  15. #include "usb.h"
  16. #include "usblib.h"
  17. #include "usbsetup.h"
  18. // *** End point information ***
  19. //   EP0: control
  20. //   EP1: bulk in end point
  21. //   EP2: not used
  22. //   EP3: bulk out end point
  23. //   EP4: not used
  24. // *** VERY IMPORTANT NOTE ***
  25. // Every descriptor size of EP0 should be 8n+m(m=1~7).
  26. // Otherwise, USB will not operate normally because the program
  27. // doesn't prepare the case that the descriptor size is 8n+0.
  28. // If the size of a descriptor is 8n, the 0 length packit should be sent. 
  29. // Special thanks to E.S.Choi for reminding me of this USB specification.
  30. // ===================================================================
  31. // All following commands will operate only in case 
  32. // - ep0_csr is valid.
  33. // ===================================================================
  34. #define CLR_EP0_OUT_PKT_RDY()  rEP0_CSR=( ep0_csr & (~EP0_WR_BITS)| 
  35. EP0_SERVICED_OUT_PKT_RDY )  
  36. #define CLR_EP0_OUTPKTRDY_DATAEND()  rEP0_CSR=( ep0_csr & (~EP0_WR_BITS)| 
  37. (EP0_SERVICED_OUT_PKT_RDY|EP0_DATA_END) )  
  38. #define SET_EP0_IN_PKT_RDY()  rEP0_CSR=( ep0_csr & (~EP0_WR_BITS)| 
  39. (EP0_IN_PKT_READY) )  
  40. #define SET_EP0_INPKTRDY_DATAEND()  rEP0_CSR=( ep0_csr & (~EP0_WR_BITS)| 
  41. (EP0_IN_PKT_READY|EP0_DATA_END) )  
  42. #define CLR_EP0_SETUP_END()  rEP0_CSR=( ep0_csr & (~EP0_WR_BITS)| 
  43. (EP0_SERVICED_SETUP_END) )
  44. #define CLR_EP0_SENT_STALL()  rEP0_CSR=( ep0_csr & (~EP0_WR_BITS)& 
  45. (~EP0_SENT_STALL) )
  46. #define FLUSH_EP0_FIFO()  {while(rOUT_FIFO_CNT1_REG)rEP0_FIFO;}
  47. extern volatile int isUsbdSetConfiguration;
  48. volatile U8 Rwuen;
  49. volatile U8 Configuration=1;
  50. volatile U8 AlterSetting;
  51. volatile U8 Selfpwr=TRUE;
  52. volatile U8 device_status;
  53. volatile U8 interface_status;
  54. volatile U8 endpoint0_status;
  55. volatile U8 endpoint1_status;
  56. volatile U8 endpoint3_status;
  57. struct USB_SETUP_DATA descSetup;
  58. struct USB_DEVICE_DESCRIPTOR descDev;
  59. struct USB_CONFIGURATION_SET ConfigSet;
  60. struct USB_INTERFACE_GET InterfaceGet;
  61. struct USB_GET_STATUS StatusGet;   //={0,0,0,0,0};
  62. static const U8 descStr0[]=
  63. {
  64.     4,STRING_TYPE,LANGID_US_L,LANGID_US_H,  //codes representing languages
  65. };
  66. static const U8 descStr1[]=   //Manufacturer
  67. {
  68.     (16+2),STRING_TYPE,
  69.     'M',0x0,'i',0x0,'a',0x0,'r',0x0,'t',0x0,'e',0x0,'c',0x0,'h',0x0,
  70. };
  71. static const U8 descStr2[]=   //Product
  72. {
  73.     (50+2),STRING_TYPE,
  74.     'U',0x0,'S',0x0,'B',0x0,' ',0x0,'S',0x0,'e',0x0,'r',0x0,'i',0x0,
  75.     'a',0x0,'l',0x0,' ',0x0,'T',0x0,'e',0x0,'s',0x0,'t',0x0,' ',0x0,
  76.     'b',0x0,'y',0x0,' ',0x0,'T',0x0,'i',0x0,'n',0x0,'n',0x0,'a',0x0,
  77.     'l',0x0,
  78. };
  79. //Tinnal Add
  80. struct USB_GET_DESCRIPTOR
  81. {
  82.     struct USB_CONFIGURATION_DESCRIPTOR descConf;
  83.     struct USB_INTERFACE_DESCRIPTOR  descIf0;
  84.     U8 CS_INTERFACE0[19];
  85. struct USB_ENDPOINT_DESCRIPTOR  descEndpt2;
  86. struct USB_INTERFACE_DESCRIPTOR  descIf1;
  87.     struct USB_ENDPOINT_DESCRIPTOR  descEndpt0;
  88.     struct USB_ENDPOINT_DESCRIPTOR  descEndpt1;
  89. }descriptor;
  90. U8 line_coding[7] =
  91. {
  92. 0x00, //band rate
  93. 0xE1,
  94. 0x00,
  95. 0x00,
  96. 0, //stop bit
  97. 1, //parity
  98. 8, //databits
  99. };
  100. U32 ep0State = EP0_SETUP_END;
  101. U8 *setupData; //setup回应包指针,每次向后EP0_PKT_SIZE字节
  102. U32 setupDataLen = 0; //setup回应包的总长度
  103. U32 setupDataSegmentLen = 0; //当前分段的长度
  104. U32 segmentCount =0; //调试用。
  105. //Tinnal Add end
  106. void PrintSentPkt(U8 *pt, U32 count)
  107. {
  108.     int i;
  109.     DbgPrintf("[SEND:");
  110.     for (i=0;i<count;i++)
  111.         DbgPrintf("%x,",pt[i]);
  112.     DbgPrintf("]");
  113. }
  114. void Ep0Handler(void)
  115. {
  116.     int i;
  117.     U8 ep0_csr;
  118.     rINDEX_REG=0;
  119.     ep0_csr=rEP0_CSR;
  120.     DbgPrintf("<0:%x]",ep0_csr);
  121.     //DATAEND interrupt(ep0_csr==0x0) will be ignored
  122.     //because ep0State==EP0_STATE_INIT when the DATAEND interrupt is issued.
  123.     if (ep0_csr & EP0_SETUP_END)
  124.     {
  125.         // Host may end GET_DESCRIPTOR operation without completing the IN data stage.
  126.         // If host does that, SETUP_END bit will be set.
  127.         // OUT_PKT_RDY has to be also cleared because status stage sets OUT_PKT_RDY to 1.
  128.         DbgPrintf("[SETUPEND]");
  129.         CLR_EP0_SETUP_END();
  130.         if (ep0_csr & EP0_OUT_PKT_READY)
  131.         {
  132.             FLUSH_EP0_FIFO(); //(???)
  133.             //I think this isn't needed because EP0 flush is done automatically.
  134.             CLR_EP0_OUT_PKT_RDY();
  135.         }
  136.         ep0State=EP0_SETUP_STATE;
  137.         return;
  138.     }
  139.     //I think that EP0_SENT_STALL will not be set to 1.
  140.     if (ep0_csr & EP0_SENT_STALL)
  141.     {
  142.         DbgPrintf("[STALL]");
  143.         CLR_EP0_SENT_STALL();
  144.         if (ep0_csr & EP0_OUT_PKT_READY)
  145.         {
  146.             CLR_EP0_OUT_PKT_RDY();
  147.         }
  148.         ep0State=EP0_SETUP_STATE;
  149.         return;
  150.     }
  151. if(ep0_csr & EP0_OUT_PKT_READY)
  152. {
  153. DbgPrintf("[INDATA]");
  154.     if (ep0State == EP0_SETUP_STATE )
  155.     {
  156.      RdPktEp0((U8 *)&descSetup,8);
  157.      PrintEp0Pkt((U8 *)(&descSetup));
  158.         switch (descSetup.bRequest)
  159.         {
  160.         case GET_DESCRIPTOR:
  161.             switch (descSetup.bValueH)
  162.             {
  163.             case DEVICE_TYPE:
  164.                 DbgPrintf("[GDD]");
  165.                 CLR_EP0_OUT_PKT_RDY();
  166.                 ep0State=EP0_IN_DATA_STATE;
  167.                 setupData = (U8*)&descDev;
  168.                 setupDataLen = sizeof(descDev);
  169.                 break;
  170.             case CONFIGURATION_TYPE:
  171.                     DbgPrintf("[GDC]");
  172.                     CLR_EP0_OUT_PKT_RDY();
  173.                     if ((descSetup.bLengthL+(descSetup.bLengthH<<8))>0x9)
  174.                         //bLengthH should be used for bLength=0x209 at WIN2K.
  175.                     {
  176.                         ep0State=EP0_IN_DATA_STATE; //for WIN98,WIN2K
  177.                         setupData = (U8*)&descriptor.descConf;
  178.                         setupDataLen = sizeof(descriptor);
  179.                     }
  180.                     else
  181.                     {
  182.                         ep0State=EP0_IN_DATA_STATE; //for WIN2K
  183.                         setupData = (U8*)&descriptor.descConf;
  184.                         setupDataLen = sizeof(descriptor.descConf);
  185.                     }
  186.                 break;
  187.             case STRING_TYPE:
  188.                 DbgPrintf("[GDS]");
  189.                 CLR_EP0_OUT_PKT_RDY();
  190.                 switch (descSetup.bValueL)
  191.                 {
  192.                 case 0:
  193.                     //ep0State=EP0_STATE_GD_STR_I0;
  194.                     ep0State = EP0_IN_DATA_STATE;
  195.                     setupData = (U8*)descStr0;
  196.                     setupDataLen = sizeof(descStr0);
  197.                     break;
  198.                 case 1:
  199.                     //ep0State=EP0_STATE_GD_STR_I1;
  200.                     ep0State = EP0_IN_DATA_STATE;
  201.                     setupData = (U8*)descStr1;
  202.                     setupDataLen = sizeof(descStr1);
  203.                     break;
  204.                 case 2:
  205.                     //ep0State=EP0_STATE_GD_STR_I2;
  206.                     ep0State = EP0_IN_DATA_STATE;
  207.                     setupData = (U8*)descStr2;
  208.                     setupDataLen = sizeof(descStr2);
  209.                     break;
  210.                 default:
  211.                     DbgPrintf("[UE:STRI?]");
  212.                     break;
  213.                 }
  214.                 break;
  215. /*
  216.             case INTERFACE_TYPE:
  217.                     DbgPrintf("[GDI]");
  218.                     CLR_EP0_OUT_PKT_RDY();
  219.                     //ep0State=EP0_STATE_GD_IF_ONLY_0; //for WIN98
  220.                     setupData = (U8*)&descriptor.descIf;
  221.                     setupDataLen = sizeof(descriptor.descIf);
  222.                     break;
  223. */
  224.             case ENDPOINT_TYPE:
  225.                 DbgPrintf("[GDE]");
  226.                 CLR_EP0_OUT_PKT_RDY();
  227.                 switch (descSetup.bValueL&0xf)
  228.                 {
  229.                 case 0:
  230.                   //ep0State=EP0_STATE_GD_EP0_ONLY_0;
  231.                   ep0State = EP0_IN_DATA_STATE;
  232.                   setupData = (U8*)&descriptor.descEndpt0;
  233.                   setupDataLen = sizeof(descriptor.descEndpt0);
  234.                     break;
  235.                 case 1:
  236.                     //ep0State=EP0_STATE_GD_EP1_ONLY_0;
  237.                     ep0State = EP0_IN_DATA_STATE;
  238.                     setupData = (U8*)&descriptor.descEndpt1;
  239.                     setupDataLen = sizeof(descriptor.descEndpt1);
  240.                     break;
  241.                     
  242.                 case 2:
  243.                  ep0State = EP0_IN_DATA_STATE;
  244.                     setupData = (U8*)&descriptor.descEndpt2;
  245.                     setupDataLen = sizeof(descriptor.descEndpt2);
  246.                     break;
  247.                 default:
  248.                     DbgPrintf("[UE:GDE?]");
  249.                     break;
  250.                 }
  251.                 break;
  252.             default:
  253.                 DbgPrintf("[UE:GD?]");
  254.                 break;
  255.             }
  256.             break; 
  257.             //end case GET_DESCRIPTOR
  258.         case SET_ADDRESS:
  259.             DbgPrintf("[SA:%d]",descSetup.bValueL);
  260.             rFUNC_ADDR_REG=descSetup.bValueL | 0x80;
  261.             CLR_EP0_OUTPKTRDY_DATAEND(); //Because of no data control transfers.
  262.             ep0State=EP0_SETUP_STATE;
  263.             break;
  264.         case SET_CONFIGURATION:
  265.             DbgPrintf("[SC]");
  266.             ConfigSet.ConfigurationValue=descSetup.bValueL;
  267.             CLR_EP0_OUTPKTRDY_DATAEND(); //Because of no data control transfers.
  268.             ep0State=EP0_SETUP_STATE;
  269.             isUsbdSetConfiguration=1;
  270.             break;
  271.             //////////////////////// For chapter 9 test ////////////////////
  272.         case CLEAR_FEATURE:
  273.             switch (descSetup.bmRequestType)
  274.             {
  275.             case DEVICE_RECIPIENT:
  276.                 if (descSetup.bValueL == 1)
  277.                     Rwuen = FALSE;
  278.                 break;
  279.             case ENDPOINT_RECIPIENT:
  280.                 if (descSetup.bValueL == 0)
  281.                 {
  282.                     if ((descSetup.bIndexL & 0x7f) == 0x00)
  283.                     {
  284.                         StatusGet.Endpoint0= 0;
  285.                     }
  286.                     if ((descSetup.bIndexL & 0x8f) == 0x81)           // IN  Endpoint 1
  287.                     {
  288.                         StatusGet.Endpoint1= 0;
  289.                     }
  290.                     if ((descSetup.bIndexL & 0x8f) == 0x03)          // OUT Endpoint 3
  291.                     {
  292.                         StatusGet.Endpoint3= 0;
  293.                     }
  294.                 }
  295.                 break;
  296.             default:
  297.                 break;
  298.             }
  299.             CLR_EP0_OUTPKTRDY_DATAEND();
  300.             ep0State=EP0_SETUP_STATE;
  301.             break;
  302.         case GET_CONFIGURATION:
  303.             CLR_EP0_OUT_PKT_RDY();
  304.             ep0State=EP0_IN_DATA_STATE;
  305.             setupData = (U8 *)&ConfigSet;
  306.             setupDataLen = 1;
  307.             break;
  308.         case GET_INTERFACE:
  309.             CLR_EP0_OUT_PKT_RDY();
  310.             ep0State=EP0_IN_DATA_STATE;
  311.             setupData = (U8 *)&InterfaceGet;
  312.             setupDataLen = 1;
  313.             break;
  314.         case GET_STATUS:
  315.             switch (descSetup.bmRequestType)
  316.             {
  317. /*            case  (0x80):
  318.                 CLR_EP0_OUT_PKT_RDY();
  319.                 StatusGet.Device=((U8)Rwuen<<1)|(U8)Selfpwr;
  320.                 //ep0State=EP0_GET_STATUS0;
  321.                 setupData = (U8 *)&StatusGet+0;
  322.                 setupDataLen = sizeof(descriptor.descIf);
  323.                 break;*/
  324.             case  (0x81):
  325.                 CLR_EP0_OUT_PKT_RDY();
  326.                 StatusGet.Interface=0;
  327.                 ep0State=EP0_IN_DATA_STATE;
  328.                 setupData = (U8 *)&StatusGet+1;
  329.                 setupDataLen = 1;
  330.                 break;
  331.             case  (0x82):
  332.                 CLR_EP0_OUT_PKT_RDY();
  333.                 if ((descSetup.bIndexL & 0x7f) == 0x00)
  334.          {
  335.                      ep0State=EP0_IN_DATA_STATE;
  336.                     setupData = (U8 *)&StatusGet+2;
  337.                  setupDataLen = 1;
  338.                 }
  339.                 if ((descSetup.bIndexL & 0x8f) == 0x81)
  340.                 {
  341.                     ep0State=EP0_IN_DATA_STATE;
  342.                     setupData = (U8 *)&StatusGet+3;
  343.                  setupDataLen = 1;
  344.                 }
  345.                 if ((descSetup.bIndexL & 0x8f) == 0x03)
  346.                 {
  347.                     ep0State=EP0_IN_DATA_STATE;
  348.                     setupData = (U8 *)&StatusGet+4;
  349.                  setupDataLen = 1;
  350.                 }
  351.                 break;
  352.             default:
  353.                 break;
  354.             }
  355.             break;
  356.         case SET_DESCRIPTOR:
  357.             CLR_EP0_OUTPKTRDY_DATAEND();
  358.             ep0State=EP0_SETUP_STATE;
  359.             break;
  360.         case SET_FEATURE:
  361.             switch (descSetup.bmRequestType)
  362.             {
  363.             case DEVICE_RECIPIENT:
  364.                 if (descSetup.bValueL == 1)
  365.                     Rwuen = TRUE;
  366.                 break;
  367.             case ENDPOINT_RECIPIENT:
  368.                 if (descSetup.bValueL == 0)
  369.                 {
  370.                     if ((descSetup.bIndexL & 0x7f) == 0x00)
  371.                     {
  372.                         StatusGet.Endpoint0= 1;
  373.                     }
  374.                     if ((descSetup.bIndexL & 0x8f) == 0x81)
  375.                     {
  376.                         StatusGet.Endpoint1= 1;
  377.                     }
  378.                     if ((descSetup.bIndexL & 0x8f) == 0x03)
  379.                     {
  380.                         StatusGet.Endpoint3= 1;
  381.                     }
  382.                 }
  383.                 break;
  384.             default:
  385.                 break;
  386.             }
  387.             CLR_EP0_OUTPKTRDY_DATAEND();
  388.             ep0State=EP0_SETUP_STATE;
  389.             break;
  390.         case SET_INTERFACE:
  391.             InterfaceGet.AlternateSetting= descSetup.bValueL;
  392.             CLR_EP0_OUTPKTRDY_DATAEND();
  393.             ep0State=EP0_SETUP_STATE;
  394.             break;
  395.         case SYNCH_FRAME:
  396.             ep0State=EP0_SETUP_STATE;
  397.             break;
  398.             //////////////////////////////////////////////////////////////
  399.             
  400.         //### 下面这些为虚拟串口对应的请求 ##########
  401. case SET_LINE_CODING:
  402. DbgPrintf("[SET_LINE_CODING]");
  403. CLR_EP0_OUT_PKT_RDY();
  404. ep0State=EP0_OUT_DATA_STATE;
  405. setupData = (U8 *)&line_coding;
  406.          setupDataLen = 7;
  407.             break;
  408. case GET_LINE_CODING:
  409. DbgPrintf("[GET_LINE_CODING]");
  410. CLR_EP0_OUT_PKT_RDY();
  411. ep0State=EP0_IN_DATA_STATE;
  412.             setupData = (U8 *)&line_coding;
  413.          setupDataLen = 7;
  414.             break;
  415. case SET_CONTROL_LINE_STATE:
  416. DbgPrintf("[SET_LINE_STATE]");
  417. CLR_EP0_OUTPKTRDY_DATAEND();
  418.             ep0State=EP0_SETUP_STATE;
  419.             break;
  420.             
  421. case SEND_BREAK:
  422. DbgPrintf("[BREAK]");
  423. CLR_EP0_OUTPKTRDY_DATAEND();
  424.             ep0State=EP0_SETUP_STATE;
  425.             break;
  426.             
  427.         //### end CDC
  428.         default:
  429.             DbgPrintf("[UE:SETUP=%x]",descSetup.bRequest);
  430.             CLR_EP0_OUTPKTRDY_DATAEND(); //Because of no data control transfers.
  431.             ep0State=EP0_SETUP_STATE;
  432.             break;
  433.         }
  434.        //Clear Counter
  435.      segmentCount = 0;
  436.     }
  437.     else if(ep0State == EP0_OUT_DATA_STATE)
  438.     {
  439.      DbgPrintf("[OUTDATE:%d]", rOUT_FIFO_CNT1_REG);
  440.     
  441.      DbgPrintf("[GetDate:");
  442.      while((setupDataLen != 0) && (rOUT_FIFO_CNT1_REG !=0))
  443.      {
  444.      *setupData =rEP0_FIFO;
  445.      DbgPrintf("%x,", *setupData);
  446.      setupData++;
  447.      setupDataLen--;
  448.      }
  449. DbgPrintf("]");
  450.      FLUSH_EP0_FIFO(); //给我的比我要的多?
  451.     
  452.      if(setupDataLen == 0)
  453.      {
  454.      DbgPrintf("OUTRDYEND");
  455.      CLR_EP0_OUTPKTRDY_DATAEND();
  456.     
  457.      ep0State=EP0_SETUP_STATE;
  458.      }
  459.      else
  460.      {
  461.      DbgPrintf("OUTRDY");
  462.      CLR_EP0_OUT_PKT_RDY();  
  463.      }
  464.     }
  465. }
  466. if(ep0State == EP0_IN_DATA_STATE)
  467. {
  468. //如果一次发不完,就要分包了。
  469.     if (setupDataLen > EP0_PKT_SIZE)
  470.     {
  471.      DbgPrintf("[Seg%d]",segmentCount++);
  472.         setupDataSegmentLen = EP0_PKT_SIZE;
  473.         WrPktEp0((U8 *)setupData,setupDataSegmentLen);
  474.         PrintSentPkt(setupData,setupDataSegmentLen);
  475.         SET_EP0_IN_PKT_RDY();
  476.         
  477.         setupData += EP0_PKT_SIZE;
  478.         setupDataLen -= EP0_PKT_SIZE;
  479.     }
  480.     //剩下一点了。
  481.     else if(setupDataLen > 0)
  482.     {
  483.      DbgPrintf("[Seg%d]",segmentCount++);
  484.         setupDataSegmentLen = setupDataLen;
  485.         WrPktEp0((U8 *)setupData,setupDataSegmentLen);
  486.         PrintSentPkt(setupData,setupDataSegmentLen);
  487.         setupDataLen = 0;
  488.         segmentCount = 0;
  489.         
  490.         ep0State = EP0_HANDSHAKE_STATE;
  491.     }
  492. }
  493. if(ep0State == EP0_HANDSHAKE_STATE)
  494. {
  495. DbgPrintf("[ENDIN]");
  496. SET_EP0_INPKTRDY_DATAEND();
  497. ep0State = EP0_SETUP_STATE;
  498. }
  499. }
  500. void PrintEp0Pkt(U8 *pt)
  501. {
  502.     int i;
  503.     DbgPrintf("[RCV:");
  504.     for (i=0;i<EP0_PKT_SIZE;i++)
  505.         DbgPrintf("%x,",pt[i]);
  506.     DbgPrintf("]");
  507. }
  508. void InitDescriptorTable(void)
  509. {
  510. U8 tmp[19] = { 0x05, 0x24, 0x00, 0x10, 0x01, 0x05, 0x24, 0x01, 0x03, 
  511. 0x01, 0x04, 0x24, 0x02, 0x06,0x05, 0x24, 0x06, 0x00, 0x01 };
  512.     //Standard device descriptor
  513.     descDev.bLength=0x12; //EP0_DEV_DESC_SIZE=0x12 bytes
  514.     descDev.bDescriptorType=DEVICE_TYPE;
  515.     descDev.bcdUSBL=0x10;
  516.     descDev.bcdUSBH=0x01;  //Ver 1.10
  517.     descDev.bDeviceClass=0x02;
  518.     descDev.bDeviceSubClass=0x0;
  519.     descDev.bDeviceProtocol=0x0;
  520.     descDev.bMaxPacketSize0=0x8;
  521.     descDev.idVendorL=0x83;
  522.     descDev.idVendorH=0x04;
  523.     descDev.idProductL=0x40;
  524.     descDev.idProductH=0x57;
  525.     descDev.bcdDeviceL=0x00;
  526.     descDev.bcdDeviceH=0x01;
  527.     descDev.iManufacturer=0x1;  //index of string descriptor
  528.     descDev.iProduct=0x2; //index of string descriptor
  529.     descDev.iSerialNumber=0x0;
  530.     descDev.bNumConfigurations=0x1;
  531.     //Standard configuration descriptor
  532.     descriptor.descConf.bLength=0x9;
  533.     descriptor.descConf.bDescriptorType=CONFIGURATION_TYPE;
  534.     descriptor.descConf.wTotalLengthL= sizeof(struct USB_GET_DESCRIPTOR);
  535.     descriptor.descConf.wTotalLengthH=0;
  536.     descriptor.descConf.bNumInterfaces=2;
  537. //dbg    descConf.bConfigurationValue=2;  //why 2? There's no reason.
  538.     descriptor.descConf.bConfigurationValue=1;
  539.     descriptor.descConf.iConfiguration=0;
  540.     descriptor.descConf.bmAttributes=CONF_ATTR_DEFAULT|CONF_ATTR_SELFPOWERED;  //bus powered only.
  541.     descriptor.descConf.maxPower=25; //draws 50mA current from the USB bus.
  542. descriptor.descIf0.bLength=0x9;
  543.     descriptor.descIf0.bDescriptorType=INTERFACE_TYPE;
  544.     descriptor.descIf0.bInterfaceNumber=0x0;
  545.     descriptor.descIf0.bAlternateSetting=0x0; //?
  546.     descriptor.descIf0.bNumEndpoints=1; //# of endpoints except EP0
  547.     descriptor.descIf0.bInterfaceClass=0x02;  /*CDC ACM Comm*/
  548.     descriptor.descIf0.bInterfaceSubClass=0x02;
  549.     descriptor.descIf0.bInterfaceProtocol=0x01;
  550.     descriptor.descIf0.iInterface=0x0;
  551. memcpy(descriptor.CS_INTERFACE0, tmp, 19);
  552. //这个端口是一个中段转输端口,用来报告状态的,我们没有正真用上它。
  553.     descriptor.descEndpt2.bLength=0x7;
  554.     descriptor.descEndpt2.bDescriptorType=ENDPOINT_TYPE;
  555.     descriptor.descEndpt2.bEndpointAddress=2|EP_ADDR_IN; 
  556.     descriptor.descEndpt2.bmAttributes=EP_ATTR_INTERRUPT;
  557.     descriptor.descEndpt2.wMaxPacketSizeL=EP1_PKT_SIZE; //64
  558.     descriptor.descEndpt2.wMaxPacketSizeH=0x0;
  559.     descriptor.descEndpt2.bInterval=0x02;   
  560.     
  561.     //Standard interface descriptor
  562.     descriptor.descIf1.bLength=0x9;
  563.     descriptor.descIf1.bDescriptorType=INTERFACE_TYPE;
  564.     descriptor.descIf1.bInterfaceNumber=0x1;
  565.     descriptor.descIf1.bAlternateSetting=0x0;
  566.     descriptor.descIf1.bNumEndpoints=2;
  567.     descriptor.descIf1.bInterfaceClass=0x0A; /*CDC ACM Data*/
  568.     descriptor.descIf1.bInterfaceSubClass=0x0;
  569.     descriptor.descIf1.bInterfaceProtocol=0x0;
  570.     descriptor.descIf1.iInterface=0x0;
  571.     //Standard endpoint0 descriptor
  572.     descriptor.descEndpt0.bLength=0x7;
  573.     descriptor.descEndpt0.bDescriptorType=ENDPOINT_TYPE;
  574.     descriptor.descEndpt0.bEndpointAddress=1|EP_ADDR_IN;   // 2400Xendpoint 1 is IN endpoint.
  575.     descriptor.descEndpt0.bmAttributes=EP_ATTR_BULK;
  576.     descriptor.descEndpt0.wMaxPacketSizeL=EP1_PKT_SIZE; //64
  577.     descriptor.descEndpt0.wMaxPacketSizeH=0x0;
  578.     descriptor.descEndpt0.bInterval=0x0; //not used
  579.     //Standard endpoint1 descriptor
  580.     descriptor.descEndpt1.bLength=0x7;
  581.     descriptor.descEndpt1.bDescriptorType=ENDPOINT_TYPE;
  582.     descriptor.descEndpt1.bEndpointAddress=3|EP_ADDR_OUT;   // 2400X endpoint 3 is OUT endpoint.
  583.     descriptor.descEndpt1.bmAttributes=EP_ATTR_BULK;
  584.     descriptor.descEndpt1.wMaxPacketSizeL=EP3_PKT_SIZE; //64
  585.     descriptor.descEndpt1.wMaxPacketSizeH=0x0;
  586.     descriptor.descEndpt1.bInterval=0x0; //not used
  587. }