📄 usbcore.lst
字号:
500 void UsbEp0SendData(void) //
501 {
502 1 //将数据写到端点中去准备发送
503 1 //写之前要先判断一下需要发送的数据是否比端点0
504 1 //最大长度大,如果超过端点大小,则一次只能发送
505 1 //最大包长的数据。端点0的最大包长在DeviceDescriptor[7]
506 1 if(SendLength>DeviceDescriptor[7])
507 1 {
508 2 //按最大包长度发送
509 2 D12WriteEndpointBuffer(1,DeviceDescriptor[7],pSendData);
510 2 //发送后剩余字节数减少最大包长
511 2 SendLength-=DeviceDescriptor[7];
512 2 //发送一次后指针位置要调整
513 2 pSendData+= DeviceDescriptor[7];
514 2 }
515 1 else
516 1 {
517 2 if(SendLength!=0)
518 2 {
519 3 //不够最大包长,可以直接发送
520 3 D12WriteEndpointBuffer(1,SendLength,pSendData);
521 3 //发送完毕后,SendLength长度变为0
522 3 SendLength=0;
523 3 }
524 2 else //如果要发送的数据包长度为0
525 2 {
526 3 if(NeedZeroPacket==1) //如果需要发送0长度数据
527 3 {
528 4 D12WriteEndpointBuffer(1,0,pSendData); //发送0长度数据包
529 4 NeedZeroPacket=0; //清需要发送0长度数据包标志
530 4 }
531 3 }
532 2 }
533 1 }
534 ////////////////////////End of function//////////////////////////////
535
536 /********************************************************************
537 函数功能:端点0输出中断处理函数。
538 入口参数:无。
539 返 回:无。
540 备 注:无。
541 ********************************************************************/
542 void UsbEp0Out(void)
543 {
544 1 #ifdef DEBUG0
Prints("USB端点0输出中断。\r\n");
#endif
547 1
548 1 //读取端点0输出最后传输状态,该操作清除中断标志
549 1 //并判断第5位是否为1,如果是,则说明是建立包
550 1 if(D12ReadEndpointLastStatus(0)&0x20)
551 1 {
C51 COMPILER V8.02 USBCORE 06/17/2010 09:52:10 PAGE 10
552 2 D12ReadEndpointBuffer(0,16,Buffer); //读建立过程数据
553 2 D12AcknowledgeSetup(); //应答建立包
554 2 D12ClearBuffer(); //清缓冲区
555 2 //将缓冲数据填到设备请求的各字段中
556 2 bmRequestType=Buffer[0];
557 2 bRequest=Buffer[1];
558 2 wValue=Buffer[2]+(((uint16)Buffer[3])<<8);
559 2 wIndex=Buffer[4]+(((uint16)Buffer[5])<<8);
560 2 wLength=Buffer[6]+(((uint16)Buffer[7])<<8);
561 2 //下面的代码判断具体的请求,并根据不同的请求进行相关操作
562 2 //如果D7位为1,则说明是输入请求
563 2 if((bmRequestType&0x80)==0x80)
564 2 {
565 3 //根据bmRequestType的D6~5位散转,D6~5位表示请求的类型
566 3 //0为标准请求,1为类请求,2为厂商请求。
567 3 switch((bmRequestType>>5)&0x03)
568 3 {
569 4 case 0: //标准请求
570 4 #ifdef DEBUG0
Prints("USB标准输入请求:");
#endif
573 4 //USB协议定义了几个标准输入请求,我们实现这些标准请求即可
574 4 //请求的代码在bRequest中,对不同的请求代码进行散转
575 4 //事实上,我们还需要对接收者进行散转,因为不同的请求接收者
576 4 //是不一样的。接收者在bmRequestType的D4~D0位中定义。
577 4 //我们这里为了简化操作,有些就省略了对接收者的判断。
578 4 //例如获取描述符的请求,只根据描述符的类型来区别。
579 4 switch(bRequest)
580 4 {
581 5 case GET_CONFIGURATION: //获取配置
582 5 #ifdef DEBUG0
Prints("获取配置。\r\n");
#endif
585 5 break;
586 5
587 5 case GET_DESCRIPTOR: //获取描述符
588 5 #ifdef DEBUG0
Prints("获取描述符——");
#endif
591 5 //对描述符类型进行散转,对于全速设备,
592 5 //标准请求只支持发送到设备的设备、配置、字符串三种描述符
593 5 switch((wValue>>8)&0xFF)
594 5 {
595 6 case DEVICE_DESCRIPTOR: //设备描述符
596 6 #ifdef DEBUG0
Prints("设备描述符。\r\n");
#endif
599 6 pSendData=DeviceDescriptor; //需要发送的数据
600 6 //判断请求的字节数是否比实际需要发送的字节数多
601 6 //这里请求的是设备描述符,因此数据长度就是
602 6 //DeviceDescriptor[0]。如果请求的比实际的长,
603 6 //那么只返回实际长度的数据
604 6 if(wLength>DeviceDescriptor[0])
605 6 {
606 7 SendLength=DeviceDescriptor[0];
607 7 if(SendLength%DeviceDescriptor[7]==0) //并且刚好是整数个数据包时
608 7 {
609 8 NeedZeroPacket=1; //需要返回0长度的数据包
610 8 }
611 7 }
612 6 else
613 6 {
C51 COMPILER V8.02 USBCORE 06/17/2010 09:52:10 PAGE 11
614 7 SendLength=wLength;
615 7 }
616 6 //将数据通过EP0返回
617 6 UsbEp0SendData();
618 6 break;
619 6
620 6 case CONFIGURATION_DESCRIPTOR: //配置描述符
621 6 #ifdef DEBUG0
Prints("配置描述符。\r\n");
#endif
624 6 pSendData=ConfigurationDescriptor; //需要发送的数据为配置描述符
625 6 //判断请求的字节数是否比实际需要发送的字节数多
626 6 //这里请求的是配置描述符集合,因此数据长度就是
627 6 //ConfigurationDescriptor[3]*256+ConfigurationDescriptor[2]。
628 6 //如果请求的比实际的长,那么只返回实际长度的数据
629 6 SendLength=ConfigurationDescriptor[3];
630 6 SendLength=SendLength*256+ConfigurationDescriptor[2];
631 6 if(wLength>SendLength)
632 6 {
633 7 if(SendLength%DeviceDescriptor[7]==0) //并且刚好是整数个数据包时
634 7 {
635 8 NeedZeroPacket=1; //需要返回0长度的数据包
636 8 }
637 7 }
638 6 else
639 6 {
640 7 SendLength=wLength;
641 7 }
642 6 //将数据通过EP0返回
643 6 UsbEp0SendData();
644 6 break;
645 6
646 6 case STRING_DESCRIPTOR: //字符串描述符
647 6 #ifdef DEBUG0
Prints("字符串描述符");
#endif
650 6 switch(wValue&0xFF) //根据wValue的低字节(索引值)散转
651 6 {
652 7 case 0: //获取语言ID
653 7 #ifdef DEBUG0
Prints("(语言ID)。\r\n");
#endif
656 7 pSendData=LanguageId;
657 7 SendLength=LanguageId[0];
658 7 break;
659 7
660 7 case 1: //厂商字符串的索引值为1,所以这里为厂商字符串
661 7 #ifdef DEBUG0
Prints("(厂商描述)。\r\n");
#endif
664 7 pSendData=ManufacturerStringDescriptor;
665 7 SendLength=ManufacturerStringDescriptor[0];
666 7 break;
667 7
668 7 case 2: //产品字符串的索引值为2,所以这里为产品字符串
669 7 #ifdef DEBUG0
Prints("(产品描述)。\r\n");
#endif
672 7 pSendData=ProductStringDescriptor;
673 7 SendLength=ProductStringDescriptor[0];
674 7 break;
675 7
C51 COMPILER V8.02 USBCORE 06/17/2010 09:52:10 PAGE 12
676 7 case 3: //产品序列号的索引值为3,所以这里为序列号
677 7 #ifdef DEBUG0
Prints("(产品序列号)。\r\n");
#endif
680 7 pSendData=SerialNumberStringDescriptor;
681 7 SendLength=SerialNumberStringDescriptor[0];
682 7 break;
683 7
684 7 default :
685 7 #ifdef DEBUG0
Prints("(未知的索引值)。\r\n");
#endif
688 7 //对于未知索引值的请求,返回一个0长度的包
689 7 SendLength=0;
690 7 NeedZeroPacket=1;
691 7 break;
692 7 }
693 6 //判断请求的字节数是否比实际需要发送的字节数多
694 6 //如果请求的比实际的长,那么只返回实际长度的数据
695 6 if(wLength>SendLength)
696 6 {
697 7 if(SendLength%DeviceDescriptor[7]==0) //并且刚好是整数个数据包时
698 7 {
699 8 NeedZeroPacket=1; //需要返回0长度的数据包
700 8 }
701 7 }
702 6 else
703 6 {
704 7 SendLength=wLength;
705 7 }
706 6 //将数据通过EP0返回
707 6 UsbEp0SendData();
708 6 break;
709 6
710 6 case REPORT_DESCRIPTOR: //报告描述符
711 6 #ifdef DEBUG0
Prints("报告描述符。\r\n");
#endif
714 6 pSendData=ReportDescriptor; //需要发送的数据为报告描述符
715 6 SendLength=sizeof(ReportDescriptor); //需要返回的数据长度
716 6 //判断请求的字节数是否比实际需要发送的字节数多
717 6 //如果请求的比实际的长,那么只返回实际长度的数据
718 6 if(wLength>SendLength)
719 6 {
720 7 if(SendLength%DeviceDescriptor[7]==0) //并且刚好是整数个数据包时
721 7 {
722 8 NeedZeroPacket=1; //需要返回0长度的数据包
723 8 }
724 7 }
725 6 else
726 6 {
727 7 SendLength=wLength;
728 7 }
729 6 //将数据通过EP0返回
730 6 UsbEp0SendData();
731 6 break;
732 6
733 6 default: //其它描述符
734 6 #ifdef DEBUG0
Prints("其他描述符,描述符代码:");
PrintHex((wValue>>8)&0xFF);
Prints("\r\n");
C51 COMPILER V8.02 USBCORE 06/17/2010 09:52:10 PAGE 13
#endif
739 6 break;
740 6 }
741 5 break;
742 5
743 5 case GET_INTERFACE: //获取接口
744 5 #ifdef DEBUG0
Prints("获取接口。\r\n");
#endif
747 5 break;
748 5
749 5 case GET_STATUS: //获取状态
750 5 #ifdef DEBUG0
Prints("获取状态。\r\n");
#endif
753 5 break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -