五一七教育网
您的当前位置:首页USB通信协议

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) FIFO_FLAG=0x0f; //READY

if(MISC&0x80!=0) FIF0_FLAG&=0xf0;//Len0 Detected MISC&=0xfe; //clear REQ return FIFO_FLAG; }

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) FIFO_FLAG=0x0f;//READY

if(MISC&0x80!=0) FIF0_FLAG&=0xf0;//Len0 Detected MISC&=0xfe;//clear REQ return FIFO_FLAG; }

void Read_FIFO(BYTE *Fifo_Addr,BYTE Fifo_Size,BYTE *buffer) {

int i=0;

MISC|=0x01; //Set Request for(i=0;ibuffer[i]=Fifo_Addr[0];//从FIFO地址取值 Delay_28us();

if(MISC&0x40==0) break; //Not Ready }

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;iFifo_Addr[0]=buffer[i];//将要发送的数据放至相应的Fifo中 Delay_28us();

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) bFlag_Real_Cmd=TRUE; if(MISC&0X80!=0) bFlag_Real_Cmd=TRUE; return bFlag_Real_Cmd; }

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 }

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

if(buffer[7]!=0) //FIFO_WLENGTHH return;

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) return;

if(FIFO_WR_CHECK(0)&0xff==0) continue;//Not Ready }

Write_FIFO(Fifo_0_Addr,0x02,buffer); }

//************************************************** // 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(); }

//************************************************** // SetInterface(): 设置Interface函数 //

//**************************************************

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; }

//************************************************** // 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); }

//************************************************** // GetConfiguration(): 设置配置的函数 //

//************************************************** 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); }

//************************************************** // GetInterface(): 获取Interface接口的函数 //

//************************************************** 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) return;

if(FIFO_WR_CHECK(0)&0xff==0) continue;//Not Ready }

Write_FIFO(Fifo_0_Addr,FIFO_SendLen,buffer) }

//************************************************** // SetReport(): 设置Report的函数 //

//************************************************** 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;//返回命令索引号 }

//************************************************** // 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) return;

if(FIFO_WR_CHECK(0)&0xff==0) continue;//Not Ready }

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) return;

if(FIFO_WR_CHECK(0)&0xff==0) continue;//Not Ready }

Write_FIFO(Fifo_0_Addr,0x02,buffer) }

//************************************************** // GetMax(): 获取各种最大信息的函数 // 包括Speaker,Mic

//************************************************** 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) return;

if(FIFO_WR_CHECK(0)&0xff==0) continue;//Not Ready }

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) return;

if(FIFO_WR_CHECK(0)&0xff==0) continue;//Not Ready }

Write_FIFO(Fifo_0_Addr,0x02,buffer) }

//************************************************** // GetRes(): //

//************************************************** void GetRes(BYTE *buffer) {

buffer[0]=0x00; buffer[1]=0x01; while(1) {

if(Check_Real_Cmd()==TRUE) return;

if(FIFO_WR_CHECK(0)&0xff==0) continue;//Not Ready }

Write_FIFO(Fifo_0_Addr,0x02,buffer) }

//************************************************** // GetCur(): //

//************************************************** 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

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 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 class WORD 0x0800 ,//bMaxPacketSize0 maximum packet size , bDeviceProtocol

WORD 0x04D9 ,//vendor ID = 004D9H

WORD 0x2851 ,//product version ID (Sample Device) WORD 0x0100 ,//product version ID Device Release Code

WORD 0x0201 ,//product string index , manufacturer string index WORD 0x0103 ,//number of configurations , serial number string index }

BYTE config_desc_table[]={//9 bytes

WORD 0x0209 ,//descriptor type (config descriptor) , size of descriptor WORD 0x00D9 ,//total length of descriptor (D9 H=217 bytes) WORD 0x0104 ,//index of this configuration , 4 interface WORD 0x3F00 ,//configuration string index

WORD 0x3F80 ,//configuration attributes (bus supply) WORD 0x3FFA ,//maxpower (500ma) }

因篇幅问题不能全部显示,请点此查看更多更全内容