void UsbEp0Out(void) { #ifdef DEBUG Prints("USB ep0 out interrupt.\r\n"); #endif if(D12ReadEndPointLastStatus(0)&0x20) { D12ReadEndPointBuffer(0,16,Buffer); D12AckSetup(); D12ClearBuffer(); bmRequestType=Buffer[0]; bRequest=Buffer[1]; wValue=Buffer[2]+(((u16)Buffer[3])<<8); wIndex=Buffer[4]+(((u16)Buffer[5])<<8); wLength=Buffer[6]+(((u16)Buffer[7])<<8); if((bmRequestType&0x80)==0x80) { switch((bmRequestType>>5)&0x03) { case 0: #ifdef DEBUG Prints("USB Standard in request.\r\n"); #endif switch(bRequest) { case GET_CONFIGURATION: #ifdef DEBUG Prints("Get configuration.\r\n"); #endif break; case GET_DESCRIPTOR: #ifdef DEBUG Prints("Get descriptor.\r\n"); #endif switch((wValue>>8)&0xff) { case DEVICE_DESCRIPTOR: #ifdef DEBUG Prints("-Get device descriptor.\r\n"); #endif pSendData=DeviceDescriptor; if(wLength>DeviceDescriptor[0]) { #ifdef DEBUG Prints("Host want length of device descriptor is:"); PrintShortIntHex(DeviceDescriptor[0]); Prints("\r\n"); #endif SendLength=DeviceDescriptor[0]; if(SendLength%DeviceDescriptor[7]==0) { NeedZeroPacket=1; } } else { SendLength=wLength; } UsbEp0SendData(); break; case CONFIGURATION_DESCRIPTOR: #ifdef DEBUG Prints("-Get configuration descriptor.\r\n"); #endif pSendData=ConfigurationDescriptor; SendLength=ConfigurationDescriptor[3]; SendLength=SendLength*256+ConfigurationDescriptor[2]; if(wLength>SendLength) { if(SendLength%DeviceDescriptor[7]==0) { NeedZeroPacket=1; } } else { SendLength=wLength; } UsbEp0SendData(); break; case STRING_DESCRIPTOR: #ifdef DEBUG Prints("-Get string descriptor.\r\n"); #endif switch(wValue&0xff) { case 0: #ifdef DEBUG Prints("--Get Language ID.\r\n"); #endif pSendData=LanguageId; SendLength=LanguageId[0]; break; case 1: #ifdef DEBUG Prints("--Get Manufacturer string.\r\n"); #endif pSendData=ManufacturerStringDescriptor; SendLength=ManufacturerStringDescriptor[0]; break; case 2: #ifdef DEBUG Prints("--Get product string.\r\n"); #endif pSendData=ProductStringDescriptor; SendLength=ProductStringDescriptor[0]; break; case 3: #ifdef DEBUG Prints("--Get serial string.\r\n"); #endif pSendData=SerialNumberStringDescriptor; SendLength=SerialNumberStringDescriptor[0]; break; default: #ifdef DEBUG Prints("Undefined index.\r\n"); #endif SendLength=0; NeedZeroPacket=1; break; } if(wLength>SendLength) { if(SendLength%DeviceDescriptor[7]==0) NeedZeroPacket=1; } else { SendLength=wLength; } UsbEp0SendData(); break; case REPORT_DESCRIPTOR: #ifdef DEBUG Prints("Get report descriptor.\r\n"); #endif if(wLength>SendLength) { pSendData=ReportDescriptor; SendLength=sizeof(ReportDescriptor); if(wLength%DeviceDescriptor[7]==0) { NeedZeroPacket=1; } else { SendLength=wLength; } UsbEp0SendData(); } break; default: #ifdef DEBUG Prints("-Get other descriptor(unrecognized).\r\n"); #endif break; } break; case GET_INTERFACE: #ifdef DEBUG Prints("Get Interface.\r\n"); #endif break; case GET_STATUS: #ifdef DEBUG Prints("Get status.\r\n"); #endif break; case SYNCH_FRAME: #ifdef DEBUG Prints("Synch frame.\r\n"); #endif break; default: #ifdef DEBUG Prints("Error,undefined standard device request.\r\n"); #endif break; } break; case 1: //Class request. #ifdef DEBUG Prints("Class request.\r\n"); #endif break; case 2: //³§ÉÌÇëÇó #ifdef DEBUG Prints("Vendor request.\r\n"); #endif break; default: #ifdef DEBUG Prints("Error,undefined request.\r\n"); #endif break; } } else { switch((bmRequestType>>5)&0x03)
/******************************************************************** 函数功能:端点0输出中断处理函数。 入口参数:无。 返 回:无。 备 注:无。 ********************************************************************/ void UsbEp0Out(void) { #ifdef DEBUG0 Prints("USB端点0输出中断。\r\n"); #endif //读取端点0输出最后传输状态,该操作清除中断标志 //并判断第5位是否为1,如果是,则说明是建立包 if(D12ReadEndpointLastStatus(0)&0x20) { D12ReadEndpointBuffer(0,16,Buffer); //读建立过程数据 D12AcknowledgeSetup(); //应答建立包 D12ClearBuffer(); //清缓冲区 //将缓冲数据填到设备请求的各字段中 bmRequestType=Buffer[0]; bRequest=Buffer[1]; wValue=Buffer[2]+(((uint16)Buffer[3])<<8); wIndex=Buffer[4]+(((uint16)Buffer[5])<<8); wLength=Buffer[6]+(((uint16)Buffer[7])<<8); //下面的代码判断具体的请求,并根据不同的请求进行相关操作 //如果D7位为1,则说明是输入请求 if((bmRequestType&0x80)==0x80) { //根据bmRequestType的D6~5位散转,D6~5位表示请求的类型 //0为标准请求,1为类请求,2为厂商请求。 switch((bmRequestType>>5)&0x03) { case 0: //标准请求 #ifdef DEBUG0 Prints("USB标准输入请求:"); #endif //USB协议定义了几个标准输入请求,我们实现这些标准请求即可 //请求的代码在bRequest中,对不同的请求代码进行散转 //事实上,我们还需要对接收者进行散转,因为不同的请求接收者 //是不一样的。接收者在bmRequestType的D4~D0位中定义。 //我们这里为了简化操作,有些就省略了对接收者的判断。 //例如获取描述符的请求,只根据描述符的类型来区别。 switch(bRequest) { case GET_CONFIGURATION: //获取配置 #ifdef DEBUG0 Prints("获取配置。\r\n"); #endif break; case GET_DESCRIPTOR: //获取描述符 #ifdef DEBUG0 Prints("获取描述符——"); #endif //对描述符类型进行散转,对于全速设备, //标准请求只支持发送到设备的设备、配置、字符串三种描述符 switch((wValue>>8)&0xFF) { case DEVICE_DESCRIPTOR: //设备描述符 #ifdef DEBUG0 Prints("设备描述符。\r\n"); #endif pSendData=DeviceDescriptor; //需要发送的数据 //判断请求的字节数是否比实际需要发送的字节数多 //这里请求的是设备描述符,因此数据长度就是 //DeviceDescriptor[0]。如果请求的比实际的长, //那么只返回实际长度的数据 if(wLength>DeviceDescriptor[0]) { SendLength=DeviceDescriptor[0]; if(SendLength%DeviceDescriptor[7]==0) //并且刚好是整数个数据包时 { NeedZeroPacket=1; //需要返回0长度的数据包 } } else { SendLength=wLength; } //将数据通过EP0返回 UsbEp0SendData(); break; case CONFIGURATION_DESCRIPTOR: //配置描述符 #ifdef DEBUG0 Prints("配置描述符。\r\n"); #endif pSendData=ConfigurationDescriptor; //需要发送的数据为配置描述符 //判断请求的字节数是否比实际需要发送的字节数多 //这里请求的是配置描述符集合,因此数据长度就是 //ConfigurationDescriptor[3]*256+ConfigurationDescriptor[2]。 //如果请求的比实际的长,那么只返回实际长度的数据 SendLength=ConfigurationDescriptor[3]; SendLength=SendLength*256+ConfigurationDescriptor[2]; if(wLength>SendLength) { if(SendLength%DeviceDescriptor[7]==0) //并且刚好是整数个数据包时 { NeedZeroPacket=1; //需要返回0长度的数据包 } } else { SendLength=wLength; } //将数据通过EP0返回 UsbEp0SendData(); break; case STRING_DESCRIPTOR: //字符串描述符 #ifdef DEBUG0 Prints("字符串描述符"); #endif switch(wValue&0xFF) //根据wValue的低字节(索引值)散转 { case 0: //获取语言ID #ifdef DEBUG0 Prints("(语言ID)。\r\n"); #endif pSendData=LanguageId; SendLength=LanguageId[0]; break; case 1: //厂商字符串的索引值为1,所以这里为厂商字符串 #ifdef DEBUG0 Prints("(厂商描述)。\r\n"); #endif pSendData=ManufacturerStringDescriptor; SendLength=ManufacturerStringDescriptor[0]; break; case 2: //产品字符串的索引值为2,所以这里为产品字符串 #ifdef DEBUG0 Prints("(产品描述)。\r\n"); #endif pSendData=ProductStringDescriptor; SendLength=ProductStringDescriptor[0]; break; case 3: //产品序列号的索引值为3,所以这里为序列号 #ifdef DEBUG0 Prints("(产品序列号)。\r\n"); #endif pSendData=SerialNumberStringDescriptor; SendLength=SerialNumberStringDescriptor[0]; break; default : #ifdef DEBUG0 Prints("(未知的索引值)。\r\n"); #endif //对于未知索引值的请求,返回一个0长度的包 SendLength=0; NeedZeroPacket=1; break; } //判断请求的字节数是否比实际需要发送的字节数多 //如果请求的比实际的长,那么只返回实际长度的数据 if(wLength>SendLength) { if(SendLength%DeviceDescriptor[7]==0) //并且刚好是整数个数据包时 { NeedZeroPacket=1; //需要返回0长度的数据包 } } else { SendLength=wLength; } //将数据通过EP0返回 UsbEp0SendData(); break; case REPORT_DESCRIPTOR: //报告描述符 #ifdef DEBUG0 Prints("报告描述符。\r\n"); #endif pSendData=ReportDescriptor; //需要发送的数据为报告描述符 SendLength=sizeof(ReportDescriptor); //需要返回的数据长度 //判断请求的字节数是否比实际需要发送的字节数多 //如果请求的比实际的长,那么只返回实际长度的数据 if(wLength>SendLength) { if(SendLength%DeviceDescriptor[7]==0) //并且刚好是整数个数据包时 { NeedZeroPacket=1; //需要返回0长度的数据包 } } else { SendLength=wLength; } //将数据通过EP0返回 UsbEp0SendData(); break; default: //其它描述符 #ifdef DEBUG0 Prints("其他描述符,描述符代码:"); PrintHex((wValue>>8)&0xFF); Prints("\r\n"); #endif break; } break; case GET_INTERFACE: //获取接口 #ifdef DEBUG0 Prints("获取接口。\r\n"); #endif break; case GET_STATUS: //获取状态 #ifdef DEBUG0 Prints("获取状态。\r\n"); #endif break; case SYNCH_FRAME: //同步帧 #ifdef DEBUG0 Prints("同步帧。\r\n"); #endif break; default: //未定义的标准请求 #ifdef DEBUG0 Prints("错误:未定义的标准输入请求。\r\n"); #endif break; } break; case 1: //类请求 #ifdef DEBUG0 Prints("USB类输入请求:\r\n"); #endif break; case 2: //厂商请求 #ifdef DEBUG0 Prints("USB厂商输入请求:\r\n"); #endif break; default: //未定义的请求。这里只显示一个报错信息。 #ifdef DEBUG0 Prints("错误:未定义的输入请求。\r\n"); #endif break; } } //否则说明是输出请求 else //if(bmRequestType&0x80==0x80)之else { //根据bmRequestType的D6~5位散转,D6~5位表示请求的类型 //0为标准请求,1为类请求,2为厂商请求。 switch((bmRequestType>>5)&0x03)