当前位置:首页 >> 工学 >>

USB通信协议


做了一段时间的 USB 方面的开发,虽然是现成的方案,我们只需要搞清楚它的架构,再添加我们的代码就 行了。空闲之余,研究了一下 USB 通信过程,也把 82A851R 部分的汇编代码重新用 C 语言描述了一篇 (仅是描述,不代表能真正运行) 。发现汇编代码条理性太在太差了,不好读。一把 C 语言的代码一写, 马上觉得清楚很多。废话少说,开始贴图,贴代码。

================下面是将一些函数重新用 C 语言描述了一遍=========== =

#define BYTE unsigned char //************************************************** // 基本定义函数 //************************************************** BYTE FIFO_RD_CHECK(BYTE num) { BYTE FIFO_FLAG=0; UCC|=num;//选择 Endpoint,0,1,2,3,4, MISC&=0xf8;//低 3 位置 0 MISC|=0X00;//TX 位置 0; Delay_3us(); MISC|=0X01;//Set Request Delay_28us();

if(MISC&0X40!=0) if(MISC&0x80!=0) return FIFO_FLAG; }

FIFO_FLAG=0x0f;//READY FIF0_FLAG&=0xf0;//Len0 Detected

MISC&=0xfe;//clear REQ

BYTE FIFO_WR_CHECK(BYTE num) { BYTE FIFO_FLAG=0;//后 4 位表示 Ready 位,前四位表示 Len0 位的状态是否有被设置 UCC|=num;//选择 Endpoint,0,1,2,3,4, MISC&=0xf8;//低 3 位置 0 MISC|=0X02;//TX 位置 0; Delay_3us(); MISC|=0X01;//Set Request Delay_28us(); if(MISC&0X40!=0) if(MISC&0x80!=0) return FIFO_FLAG; } void Read_FIFO(BYTE *Fifo_Addr,BYTE Fifo_Size,BYTE *buffer) { int i=0; MISC|=0x01;//Set Request for(i=0;i<Fifo_Size;i++) { buffer[i]=Fifo_Addr[0];//从 FIFO 地址取值 Delay_28us(); if(MISC&0x40==0) } MISC^=0X02;//改变 TX 位状态 Delay_3us(); MISC&=0XFE;//Clear Request } void Write_FIFO(BYTE *Fifo_Addr,BYTE SendLenth,BYTE *buffer) { int i=0; MISC|=0X01;//Set Request for(i=0;i<SendLenth;i++) { Fifo_Addr[0]=buffer[i];//将要发送的数据放至相应的 Fifo 中 Delay_28us(); break;//Not Ready FIFO_FLAG=0x0f;//READY FIF0_FLAG&=0xf0;//Len0 Detected

MISC&=0xfe;//clear REQ

if(MISC&0x40==0) }

break;//Not Ready

MISC^=0X02;//改变 TX 位状态 Delay_3us(); MISC&=0XFE;//Clear Request } BOOL Check_Real_Cmd() { BYTE bFlag_Real_Cmd=FALSE; if(MISC&0X20!=0) if(MISC&0X80!=0) } void Send_hand() { BOOL IsRealCmd,Status_Flag; while(1) { IsRealCmd=Check_Real_Cmd(); if(IsRealCmd==TRUE) return; else { Status_Flag=FIFO_WR_CHECK(0); if(Status_Flag&0x0f!=0)//Fifo_Ready break; else continue; } } MISC|=0x01;//Set Requset MISC^=0X02;//改变 TX 位状态 Delay_3us(); MISC&=0XFE;//Clear Request } bFlag_Real_Cmd=TRUE; bFlag_Real_Cmd=TRUE;

return bFlag_Real_Cmd;

void control_read(WORD *rom_dataptr,BYTE *buffer)//从中读取数据, { BYTE temp,i=0; if(buffer[7]!=0) //FIFO_WLENGTHH return; //rom_dataptr 是全局的在其他函数中赋值改变

