资源描述
精选资料
[原创]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;i<Fifo_Size;i++)
{
buffer[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;i<SendLenth;i++)
{
Fifo_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)
展开阅读全文