USB2.0速度識別

USB2.0是向下兼容USB1.X的,即USB2.0支持高速,全速,低速的USB設備(HIGH-SPEED,FULL-SPEED,LOW-SPEED),而USB1.X不支持高速設備。因此如果高速設備接在USB1.X的hub上,也只能工作在全速狀態。因此對速度的識別是很重要的,否則沒辦法以想要的速度通信。

全速和低速區分

根據規範,全速和低速很好區分。因爲在設備端有一個1.5K的上拉電阻,上電後,有上拉電阻的那根數據線會被拉高,根據 D+或D-的電平狀態來檢測是全速還是低速設備。如下圖:

高速識別


全速,高速的識別比較簡單,但是USB2.0,USB1.X只有一對數據線,就沒辦法有第三種狀態來表示高速設備了,所以高速設備的識別稍微複雜。

高速設備是以一個全速設備的身份出現的,即和全速設備一樣,高速設備也在D+端有一個1.5K的上拉電阻。USB2.0的HUB把設備當成一個全速設備,然後進行一系列的握手信號來確認雙方的身份,一方面HUB要檢測設備是高速還是全速,另一方面設備也要檢測HUB是USB2.0還是USB1.X的,如果HUB是USB2.0,設備也是高速的 就工作在高速模式,否則只能工作在全速模式。

下圖展示了一個高速設備連到USB2.0 hub上的情形:

HUB連接到設備或上電時,向主機報告,主機通過發送Set_port_feature請求讓hub復位新插入的設備。設備復位操作是驅動數據線到復位SE0(D+,D-都爲低電平),並持續至少10MS。

高速設備復位後,通過內部的電流源向D-持續灌17.78MA大小的電流。因爲此時D+端的1.5K上拉電阻還沒撤銷,在hub端,全速/低速驅動器形成一個45歐姆的終端電阻,兩電阻並聯約形成45歐姆的阻抗,所以在HUB端可以看到一個 800ma(17.78*45)的電壓,這個就是Chirp K信號。Chirp K 的持續時間是 1ms -  7ms.

在HUB端,雖然下達了復位信號,並一直驅動着SE0,但usb2.0的高速接收器一直在檢測 Chirp  K信號,如果沒有檢測到,就繼續復位操作,知道復位結束,然後就工作在全速狀態。如果只是一個全速的hub,不支持高速設備,那麼hub也不會理會Chirp k信號,之後設備也不會切換到高速模式。

如果是高速 HUB,設備在發送的Chirp k信號結束後的100us內,HUB必須回覆一連串的KJKJKJ........序列,向設備表明這是一個usb2.0的hub,這裏的kj序列式連續的,且不能中斷,每個K或J的持續時間是 40us--60us.

再回到設備端,設備檢測到6個hub發送的 Chirp信號(3對KJ)後,它必須在500us內切換到高速模式。切換動作有:

 1.斷開1.5K的上拉電阻

2. 連接D+/D-上的高速終端電阻(high-speed termination),其實就是全速/低速差分驅動器。

3.進入默認的高速狀態

執行完 1,2兩步後,USB信號線上看的到現象就發生變化了:HUB發動的 Chirp降到原來的一半,400mv。這是因爲設備端掛載新的終端電阻後,並聯原來的終端電阻,結果爲22.5歐姆,17.78*22.5爲 400mv,以後高速設備操作的 信號幅值就是 400mv而不是 全速/低速的 3.3V。

至此高速設備與usb2.0握手完畢,開始進行480Mbps的通信。

轉帖,原帖出自: http://hi.baidu.com/doyanger/blog/item/af45d995dd64f419d31b704d.html


USB的描述符及各種描述符之間的依賴關係

USB是個通用的總線,端口都是統一的。但是USB設備卻各種各樣,例如USB鼠標,USB鍵盤,U盤等等,那麼USB主機是如何識別出不同的設備的呢?這就要依賴於描述符了。

USB的描述符主要有設備描述符,配置描述符,接口描述符,端點描述符,字符串描述符,HID描述符,報告描述符等等。

關於報告描述符,請看:《USB HID報告及報告描述符簡介 》

http://group.****.com/93/198.aspx。

 

一個USB設備有一個設備描述符,設備描述符裏面決定了該設備有多少種配置,每種配置描述符對應着配置描述符;而在配置描述符中又定義了該配置裏面有多少個接口,每個接口有對應的接口描述符;在接口描述符裏面又定義了該接口有多少個端點,每個端點對應一個端點描述符;端點描述符定義了端點的大小,類型等等。

 

由此我們可以看出,USB的描述符之間的關係是一層一層的,最上一層是設備描述符,下面是配置描述符,再下面是接口描述符,再下面是端點描述符。在獲取描述符時,先獲取設備描述符,然後再獲取配置描述符,根據配置描述符中的配置集合長度,一次將配置描述符、接口描述符、端點描述符一起一次讀回。其中可能還會有獲取設備序列號,廠商字符串,產品字符串等。

 

 

每種描述符都有自己獨立的編號,如下:

 

#define DEVICE_DESCRIPTOR               0x01 //設備描述符