if(buffer[6]==0) //FIFO_WLENGTHL return; if(buffer[6]>data_start[0])//请求的数据超出 ROM 数据 return; data_count=buffer[6]; if(MISC&0x40!=0)//是控制指令 return; if(data_count==0) { Send_Hand_Shake(); return; } //开始真正的 control_read while(1) { if(bFlag_RD_HTable==0)//Read Low Byte { bFlag_RD_HTable=1; buffer[i]=(BYTE )*rom_dataptr;//取其低位 i++; data_count--;//全局变量,要发送的总长度 if(data_count<=1) break; if(i+1==8)//FIFO_size=8 break; } else//Read Hight Byte { bFlag_RD_HTable=0; buffer[i]=(BYTE )(*rom_dataptr)>>8;//取其高位 rom_dataptr++;//将 ROM 指针前移 if(buffer[i]==0x3f) continue; else { i++; if(data_count<=1) break; if(i+1==8) break; } } }//填充完毕,结束循环,开始向 FIFO 发送数据 while(1)

{ if(Check_Real_Cmd()==TRUE) } Write_FIFO(Fifo_0_Addr,0x02,buffer); } return; if(FIFO_WR_CHECK(0)&0xff==0) continue;//Not Ready

//************************************************** // SetAddress(): 重新设定 Endpoint 地址函数 //************************************************** void SetAddress(BYTE *buffer) { BYTE Dev_Addr; Dev_Addr=buffer[2]//FIFO_OUT3,FIFO_WVALUEL SIES|=0x01;//主机从设备读操作后将更新在 AWR 中的地址,否则为 0 则立即更新 Dev_Addr&=0XFE; USB_AWR=Dev_Addr; Send_Hand_Shake(); } //************************************************** // SetConfiguration(): 设置配置函数 //************************************************** void SetConfiguration(BYTE *buffer,BYTE *USB_Configuration) { USVC|=0x80; PGA_CTRL|=0x80; *USB_Configuration=buffer[2];//FIFO_WVALUEL STALL&=0x00;//设置好以上的寄存器 Send_Hand_Shake(); } //************************************************** // ClearFeature(): 清徐 Feature 函数 //************************************************** void ClearFeature(BYTE *buffer) { BYTE temp; temp=buffer[2];//FIFO_wValueL if(temp=0x01) { Send_Hand_Shake();

} else STALL0|=0x01;//SendStall0(); } void ClearFeature_Endpoint(BYTE *buffer) { BYTE temp; temp=buffer[4];//FIFO_wIndexL if(bFlag_SetConfiguration_Ready==TRUE);//表明已经配置过了 temp=GetPipeBit(temp);//获取对应位 temp=~temp;//取反 STALL=temp&STALL;//与 STALL 寄存器相与,将需要的位置 0 Send_Hand_Shake(); } //************************************************** // // SetFeature(): 设置 Feature 函数 包括 Endpoint 部分

//************************************************** void SetFeature(BYTE *buffer) { BYTE FIFO_wValueL=buffer[2]; BYTE FIFO_wValueH=buffer[3]; if(FIFO_wValueH==0x00) { if(FIFO_wValueL==0x01) { Send_Hand_Shake(); } else STALL0|=0x01;//SendStall0(); } else if(FIFO_wValueH>=0X81<=0X84) { if(FIFO_wValueL==0x00) { Send_Hand_Shake(); } else STALL0|=0x01;//SendStall0(); } else } STALL0|=0x01;//SendStall0();

void SetFeature_Endpoint(BYTE *buffer) { BYTE temp; temp=buffer[4];//FIFO_wIndexL if(bFlag_SetConfiguration_Ready!=TRUE) return;//有没有被 SetConfiguration()设置 temp&=0x7f; temp=GetPipeBit(temp);//获取对应位 STALL=temp|STALL;//将指定的 Enpoint 置 1 Send_Hand_Shake(); } //************************************************** // // //************************************************** BOOL SetInterface(BYTE *buffer,BYTE *USB_Interface_Alt,BYTE *USB_Interface) { *USB_Interface_Alt=buffer[2];//FIFO_WVALUEL *USB_Interface=buffer[4];//FIFO_WINDEXL PA|=0X01;//Set PA.0 Send_Hand_Shake(); return TRUE; } SetInterface(): 设置 Interface 函数

//************************************************** // // GetDescriptor(): 描述的函数 获取 Descriptor

//************************************************** void GetDescriptor(BYTE *buffer) { BYTE FIFO_WvalueH=buffer[3]; BYTE FIFO_wIndexL=buffer[4]; switch(FIFO_WvalueH) { case 01://device, 80 06 00 01 GetDeviceDescriptor(); return; case 02://configurationDescriptor 80 06 00 02 GetConfigurationDescriptor(); return; case 03://string,80 06 00 03

GetStringDescriptor(); default: break; } //********************************** //****Then test for HID class Descriptor //*********************************** if(FIFO_wIndexL==0x03)//Check Interface 3,被配置为 HID { switch(FIFO_WvalueH) { case 22://report,81 06 00 22 GetReportDescriptor(); break; case 21://HID,81 06 00 21 GetHIDDescriptor(); break; default: STALL0|=0x01;//SendStall0();//无法解析的情况 break; } } else STALL0|=0x01;//SendStall0();//无法解析的情况 } void GetDeviceDescriptor(BYTE *buffer) { BYTE data_count; BYTE *data_start; data_count=device_desc_table[0];//低字节存放长度 data_start=device_desc_table; } //************************************************** // // GetStatus(): 设置 USB 状态的函数 包括 Endpoint 部分

