www.pudn.com > arm_uDisk.rar > USBSETUP.C
/************************************************************** NAME: usbsetup.c DESC: process the USB setup stage operations. HISTORY: MAR.25.2002:purnnamu: S3C2400X usbsetup.c is ported for S3C2410X. AUG.20.2002:purnnamu: rEP0_CSR should be used instead of rOUT_CSR1_REG for EP0 macros. ***************************************************************/ #include#include "option.h" #include "2410addr.h" #include "2410lib.h" #include "def.h" #include "2410usb.h" #include "usbmain.h" #include "usb.h" #include "usblib.h" #include "usbsetup.h" // *** End point information *** // EP0: control // EP1: bulk in end point // EP2: not used // EP3: bulk out end point // EP4: not used // *** VERY IMPORTANT NOTE *** // Every descriptor size of EP0 should be 8n+m(m=1~7). // Otherwise, USB will not operate normally because the program // doesn't prepare the case that the descriptor size is 8n+0. // If the size of a descriptor is 8n, the 0 length packit should be sent. // Special thanks to E.S.Choi for reminding me of this USB specification. // =================================================================== // All following commands will operate only in case // - ep0_csr is valid. // =================================================================== #define CLR_EP0_OUT_PKT_RDY() rEP0_CSR=( ep0_csr & (~EP0_WR_BITS)| \ EP0_SERVICED_OUT_PKT_RDY ) #define CLR_EP0_OUTPKTRDY_DATAEND() rEP0_CSR=( ep0_csr & (~EP0_WR_BITS)| \ (EP0_SERVICED_OUT_PKT_RDY|EP0_DATA_END) ) #define SET_EP0_IN_PKT_RDY() rEP0_CSR=( ep0_csr & (~EP0_WR_BITS)| \ (EP0_IN_PKT_READY) ) #define SET_EP0_INPKTRDY_DATAEND() rEP0_CSR=( ep0_csr & (~EP0_WR_BITS)| \ (EP0_IN_PKT_READY|EP0_DATA_END) ) #define CLR_EP0_SETUP_END() rEP0_CSR=( ep0_csr & (~EP0_WR_BITS)| \ (EP0_SERVICED_SETUP_END) ) #define CLR_EP0_SENT_STALL() rEP0_CSR=( ep0_csr & (~EP0_WR_BITS)& \ (~EP0_SENT_STALL) ) #define FLUSH_EP0_FIFO() {while(rOUT_FIFO_CNT1_REG)rEP0_FIFO;} U32 ep0State; //U32=Unsigned int (32bit) U32 ep0SubState; extern volatile int isUsbdSetConfiguration; struct USB_SETUP_DATA descSetup; struct USB_DEVICE_DESCRIPTOR descDev; struct USB_CONFIGURATION_DESCRIPTOR descConf; struct USB_INTERFACE_DESCRIPTOR descIf; struct USB_ENDPOINT_DESCRIPTOR descEndpt0; struct USB_ENDPOINT_DESCRIPTOR descEndpt1; static const U8 descStr0[]={ 4,STRING_TYPE,LANGID_US_L,LANGID_US_H, //codes representing languages };//Total 4 string #ifdef _FOR_UDISK_ static const U8 descStr1_1[18]= //设备序列号 {0x12,0x03,0x32,0x00,0x30,0x00,0x37,0x00,0x31,0x00,0x30,0x00,0x39,0x00,0x38,0x00,0x32,0x00}; static const U8 descStr2_1[]={ //Product (0x2a+2+2),STRING_TYPE, 'U',0x0,'S',0x0,'B',0x0,' ',0x0,'M',0x0,'a',0x0,'s',0x0,'s',0x0, ' ',0x0,'S',0x0,'t',0x0,'o',0x0,'r',0x0,'a',0x0,'g',0x0,'e',0x0, ' ',0x0,'D',0x0,'e',0x0,'v',0x0,'i',0x0,'c',0x0,'e',0x0 };//Total 46 string #endif /* #define STRING_TYPE=(3) #define LANGID_US_L=(0x09) #define LANGID_US_H=(0x04) */ static const U8 descStr1[]={ //Manufacturer (0x14+2),STRING_TYPE, 'S',0x0,'y',0x0,'s',0x0,'t',0x0,'e',0x0,'m',0x0,' ',0x0,'M',0x0, 'C',0x0,'U',0x0, };//Total 22 string static const U8 descStr2[]={ //Product (0x2a+2+2),STRING_TYPE, 'U',0x0,'S',0x0,'B',0x0,' ',0x0,'M',0x0,'a',0x0,'s',0x0,'s',0x0, ' ',0x0,'S',0x0,'t',0x0,'o',0x0,'r',0x0,'a',0x0,'g',0x0,'e',0x0, ' ',0x0,'D',0x0,'e',0x0,'v',0x0,'i',0x0,'c',0x0,'e',0x0 };//Total 44 string void Ep0Handler(void) { static int ep0SubState; int i; U8 ep0_csr; #ifdef _FOR_UDISK_ unsigned char max_LUN=0; //只有一个逻辑单元 #endif rINDEX_REG=0; ep0_csr=rEP0_CSR;//Push to buffer //DbgPrintf("<0:%x]",ep0_csr); //DATAEND interrupt(ep0_csr==0x0) will be ignored //because ep0State==EP0_STATE_INIT when the DATAEND interrupt is issued. if(ep0_csr & EP0_SETUP_END)//define EP0_SETUP_END=0x10 { // Host may end GET_DESCRIPTOR operation without completing the IN data stage. // If host does that, SETUP_END bit will be set. // OUT_PKT_RDY has to be also cleared because status stage sets OUT_PKT_RDY to 1. //DbgPrintf("[SETUPEND]"); CLR_EP0_SETUP_END(); if(ep0_csr & EP0_OUT_PKT_READY) { FLUSH_EP0_FIFO(); //(???) //I think this isn't needed because EP0 flush is done automatically. CLR_EP0_OUT_PKT_RDY(); } ep0State=EP0_STATE_INIT;//#define EP0_STATE_INIT=0 return; } //I think that EP0_SENT_STALL will not be set to 1. if(ep0_csr & EP0_SENT_STALL) { //DbgPrintf("[STALL]"); CLR_EP0_SENT_STALL(); if(ep0_csr & EP0_OUT_PKT_READY) { CLR_EP0_OUT_PKT_RDY(); } ep0State=EP0_STATE_INIT;//#define EP0_STATE_INIT=0 return; } if((ep0_csr & EP0_OUT_PKT_READY) && (ep0State==EP0_STATE_INIT)) { RdPktEp0((U8 *)&descSetup,EP0_PKT_SIZE);//Read data from EP0_FIFO #ifdef _FOR_UDISK_ CLR_EP0_OUT_PKT_RDY(); #endif //PrintEp0Pkt((U8 *)(&descSetup)); //DEBUG switch(descSetup.bRequest)//SW1 { #ifdef _FOR_UDISK_ case 0xFE: // CLR_EP0_OUT_PKT_RDY(); if(USBD_flg==1) { if(descSetup.bmRequestType==0xA1) { WrPktEp0((U8 *)&max_LUN,1); SET_EP0_IN_PKT_RDY(); } } break; #endif case GET_DESCRIPTOR://0x06 switch(descSetup.bValueH)//SW2 { case DEVICE_TYPE://0x01 //DbgPrintf("[GDD]"); #ifndef _FOR_UDISK_ CLR_EP0_OUT_PKT_RDY(); #endif ep0State=EP0_STATE_GD_DEV_0; break; case CONFIGURATION_TYPE://0x02 //DbgPrintf("[GDC]"); #ifndef _FOR_UDISK_ CLR_EP0_OUT_PKT_RDY(); #endif if((descSetup.bLengthL+(descSetup.bLengthH<<8))>0x09) //bLengthH should be used for bLength=0x209 at WIN2K. ep0State=EP0_STATE_GD_CFG_0; //for WIN98,WIN2K else ep0State=EP0_STATE_GD_CFG_ONLY_0; //for WIN2K break; case STRING_TYPE://0x03 //DbgPrintf("[GDS]"); #ifndef _FOR_UDISK_ CLR_EP0_OUT_PKT_RDY(); #endif switch(descSetup.bValueL)//SW3 { case 0: ep0State=EP0_STATE_GD_STR_I0; break; case 1: ep0State=EP0_STATE_GD_STR_I1; break; case 2: ep0State=EP0_STATE_GD_STR_I2; break; default: //DbgPrintf("[UE:STRI?]"); break; }//End of SW3 ep0SubState=0; break; case INTERFACE_TYPE: //DbgPrintf("[GDI]"); #ifndef _FOR_UDISK_ CLR_EP0_OUT_PKT_RDY(); #endif ep0State=EP0_STATE_GD_IF_ONLY_0; //for WIN98 break; case ENDPOINT_TYPE: //DbgPrintf("[GDE]"); #ifndef _FOR_UDISK_ CLR_EP0_OUT_PKT_RDY(); #endif switch(descSetup.bValueL&0xf)//SW4 { case 0: ep0State=EP0_STATE_GD_EP0_ONLY_0; break; case 1: ep0State=EP0_STATE_GD_EP1_ONLY_0; break; default: //DbgPrintf("[UE:GDE?]"); break; }//End of SW4 break; default: //DbgPrintf("[UE:GD?]"); break; }//End of SW2 break; case SET_ADDRESS: //DbgPrintf("[SA:%d]",descSetup.bValueL); #ifdef _FOR_UDISK_ if(USBD_flg==1) WrPktEp0(0,0); #endif rFUNC_ADDR_REG=descSetup.bValueL | 0x80; CLR_EP0_OUTPKTRDY_DATAEND(); //Because of no data control transfers. ep0State=EP0_STATE_INIT; break; case SET_CONFIGURATION: //DbgPrintf("[SC]"); #ifdef _FOR_UDISK_ if(USBD_flg==1) WrPktEp0(0,0); #endif CLR_EP0_OUTPKTRDY_DATAEND(); //Because of no data control transfers. ep0State=EP0_STATE_INIT; isUsbdSetConfiguration=1; break; default: //DbgPrintf("[UE:SETUP=%x]",descSetup.bRequest); CLR_EP0_OUTPKTRDY_DATAEND(); //Because of no data control transfers. ep0State=EP0_STATE_INIT; break; }//End of SW1 }// switch(ep0State) { case EP0_STATE_INIT: break; //=== GET_DESCRIPTOR:DEVICE === // Send USB device descriptor to USB host, total 18 bytes. case EP0_STATE_GD_DEV_0: //DbgPrintf("[GDD0]"); //Uart_Printf("start of USB_DEVICE_DESCRIPTOR\n"); WrPktEp0((U8 *)&descDev+0x00,8); //Write 8 bytes data (0-7) of USB_DEVICE_DESCRIPTOR into EP0_FIFO SET_EP0_IN_PKT_RDY(); ep0State=EP0_STATE_GD_DEV_1; break; case EP0_STATE_GD_DEV_1: //DbgPrintf("[GDD1]"); WrPktEp0((U8 *)&descDev+0x08,8); //Write 8 bytes data (8-15) of USB_DEVICE_DESCRIPTOR into EP0_FIFO SET_EP0_IN_PKT_RDY(); ep0State=EP0_STATE_GD_DEV_2; break; case EP0_STATE_GD_DEV_2: //DbgPrintf("[GDD2]"); WrPktEp0((U8 *)&descDev+0x10,2); //8+8+2=0x12 //Write 2 bytes data (16-17) of USB_DEVICE_DESCRIPTOR into EP0_FIFO SET_EP0_INPKTRDY_DATAEND(); ep0State=EP0_STATE_INIT; //Uart_Printf("end of USB_DEVICE_DESCRIPTOR\n"); break; //=== GET_DESCRIPTOR:CONFIGURATION+INTERFACE+ENDPOINT0+ENDPOINT1 === //Windows98 gets these 4 descriptors all together by issuing only a request. //Windows2000 gets each descriptor seperately. case EP0_STATE_GD_CFG_0: //DbgPrintf("[GDC0]"); WrPktEp0((U8 *)&descConf+0x00,8); //EP0_PKT_SIZE SET_EP0_IN_PKT_RDY(); ep0State=EP0_STATE_GD_CFG_1; break; case EP0_STATE_GD_CFG_1: //DbgPrintf("[GDC1]"); WrPktEp0((U8 *)&descConf+0x08,1); WrPktEp0((U8 *)&descIf+0x00,7); SET_EP0_IN_PKT_RDY(); ep0State=EP0_STATE_GD_CFG_2; break; case EP0_STATE_GD_CFG_2: //DbgPrintf("[GDC2]"); WrPktEp0((U8 *)&descIf+0x07,2); WrPktEp0((U8 *)&descEndpt0+0x00,6); SET_EP0_IN_PKT_RDY(); ep0State=EP0_STATE_GD_CFG_3; break; case EP0_STATE_GD_CFG_3: //DbgPrintf("[GDC3]"); WrPktEp0((U8 *)&descEndpt0+0x06,1); WrPktEp0((U8 *)&descEndpt1+0x00,7); SET_EP0_IN_PKT_RDY(); ep0State=EP0_STATE_GD_CFG_4; break; case EP0_STATE_GD_CFG_4: //DbgPrintf("[GDC4]"); //zero length data packit SET_EP0_INPKTRDY_DATAEND(); ep0State=EP0_STATE_INIT; break; //=== GET_DESCRIPTOR:CONFIGURATION ONLY , For Win2K only === // Send USB configuration descriptor to USB host, total 9 bytes. case EP0_STATE_GD_CFG_ONLY_0: //DbgPrintf("[GDCO0]"); WrPktEp0((U8 *)&descConf+0x00,8); //EP0_PKT_SIZE SET_EP0_IN_PKT_RDY(); ep0State=EP0_STATE_GD_CFG_ONLY_1; break; case EP0_STATE_GD_CFG_ONLY_1: //DbgPrintf("[GDCO1]"); WrPktEp0((U8 *)&descConf+0x08,1); SET_EP0_INPKTRDY_DATAEND(); ep0State=EP0_STATE_INIT; break; //=== GET_DESCRIPTOR:INTERFACE ONLY=== // Send USB interface descriptor to USB host, total 9 bytes. case EP0_STATE_GD_IF_ONLY_0: //DbgPrintf("[GDI0]"); WrPktEp0((U8 *)&descIf+0,8); SET_EP0_IN_PKT_RDY(); ep0State=EP0_STATE_GD_IF_ONLY_1; break; case EP0_STATE_GD_IF_ONLY_1: //DbgPrintf("[GDI1]"); WrPktEp0((U8 *)&descIf+8,1); SET_EP0_INPKTRDY_DATAEND(); ep0State=EP0_STATE_INIT; break; //=== GET_DESCRIPTOR:ENDPOINT 0 ONLY=== // Send USB ENDPOINT_0 descriptor to USB host, total 7 bytes. case EP0_STATE_GD_EP0_ONLY_0: //DbgPrintf("[GDE00]"); WrPktEp0((U8 *)&descEndpt0+0,7); SET_EP0_INPKTRDY_DATAEND(); ep0State=EP0_STATE_INIT; break; //=== GET_DESCRIPTOR:ENDPOINT 1 ONLY=== // Send USB ENDPOINT_1 descriptor to USB host, total 7 bytes. case EP0_STATE_GD_EP1_ONLY_0: //DbgPrintf("[GDE10]"); WrPktEp0((U8 *)&descEndpt1+0,7); SET_EP0_INPKTRDY_DATAEND(); ep0State=EP0_STATE_INIT; break; //=== GET_DESCRIPTOR:STRING === case EP0_STATE_GD_STR_I0: //DbgPrintf("[GDS0_0]"); #ifdef _FOR_UDISK_ if(USBD_flg==1) { if(descSetup.bLengthL+(descSetup.bLengthH<<8) <4) WrPktEp0((U8 *)descStr0, /*4*/descSetup.bLengthL+(descSetup.bLengthH<<8) ); else SET_EP0_INPKTRDY_DATAEND(); } else if(USBD_flg==0) { WrPktEp0((U8 *)descStr0, 4 ); SET_EP0_INPKTRDY_DATAEND(); } #else WrPktEp0((U8 *)descStr0, 4 ); SET_EP0_INPKTRDY_DATAEND(); #endif ep0State=EP0_STATE_INIT; ep0SubState=0; break; case EP0_STATE_GD_STR_I1: //DbgPrintf("[GDS1_%d]",ep0SubState); #ifndef _FOR_UDISK_ if((ep0SubState*EP0_PKT_SIZE+EP0_PKT_SIZE) < sizeof(descStr1)) { WrPktEp0((U8 *)descStr1+(ep0SubState*EP0_PKT_SIZE),EP0_PKT_SIZE); SET_EP0_IN_PKT_RDY(); ep0State=EP0_STATE_GD_STR_I1; ep0SubState++; } else { WrPktEp0((U8 *)descStr1+(ep0SubState*EP0_PKT_SIZE), sizeof(descStr1)-(ep0SubState*EP0_PKT_SIZE)); SET_EP0_INPKTRDY_DATAEND(); ep0State=EP0_STATE_INIT; ep0SubState=0; } #else if(USBD_flg==1) { while(1) { //Uart_Printf("[GDS1_%d]",ep0SubState); if(descSetup.bLengthL+(descSetup.bLengthH<<8) + + + descConf.wTotalLengthH=0; descConf.bNumInterfaces=1; //dbg descConf.bConfigurationValue=2; //why 2? There's no reason. descConf.bConfigurationValue=1; descConf.iConfiguration=0; descConf.bmAttributes=CONF_ATTR_DEFAULT;//bus powered only. descConf.maxPower=25; //draws 50mA current from the USB bus. //Standard interface descriptor descIf.bLength=0x9; descIf.bDescriptorType=INTERFACE_TYPE;//0x04 descIf.bInterfaceNumber=0x0; descIf.bAlternateSetting=0x0; //? descIf.bNumEndpoints=2; //# of endpoints except EP0 descIf.bInterfaceClass=0xff; //0x0 ? descIf.bInterfaceSubClass=0x0; descIf.bInterfaceProtocol=0x0; descIf.iInterface=0x0; //Standard endpoint0 descriptor descEndpt0.bLength=0x7; descEndpt0.bDescriptorType=ENDPOINT_TYPE;//0x05 descEndpt0.bEndpointAddress=1|EP_ADDR_IN;//0x80|0x01=0x81 // 2400Xendpoint 1 is IN endpoint. descEndpt0.bmAttributes=EP_ATTR_BULK;//0x02,transmition type = Bulk descEndpt0.wMaxPacketSizeL=EP1_PKT_SIZE; //64 descEndpt0.wMaxPacketSizeH=0x0; descEndpt0.bInterval=0x0; //not used //Standard endpoint1 descriptor descEndpt1.bLength=0x7; descEndpt1.bDescriptorType=ENDPOINT_TYPE;//0x05 descEndpt1.bEndpointAddress=3|EP_ADDR_OUT;//0x00|0x03=0x03 // 2400X endpoint 3 is OUT endpoint. descEndpt1.bmAttributes=EP_ATTR_BULK;//0x02,transmition type = Bulk descEndpt1.wMaxPacketSizeL=EP3_PKT_SIZE; //64 descEndpt1.wMaxPacketSizeH=0x0; descEndpt1.bInterval=0x0; //not used #else if(USBD_flg==1) { //Uart_Printf("InitDescriptorTable()\n"); //Standard device descriptor descDev.bLength=0x12;//EP0_DEV_DESC_SIZE=0x12 bytes descDev.bDescriptorType=DEVICE_TYPE; descDev.bcdUSBL=0x10; descDev.bcdUSBH=0x01;//Indicate USB Ver 1.10 descDev.bDeviceClass=0x00;//Vendor specific descDev.bDeviceSubClass=0x0; descDev.bDeviceProtocol=0x0;//?? should be 0xff descDev.bMaxPacketSize0=0x8;//EndPoint_0's max Packet Size descDev.idVendorL=0x71;//0x40;//Vendor ID_h descDev.idVendorH=0x11;//0x52;//Vendor ID_l descDev.idProductL=0xf0;//0x03;//Product ID_h descDev.idProductH=0xff;//0x04;//Product ID_l descDev.bcdDeviceL=0x00;//Product version_h descDev.bcdDeviceH=0x01;//Product version_l descDev.iManufacturer=0x1;//index of string descriptor index descDev.iProduct=0x2;//index of string descriptor index descDev.iSerialNumber=0x0;//Product serial number string descriptor index descDev.bNumConfigurations=0x1;//Device descriptor number //Standard configuration descriptor descConf.bLength=0x09; descConf.bDescriptorType=CONFIGURATION_TYPE;//0x02 descConf.wTotalLengthL=0x20; // + + + descConf.wTotalLengthH=0; descConf.bNumInterfaces=1; //dbg descConf.bConfigurationValue=2; //why 2? There's no reason. descConf.bConfigurationValue=1; descConf.iConfiguration=0; descConf.bmAttributes=CONF_ATTR_DEFAULT;//0x0a;//bus powered only. descConf.maxPower=0x32;//25; //draws 50mA current from the USB bus. //Standard interface descriptor descIf.bLength=0x9; descIf.bDescriptorType=INTERFACE_TYPE;//0x04 descIf.bInterfaceNumber=0x0; descIf.bAlternateSetting=0x0; //? descIf.bNumEndpoints=2; //# of endpoints except EP0 descIf.bInterfaceClass=0x08; //0x0 ? descIf.bInterfaceSubClass=0x06;//0x04;//0x04:软盘,oxo6:普通邋邋SCSI descIf.bInterfaceProtocol=0x50; descIf.iInterface=0x0; //Standard endpoint1 descriptor(IN) descEndpt0.bLength=0x7; descEndpt0.bDescriptorType=ENDPOINT_TYPE;//0x05 descEndpt0.bEndpointAddress=1|EP_ADDR_IN;//0x80|0x01=0x81 // 2400Xendpoint 1 is IN endpoint. descEndpt0.bmAttributes=EP_ATTR_BULK;//0x02,transmition type = Bulk descEndpt0.wMaxPacketSizeL=EP1_PKT_SIZE; //64 descEndpt0.wMaxPacketSizeH=0x0; descEndpt0.bInterval=0x0; //not used //Standard endpoint3 descriptor(OUT) descEndpt1.bLength=0x7; descEndpt1.bDescriptorType=ENDPOINT_TYPE;//0x05 descEndpt1.bEndpointAddress=3|EP_ADDR_OUT;//0x00|0x03=0x03 // 2400X endpoint 3 is OUT endpoint. descEndpt1.bmAttributes=EP_ATTR_BULK;//0x02,transmition type = Bulk descEndpt1.wMaxPacketSizeL=EP3_PKT_SIZE; //64 descEndpt1.wMaxPacketSizeH=0x0; descEndpt1.bInterval=0x0; //not used } else if(USBD_flg==0) { //Standard device descriptor descDev.bLength=0x12;//EP0_DEV_DESC_SIZE=0x12 bytes descDev.bDescriptorType=DEVICE_TYPE; descDev.bcdUSBL=0x10; descDev.bcdUSBH=0x01;//Indicate USB Ver 1.10 descDev.bDeviceClass=0xFF;//Vendor specific descDev.bDeviceSubClass=0x0; descDev.bDeviceProtocol=0x0;//?? should be 0xff descDev.bMaxPacketSize0=0x8;//EndPoint_0's max Packet Size descDev.idVendorL=0x45;//Vendor ID_h descDev.idVendorH=0x53;//Vendor ID_l descDev.idProductL=0x34;//Product ID_h descDev.idProductH=0x12;//Product ID_l descDev.bcdDeviceL=0x00;//Product version_h descDev.bcdDeviceH=0x01;//Product version_l descDev.iManufacturer=0x1;//index of string descriptor index descDev.iProduct=0x2;//index of string descriptor index descDev.iSerialNumber=0x0;//Product serial number string descriptor index descDev.bNumConfigurations=0x1;//Device descriptor number //Standard configuration descriptor descConf.bLength=0x09; descConf.bDescriptorType=CONFIGURATION_TYPE;//0x02 descConf.wTotalLengthL=0x20; // + + + descConf.wTotalLengthH=0; descConf.bNumInterfaces=1; //dbg descConf.bConfigurationValue=2; //why 2? There's no reason. descConf.bConfigurationValue=1; descConf.iConfiguration=0; descConf.bmAttributes=CONF_ATTR_DEFAULT;//bus powered only. descConf.maxPower=25; //draws 50mA current from the USB bus. //Standard interface descriptor descIf.bLength=0x9; descIf.bDescriptorType=INTERFACE_TYPE;//0x04 descIf.bInterfaceNumber=0x0; descIf.bAlternateSetting=0x0; //? descIf.bNumEndpoints=2; //# of endpoints except EP0 descIf.bInterfaceClass=0xff; //0x0 ? descIf.bInterfaceSubClass=0x0; descIf.bInterfaceProtocol=0x0; descIf.iInterface=0x0; //Standard endpoint0 descriptor descEndpt0.bLength=0x7; descEndpt0.bDescriptorType=ENDPOINT_TYPE;//0x05 descEndpt0.bEndpointAddress=1|EP_ADDR_IN;//0x80|0x01=0x81 // 2400Xendpoint 1 is IN endpoint. descEndpt0.bmAttributes=EP_ATTR_BULK;//0x02,transmition type = Bulk descEndpt0.wMaxPacketSizeL=EP1_PKT_SIZE; //64 descEndpt0.wMaxPacketSizeH=0x0; descEndpt0.bInterval=0x0; //not used //Standard endpoint1 descriptor descEndpt1.bLength=0x7; descEndpt1.bDescriptorType=ENDPOINT_TYPE;//0x05 descEndpt1.bEndpointAddress=3|EP_ADDR_OUT;//0x00|0x03=0x03 // 2400X endpoint 3 is OUT endpoint. descEndpt1.bmAttributes=EP_ATTR_BULK;//0x02,transmition type = Bulk descEndpt1.wMaxPacketSizeL=EP3_PKT_SIZE; //64 descEndpt1.wMaxPacketSizeH=0x0; descEndpt1.bInterval=0x0; //not used } #endif }