📄 usbcore.lst
字号:
536 1 Prints("USB总线挂起。\r\n");
537 1 #endif
538 1 }
539 ////////////////////////End of function//////////////////////////////
540
541 /********************************************************************
542 函数功能:总线复位中断处理函数。
543 入口参数:无。
544 返 回:无。
545 备 注:无。
546 ********************************************************************/
547 void UsbBusReset(void)
548 {
549 1 #ifdef DEBUG0
550 1 Prints("USB总线复位。\r\n");
551 1 #endif
C51 COMPILER V8.02 USBCORE 06/17/2010 09:51:39 PAGE 10
552 1 Ep1InIsBusy=0; //复位后端点1输入缓冲区空闲。
553 1 }
554 ////////////////////////End of function//////////////////////////////
555
556 /********************************************************************
557 函数功能:根据pData和SendLength将数据发送到端点0的函数。
558 入口参数:无。
559 返 回:无。
560 备 注:无。
561 ********************************************************************/
562 void UsbEp0SendData(void)
563 {
564 1 //将数据写到端点中去准备发送
565 1 //写之前要先判断一下需要发送的数据是否比端点0
566 1 //最大长度大,如果超过端点大小,则一次只能发送
567 1 //最大包长的数据。端点0的最大包长在DeviceDescriptor[7]
568 1 if(SendLength>DeviceDescriptor[7])
569 1 {
570 2 //按最大包长度发送
571 2 D12WriteEndpointBuffer(1,DeviceDescriptor[7],pSendData);
572 2 //发送后剩余字节数减少最大包长
573 2 SendLength-=DeviceDescriptor[7];
574 2 //发送一次后指针位置要调整
575 2 pSendData+= DeviceDescriptor[7];
576 2 }
577 1 else
578 1 {
579 2 if(SendLength!=0)
580 2 {
581 3 //不够最大包长,可以直接发送
582 3 D12WriteEndpointBuffer(1,SendLength,pSendData);
583 3 //发送完毕后,SendLength长度变为0
584 3 SendLength=0;
585 3 }
586 2 else //如果要发送的数据包长度为0
587 2 {
588 3 if(NeedZeroPacket==1) //如果需要发送0长度数据
589 3 {
590 4 D12WriteEndpointBuffer(1,0,pSendData); //发送0长度数据包
591 4 NeedZeroPacket=0; //清需要发送0长度数据包标志
592 4 }
593 3 }
594 2 }
595 1 }
596 ////////////////////////End of function//////////////////////////////
597
598 /********************************************************************
599 函数功能:端点0输出中断处理函数。
600 入口参数:无。
601 返 回:无。
602 备 注:无。
603 ********************************************************************/
604 void UsbEp0Out(void)
605 {
606 1 #ifdef DEBUG0
607 1 Prints("USB端点0输出中断。\r\n");
608 1 #endif
609 1 //读取端点0输出最后传输状态,该操作清除中断标志
610 1 //并判断第5位是否为1,如果是,则说明是建立包
611 1 if(D12ReadEndpointLastStatus(0)&0x20)
612 1 {
613 2 D12ReadEndpointBuffer(0,16,Buffer); //读建立过程数据
C51 COMPILER V8.02 USBCORE 06/17/2010 09:51:39 PAGE 11
614 2 D12AcknowledgeSetup(); //应答建立包
615 2 D12ClearBuffer(); //清缓冲区
616 2 //将缓冲数据填到设备请求的各字段中
617 2 bmRequestType=Buffer[0];
618 2 bRequest=Buffer[1];
619 2 wValue=Buffer[2]+(((uint16)Buffer[3])<<8);
620 2 wIndex=Buffer[4]+(((uint16)Buffer[5])<<8);
621 2 wLength=Buffer[6]+(((uint16)Buffer[7])<<8);
622 2 //下面的代码判断具体的请求,并根据不同的请求进行相关操作
623 2 //如果D7位为1,则说明是输入请求
624 2 if((bmRequestType&0x80)==0x80)
625 2 {
626 3 //根据bmRequestType的D6~5位散转,D6~5位表示请求的类型
627 3 //0为标准请求,1为类请求,2为厂商请求。
628 3 switch((bmRequestType>>5)&0x03)
629 3 {
630 4 case 0: //标准请求
631 4 #ifdef DEBUG0
632 4 Prints("USB标准输入请求:");
633 4 #endif
634 4 //USB协议定义了几个标准输入请求,我们实现这些标准请求即可
635 4 //请求的代码在bRequest中,对不同的请求代码进行散转
636 4 //事实上,我们还需要对接收者进行散转,因为不同的请求接收者
637 4 //是不一样的。接收者在bmRequestType的D4~D0位中定义。
638 4 //我们这里为了简化操作,有些就省略了对接收者的判断。
639 4 //例如获取描述符的请求,只根据描述符的类型来区别。
640 4 switch(bRequest)
641 4 {
642 5 case GET_CONFIGURATION: //获取配置
643 5 #ifdef DEBUG0
644 5 Prints("获取配置。\r\n");
645 5 #endif
646 5 break;
647 5
648 5 case GET_DESCRIPTOR: //获取描述符
649 5 #ifdef DEBUG0
650 5 Prints("获取描述符——");
651 5 #endif
652 5 //对描述符类型进行散转,对于全速设备,
653 5 //标准请求只支持发送到设备的设备、配置、字符串三种描述符
654 5 switch((wValue>>8)&0xFF)
655 5 {
656 6 case DEVICE_DESCRIPTOR: //设备描述符
657 6 #ifdef DEBUG0
658 6 Prints("设备描述符。\r\n");
659 6 #endif
660 6 pSendData=DeviceDescriptor; //需要发送的数据
661 6 //判断请求的字节数是否比实际需要发送的字节数多
662 6 //这里请求的是设备描述符,因此数据长度就是
663 6 //DeviceDescriptor[0]。如果请求的比实际的长,
664 6 //那么只返回实际长度的数据
665 6 if(wLength>DeviceDescriptor[0])
666 6 {
667 7 SendLength=DeviceDescriptor[0];
668 7 if(SendLength%DeviceDescriptor[7]==0) //并且刚好是整数个数据包时
669 7 {
670 8 NeedZeroPacket=1; //需要返回0长度的数据包
671 8 }
672 7 }
673 6 else
674 6 {
675 7 SendLength=wLength;
C51 COMPILER V8.02 USBCORE 06/17/2010 09:51:39 PAGE 12
676 7 }
677 6 //将数据通过EP0返回
678 6 UsbEp0SendData();
679 6 break;
680 6
681 6 case CONFIGURATION_DESCRIPTOR: //配置描述符
682 6 #ifdef DEBUG0
683 6 Prints("配置描述符。\r\n");
684 6 #endif
685 6 pSendData=ConfigurationDescriptor; //需要发送的数据为配置描述符
686 6 //判断请求的字节数是否比实际需要发送的字节数多
687 6 //这里请求的是配置描述符集合,因此数据长度就是
688 6 //ConfigurationDescriptor[3]*256+ConfigurationDescriptor[2]。
689 6 //如果请求的比实际的长,那么只返回实际长度的数据
690 6 SendLength=ConfigurationDescriptor[3];
691 6 SendLength=SendLength*256+ConfigurationDescriptor[2];
692 6 if(wLength>SendLength)
693 6 {
694 7 if(SendLength%DeviceDescriptor[7]==0) //并且刚好是整数个数据包时
695 7 {
696 8 NeedZeroPacket=1; //需要返回0长度的数据包
697 8 }
698 7 }
699 6 else
700 6 {
701 7 SendLength=wLength;
702 7 }
703 6 //将数据通过EP0返回
704 6 UsbEp0SendData();
705 6 break;
706 6
707 6 case STRING_DESCRIPTOR: //字符串描述符
708 6 #ifdef DEBUG0
709 6 Prints("字符串描述符");
710 6 #endif
711 6 switch(wValue&0xFF) //根据wValue的低字节(索引值)散转
712 6 {
713 7 case 0: //获取语言ID
714 7 #ifdef DEBUG0
715 7 Prints("(语言ID)。\r\n");
716 7 #endif
717 7 pSendData=LanguageId;
718 7 SendLength=LanguageId[0];
719 7 break;
720 7
721 7 case 1: //厂商字符串的索引值为1,所以这里为厂商字符串
722 7 #ifdef DEBUG0
723 7 Prints("(厂商描述)。\r\n");
724 7 #endif
725 7 pSendData=ManufacturerStringDescriptor;
726 7 SendLength=ManufacturerStringDescriptor[0];
727 7 break;
728 7
729 7 case 2: //产品字符串的索引值为2,所以这里为产品字符串
730 7 #ifdef DEBUG0
731 7 Prints("(产品描述)。\r\n");
732 7 #endif
733 7 pSendData=ProductStringDescriptor;
734 7 SendLength=ProductStringDescriptor[0];
735 7 break;
736 7
737 7 case 3: //产品序列号的索引值为3,所以这里为序列号
C51 COMPILER V8.02 USBCORE 06/17/2010 09:51:39 PAGE 13
738 7 #ifdef DEBUG0
739 7 Prints("(产品序列号)。\r\n");
740 7 #endif
741 7 pSendData=SerialNumberStringDescriptor;
742 7 SendLength=SerialNumberStringDescriptor[0];
743 7 break;
744 7
745 7 default :
746 7 #ifdef DEBUG0
747 7 Prints("(未知的索引值)。\r\n");
748 7 #endif
749 7 //对于未知索引值的请求,返回一个0长度的包
750 7 SendLength=0;
751 7 NeedZeroPacket=1;
752 7 break;
753 7 }
754 6 //判断请求的字节数是否比实际需要发送的字节数多
755 6 //如果请求的比实际的长,那么只返回实际长度的数据
756 6 if(wLength>SendLength)
757 6 {
758 7 if(SendLength%DeviceDescriptor[7]==0) //并且刚好是整数个数据包时
759 7 {
760 8 NeedZeroPacket=1; //需要返回0长度的数据包
761 8 }
762 7 }
763 6 else
764 6 {
765 7 SendLength=wLength;
766 7 }
767 6 //将数据通过EP0返回
768 6 UsbEp0SendData();
769 6 break;
770 6
771 6 case REPORT_DESCRIPTOR: //报告描述符
772 6 #ifdef DEBUG0
773 6 Prints("报告描述符。\r\n");
774 6 #endif
775 6 pSendData=ReportDescriptor; //需要发送的数据为报告描述符
776 6 SendLength=sizeof(ReportDescriptor); //需要返回的数据长度
777 6 //判断请求的字节数是否比实际需要发送的字节数多
778 6 //如果请求的比实际的长,那么只返回实际长度的数据
779 6 if(wLength>SendLength)
780 6 {
781 7 if(SendLength%DeviceDescriptor[7]==0) //并且刚好是整数个数据包时
782 7 {
783 8 NeedZeroPacket=1; //需要返回0长度的数据包
784 8 }
785 7 }
786 6 else
787 6 {
788 7 SendLength=wLength;
789 7 }
790 6 //将数据通过EP0返回
791 6 UsbEp0SendData();
792 6 break;
793 6
794 6 default: //其它描述符
795 6 #ifdef DEBUG0
796 6 Prints("其他描述符,描述符代码:");
797 6 PrintHex((wValue>>8)&0xFF);
798 6 Prints("\r\n");
799 6 #endif
C51 COMPILER V8.02 USBCORE 06/17/2010 09:51:39 PAGE 14
800 6 break;
801 6 }
802 5 break;
803 5
804 5 case GET_INTERFACE: //获取接口
805 5 #ifdef DEBUG0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -