📄 usbcore.lst
字号:
588 2 {
589 3 if(NeedZeroPacket==1) //如果需要发送0长度数据
590 3 {
591 4 D12WriteEndpointBuffer(1,0,pSendData); //发送0长度数据包
592 4 NeedZeroPacket=0; //清需要发送0长度数据包标志
593 4 }
594 3 }
595 2 }
596 1 }
597 ////////////////////////End of function//////////////////////////////
598
599 /********************************************************************
600 函数功能:USB端点0数据过程数据处理函数。
601 入口参数:无。
602 返 回:无。
603 备 注:该函数用来处理0端点控制传输的数据或状态过程。
604 ********************************************************************/
605 void UsbEp0DataOut(void)
606 {
607 1 //由于本程序中只有一个请求输出数据,所以可以直接使用if语句判断条件,
608 1 //如果有很多请求的话,使用if语句就不方便了,而应该使用switch语句散转。
609 1 if((bmRequestType==0x21)&&(bRequest==SET_LINE_CODING))
610 1 {
611 2 uint32 BitRate;
612 2 uint8 Length;
613 2
C51 COMPILER V7.06 USBCORE 11/16/2008 16:00:07 PAGE 11
614 2 //读回7字节的LineCoding值
615 2 Length=D12ReadEndpointBuffer(0,7,LineCoding);
616 2 D12ClearBuffer(); //清除缓冲区
617 2
618 2 if(Length==7) //如果长度正确
619 2 {
620 3 //从LineCoding计算设置的波特率
621 3 BitRate=LineCoding[3];
622 3 BitRate=(BitRate<<8)+LineCoding[2];
623 3 BitRate=(BitRate<<8)+LineCoding[1];
624 3 BitRate=(BitRate<<8)+LineCoding[0];
625 3 #ifdef DEBUG0
Prints("波特率设置为:");
PrintLongInt(BitRate);
Prints("bps\r\n");
#endif
630 3 //设置串口的波特率
631 3 BitRate=UartSetBitRate(BitRate);
632 3
633 3 //将LineCoding的值设置为实际的设置值
634 3 LineCoding[0]=BitRate&0xFF;
635 3 LineCoding[1]=(BitRate>>8)&0xFF;
636 3 LineCoding[2]=(BitRate>>16)&0xFF;
637 3 LineCoding[3]=(BitRate>>24)&0xFF;
638 3
639 3 //由于只支持一停止位、无校验、8位数据位,
640 3 //所以固定这些数据。
641 3 LineCoding[4]=0x00;
642 3 LineCoding[5]=0x00;
643 3 LineCoding[6]=0x08;
644 3 }
645 2 //返回0长度的状态数据包。
646 2 D12WriteEndpointBuffer(1,0,0);
647 2 }
648 1 else //其它请求的数据过程或者状态过程
649 1 {
650 2 D12ReadEndpointBuffer(0,16,Buffer);
651 2 D12ClearBuffer();
652 2 }
653 1 }
654 ////////////////////////End of function//////////////////////////////
655
656 /********************************************************************
657 函数功能:端点0输出中断处理函数。
658 入口参数:无。
659 返 回:无。
660 备 注:无。
661 ********************************************************************/
662 void UsbEp0Out(void)
663 {
664 1 #ifdef DEBUG0
Prints("USB端点0输出中断。\r\n");
#endif
667 1 //读取端点0输出最后传输状态,该操作清除中断标志
668 1 //并判断第5位是否为1,如果是,则说明是建立包
669 1 if(D12ReadEndpointLastStatus(0)&0x20)
670 1 {
671 2 D12ReadEndpointBuffer(0,16,Buffer); //读建立过程数据
672 2 D12AcknowledgeSetup(); //应答建立包
673 2 D12ClearBuffer(); //清缓冲区
674 2 //将缓冲数据填到设备请求的各字段中
675 2 bmRequestType=Buffer[0];
C51 COMPILER V7.06 USBCORE 11/16/2008 16:00:07 PAGE 12
676 2 bRequest=Buffer[1];
677 2 wValue=Buffer[2]+(((uint16)Buffer[3])<<8);
678 2 wIndex=Buffer[4]+(((uint16)Buffer[5])<<8);
679 2 wLength=Buffer[6]+(((uint16)Buffer[7])<<8);
680 2 //下面的代码判断具体的请求,并根据不同的请求进行相关操作
681 2 //如果D7位为1,则说明是输入请求
682 2 if((bmRequestType&0x80)==0x80)
683 2 {
684 3 //根据bmRequestType的D6~5位散转,D6~5位表示请求的类型
685 3 //0为标准请求,1为类请求,2为厂商请求。
686 3 switch((bmRequestType>>5)&0x03)
687 3 {
688 4 case 0: //标准请求
689 4 #ifdef DEBUG0
Prints("USB标准输入请求:");
#endif
692 4 //USB协议定义了几个标准输入请求,我们实现这些标准请求即可
693 4 //请求的代码在bRequest中,对不同的请求代码进行散转
694 4 //事实上,我们还需要对接收者进行散转,因为不同的请求接收者
695 4 //是不一样的。接收者在bmRequestType的D4~D0位中定义。
696 4 //我们这里为了简化操作,有些就省略了对接收者的判断。
697 4 //例如获取描述符的请求,只根据描述符的类型来区别。
698 4 switch(bRequest)
699 4 {
700 5 case GET_CONFIGURATION: //获取配置
701 5 #ifdef DEBUG0
Prints("获取配置。\r\n");
#endif
704 5 break;
705 5
706 5 case GET_DESCRIPTOR: //获取描述符
707 5 #ifdef DEBUG0
Prints("获取描述符——");
#endif
710 5 //对描述符类型进行散转,对于全速设备,
711 5 //标准请求只支持发送到设备的设备、配置、字符串三种描述符
712 5 switch((wValue>>8)&0xFF)
713 5 {
714 6 case DEVICE_DESCRIPTOR: //设备描述符
715 6 #ifdef DEBUG0
Prints("设备描述符。\r\n");
#endif
718 6 pSendData=DeviceDescriptor; //需要发送的数据
719 6 //判断请求的字节数是否比实际需要发送的字节数多
720 6 //这里请求的是设备描述符,因此数据长度就是
721 6 //DeviceDescriptor[0]。如果请求的比实际的长,
722 6 //那么只返回实际长度的数据
723 6 if(wLength>DeviceDescriptor[0])
724 6 {
725 7 SendLength=DeviceDescriptor[0];
726 7 if(SendLength%DeviceDescriptor[7]==0) //并且刚好是整数个数据包时
727 7 {
728 8 NeedZeroPacket=1; //需要返回0长度的数据包
729 8 }
730 7 }
731 6 else
732 6 {
733 7 SendLength=wLength;
734 7 }
735 6 //将数据通过EP0返回
736 6 UsbEp0SendData();
737 6 break;
C51 COMPILER V7.06 USBCORE 11/16/2008 16:00:07 PAGE 13
738 6
739 6 case CONFIGURATION_DESCRIPTOR: //配置描述符
740 6 #ifdef DEBUG0
Prints("配置描述符。\r\n");
#endif
743 6 pSendData=ConfigurationDescriptor; //需要发送的数据为配置描述符
744 6 //判断请求的字节数是否比实际需要发送的字节数多
745 6 //这里请求的是配置描述符集合,因此数据长度就是
746 6 //ConfigurationDescriptor[3]*256+ConfigurationDescriptor[2]。
747 6 //如果请求的比实际的长,那么只返回实际长度的数据
748 6 SendLength=ConfigurationDescriptor[3];
749 6 SendLength=SendLength*256+ConfigurationDescriptor[2];
750 6 if(wLength>SendLength)
751 6 {
752 7 if(SendLength%DeviceDescriptor[7]==0) //并且刚好是整数个数据包时
753 7 {
754 8 NeedZeroPacket=1; //需要返回0长度的数据包
755 8 }
756 7 }
757 6 else
758 6 {
759 7 SendLength=wLength;
760 7 }
761 6 //将数据通过EP0返回
762 6 UsbEp0SendData();
763 6 break;
764 6
765 6 case STRING_DESCRIPTOR: //字符串描述符
766 6 #ifdef DEBUG0
Prints("字符串描述符");
#endif
769 6 switch(wValue&0xFF) //根据wValue的低字节(索引值)散转
770 6 {
771 7 case 0: //获取语言ID
772 7 #ifdef DEBUG0
Prints("(语言ID)。\r\n");
#endif
775 7 pSendData=LanguageId;
776 7 SendLength=LanguageId[0];
777 7 break;
778 7
779 7 case 1: //厂商字符串的索引值为1,所以这里为厂商字符串
780 7 #ifdef DEBUG0
Prints("(厂商描述)。\r\n");
#endif
783 7 pSendData=ManufacturerStringDescriptor;
784 7 SendLength=ManufacturerStringDescriptor[0];
785 7 break;
786 7
787 7 case 2: //产品字符串的索引值为2,所以这里为产品字符串
788 7 #ifdef DEBUG0
Prints("(产品描述)。\r\n");
#endif
791 7 pSendData=ProductStringDescriptor;
792 7 SendLength=ProductStringDescriptor[0];
793 7 break;
794 7
795 7 case 3: //产品序列号的索引值为3,所以这里为序列号
796 7 #ifdef DEBUG0
Prints("(产品序列号)。\r\n");
#endif
799 7 pSendData=SerialNumberStringDescriptor;
C51 COMPILER V7.06 USBCORE 11/16/2008 16:00:07 PAGE 14
800 7 SendLength=SerialNumberStringDescriptor[0];
801 7 break;
802 7
803 7 default :
804 7 #ifdef DEBUG0
Prints("(未知的索引值)。\r\n");
#endif
807 7 //对于未知索引值的请求,返回一个0长度的包
808 7 SendLength=0;
809 7 NeedZeroPacket=1;
810 7 break;
811 7 }
812 6 //判断请求的字节数是否比实际需要发送的字节数多
813 6 //如果请求的比实际的长,那么只返回实际长度的数据
814 6 if(wLength>SendLength)
815 6 {
816 7 if(SendLength%DeviceDescriptor[7]==0) //并且刚好是整数个数据包时
817 7 {
818 8 NeedZeroPacket=1; //需要返回0长度的数据包
819 8 }
820 7 }
821 6 else
822 6 {
823 7 SendLength=wLength;
824 7 }
825 6 //将数据通过EP0返回
826 6 UsbEp0SendData();
827 6 break;
828 6
829 6 default: //其它描述符
830 6 #ifdef DEBUG0
Prints("其他描述符,描述符代码:");
PrintHex((wValue>>8)&0xFF);
Prints("\r\n");
#endif
835 6 break;
836 6 }
837 5 break;
838 5
839 5 case GET_INTERFACE: //获取接口
840 5 #ifdef DEBUG0
Prints("获取接口。\r\n");
#endif
843 5 break;
844 5
845 5 case GET_STATUS: //获取状态
846 5 #ifdef DEBUG0
Prints("获取状态。\r\n");
#endif
849 5 break;
850 5
851 5 case SYNCH_FRAME: //同步帧
852 5 #ifdef DEBUG0
Prints("同步帧。\r\n");
#endif
855 5 break;
856 5
857 5 default: //未定义的标准请求
858 5 #ifdef DEBUG0
Prints("错误:未定义的标准输入请求。\r\n");
#endif
861 5 break;
C51 COMPILER V7.06 USBCORE 11/16/2008 16:00:07 PAGE 15
862 5 }
863 4 break;
864 4
865 4 case 1: //类请求
866 4 #ifdef DEBUG0
Prints("USB类输入请求:");
#endif
869 4 switch(bRequest)
870 4 {
871 5 case GET_LINE_CODING: //GET_LINE_CODING请求
872 5 #ifdef DEBUG0
Prints("GET_LINE_CODING。\r\n");
#endif
875 5 SendLength=0x07; //7字节的LineCoding
876 5 pSendData=LineCoding;
877 5 break;
878 5
879 5 case SERIAL_STATE: //获取SERIAL_STATE请求
880 5 //本来该请求是获取串口状态的,但是圈圈在实际使用中,
881 5 //发现主机从来未发送过该请求,因而这里并不对它进行处理,
882 5 //只是简单地发送一个0长度的数据包。
883 5 #ifdef DEBUG0
Prints("SERIAL_STATE。\r\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -