USB通信协议源代码.docx
做了一段时间的USB方面的开发,虽然是现成的方案,我们只需要弄清晰它的架构,再添加我们的代码就行了。空闲之余,研究了一下USB通信过程,也把82A851R部分的汇编代码重新用C语言描述了一篇(仅是描述,不代表能真正运营)。发现汇编代码条理性太在太差了,不好读。一把C语言的代码一写,立即觉得清晰诸多。废话少说,开始贴图,贴代码。二=下面是将某些函数重新用C语言描述了基本定*A义函数I*aBYTEFIFO_RD_CHECK(BYTEnum)aBYTEFIFO_F1AG=O;UCCI=num;/选择Endpoint,Oz1,2,3,4,MISC&=0xf8;低3位置0MISCI=OX00;/TX位置0;ADe1ay_3us();M1SCI=OXO1;/SetReqUeSMDe1ay_28us()if(MISC8<0X40!=0)FIFO_F1AG=OxOf;/READYif(MISC&0x80!=0)FIFO.F1AG&=0xf0;/1e0DetectcaMISC&=0xfe;/c1earREQreturnFIFO_F1AG;aaBYTEFIFO_WR_CHECK(BYTEnum)(BYTEFIFO_F1AG=0;/后4位表达R号。dy位,前四位表达1en0位的状态与否有被设立AUCC|=num;选择Endpoit0,1,2z3,4,MISC&=OXf8;低3位置OAMISCI=OXO2;/TX位置0;De1ay_3us();MISCI=0X01;/SetRequestDeIay_28us();if(MISC&0x80!=O)FIFO_F1AG&=OXfO;/1e1oDetectedMISC&=Oxfe;/c1erREQareturnF1FC1F1AG;AvoidRead_FIFO(BYTE*Fifo_AddrzBYTEFifo_Size,BYTE*buffer)(inti=0;MISCI=OxO1;/SetRequestafor(i=0;i<Fifo_Size;i+)abufferi=Fifo_Addr0;从FIFO地址取值DeIay_28US();Aif(MISC&0x40=O)break;/NotReady)MISC=0X02;变化TX位状态DeIay_3US();AMISC&=0XFE;/CIearRequesbavoidWrite_FIFO(BYTE*Fifo.AddrzBYTESend1enth,BYTE*buffer)aainti=0;MISCI=OXO1;/SetRequeshfor(i=Oji<Send1eth;i+)aFifo_Addr0=bufferi;/将要发送的数据放至相应的Fifo中DeIQy_28Us();if(MISC&Ox4O=O)breok;/NotReQdyAMISCA=OXO2;/变化TX位状痴DeIay_3us();MISC&=0XFE;/CIearReq1JeStA)BOO1Check_Rea1_Cmd()rBYTEbFIag_Rea1_Cmd=FA1SE;if(MISC&0X20!=0)bF1ag_Rea1Cmd=TRUE;if(MISC&0X8O!=0)bF1ag_Rea1_Cmd=TRUE;returbFIag_Rea1_Cmd;AvoidSend_hand()aaBOO1IsReaICmdzStatus_F1ag;WhiIe(I)AIsReaICmd=Check_Rea1Cmd();Aif(IsReaICmd=TRUE)return;aeI$eaaStatus_FIag=FIFO_WR_CHECK(O)泠if(Status_FIag&OxOf!=O)/Fifo_ReadybreakISacontinues)MISCI=OxO1;/SetRequsetMISCA=OX02;/变化TX位状态ADe1y_3us();aM1SC&=0XFE;/CIearReqUeSta卜voidcontro1_read(WORD*rom_dataptrzBYTE*buffer)/从中读取数据,/rom_dataptr是全局时在其他函数中赋值变化ABYTEtempzi=0;if(buffer7!=0)/FIFO_W1ENGTHHreturn;Aif(buffer6=0)/FIFO_W1ENGTH1return/if(buffer6>data_start0)/祈求的数据超过ROM数据return;data_count=buffer6;if(MISC&0x40。0)/是控制指令return;Aif(data_count=0)ASend_Hand_ShQke();Areturn;a/开始真正的contro1_reacAwhi1e(1)aaif(bF1ag_RD_HTab1e=O)Read1owBytea*rom_dataptr;取其低位Ai+;data_count;/全局变量,要发送的总长度if(dota_cout<=I)Abreak;Aif(i+1=8)FIFO_size=&break;ae1se/ReadHightByteabF1ag_RD_HTabIe=O;bufferi=(BYTE)(*rom_dataptr)>>8;/¢(其高位Arom_dataptr+;将ROM指针前移if(bufferi=0x3f)cotinue;e1saai+;if(dta_cout<=1)abreak;if(i+1=8)abreQk;Aaa/填充完毕,结束循环,开始向F1FO发送数据AwhiI(1)aSif(Check_Rea1Cmd()=TRUE)return/if(FIFO_WR_CHECK(0)&0xff=O)continue;/NotReQdyaaWrite_FIFO(Fifo_0_AddrzOxO2zbuffer);)*aSetAddress():重新设定EndPoint地力卜/*aVoidSetAddress(BYTE*bffe)aBYTEDev_Addr;Dev_Addr=buffer2/FIFO_OUT3zFIFO_WVA1UE1SIES1=OXo1;/主机从设备读操作后将更新在AWR中的地址,否则为0则立即更新ADev_Addr&=OXFE;USB-AWR=Dev_Addr;ASene1HQne1ShQke();AA/*/SetConfigurtion():设立配备函数I*aV0idSetConfiguration(BYTE*bufferzBYTE*USB_Configuration)(USVCI=Ox80;PGA_CTR1=Ox80;A*USB_Cofiguratio=buffer2;/FIFO_WVA1UE1STA11&=0x00设立好以上的寄存器SenC1HQnC1Shake();*/C1earFefure():清徐FeQtUre函数A*4、,Z"XCAVOIGUIearFeature(BYTE*buffer)(BYTEtemp?temp=buffer2;/FIFe1WVC11Ue1Aif(temp=OXOI)aaSend_Hand_Shake();)e1seSTA11OI=OxO1;/SedSta11();aavoidC1earFeature_Endpoint(BYTE*buffer)aaBYTEtemp;temp=buffer4;/FIFO_w1ndex1if(bF1ag_SetConfiguration_Ready=TRUE);表白已经配备过了Atemp=GetPipeBit(temp);获取相应位Atemp=temp;取反ASTA11=temp&STA11;与STA11寄存器相与,将需要的位置0Sed_Hand_Shke();aAI/*/SetFeature():设立Feature函数A/ErdPC)irt吾B分A*avoidSetFeture(BYTE*buffer)aBYTEFIFO_wVa1ue1=bffer2;BYTEFIFO_wVaIueH=buffer3;Aif(FIFO_wVa1ueH=OxOO)aaif(FIFO_WVaIue1=0x01)aSend_Hand_Shake()泠eIsSTA11OI=0x01;/SendStaI10();ae1seif(FIFO_wVa1ueH>=0X81<=0X84)aaif(FIFO_wVa1ue1=0x00)aSene1HQnC1ShQke()?)e1seSTA11O=Ox01;/SendSta1I0();Aae1seSTA11O=0x01;/SendStaII0();)voidSetFeatre-Edpoint(BYTE*buffer)ABYTEtemp;Atemp=buffer4;/FIFO_w1ndex1if(bFIag_SetConfiguration_Ready!=TRUE)return;/有无被SetConfiguration。设立ternp&=Ox7f;temp=GetPipeBit(temp);获取相应位STA11=tempSTA11;将指定的Enpoint置IASend_HQnC1Shke()淮)*A/Set1nterface():设立InterfaCe函数A/*aBOO1SetInterface(BYTE*bufferzBYTE*USBnterfa