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