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