usbsetup.c
资源名称:u241mon.zip [点击查看]
上传用户:hank9955
上传日期:2022-08-05
资源大小:14k
文件大小:21k
源码类别:
USB编程
开发平台:
C/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 <string.h>
- #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;}
- extern volatile int isUsbdSetConfiguration;
- volatile U8 Rwuen;
- volatile U8 Configuration=1;
- volatile U8 AlterSetting;
- volatile U8 Selfpwr=TRUE;
- volatile U8 device_status;
- volatile U8 interface_status;
- volatile U8 endpoint0_status;
- volatile U8 endpoint1_status;
- volatile U8 endpoint3_status;
- struct USB_SETUP_DATA descSetup;
- struct USB_DEVICE_DESCRIPTOR descDev;
- struct USB_CONFIGURATION_SET ConfigSet;
- struct USB_INTERFACE_GET InterfaceGet;
- struct USB_GET_STATUS StatusGet; //={0,0,0,0,0};
- static const U8 descStr0[]=
- {
- 4,STRING_TYPE,LANGID_US_L,LANGID_US_H, //codes representing languages
- };
- static const U8 descStr1[]= //Manufacturer
- {
- (16+2),STRING_TYPE,
- 'M',0x0,'i',0x0,'a',0x0,'r',0x0,'t',0x0,'e',0x0,'c',0x0,'h',0x0,
- };
- static const U8 descStr2[]= //Product
- {
- (50+2),STRING_TYPE,
- 'U',0x0,'S',0x0,'B',0x0,' ',0x0,'S',0x0,'e',0x0,'r',0x0,'i',0x0,
- 'a',0x0,'l',0x0,' ',0x0,'T',0x0,'e',0x0,'s',0x0,'t',0x0,' ',0x0,
- 'b',0x0,'y',0x0,' ',0x0,'T',0x0,'i',0x0,'n',0x0,'n',0x0,'a',0x0,
- 'l',0x0,
- };
- //Tinnal Add
- struct USB_GET_DESCRIPTOR
- {
- struct USB_CONFIGURATION_DESCRIPTOR descConf;
- struct USB_INTERFACE_DESCRIPTOR descIf0;
- U8 CS_INTERFACE0[19];
- struct USB_ENDPOINT_DESCRIPTOR descEndpt2;
- struct USB_INTERFACE_DESCRIPTOR descIf1;
- struct USB_ENDPOINT_DESCRIPTOR descEndpt0;
- struct USB_ENDPOINT_DESCRIPTOR descEndpt1;
- }descriptor;
- U8 line_coding[7] =
- {
- 0x00, //band rate
- 0xE1,
- 0x00,
- 0x00,
- 0, //stop bit
- 1, //parity
- 8, //databits
- };
- U32 ep0State = EP0_SETUP_END;
- U8 *setupData; //setup回应包指针,每次向后EP0_PKT_SIZE字节
- U32 setupDataLen = 0; //setup回应包的总长度
- U32 setupDataSegmentLen = 0; //当前分段的长度
- U32 segmentCount =0; //调试用。
- //Tinnal Add end
- void PrintSentPkt(U8 *pt, U32 count)
- {
- int i;
- DbgPrintf("[SEND:");
- for (i=0;i<count;i++)
- DbgPrintf("%x,",pt[i]);
- DbgPrintf("]");
- }
- void Ep0Handler(void)
- {
- int i;
- U8 ep0_csr;
- rINDEX_REG=0;
- ep0_csr=rEP0_CSR;
- 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)
- {
- // 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_SETUP_STATE;
- 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_SETUP_STATE;
- return;
- }
- if(ep0_csr & EP0_OUT_PKT_READY)
- {
- DbgPrintf("[INDATA]");
- if (ep0State == EP0_SETUP_STATE )
- {
- RdPktEp0((U8 *)&descSetup,8);
- PrintEp0Pkt((U8 *)(&descSetup));
- switch (descSetup.bRequest)
- {
- case GET_DESCRIPTOR:
- switch (descSetup.bValueH)
- {
- case DEVICE_TYPE:
- DbgPrintf("[GDD]");
- CLR_EP0_OUT_PKT_RDY();
- ep0State=EP0_IN_DATA_STATE;
- setupData = (U8*)&descDev;
- setupDataLen = sizeof(descDev);
- break;
- case CONFIGURATION_TYPE:
- DbgPrintf("[GDC]");
- CLR_EP0_OUT_PKT_RDY();
- if ((descSetup.bLengthL+(descSetup.bLengthH<<8))>0x9)
- //bLengthH should be used for bLength=0x209 at WIN2K.
- {
- ep0State=EP0_IN_DATA_STATE; //for WIN98,WIN2K
- setupData = (U8*)&descriptor.descConf;
- setupDataLen = sizeof(descriptor);
- }
- else
- {
- ep0State=EP0_IN_DATA_STATE; //for WIN2K
- setupData = (U8*)&descriptor.descConf;
- setupDataLen = sizeof(descriptor.descConf);
- }
- break;
- case STRING_TYPE:
- DbgPrintf("[GDS]");
- CLR_EP0_OUT_PKT_RDY();
- switch (descSetup.bValueL)
- {
- case 0:
- //ep0State=EP0_STATE_GD_STR_I0;
- ep0State = EP0_IN_DATA_STATE;
- setupData = (U8*)descStr0;
- setupDataLen = sizeof(descStr0);
- break;
- case 1:
- //ep0State=EP0_STATE_GD_STR_I1;
- ep0State = EP0_IN_DATA_STATE;
- setupData = (U8*)descStr1;
- setupDataLen = sizeof(descStr1);
- break;
- case 2:
- //ep0State=EP0_STATE_GD_STR_I2;
- ep0State = EP0_IN_DATA_STATE;
- setupData = (U8*)descStr2;
- setupDataLen = sizeof(descStr2);
- break;
- default:
- DbgPrintf("[UE:STRI?]");
- break;
- }
- break;
- /*
- case INTERFACE_TYPE:
- DbgPrintf("[GDI]");
- CLR_EP0_OUT_PKT_RDY();
- //ep0State=EP0_STATE_GD_IF_ONLY_0; //for WIN98
- setupData = (U8*)&descriptor.descIf;
- setupDataLen = sizeof(descriptor.descIf);
- break;
- */
- case ENDPOINT_TYPE:
- DbgPrintf("[GDE]");
- CLR_EP0_OUT_PKT_RDY();
- switch (descSetup.bValueL&0xf)
- {
- case 0:
- //ep0State=EP0_STATE_GD_EP0_ONLY_0;
- ep0State = EP0_IN_DATA_STATE;
- setupData = (U8*)&descriptor.descEndpt0;
- setupDataLen = sizeof(descriptor.descEndpt0);
- break;
- case 1:
- //ep0State=EP0_STATE_GD_EP1_ONLY_0;
- ep0State = EP0_IN_DATA_STATE;
- setupData = (U8*)&descriptor.descEndpt1;
- setupDataLen = sizeof(descriptor.descEndpt1);
- break;
- case 2:
- ep0State = EP0_IN_DATA_STATE;
- setupData = (U8*)&descriptor.descEndpt2;
- setupDataLen = sizeof(descriptor.descEndpt2);
- break;
- default:
- DbgPrintf("[UE:GDE?]");
- break;
- }
- break;
- default:
- DbgPrintf("[UE:GD?]");
- break;
- }
- break;
- //end case GET_DESCRIPTOR
- case SET_ADDRESS:
- DbgPrintf("[SA:%d]",descSetup.bValueL);
- rFUNC_ADDR_REG=descSetup.bValueL | 0x80;
- CLR_EP0_OUTPKTRDY_DATAEND(); //Because of no data control transfers.
- ep0State=EP0_SETUP_STATE;
- break;
- case SET_CONFIGURATION:
- DbgPrintf("[SC]");
- ConfigSet.ConfigurationValue=descSetup.bValueL;
- CLR_EP0_OUTPKTRDY_DATAEND(); //Because of no data control transfers.
- ep0State=EP0_SETUP_STATE;
- isUsbdSetConfiguration=1;
- break;
- //////////////////////// For chapter 9 test ////////////////////
- case CLEAR_FEATURE:
- switch (descSetup.bmRequestType)
- {
- case DEVICE_RECIPIENT:
- if (descSetup.bValueL == 1)
- Rwuen = FALSE;
- break;
- case ENDPOINT_RECIPIENT:
- if (descSetup.bValueL == 0)
- {
- if ((descSetup.bIndexL & 0x7f) == 0x00)
- {
- StatusGet.Endpoint0= 0;
- }
- if ((descSetup.bIndexL & 0x8f) == 0x81) // IN Endpoint 1
- {
- StatusGet.Endpoint1= 0;
- }
- if ((descSetup.bIndexL & 0x8f) == 0x03) // OUT Endpoint 3
- {
- StatusGet.Endpoint3= 0;
- }
- }
- break;
- default:
- break;
- }
- CLR_EP0_OUTPKTRDY_DATAEND();
- ep0State=EP0_SETUP_STATE;
- break;
- case GET_CONFIGURATION:
- CLR_EP0_OUT_PKT_RDY();
- ep0State=EP0_IN_DATA_STATE;
- setupData = (U8 *)&ConfigSet;
- setupDataLen = 1;
- break;
- case GET_INTERFACE:
- CLR_EP0_OUT_PKT_RDY();
- ep0State=EP0_IN_DATA_STATE;
- setupData = (U8 *)&InterfaceGet;
- setupDataLen = 1;
- break;
- case GET_STATUS:
- switch (descSetup.bmRequestType)
- {
- /* case (0x80):
- CLR_EP0_OUT_PKT_RDY();
- StatusGet.Device=((U8)Rwuen<<1)|(U8)Selfpwr;
- //ep0State=EP0_GET_STATUS0;
- setupData = (U8 *)&StatusGet+0;
- setupDataLen = sizeof(descriptor.descIf);
- break;*/
- case (0x81):
- CLR_EP0_OUT_PKT_RDY();
- StatusGet.Interface=0;
- ep0State=EP0_IN_DATA_STATE;
- setupData = (U8 *)&StatusGet+1;
- setupDataLen = 1;
- break;
- case (0x82):
- CLR_EP0_OUT_PKT_RDY();
- if ((descSetup.bIndexL & 0x7f) == 0x00)
- {
- ep0State=EP0_IN_DATA_STATE;
- setupData = (U8 *)&StatusGet+2;
- setupDataLen = 1;
- }
- if ((descSetup.bIndexL & 0x8f) == 0x81)
- {
- ep0State=EP0_IN_DATA_STATE;
- setupData = (U8 *)&StatusGet+3;
- setupDataLen = 1;
- }
- if ((descSetup.bIndexL & 0x8f) == 0x03)
- {
- ep0State=EP0_IN_DATA_STATE;
- setupData = (U8 *)&StatusGet+4;
- setupDataLen = 1;
- }
- break;
- default:
- break;
- }
- break;
- case SET_DESCRIPTOR:
- CLR_EP0_OUTPKTRDY_DATAEND();
- ep0State=EP0_SETUP_STATE;
- break;
- case SET_FEATURE:
- switch (descSetup.bmRequestType)
- {
- case DEVICE_RECIPIENT:
- if (descSetup.bValueL == 1)
- Rwuen = TRUE;
- break;
- case ENDPOINT_RECIPIENT:
- if (descSetup.bValueL == 0)
- {
- if ((descSetup.bIndexL & 0x7f) == 0x00)
- {
- StatusGet.Endpoint0= 1;
- }
- if ((descSetup.bIndexL & 0x8f) == 0x81)
- {
- StatusGet.Endpoint1= 1;
- }
- if ((descSetup.bIndexL & 0x8f) == 0x03)
- {
- StatusGet.Endpoint3= 1;
- }
- }
- break;
- default:
- break;
- }
- CLR_EP0_OUTPKTRDY_DATAEND();
- ep0State=EP0_SETUP_STATE;
- break;
- case SET_INTERFACE:
- InterfaceGet.AlternateSetting= descSetup.bValueL;
- CLR_EP0_OUTPKTRDY_DATAEND();
- ep0State=EP0_SETUP_STATE;
- break;
- case SYNCH_FRAME:
- ep0State=EP0_SETUP_STATE;
- break;
- //////////////////////////////////////////////////////////////
- //### 下面这些为虚拟串口对应的请求 ##########
- case SET_LINE_CODING:
- DbgPrintf("[SET_LINE_CODING]");
- CLR_EP0_OUT_PKT_RDY();
- ep0State=EP0_OUT_DATA_STATE;
- setupData = (U8 *)&line_coding;
- setupDataLen = 7;
- break;
- case GET_LINE_CODING:
- DbgPrintf("[GET_LINE_CODING]");
- CLR_EP0_OUT_PKT_RDY();
- ep0State=EP0_IN_DATA_STATE;
- setupData = (U8 *)&line_coding;
- setupDataLen = 7;
- break;
- case SET_CONTROL_LINE_STATE:
- DbgPrintf("[SET_LINE_STATE]");
- CLR_EP0_OUTPKTRDY_DATAEND();
- ep0State=EP0_SETUP_STATE;
- break;
- case SEND_BREAK:
- DbgPrintf("[BREAK]");
- CLR_EP0_OUTPKTRDY_DATAEND();
- ep0State=EP0_SETUP_STATE;
- break;
- //### end CDC
- default:
- DbgPrintf("[UE:SETUP=%x]",descSetup.bRequest);
- CLR_EP0_OUTPKTRDY_DATAEND(); //Because of no data control transfers.
- ep0State=EP0_SETUP_STATE;
- break;
- }
- //Clear Counter
- segmentCount = 0;
- }
- else if(ep0State == EP0_OUT_DATA_STATE)
- {
- DbgPrintf("[OUTDATE:%d]", rOUT_FIFO_CNT1_REG);
- DbgPrintf("[GetDate:");
- while((setupDataLen != 0) && (rOUT_FIFO_CNT1_REG !=0))
- {
- *setupData =rEP0_FIFO;
- DbgPrintf("%x,", *setupData);
- setupData++;
- setupDataLen--;
- }
- DbgPrintf("]");
- FLUSH_EP0_FIFO(); //给我的比我要的多?
- if(setupDataLen == 0)
- {
- DbgPrintf("OUTRDYEND");
- CLR_EP0_OUTPKTRDY_DATAEND();
- ep0State=EP0_SETUP_STATE;
- }
- else
- {
- DbgPrintf("OUTRDY");
- CLR_EP0_OUT_PKT_RDY();
- }
- }
- }
- if(ep0State == EP0_IN_DATA_STATE)
- {
- //如果一次发不完,就要分包了。
- if (setupDataLen > EP0_PKT_SIZE)
- {
- DbgPrintf("[Seg%d]",segmentCount++);
- setupDataSegmentLen = EP0_PKT_SIZE;
- WrPktEp0((U8 *)setupData,setupDataSegmentLen);
- PrintSentPkt(setupData,setupDataSegmentLen);
- SET_EP0_IN_PKT_RDY();
- setupData += EP0_PKT_SIZE;
- setupDataLen -= EP0_PKT_SIZE;
- }
- //剩下一点了。
- else if(setupDataLen > 0)
- {
- DbgPrintf("[Seg%d]",segmentCount++);
- setupDataSegmentLen = setupDataLen;
- WrPktEp0((U8 *)setupData,setupDataSegmentLen);
- PrintSentPkt(setupData,setupDataSegmentLen);
- setupDataLen = 0;
- segmentCount = 0;
- ep0State = EP0_HANDSHAKE_STATE;
- }
- }
- if(ep0State == EP0_HANDSHAKE_STATE)
- {
- DbgPrintf("[ENDIN]");
- SET_EP0_INPKTRDY_DATAEND();
- ep0State = EP0_SETUP_STATE;
- }
- }
- void PrintEp0Pkt(U8 *pt)
- {
- int i;
- DbgPrintf("[RCV:");
- for (i=0;i<EP0_PKT_SIZE;i++)
- DbgPrintf("%x,",pt[i]);
- DbgPrintf("]");
- }
- void InitDescriptorTable(void)
- {
- U8 tmp[19] = { 0x05, 0x24, 0x00, 0x10, 0x01, 0x05, 0x24, 0x01, 0x03,
- 0x01, 0x04, 0x24, 0x02, 0x06,0x05, 0x24, 0x06, 0x00, 0x01 };
- //Standard device descriptor
- descDev.bLength=0x12; //EP0_DEV_DESC_SIZE=0x12 bytes
- descDev.bDescriptorType=DEVICE_TYPE;
- descDev.bcdUSBL=0x10;
- descDev.bcdUSBH=0x01; //Ver 1.10
- descDev.bDeviceClass=0x02;
- descDev.bDeviceSubClass=0x0;
- descDev.bDeviceProtocol=0x0;
- descDev.bMaxPacketSize0=0x8;
- descDev.idVendorL=0x83;
- descDev.idVendorH=0x04;
- descDev.idProductL=0x40;
- descDev.idProductH=0x57;
- descDev.bcdDeviceL=0x00;
- descDev.bcdDeviceH=0x01;
- descDev.iManufacturer=0x1; //index of string descriptor
- descDev.iProduct=0x2; //index of string descriptor
- descDev.iSerialNumber=0x0;
- descDev.bNumConfigurations=0x1;
- //Standard configuration descriptor
- descriptor.descConf.bLength=0x9;
- descriptor.descConf.bDescriptorType=CONFIGURATION_TYPE;
- descriptor.descConf.wTotalLengthL= sizeof(struct USB_GET_DESCRIPTOR);
- descriptor.descConf.wTotalLengthH=0;
- descriptor.descConf.bNumInterfaces=2;
- //dbg descConf.bConfigurationValue=2; //why 2? There's no reason.
- descriptor.descConf.bConfigurationValue=1;
- descriptor.descConf.iConfiguration=0;
- descriptor.descConf.bmAttributes=CONF_ATTR_DEFAULT|CONF_ATTR_SELFPOWERED; //bus powered only.
- descriptor.descConf.maxPower=25; //draws 50mA current from the USB bus.
- descriptor.descIf0.bLength=0x9;
- descriptor.descIf0.bDescriptorType=INTERFACE_TYPE;
- descriptor.descIf0.bInterfaceNumber=0x0;
- descriptor.descIf0.bAlternateSetting=0x0; //?
- descriptor.descIf0.bNumEndpoints=1; //# of endpoints except EP0
- descriptor.descIf0.bInterfaceClass=0x02; /*CDC ACM Comm*/
- descriptor.descIf0.bInterfaceSubClass=0x02;
- descriptor.descIf0.bInterfaceProtocol=0x01;
- descriptor.descIf0.iInterface=0x0;
- memcpy(descriptor.CS_INTERFACE0, tmp, 19);
- //这个端口是一个中段转输端口,用来报告状态的,我们没有正真用上它。
- descriptor.descEndpt2.bLength=0x7;
- descriptor.descEndpt2.bDescriptorType=ENDPOINT_TYPE;
- descriptor.descEndpt2.bEndpointAddress=2|EP_ADDR_IN;
- descriptor.descEndpt2.bmAttributes=EP_ATTR_INTERRUPT;
- descriptor.descEndpt2.wMaxPacketSizeL=EP1_PKT_SIZE; //64
- descriptor.descEndpt2.wMaxPacketSizeH=0x0;
- descriptor.descEndpt2.bInterval=0x02;
- //Standard interface descriptor
- descriptor.descIf1.bLength=0x9;
- descriptor.descIf1.bDescriptorType=INTERFACE_TYPE;
- descriptor.descIf1.bInterfaceNumber=0x1;
- descriptor.descIf1.bAlternateSetting=0x0;
- descriptor.descIf1.bNumEndpoints=2;
- descriptor.descIf1.bInterfaceClass=0x0A; /*CDC ACM Data*/
- descriptor.descIf1.bInterfaceSubClass=0x0;
- descriptor.descIf1.bInterfaceProtocol=0x0;
- descriptor.descIf1.iInterface=0x0;
- //Standard endpoint0 descriptor
- descriptor.descEndpt0.bLength=0x7;
- descriptor.descEndpt0.bDescriptorType=ENDPOINT_TYPE;
- descriptor.descEndpt0.bEndpointAddress=1|EP_ADDR_IN; // 2400Xendpoint 1 is IN endpoint.
- descriptor.descEndpt0.bmAttributes=EP_ATTR_BULK;
- descriptor.descEndpt0.wMaxPacketSizeL=EP1_PKT_SIZE; //64
- descriptor.descEndpt0.wMaxPacketSizeH=0x0;
- descriptor.descEndpt0.bInterval=0x0; //not used
- //Standard endpoint1 descriptor
- descriptor.descEndpt1.bLength=0x7;
- descriptor.descEndpt1.bDescriptorType=ENDPOINT_TYPE;
- descriptor.descEndpt1.bEndpointAddress=3|EP_ADDR_OUT; // 2400X endpoint 3 is OUT endpoint.
- descriptor.descEndpt1.bmAttributes=EP_ATTR_BULK;
- descriptor.descEndpt1.wMaxPacketSizeL=EP3_PKT_SIZE; //64
- descriptor.descEndpt1.wMaxPacketSizeH=0x0;
- descriptor.descEndpt1.bInterval=0x0; //not used
- }