#define CONFIGURATION_DESCRIPTOR        0x02 //配置描述符

#define STRING_DESCRIPTOR               0x03 //字符串描述符

#define INTERFACE_DESCRIPTOR            0x04 //接口描述符

#define ENDPOINT_DESCRIPTOR             0x05 //端點描述符

 

下面分別詳細介紹一下各描述符。

 

1.設備描述符

 

//定義標準的設備描述符結構

 

typedef struct _DEVICE_DCESCRIPTOR_STRUCT

 

{

 

BYTE blength;                               //設備描述符的字節數大小

 

BYTE bDescriptorType;                      //設備描述符類型編號

 

WORD bcdUSB;                                //USB版本號

 

BYTE bDeviceClass;                          //USB分配的設備類代碼

 

BYTE bDeviceSubClass;                       //USB分配的子類代碼

 

BYTE bDeviceProtocol;                       //USB分配的設備協議代碼

 

BYTE bMaxPacketSize0;                       //端點0的最大包大小

 

WORD idVendor;                              //廠商編號

 

WORD idProduct;                             //產品編號

 

WORD bcdDevice;                             //設備出廠編號

 

BYTE iManufacturer;                         //設備廠商字符串的索引

 

BYTE iProduct;                              //描述產品字符串的索引

 

BYTE iSerialNumber;                         //描述設備序列號字符串的索引

 

BYTE bNumConfigurations;                    //可能的配置數量

 

}

 

DEVICE_DESCRIPTOR_STRUCT, * pDEVICE_DESCRIPTOR_STRUCT;

 

//實際的設備描述符示例

 

code DEVICE_DESCRIPTOR_STRUCT device_descriptor=   //設備描述符

 

{

 

sizeof(DEVICE_DESCRIPTOR_STRUCT),                   //設備描述符的字節數大小,這裏是18字節

 

DEVICE_DESCRIPTOR,                              //設備描述符類型編號,設備描述符是01

 

0x1001,   //USB版本號,這裏是USB01.10,即USB1.1。由於51是大端模式,所以高低字節交換

 

0x00,                                 //USB分配的設備類代碼,0表示類型在接口描述符中定義

 

0x00,                                 //USB分配的子類代碼,上面一項爲0時,本項也要設置爲0

 

0x00,                                //USB分配的設備協議代碼,上面一項爲0時,本項也要設置爲0

 

0x10,                                //端點0的最大包大小,這裏爲16字節

 

0x7104,                             //廠商編號,這個是需要跟USB組織申請的ID號,表示廠商代號。

 

0xf0ff,        //該產品的編號,跟廠商編號一起配合使用,讓主機註冊該設備並加載相應的驅動程序

 

0x0100,       //設備出廠編號

 

0x01,        //設備廠商字符串的索引,在獲取字符串描述符時,使用該索引號來識別不同的字符串

 

0x02,        //描述產品字符串的索引,同上

 

0x03,         //描述設備序列號字符串的索引,同上

 

0x01                        //可能的配置數爲1,即該設備只有一個配置

 

};

 

2.配置描述符

 

//定義標準的配置描述符結構

 

typedef struct _CONFIGURATION_DESCRIPTOR_STRUCT

 

{

 

BYTE bLength;                               //配置描述符的字節數大小

 

BYTE bDescriptorType;                       //配置描述符類型編號

 

WORD wTotalLength;                          //此配置返回的所有數據大小

 

BYTE bNumInterfaces;                        //此配置所支持的接口數量

 

BYTE bConfigurationValue;                   //Set_Configuration命令所需要的參數值

 

BYTE iConfiguration;                        //描述該配置的字符串的索引值

 

BYTE bmAttributes;                          //供電模式的選擇

 

BYTE MaxPower;                              //設備從總線提取的最大電流

 

}

 

CONFIGURATION_DESCRIPTOR_STRUCT, * pCONFIGURATION_DESCRIPTOR_STRUCT;

 

2.接口描述符

 

//定義標準的接口描述符結構

 

typedef struct _INTERFACE_DESCRIPTOR_STRUCT

 

{

 

BYTE bLength;                               //接口描述符的字節數大小

 

BYTE bDescriptorType;                       //接口描述符的類型編號

 

BYTE bInterfaceNumber;                      //該接口的編號

 

BYTE bAlternateSetting;                     //備用的接口描述符編號

 

BYTE bNumEndpoints;                         //該接口使用的端點數,不包括端點0

 

BYTE bInterfaceClass;                       //接口類型

 

BYTE bInterfaceSubClass;                    //接口子類型

 

BYTE bInterfaceProtocol;                    //接口遵循的協議

 

BYTE iInterface;                            //描述該接口的字符串索引值

 

}

 

INTERFACE_DESCRIPTOR_STRUCT, * pINTERFACE_DESCRIPTOR_STRUCT;

 

4.端點描述符

 

//定義標準的端點描述符結構

 

typedef struct _ENDPOINT_DESCRIPTOR_STRUCT

 

