《[原創(chuàng)]USB通信協(xié)議的理解-流程-描述》由會員分享,可在線閱讀,更多相關(guān)《[原創(chuàng)]USB通信協(xié)議的理解-流程-描述(16頁珍藏版)》請在裝配圖網(wǎng)上搜索。
[原創(chuàng)]USB通信協(xié)議的理解,流程,描述
做了一段時間的USB方面的開發(fā),雖然是現(xiàn)成的方案,我們只需要搞清楚它的架構(gòu),再添加我們的代碼就行了??臻e之余,研究了一下USB通信過程,也把82A851R部分的匯編代碼重新用C語言描述了一篇(僅是描述,不代表能真正運行)。發(fā)現(xiàn)匯編代碼條理性太在太差了,不好讀。一把C語言的代碼一寫,馬上覺得清楚很多。廢話少說,開始貼圖,貼代碼。
================下面是將一些函數(shù)重新用C語言描述了一遍============
#define BYTE unsigned char
//**************************************************
// 基本定義函數(shù)
//**************************************************
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位的狀態(tài)是否有被設(shè)置
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;i
data_start[0])//請求的數(shù)據(jù)超出ROM數(shù)據(jù)
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--;//全局變量,要發(fā)送的總長度
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;
}
}
}//填充完畢,結(jié)束循環(huán),開始向FIFO發(fā)送數(shù)據(jù)
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(): 重新設(shè)定Endpoint地址函數(shù)
//**************************************************
void SetAddress(BYTE *buffer)
{
BYTE Dev_Addr;
Dev_Addr=buffer[2]//FIFO_OUT3,FIFO_WVALUEL
SIES|=0x01;//主機從設(shè)備讀操作后將更新在AWR中的地址,否則為0則立即更新
Dev_Addr&=0XFE;
USB_AWR=Dev_Addr;
Send_Hand_Shake();
}
//**************************************************
// SetConfiguration(): 設(shè)置配置函數(shù)
//**************************************************
void SetConfiguration(BYTE *buffer,BYTE *USB_Configuration)
{
USVC|=0x80;
PGA_CTRL|=0x80;
*USB_Configuration=buffer[2];//FIFO_WVALUEL
STALL&=0x00;//設(shè)置好以上的寄存器
Send_Hand_Shake();
}
//**************************************************
// ClearFeature(): 清徐Feature函數(shù)
//**************************************************
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);//表明已經(jīng)配置過了
temp=GetPipeBit(temp);//獲取對應(yīng)位
temp=~temp;//取反
STALL=temp&STALL;//與STALL寄存器相與,將需要的位置0
Send_Hand_Shake();
}
//**************************************************
// SetFeature(): 設(shè)置Feature函數(shù)
// 包括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()設(shè)置
temp&=0x7f;
temp=GetPipeBit(temp);//獲取對應(yīng)位
STALL=temp|STALL;//將指定的Enpoint置1
Send_Hand_Shake();
}
//**************************************************
// SetInterface(): 設(shè)置Interface函數(shù)
//
//**************************************************
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
// 描述的函數(shù)
//**************************************************
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];//低字節(jié)存放長度
data_start=device_desc_table;
}
//**************************************************
// GetStatus(): 設(shè)置USB狀態(tài)的函數(shù)
// 包括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,結(jié)束會話
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);//獲取位數(shù)如: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,結(jié)束會話
if(FIFO_WR_CHECK(0)==FALSE) continue;
}
Write_FIFO(Fifo_0_Addr,FIFO_SendLen,buffer);
}
//**************************************************
// GetConfiguration(): 設(shè)置配置的函數(shù)
//
//**************************************************
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接口的函數(shù)
//
//**************************************************
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(): 設(shè)置Report的函數(shù)
//
//**************************************************
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(): 設(shè)置當前信息的函數(shù)
// 包括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(): 獲取各種最小信息的函數(shù)
// 包括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(): 獲取各種最大信息的函數(shù)
// 包括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)
}
鏈接地址:http://m.appdesigncorp.com/p-11086421.html