1、做了一段时间的 USB 方面的开发,虽然是现成的方案,我们只需要搞清楚它的架构,再添加我们的代码就行了。空闲之余,研究了一下 USB 通信过程,也把 82A851R 部分的汇编代码重新用 C 语言描述了一篇(仅是描述,不代表能真正运行) 。发现汇编代码条理性太在太差了,不好读。一把 C 语言的代码一写,马上觉得清楚很多。废话少说,开始贴图,贴代码。下面是将一些函数重新用 C 语言描述了一遍#define BYTE unsigned char/*/ 基本定义函数/*BYTE FIFO_RD_CHECK(BYTE num)BYTE FIFO_FLAG=0;UCC|=num;/选择 Endpoint
2、,0,1,2,3,4,MISC/低 3 位置 0MISC|=0X00;/TX 位置 0;Delay_3us();MISC|=0X01;/Set RequestDelay_28us();if(MISC/READYif(MISC/Len0 DetectedMISC/clear REQreturn FIFO_FLAG;BYTE FIFO_WR_CHECK(BYTE num)BYTE FIFO_FLAG=0;/后 4 位表示 Ready 位,前四位表示 Len0 位的状态是否有被设置UCC|=num;/选择 Endpoint,0,1,2,3,4,MISC/低 3 位置 0MISC|=0X02;/TX
3、位置 0;Delay_3us();MISC|=0X01;/Set RequestDelay_28us();if(MISC/READYif(MISC/Len0 DetectedMISC/clear REQreturn FIFO_FLAG;void Read_FIFO(BYTE *Fifo_Addr,BYTE Fifo_Size,BYTE *buffer)int i=0;MISC|=0x01;/Set Requestfor(i=0;idata_start0)/请求的数据超出 ROM 数据return;data_count=buffer6;if(MISCif(data_count=0)Send_Ha
4、nd_Shake();return; /开始真正的 control_readwhile(1)if(bFlag_RD_HTable=0)/Read Low BytebFlag_RD_HTable=1;bufferi=(BYTE )*rom_dataptr;/取其低位i+;data_count-;/全局变量,要发送的总长度if(data_count8;/取其高位rom_dataptr+;/将 ROM 指针前移if(bufferi=0x3f)continue;elsei+;if(data_count=0X81 0010 0000Bif(tempelse buffer0=0;buffer1=0;whi
5、le(1)if(Check_Real_Cmd()=TRUE) break;/估计是 Len0=1,结束会话if(FIFO_WR_CHECK(0)=FALSE) continue;Write_FIFO(Fifo_0_Addr,FIFO_SendLen,buffer);/*/ GetConfiguration(): 设置配置的函数 / /*void GetConfiguration(BYTE *buffer,BYTE USB_Configuration)BYTE FIFO_SendLen;buffer0=USB_Configuration;FIFO_SendLen=0x01;while(1)if(
6、Check_Real_Cmd()=TRUE) return;if(FIFO_WR_CHECK(0)Write_FIFO(Fifo_0_Addr,FIFO_SendLen,buffer);/*/ GetInterface(): 获取 Interface 接口的函数 / /*void GetInterface(BYTE USB_Interface_Alt,BYTE *buffer)BYTE FIFO_SendLen;buffer0=USB_Interface_Alt;FIFO_SendLen=0x01;while(1)if(Check_Real_Cmd()=TRUE) return;if(FIFO
7、_WR_CHECK(0)/Not ReadyWrite_FIFO(Fifo_0_Addr,FIFO_SendLen,buffer)/*/ SetReport(): 设置 Report 的函数 / /*BYTE SetReport(BYTE *buffer)BYTE FIFO_wValueH=buffer3;BYTE nCmdIndex1;if(FIFO_wValueH=0x02)/set_output_reportif(buffer4!=0x03)/check interfaceSTALL|=0x01;/ENPOINT0 Errorreturn;if(buffer6!=0x08)/FIFO_w
8、LengthL,check lengthSTALL|=0x01;/ENPOINT0 Errorreturn;nCmdIndex1=0x21;return nCmdIndex1;/返回命令索引号/*/ SetCur(): 设置当前信息的函数 / 包括 VolumeControl,MuteControl/*void SetCur(BYTE *buffer)/;21 01if(buffer3=0x01)/MUTE_CONTROLMuteControl();else if(buffer3=0x02)/VOLUME_CONTROLVolumeControl();elseSTALL0|=0x01;BYTE
9、 MuteControl(BYTE *buffer) /21 01 00 01,if have more feature , the state must be modify!BYTE nCmdIndex1;if(buffer5=0x02)/FIFO_wIndexH,MuteControl_SetSpeaker();nCmdIndex1=0x18;return nCmdIndex1;else if(buffer5=0x06)/MuteControl_SetMic();nCmdIndex1=0x19;return nCmdIndex1;BYTE VolumeControl(BYTE *buffe
10、r)BYTE nCmdIndex1;if(buffer5=0x02)/FIFO_wIndexH,VolumeControl_SetSpeaker()nCmdIndex1=0x28;return nCmdIndex1;else ifbuffer5=0x06)nCmdIndex1=0x29;return nCmdIndex1;/*/ GetMin(): 获取各种最小信息的函数 / 包括 GetMin_SetSpeaker,GetMin_SetMic/*void GetMin(BYTE *buffer)if(buffer5=0x02)/FIFO_wIndexHGetMin_SetSpeaker();
11、else if(buffer5=0x06)GetMin_SetMic();elseSTALL|=0X01;void GetMin_SetSpeaker(BYTE *buffer)buffer0=0x00;buffer1=0xe0;/Min_Volumewhile(1)if(Check_Real_Cmd()=TRUE) return;if(FIFO_WR_CHECK(0)/Not ReadyWrite_FIFO(Fifo_0_Addr,0x02,buffer)void GetMin_SetMic(BYTE *buffer)buffer0=0x00;buffer1=0x00;/MIC_Min_Vo
12、lumewhile(1)if(Check_Real_Cmd()=TRUE) return;if(FIFO_WR_CHECK(0)/Not ReadyWrite_FIFO(Fifo_0_Addr,0x02,buffer)/*/ GetMax(): 获取各种最大信息的函数 / 包括 Speaker,Mic/*void GetMax(BYTE *buffer)if(buffer5=0x02)/FIFO_wIndexHGetMax_SetSpeaker();else if(buffer5=0x06)GetMax_SetMic();elseSTALL0|=0x01;void GetMax_SetSpea
13、ker(BYTE *buffer)buffer0=0x00;buffer1=0x0c;/Max_Volumewhile(1)if(Check_Real_Cmd()=TRUE) return;if(FIFO_WR_CHECK(0)/Not ReadyWrite_FIFO(Fifo_0_Addr,0x02,buffer)void GetMax_SetMic(BYTE *buffer)buffer0=0x00;buffer1=0x0c;/MIC_Max_Volumewhile(1)if(Check_Real_Cmd()=TRUE) return;if(FIFO_WR_CHECK(0)/Not Rea
14、dyWrite_FIFO(Fifo_0_Addr,0x02,buffer)/*/ GetRes(): / /*void GetRes(BYTE *buffer)buffer0=0x00;buffer1=0x01;while(1)if(Check_Real_Cmd()=TRUE) return;if(FIFO_WR_CHECK(0)/Not ReadyWrite_FIFO(Fifo_0_Addr,0x02,buffer)/*/ GetCur(): / /*void GetCur(BYTE *buffer)BYTE FIFO_wLengthL=buffer6;BYTE FIFO_wIndexH=b
15、uffer5;BYTE FIFO_SendLen;FIFO_SendLen=FIFO_wLengthL;if(FIFO_SendLen=0x01)GetCurMute();else if(FIFO_SendLen=0x02)GetCur_Volume();elseSTALL|=0x01;void GetCur_Mute(BYTE *buffer)if(FIFO_wIndexH=0x02)GetCur_Mute_Speaker();else if(FIFO_wIndexH=0x06)GetCur_Mute_Mic();elseSTALL|=0x01;void GetCur_Mute_Mic(BY
16、TE *buffer)if(bFlag_Mic_Mute=TRUE)buffer0=0x01;else buffer0=0x00;while(1)if(Check_Real_Cmd()=TRUE) return;if(FIFO0_WR_CHECK()/未准备好elsebreak;Write_FIFO(Fifo_0_Addr,0x01,buffer);void GetCur_Mute_Speaker(BYTE *buffer)if(bFlag_Audio_Mute=TRUE)buffer0=0x01;elsebuffer0=0x00;while(1)if(Check_Real_Cmd()=TRU
17、E) return;if(FIFO0_WR_CHECK()/未准备好elsebreak;Write_FIFO(Fifo_0_Addr,0x01,buffer);void GetCur_Volume(BYTE *buffer)if(buffer5=0x02)/FIFO_wIndexHGetCur_Volume_Speaker();else if(buffer5=0x06)GetCur_Volume_Mic();elseSTALL|=0x01;void GetCur_Volume_Mic(BYTE *buffer)buffer0=0x00;buffer1=PGA_CTRLwhile(1)if(Ch
18、eck_Real_Cmd()=TRUE) return;if(FIFO0_WR_CHECK()/未准备好else break; Write_FIFO(Fifo_0_Addr,0x02,buffer);void GetCur_Volume_Speaker(BYTE *buffer,BYTE VolumeL_Save,BYTE VolumeH_Save)buffer0=VolumeH_Save;buffer1=VolumeL_Save;while(1)if(Check_Real_Cmd()=TRUE) return;if(FIFO0_WR_CHECK()/未准备好else break; Write
19、_FIFO(Fifo_0_Addr,0x02,buffer);/*/ Const String 常量/*BYTE device_desc_table=/18 bytesWORD 0x0112 ,/descriptor type (device descriptor) , size of descriptor (18 bytes)WORD 0x0110 ,/USB spec release (ver 1.1)WORD 0x0000 ,/device sub-class , Communication device classWORD 0x0800 ,/bMaxPacketSize0 maximu
20、m packet size , bDeviceProtocolWORD 0x04D9 ,/vendor ID = 004D9HWORD 0x2851 ,/product version ID (Sample Device)WORD 0x0100 ,/product version ID Device Release CodeWORD 0x0201 ,/product string index , manufacturer string indexWORD 0x0103 ,/number of configurations , serial number string indexBYTE con
21、fig_desc_table=/9 bytesWORD 0x0209 ,/descriptor type (config descriptor) , size of descriptorWORD 0x00D9 ,/total length of descriptor (D9 H=217 bytes)WORD 0x0104 ,/index of this configuration , 4 interfaceWORD 0x3F00 ,/configuration string indexWORD 0x3F80 ,/configuration attributes (bus supply)WORD 0x3FFA ,/maxpower (500ma)