{

 

BYTE bLegth;                                //端點描述符字節數大小

 

BYTE bDescriptorType;                       //端點描述符類型編號

 

BYTE bEndpointAddress;                      //端點地址及輸入輸出屬性

 

BYTE bmAttributes;                          //端點的傳輸類型屬性

 

WORD wMaxPacketSize;                        //端點收、發的最大包大小

 

BYTE bInterval;                             //主機查詢端點的時間間隔

 

}

 

ENDPOINT_DESCRIPTOR_STRUCT, * pENDPOINT_DESCRIPTOR_STRUCT;

 

下面是一個配置描述符集合的定義

 

typedef struct _CON_INT_ENDP_DESCRIPTOR_STRUCT

 

{

 

CONFIGURATION_DESCRIPTOR_STRUCT configuration_descriptor;

 

INTERFACE_DESCRIPTOR_STRUCT interface_descritor;

 

ENDPOINT_DESCRIPTOR_STRUCT endpoint_descriptor[ENDPOINT_NUMBER];

 

}CON_INT_ENDP_DESCRIPTOR_STRUCT;

 

配置描述符集合的示例

 

code CON_INT_ENDP_DESCRIPTOR_STRUCT con_int_endp_descriptor= //配置描述符集合

 

{

 

//configuration_descriptor                     //配置描述符

 

{

 

sizeof(CONFIGURATION_DESCRIPTOR_STRUCT),      //配置描述符的字節數大小,這裏爲9

 

CONFIGURATION_DESCRIPTOR,                     //配置描述符類型編號,配置描述符爲2

 

(sizeof(CONFIGURATION_DESCRIPTOR_STRUCT)+

 

sizeof(INTERFACE_DESCRIPTOR_STRUCT)+

 

sizeof(ENDPOINT_DESCRIPTOR_STRUCT)*ENDPOINT_NUMBER)*256+

 

(sizeof(CONFIGURATION_DESCRIPTOR_STRUCT)+

 

sizeof(INTERFACE_DESCRIPTOR_STRUCT)+

 

sizeof(ENDPOINT_DESCRIPTOR_STRUCT)*ENDPOINT_NUMBER)/256,   //配置描述符集合的總大小

 

0x01,                                  //只包含一個接口

 

0x01,                                  //該配置的編號

 

0x00,                                  //iConfiguration字段

 

0x80,                                  //採用總線供電,不支持遠程喚醒

 

0xC8                                   //從總線獲取最大電流400mA

 

},

 

//interface_descritor                   //接口描述符

 

{

 

sizeof(INTERFACE_DESCRIPTOR_STRUCT),   //接口描述符的字節數大小,這裏爲9

 

INTERFACE_DESCRIPTOR,                  //接口描述符類型編號,接口描述符爲3

 

0x00,                                  //接口編號爲4

 

0x00,                                  //該接口描述符的編號爲0

 

ENDPOINT_NUMBER,                       //非0端點數量爲2,只使用端點主端點輸入和輸出

 

0x08,                                  //定義爲USB大容量存儲設備

 

0x06,                                  //使用的子類,爲簡化塊命令

 

0x50,                                  //使用的協議,這裏使用單批量傳輸協議

 

0x00                                   //接口描述符字符串索引,爲0,表示沒有字符串

 

},

 

//endpoint_descriptor[]

 

{

 

{                                     //主端點輸入描述

 

sizeof(ENDPOINT_DESCRIPTOR_STRUCT), //端點描述符的字節數大小,這裏爲7

 

ENDPOINT_DESCRIPTOR,                 //端點描述符類型編號,端點描述符爲5

 

MAIN_POINT_IN,                       //端點號,主輸入端點

 

ENDPOINT_TYPE_BULK,                  //使用的傳輸類型,批量傳輸

 

0x4000,                              //該端點支持的最大包尺寸,64字節

 

0x00                                 //中斷掃描時間,對批量傳輸無效

 

},

 

{                                     //主端點輸出描述

 

sizeof(ENDPOINT_DESCRIPTOR_STRUCT), //端點描述符的字節數大小,這裏爲7

 

ENDPOINT_DESCRIPTOR,                 //端點描述符類型編號,端點描述符爲5

 

MAIN_POINT_OUT,                      //端點號,主輸出端點

 

ENDPOINT_TYPE_BULK,                  //使用的傳輸類型,批量傳輸

 

0x4000,                              //該端點支持的最大包尺寸,64字節

 

0x00                                 //中斷掃描時間,對批量傳輸無效

 

}

 

}

 

};

 

其中關於端點的類型定義如下

 

//定義的端點類型

 

#define ENDPOINT_TYPE_CONTROL           0x00 //控制傳輸

 

#define ENDPOINT_TYPE_ISOCHRONOUS       0x01 //同步傳輸

 

#define ENDPOINT_TYPE_BULK              0x02 //批量傳輸

 

#define ENDPOINT_TYPE_INTERRUPT         0x03 //中斷傳輸

 

端點號的定義如下

 

#define MAIN_POINT_OUT           0x02   //2號輸出端點

 

#define MAIN_POINT_IN            0x82   //2號輸入端點



發佈了8 篇原創文章 · 獲贊 0 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章