//************************************************** void GetStatus(BYTE *buffer) { BYTE FIFO_SendLen=0X02; buffer[0]=0x00; buffer[1]=0x01;

while(1) { if(Check_Real_Cmd()==TRUE) break;//估计是 Len0=1,结束会话 if(FIFO_WR_CHECK(0)==FALSE) continue; } Write_FIFO(Fifo_0_Addr,FIFO_SendLen,buffer); } GetStatus_Endpoint(BYTE *buffer) { BYTE FIFO_SendLen=0X02; BYTE temp; temp=buffer[4];//FIFO_wIndexL,表示要检测的 Endpoint 号 temp&=0x7f; temp=GetPipeBit(temp);//获取位数如:0000 00101B => 0010 0000B if(temp&STALL==TRUE)//要检测的位置 1 buffer[0]=1; else buffer[0]=0; buffer[1]=0; while(1) { if(Check_Real_Cmd()==TRUE) break;//估计是 Len0=1,结束会话 if(FIFO_WR_CHECK(0)==FALSE) continue; } Write_FIFO(Fifo_0_Addr,FIFO_SendLen,buffer); } //************************************************** // // //************************************************** void GetConfiguration(BYTE *buffer,BYTE USB_Configuration) { BYTE FIFO_SendLen; buffer[0]=USB_Configuration; FIFO_SendLen=0x01; while(1) { if(Check_Real_Cmd()==TRUE) return; if(FIFO_WR_CHECK(0)&0x0f!=0)//Fifo Ready break; } Write_FIFO(Fifo_0_Addr,FIFO_SendLen,buffer); } GetConfiguration(): 设置配置的函数

//************************************************** // // //************************************************** void GetInterface(BYTE USB_Interface_Alt,BYTE *buffer) { BYTE FIFO_SendLen; buffer[0]=USB_Interface_Alt; FIFO_SendLen=0x01; while(1) { if(Check_Real_Cmd()==TRUE) } Write_FIFO(Fifo_0_Addr,FIFO_SendLen,buffer) } return; if(FIFO_WR_CHECK(0)&0xff==0) continue;//Not Ready GetInterface(): 获取 Interface 接口的函数

//************************************************** // // //************************************************** BYTE SetReport(BYTE *buffer) { BYTE FIFO_wValueH=buffer[3]; BYTE nCmdIndex1; if(FIFO_wValueH==0x02)//set_output_report { if(buffer[4]!=0x03)//check interface { STALL|=0x01;//ENPOINT0 Error return; } if(buffer[6]!=0x08)//FIFO_wLengthL,check length { STALL|=0x01;//ENPOINT0 Error return; } nCmdIndex1=0x21; } return nCmdIndex1;//返回命令索引号 } SetReport(): 设置 Report 的函数

//************************************************** // // SetCur(): 设置当前信息的函数 包括 VolumeControl,MuteControl

//************************************************** void SetCur(BYTE *buffer)//;21 01 { if(buffer[3]==0x01)//MUTE_CONTROL MuteControl(); else if(buffer[3]==0x02)//VOLUME_CONTROL VolumeControl(); else STALL0|=0x01; } BYTE MuteControl(BYTE *buffer) //21 01 00 01,if have more feature , the state must be modify!! { BYTE nCmdIndex1; if(buffer[5]==0x02)//FIFO_wIndexH,MuteControl_SetSpeaker(); { nCmdIndex1=0x18; return nCmdIndex1; } else if(buffer[5]==0x06)//MuteControl_SetMic(); { nCmdIndex1=0x19; return nCmdIndex1; } } BYTE VolumeControl(BYTE *buffer) { BYTE nCmdIndex1; if(buffer[5]==0x02)//FIFO_wIndexH,VolumeControl_SetSpeaker() { nCmdIndex1=0x28; return nCmdIndex1; } else ifbuffer[5]==0x06) { nCmdIndex1=0x29; return nCmdIndex1; } }

//************************************************** // // GetMin(): 获取各种最小信息的函数 包括 GetMin_SetSpeaker,GetMin_SetMic

//************************************************** void GetMin(BYTE *buffer) { if(buffer[5]==0x02)//FIFO_wIndexH GetMin_SetSpeaker(); else if(buffer[5]==0x06) GetMin_SetMic(); else STALL|=0X01; } void GetMin_SetSpeaker(BYTE *buffer) { buffer[0]=0x00; buffer[1]=0xe0;//Min_Volume while(1) { if(Check_Real_Cmd()==TRUE) } Write_FIFO(Fifo_0_Addr,0x02,buffer) } void GetMin_SetMic(BYTE *buffer) { buffer[0]=0x00; buffer[1]=0x00;//MIC_Min_Volume while(1) { if(Check_Real_Cmd()==TRUE) } Write_FIFO(Fifo_0_Addr,0x02,buffer) } //************************************************** // // GetMax(): 获取各种最大信息的函数 包括 Speaker,Mic return; if(FIFO_WR_CHECK(0)&0xff==0) continue;//Not Ready return; if(FIFO_WR_CHECK(0)&0xff==0) continue;//Not Ready

//************************************************** void GetMax(BYTE *buffer)

{ if(buffer[5]==0x02)//FIFO_wIndexH GetMax_SetSpeaker(); else if(buffer[5]==0x06) GetMax_SetMic(); else STALL0|=0x01; } void GetMax_SetSpeaker(BYTE *buffer) { buffer[0]=0x00; buffer[1]=0x0c;//Max_Volume while(1) { if(Check_Real_Cmd()==TRUE) } Write_FIFO(Fifo_0_Addr,0x02,buffer) } void GetMax_SetMic(BYTE *buffer) { buffer[0]=0x00; buffer[1]=0x0c;//MIC_Max_Volume while(1) { if(Check_Real_Cmd()==TRUE) } Write_FIFO(Fifo_0_Addr,0x02,buffer) } //************************************************** // // //************************************************** void GetRes(BYTE *buffer) { buffer[0]=0x00; buffer[1]=0x01; while(1) { if(Check_Real_Cmd()==TRUE) return; GetRes(): return; if(FIFO_WR_CHECK(0)&0xff==0) continue;//Not Ready return; if(FIFO_WR_CHECK(0)&0xff==0) continue;//Not Ready

if(FIFO_WR_CHECK(0)&0xff==0) continue;//Not Ready } Write_FIFO(Fifo_0_Addr,0x02,buffer) } //************************************************** // // //************************************************** void GetCur(BYTE *buffer) { BYTE FIFO_wLengthL=buffer[6]; BYTE FIFO_wIndexH=buffer[5]; BYTE FIFO_SendLen; FIFO_SendLen=FIFO_wLengthL; if(FIFO_SendLen==0x01) GetCurMute(); else if(FIFO_SendLen==0x02) GetCur_Volume(); else STALL|=0x01; } void GetCur_Mute(BYTE *buffer) { if(FIFO_wIndexH==0x02) GetCur_Mute_Speaker(); else if(FIFO_wIndexH==0x06) GetCur_Mute_Mic(); else STALL|=0x01; } void GetCur_Mute_Mic(BYTE *buffer) { if(bFlag_Mic_Mute==TRUE) buffer[0]=0x01; else buffer[0]=0x00; while(1) { if(Check_Real_Cmd()==TRUE) return; if(FIFO0_WR_CHECK()&0x0f==0) continue;//未准备好 else GetCur():

break; } Write_FIFO(Fifo_0_Addr,0x01,buffer); } void GetCur_Mute_Speaker(BYTE *buffer) { if(bFlag_Audio_Mute==TRUE) buffer[0]=0x01; else buffer[0]=0x00; while(1) { if(Check_Real_Cmd()==TRUE) return; if(FIFO0_WR_CHECK()&0x0f==0) continue;//未准备好 else break; } Write_FIFO(Fifo_0_Addr,0x01,buffer); } void GetCur_Volume(BYTE *buffer) { if(buffer[5]==0x02)//FIFO_wIndexH GetCur_Volume_Speaker(); else if(buffer[5]==0x06) GetCur_Volume_Mic(); else STALL|=0x01; } void GetCur_Volume_Mic(BYTE *buffer) { buffer[0]=0x00; buffer[1]=PGA_CTRL&0x3f; while(1) { if(Check_Real_Cmd()==TRUE) return; if(FIFO0_WR_CHECK()&0x0f==0) continue;//未准备好 else break; } Write_FIFO(Fifo_0_Addr,0x02,buffer); }

void {

GetCur_Volume_Speaker(BYTE

*buffer,BYTE

VolumeL_Save,BYTE

VolumeH_Save) buffer[0]=VolumeH_Save; buffer[1]=VolumeL_Save; while(1) { if(Check_Real_Cmd()==TRUE) return; if(FIFO0_WR_CHECK()&0x0f==0) continue;//未准备好 else break; } Write_FIFO(Fifo_0_Addr,0x02,buffer); }

//**************************************** // Const String 常量 //****************************************** BYTE device_desc_table[]={//18 bytes WORD (18 bytes) WORD WORD WORD bDeviceProtocol WORD WORD WORD WORD WORD } BYTE config_desc_table[]={//9 bytes WORD WORD WORD WORD WORD WORD } 0x0209 0x00D9 0x0104 0x3F00 0x3F80 0x3FFA ,//descriptor type (config descriptor) , size of descriptor ,//total length of descriptor (D9 H=217 bytes) ,//index of this configuration , 4 interface ,//configuration string index ,//configuration attributes (bus supply) ,//maxpower (500ma) 0x04D9 ,//vendor ID = 004D9H 0x2851 0x0100 0x0201 0x0103 ,//product version ID (Sample Device) ,//product version ID Device Release Code ,//product string index , manufacturer string index ,//number of configurations , serial number string index 0x0110 0x0000 ,//USB spec release (ver 1.1) ,//device sub-class , Communication device class ,//bMaxPacketSize0 maximum packet size , 0x0112 ,//descriptor type (device descriptor) , size of descriptor

0x0800


相关文章:
USB通信原理
USB通信原理_计算机硬件及网络_IT/计算机_专业资料。串口通信协议 什么是串口 串口是计算机上一种非常通用设备通信的协议 (不要与通用串行总线 UniversalSerialBus ...
USB-PD协议解说_图文
USB-PD协议解说_电子/电路_工程科技_专业资料。USB-PD USB Power Delivery 快速充电通信原理本篇文章讲的快速充电是指 USB 论坛所发布的 USB Power Delivery 快速...
USB的HID通信协议
USB的HID通信协议_计算机软件及应用_IT/计算机_专业资料。USB的HID通信协议USB 事务处理是主机和设备之间数据传输的基本单位,由一系列具有特定格式的信息包组 成。因...
USB通信协议源代码
USB通信协议源代码_IT/计算机_专业资料。USB通信协议源代码做了一段时间的 USB 方面的开发,虽然是现成的方案,我们只需要搞清楚它的架构,再添加我们的代 码就行...
USB_HID_设备类协议入门
USB_HID_设备类协议入门_职业技术培训_职业教育_教育专区。一、应用场合 USB ...HID 设备描述符 主要描述 HID 规范的版本号、HID 通信所使用的额外描述符、...
USB通信相关知识
22页 免费 USB通信协议 16页 免费 USB通信 7页 免费如要投诉违规内容,请到百度文库投诉中心;如要提出功能问题或意见建议,请点击此处进行反馈。USB...
U盘通信协议
U盘通信协议_IT/计算机_专业资料。1. usb 使用 2 根数据线传送数据 D+跟 D-,使用的是差分放大电路,所以 usb 不 使用 D+跟 D-上的信号作为自己的信号定义...
串口和USB通信
串口通信协议什么是串口串口是计算机上一种非常通用设备通信的协议(不要与通用串行总线 Universal SerialBus 或者 USB 混淆).大多数计算机包含两个基于 RS232 的串口...
usb2.0的协议及规范
usb2.0的协议及规范_信息与通信_工程科技_专业资料。Usb2.0 的协议规范 第 1 章 绪论 1.1 起因 Intel 公司开发的通用串行总线架构(USB)的目的主要基于以下三...
USB-HID协议中文版_图文
USB-HID协议中文版_合同协议_表格/模板_实用文档。第8章 USB 接口 HID 设备 ...8.2.2 HID 描述符 HID 描述符的主要作用是用来识别 HID 通信所使用的额外...
更多相关标签: