分享到plurk 分享到twitter 分享到facebook

版本 c81c17bf3bd43d90dabd25044c8274bff148f1b2

embedded/USB

Changes from c81c17bf3bd43d90dabd25044c8274bff148f1b2 to current

---
title: usb
title: USB (Universal Serial Bus)
categories: USB, STM32, STM32F4, STM32F429
...

.. image:: http://upload.wikimedia.org/wikipedia/commons/thumb/f/fd/USB_Icon.svg/200px-USB_Icon.svg.png
## USB歷史簡介
早在USB出來之前,資料的傳輸主要是使用並列埠(parallel port)傳輸,如圖

![](/embedded/parallel.png)

標準 USB 2.0 介面
^^^^^^^^^^^^^^^^
早期為了想加快傳遞資料,透過此種並列線進行平行傳輸,這比起在更早之前的串列傳輸(serial port),大大的提升了傳輸的速度,如圖

![](/embedded/serial.png)

但是在使用並列埠傳輸會遇到一些問題,像是:

- 傳輸過程容易受到外面的其他訊號干擾而出錯,所以傳輸線的長度不長。
- 雖然傳輸速度加快了,但是並列埠上導線的資料傳輸的同步不好解決。
- 連接的針腳容易彎曲變形。
以上等等問題,催生了USB的誕生。

## USB規格演變
* USB 1.0  (1996)
    - Low speed : transfer rate 1.5 Mbit/s
    - Full speed : transfer rate 12Mbit/s
    - USB 1.1 才廣為使用 (1998)
    - 12Mbit/s 是用在higher speed devices 像是disk drives
    - lower 1.5Mbit/s 使用在Joystick

* USB 2.0 (2000)
    - 傳輸速度可以高達 480Mbit/s ,稱之為High Speed
    - 2000年,有了mini-A ,mini-B 
    - 2006年,提供了新的傳輸方式,USB On-The-Go
    - 2007年,有了micro USB

* USB 3.0 (2008)
    - 傳輸速度提高到5Gbit/s,稱之為SuperSpeed
    - 減少電能的消耗
    - 增加電力輸出
    - 可以跟USB 2.0相容
    - 使用higher speed bus called SuperSpeed in parallel with USB 2.0
    - full-duplex(傳輸和接收可以同時進行) in SuperSpeed ( USB 1.x , USB 2.0 為half-duplex)

* USB 3.1 (2013)
    - Update USB 3.0 to 10Gbit/s 
    - 可以向下相容USB 2.0 , USB 3.0


## 標準 USB 2.0 介面
USB是一種序列資料傳輸界面(serial interface),設計目標為隨插即用(Plug and Play,簡稱PnP)。
亦包含實體層,資料鏈結層,網路層,傳送層...應用層等等。

實體層
=======
.. image:: /271px-Types-usb_new.svg.png
.. image:: /embedded/USB/2.png
### 實體層
![](/embedded/usb/pin.png)

![](/embedded/usb/800px-USB_InSide.JPG)

USB 訊號使用標記為D+ 和D- 的雙絞線(twisted pair)傳輸,以抵消長導線的電磁干擾。
### 訊號傳輸
* 傳輸線理論
    - USB採用  lossless transmission line 的copper wire,此種線不會吸收傳輸訊號的能量
    - 訊號在傳輸線傳遞是會有延遲的,不能忽略
    - 傳輸過程都要盡量阻抗匹配,要不然會產生反射波,導致訊號錯誤
    - 如果想要每一步的傳輸都是很穩定的,就要使傳輸線每一段的阻抗值相同,如果不相同,會導致阻抗不匹配,產生反射波,干擾訊號
    - 圖示講解傳輸線理論
  
![](/embedded/transmission_1.png)

.. image:: /400px-USB_Twisted_Pair.svg.png
![](/embedded/transmission_2.png)

它們各自使用半雙工的差動訊號(Differential signal), 並利用NRZI(non-return-to-zero Inverted)的編碼方式來傳送。
![](/embedded/transmission_3.png)

![](/embedded/transmission_4.png)


* USB 訊號使用標記為D+ 和D- 的雙絞線(twisted pair)傳輸,以抵消長導線的電磁干擾。

![](/400px-USB_Twisted_Pair.svg.png)

   它們各自使用半雙工的差動訊號(Differential signal), 並利用NRZI(non-return-to-zero Inverted)的編碼方式來傳送。

* 差動訊號:訊號傳輸在兩根不同的線上,這兩個信號的振幅相等,相位相反。

.. image:: /DiffSig.png
![](/DiffSig.png)

another illustration

![](/embedded/Differential_Signaling.png)

* NRZI Code: NRZI(Non Return to Zero Invert,不歸零就反向)的編碼方式,無需同步的時脈信號也能產生同步的資料存取。NRZI的編碼規則是,當資料位元為 “1” 時不轉換,為 “0” 時再作轉換。

.. image:: /embedded/USB/3.png
![](/embedded/USB/3.png)

* J state:Idle state(閒置)

* K state:Resume state(恢復)

在NRZI編碼下,邏輯0 會造成轉換,所以接受者在接受數據的同時,根據接收到的翻轉信號不斷調整同步頻率,保證數據傳輸正確。

但是,這樣還是會有一個問題,就是雖然接受者可以主動和發送者的頻率匹配,但是兩者之間總會有誤差。

假如數據信號是1000 個邏輯1,資料就會造成長時間無法轉換,在這種情況下,即使接受者的頻率和發送者相差千分之一,就會造成把數據採樣成1001個或者999個1了。

USB 對這個問題的解決辦法,就是強制插0,也就是bit-stuffing,如果要傳輸的數據中有7 個連續的1,發送前就會在第6 個1 後面強制插入一個0,讓發送的信號強制出現翻轉,從而強制接受者進行頻率調整。
USB 對這個問題的解決辦法,就是強制插0,也就是bit-stuffing,如果要傳輸的數據中有6 個連續的1,發送前就會在第6 個1 後面強制插入一個0,讓發送的信號強制出現翻轉,從而強制接受者進行頻率調整。


* Bit-stuffing : 如下圖所示,若是原始的串列資料中含有連續6個 “1” 位元的話,就需執行位元填塞的工作。此工作如(b)所示,就在其後填塞一個 “0” 位元。但相對的在NRZI編碼的過程中,對這連續的6個 “1” 執行如圖(c)轉換過程。因此在發送端在作資料傳輸之前,需先執行位元填塞以及NRZI編碼的工作。相對的,接收端在作資料接收之前,就必需先執行NRZI解碼,然後再作位元反填塞(unBit-Stuffing)的工作。
* Bit-stuffing : 如下圖所示,若是原始的串列資料中含有連續6個 “1” 位元的話,就需執行位元填塞的工作。

.. image:: /embedded/usb/dataNRZI.jpg
* 資料傳輸示意圖
* 相對的,接收端在作資料接收之前,就必需先執行NRZI解碼,然後再作位元反填塞(Bit-destuffing)。

.. image:: /581px-USB_signal_example.svg.png
![](/embedded/bit%20stuffing.png)

* 資料傳輸流程

.. image:: /USB_SCHEMA.gif
![](/USB_SCHEMA.gif)

網路層
========
USB網路是由星型拓撲(tiered star network)所實作的,有一個 master(host) 和多個 slaves(devices) 。
### 傳輸速率
* 上述簡介中的USB傳輸速度(low speed:1.5 Mb/s、full speed 12 Mb/s、high speed 480 Mb/s)的給定,主要是依據USB規格書上的定義,這些速度可以透過pull-up    resistor來調整
- low speed

USB host 提供一個接口,如果要連接更多週邊,需要使用hub。
![](/embedded/low_speed.png)

* 一層:提供給 host (bus master)
* 六層:提供給 hubs 或 devices
* 考慮訊號傳遞衰減和延遲,網路架構最多七層,所以USB網路最多可支援127個裝置節點。
- full speed

.. image:: /embedded/usb/tiernetwork.png
![](/embedded/full_speed.png)

USB device 又可以分為:
- high speed
    - 首先電路連接方式跟full speed一樣,就在 device 跟 host 端連接時,host端會先傳送一個USB RESET signal給device端,device端接收後,接下來就是device 端跟 host 端的速度協商,如果device有支援high speed的話,就會發出chirp K signal給host端,如果host端有支援high speed,也會回應一連串交替的chirp k 和 chirp J signal回給device端,達成handshake,就可以改用high speed傳輸。
    - 另外,chirp訊號是只有支援high speed傳輸的device和host端才會有的傳輸,如果沒有支援就不會有這種訊號傳輸!
 
![](/embedded/high%20speed.png)

### 網路層
USB網路是由階梯型星型拓撲(Tiered Star Network)所實作的,有一個 Master(Host) 和多個 Slaves(Devices) 。

USB Host 提供一個接口,如果要連接更多週邊,需要使用Hub。

* 一層:提供給 Host (Bus Master)
* 六層:提供給 Hubs 或 Devices
* 考慮訊號傳遞衰減和時間限制,網路架構最多七層。
* USB網路最多可支援127個裝置節點(7 bits in Token packet = 2^7 - 1)。

![](/embedded/usb/tiernetwork.png)

USB Device 又可以分為:

* Hub : 用來連接更多裝置
* Function : 提供特殊功能給系統,例如人機裝置, 影像裝置, 儲存裝置等等。
* Compound Device: 本身擁有功能(function),也帶有一個hub,有其他裝置連接時可以作為host。
* Compound Device: 本身擁有功能(Function),也帶有一個Hub,有其他裝置連接時可以作為Host。
* Composite Device:提供超過一個功能的裝置。

USB 封包簡介
^^^^^^^^^^^
## USB 通訊模型
從下面的圖可以看到,USB Host 和 Device 是資料傳輸的重點,分別在不同的兩層。
USB是一種Polled Bus,由Host啟動(Initiates)資料傳輸,Device做出回應。

封包是組成USB傳輸的最小單位。一個 Transaction 通常由三個封包組成,但依傳輸型態而定,一個 Transaction 可能包含一個、兩個、三個封包。
* 此處的Polling(輪詢)是Host Controller來執行,當Bus需要被注意時,會發出中斷讓OS處理。

.. image:: /packet.jpg
![](/embedded/usb/comm_model.png)

.. image:: /embedded/USB/PID types.jpg
USB由幾種Protocol Layers所組成,資料藉由Pipes傳輸。

Transaction 
=============
* Stream Pipes  : Stream pipes可以被Host或者Device控制,資料的傳輸方向必須事先定義,定義為IN或或OUT。支援 Bulk Transfers, Isochronous Transfers, and Interrupt Transfers. (have no defined USB format)

Token 封包
---------------
* Message Pipes : 為Host控制來進行資料傳輸設定,允許雙向通訊。只支援 Control Transfers。(have a defined USB format)

## Endpoints
Endpoints可以被視為資料的來源或目標(Source or Sink)。一個裝置可以擁有至多16個OUT和16個IN的Endpoints

* OUT : 從Host指向Device的方向

* IN  : 指向Host的方向

每個Endpoint只能有一個傳輸方向,只有Endpoint 0 是例外。Endpoint 0 可以有IN和OUT的雙向傳輸(透過Message Pipe),用來控制裝置(Device)。


![](/transfermodel.png)


## 傳輸型態

USB 定義了四種傳輸型態:

 - 控制傳輸(Control Transfers) : 用於控制傳輸命令及狀態操作。像是設定裝置、取得裝置資訊、發送指令到裝置等。每個USB裝置都有一個Endpoint 0,USB Core就是使用他在裝置插入後進行設定。
 - 中斷傳輸(Interrupt Transfers) : 與一般常見的中斷不同,需要 host 端先詢問(Polling)才會執行。用一個固定速傳輸少量資料,像是USB鍵盤和滑鼠就是屬於這種方式。
 - 批次傳輸(Bulk Transfers):用於大量資料傳輸且需要確保資料無誤(如傳給印表機或隨身碟),沒有速度限制,若傳輸失敗就會重傳以確保正確。
 - 同時傳輸(Isochronous Transfers) : 同樣用於大量資料傳輸,但不確保資料是否到達。例如例如USB視訊裝置,使用者會期望傳輸聲音或影像的速率是穩定的,若有幾張frame遺失,沒有通過CRC資料也不會重傳。

## USB 資料連結
Transaction指USB資料的傳輸,大部分的傳輸包含了三種封包,封包是組成USB傳輸的最小單位。

一個 Transaction 通常由三個封包組成,但依傳輸型態而定,一個 Transaction 可能包含一個、兩個、三個封包。


![](/packet.jpg)

![](/embedded/USB/PID%20types.jpg)

由上面的表可以看到,PID實際上只使用到前四個 bits,後面四個bits是前面四個bits的倒數,主要是因為USB傳輸編碼是透過NRZI,這樣的話,就可以避免出現bit-stuffing

## Transaction 

Transaction指USB資料的傳輸,大部分的傳輸包含了三種封包 (Token packet, Data packet, Handshake 或稱  Status packet )。

![](/embedded/usb/pipemodel.png)

* Transaction可能是從Host傳向Device,或是從Device傳向Host。
* 傳送方向是由Token packet中指定。  
* 一般來說,目標端利用Handshake (Status packet) 來判斷本次傳輸是否成功。

## Frame 

為了確保同步,USB把時間切割成固定長度的小區間。低速和全速的時候是以 1 ms 為單位,稱為一個Frame;高速時再把一個Frame切成八等分,一個 0.125 ms 為單位,稱為microframes。

![](/embedded/usb/ums_g_hs_frames.gif)


SOF (Start-of-Frame packet) 是一種特殊的封包,他在每一個frame開始時發送。

![](/embedded/usb/startofframe.png)

## Packet
封包被視為每次傳輸的最小單位。

![](/embedded/usb/packetmodel.png)

* 封包是以同步訊號(Synchronization Pattern)為開頭。
* 接著是資料區段,順序為Big-endian。(least significant bit first)。
* 最後已EOP訊號(End of Packet)結尾,完成一個封包的傳輸,Bus回到idle的狀態。

![](/embedded/usb/dataNRZI.jpg)

### Token 封包

* 每個Transaction以Token封包做起始。
* Token封包定義裝置、Endpoint數量,傳輸的方向。
* 用PID來識別OUT、IN、SOF與SETUP處理。
* 對於OUT和SETUP處理,位址與端點欄位用來選擇接收資料的端點。
* 對於IN處理,位址與端點欄位用來選擇傳送資料的端點。
* PID 後面緊接著他的補數,是為了避免bit-stuffing

.. image:: /Token Format.jpg
SOF(Start-of-Frame)為一個特別的Token封包類型,包含目前的frame數量,主機每隔一段很小的間隔就會發出一次SOF封包,所有裝置以及hub都會收到SOF封包。對只需要時間資訊的裝置而言,只需要知道PID為SOF即可,剩餘的frame number以及CRC的資訊皆可忽略。
![](/Token%20Format.jpg)

.. image:: /SOF Packet.jpg
SOF(Start-of-Frame)為一個特別的Token封包類型,包含目前的frame的號碼(訊框號碼),主機每隔一段很小的間隔就會發出一次SOF封包,所有裝置以及hub都會收到SOF封包。對只需要時間資訊的裝置而言,只需要知道PID為SOF即可,剩餘的frame number以及CRC的資訊皆可忽略。

![](/SOF%20Packet.jpg)

PID: Packet Identifier

ADDR: Address 

ENDP: Endpoint 

CRC: Cyclic Redundancy Checks 



Data 封包
---------------
### Data 封包

Data封包包含處理此動作的資料。在low-speed裝置中,Data封包最大的資料量為8 bytes;在full-speed裝置中,Data封包最大的資料量為1023 bytes;在high-speed裝置中,Data封包最大的資料量為1024 bytes。其中 Data0 及 Data1 是兩個基本的資料封包,使用這些資料封包以提供一個機制來確定將傳送端和接收端之間的資料切換同步(data toggle synchronization)。另外在 USB2.0 當中更增加了 Data2 及 MData 資料封包,用於執行高速的即時傳輸(Isochronous Transfers)。
Data封包包含處理此動作的資料。在low-speed裝置中,Data封包最大的資料量為8 bytes;在full-speed裝置中,Data封包最大的資料量為1023 bytes;在high-speed裝置中,Data封包最大的資料量為1024 bytes以上。其中 Data0 及 Data1 是兩個基本的資料封包,使用這些資料封包以提供一個機制來確定將傳送端和接收端之間的資料切換同步(data toggle synchronization)。另外在 USB2.0 當中更增加了 Data2 及 MData 資料封包,用於執行高速的即時傳輸(Isochronous Transfers)。

.. image:: /embedded/USB/Data Packets.jpg
![](/embedded/USB/Data%20Packets.jpg)

Handshake 封包
---------------
### Handshake 封包
除了即時型傳輸(Isochronous)外,所有的傳輸都保證資料的傳遞正確,如交握(Handshake)封包回應資料是否正確的被收到,若執行處理動作中發生錯誤,處理動作將重新執行。

Handshake封包由一個PID所組成,用來表示資料傳輸的狀態,部分Handshake封包說明如下。

* ACK表示資料封包沒有bit stuff或是CRC錯誤,也就是PID欄位以及Data欄位沒有出現錯誤。

* NAK表示裝置無法從主機接收資料或是無資料可以傳輸到主機。NAK也被當作流量控制的用途來使用,表示裝置暫時無資料傳送或無法接收資料。

* STALL表示裝置無法傳送或接收資料,需要主機介入來清除延遲狀況。

.. image:: /embedded/USB/Handshake Packet.jpg
![](/embedded/USB/Handshake%20Packet.jpg)

USB OTG (On-The-Go)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#USB OTG (On-The-Go)
原先USB裝置的角色都是固定的(主機或週邊)。
USB OTG讓原本只能為週邊的裝置也能成為主機,例如讓鍵盤接上手機使用。
USB OTG讓原本只能為週邊的裝置也能成為主機(dual-role device),例如讓鍵盤接上手機使用。

.. image:: /N110128002020110128120354.jpg
![](/N110128002020110128120354.jpg)

圖中type A connector作為host裝置,用來提供電源;type B則是目標裝置,接收電源。如此,可以避免兩個供應電源的裝置相接,引發傷害裝置的情形(嚴重甚至起火)。

* Dual Role Device (OTG-DRD)

.. image:: /DRD.png
![](/embedded/DRD.png)


協定(Protocol)
===============================
## 協定(Protocol)
OTG設備使用插頭中的ID引腳來區分A/B Device。

* ID接地被稱作為A-Device,為連接時候的USB Host,A-Device始終為總線提供電力
* ID接地被稱作為A-Device,為連接時候的USB Host,A-Device始終為總線(USB bus)提供電力
* ID懸空被稱作為B-Device,為連接時候的USB Device

設備的USB Host/USB Device角色可以通過HNP切換。

Session Request Protocol (SRP, 對話請求協議)
--------------------------------------------
USB OTG與USB2.0相比,多三種新的傳輸協定。

### Attach Detection Protocol (ADP)

Host Negotiation Protocol (HNP, 主機通令協議)
--------------------------------------------
* 讓OTG device, embedded host, USB devices藉由USB bus上供電的損失來決定裝置有沒有接附,此機制會啟動兩種現象,裝置插入的基本原理表現及讓裝置能表達目前連接的狀態。
* 如何達成上述的機制:藉由週期性的量測USB port上的電容(capacitance)變化,看有沒有裝置連上;當電容的變化大到足以表示有新裝置接上USB port,A-device會供電到USB bus,準備與裝置連線,而B-device會產生SRP(session request protocol),並等待USB bus供電。

Attach Detection Protocol (ADP)
--------------------------------------------
### Session Request Protocol (SRP, 對話請求協議)
* 當兩邊連線供電機制已經啟動後,兩個溝通的device都可取得主控權;在標準的USB機制中,只允許host端進行控制。
* 此機制能夠有效控制供電的消耗,這對於靠電池供電的裝置非常重要(ex:相機,手機…)。當有週邊裝置B-device(which can be an OTG or standard USB device)對OTG, embedded hosts發送請求時,OTG and embedded hosts再對USB link供電,因為吃電池的裝置可能沒有足夠多的備用電力,沒有裝置要求連線就不供電的機制能延長電池的使用時間。

### Host Negotiation Protocol (HNP, 主機通令協議)
* 允許兩個裝置(OTG-device)交換host/peripheral的角色,交換角色時需要透過HNP。
* OTG-device可以取得資料傳輸排程的控制權,因此任何OTG-device都可透過OTG bus控制資料傳輸。
* 最新補充版本的HNP有一個概念,HNP polling,內容是說OTG device做為host端時,在互連狀態下會週期性地問peripheral端要不要變成host。

Block Diagram
==============
## Block Diagram
![](/embedded/OTG_full_speed.png)

.. image:: /USB_block_diagram.png
 * ID pin 用來辨識OTG(on-the-go)裝置是主機還是週邊
 * marco-A插頭的ID pin接地 vs marco-B插頭的ID pin懸空,用來區別主機和週邊 (marco-A為主機,marco-B為週邊) 
 * DP/DM description -- in reference manual 34.3.2 (p.1227)
 * AHB -- Advanced High-performance Bus  
 * UTMI -- USB 2.0 transceiver macrocell interface

 1. ID pin 用來辨識OTG(on-the-go)裝置是主機還是週邊
 2. marco-A插頭的ID pin接地 vs marco-B插頭的ID pin懸空,用來區別主機和週邊 (marco-A為主機,marco-B為週邊) 
 3. DP/DM description -- in reference manual 30.3.2
 4. AHB -- Advanced High-performance Bus  
 5. UTMI -- USB 2.0 transceiver macrocell interface
## USB host and device
![](/embedded/usb%20host:device%20.png)

USB host and device
======================
.. image:: /embedded/usb host:device .png
## Bus Timing/Electrical Characteristics
可以看參考資料USB 2.0 Specification的7.3.2章的內容

 
* 什麼是Host, 什麼是Device? 
![](/embedded/USB/DCEC1.png)
![](/embedded/USB/DCEC2.png)
![](/embedded/USB/DCEC3.png)

-> "The host initiates all communication on the bus, the device only responds when asked by the host."
* Table 7-8. High-speed Source Electrical Characteristics

USB Descriptors
^^^^^^^^^^^^^^^
* Table 7-9. Full-speed Source Electrical Characteristics

* Device Descriptors : 提供裝置基本資訊,例如:USB 版本、最大的 packet 大小、廠商與型號資訊。每個 USB 裝置只能 device descriptors 只能有一個。
* Table 7-10. Low-speed Source Electrical Characteristics

* Table 7-11. Hub/Repeater Electrical Characteristics

以上Table可以參閱USB 2.0 Specification的7.3.2章

## USB Descriptors

* Device Descriptors : 提供裝置基本資訊,例如:USB 版本、最大的 packet 大小、廠商與型號資訊。每個 USB 裝置只能有一個 device descriptors 。

* Configuration Descriptors : 指出 USB 裝置的供電方式、interface 數量。每個 USB 裝置可以擁有不只一個 Configure Descriptor,可視為 interface descriptor 之 header。

* Interface Descriptors : 提供介面資訊,可視為 endpint descriptor 之 header。在 configuration descriptor 中會指定該 configuration 所擁有的 interface 數量,因此 interface descriptor 可以擁有一個以上。
* Interface Descriptors : 提供介面資訊,可視為 Endpoint descriptor 之 header。在 configuration descriptor 中會指定該 configuration 所擁有的 interface 數量,因此 interface descriptor 可以擁有一個以上。

* Endpoint Descriptors : 描述 endpoint 之行為與頻寬。

* String Descriptors : 提供人類可讀的資訊。



USB Device Class
^^^^^^^^^^^^^^^^
## USB Device Class
USB 依照裝置的不同,定義許多不同的 class code ,用來聯絡 host 端與 device 端該做出什麼適當的反應,以下為幾個常見分類:

### HID Class
Human Interface Device class,HID 設備屬於人性化介面的設備,用於操作電腦,如 USB 滑鼠,USB 鍵盤,USB 觸控版,USB 軌跡球等等設備。HID 設備不一定非要是這些人性化介面裝置,只要符合HID設備級定義規範要求的都可以認為是 HID 設備。

HID Class
=========
使用 HID 設備的一個好處就是,作業系統擁有 HID 類的驅動程式,而用戶無需去開發很麻煩的驅動程式,只要直接使用 API 即可完成傳輸。所以很多簡單的 USB 設備,喜歡定義成 HID 設備,這樣就可以不用安裝驅動而直接使用。

Human Interface Device class,HID 設備屬於人機交互操作的設備,用於操作電腦,如 USB 滑鼠,USB 鍵盤,USB 觸控版,USB 軌跡球等等設備。HID 設備不一定非要是這些人機交互設備,只要符合HID設備級定義規範要求的都可以認為是 HID 設備。
### CDC Class
Communications Device Class,CDC 類是 USB 通信設備類的簡稱。CDC 類是 USB 組織定義的一類專門給各種通信設備(電信通信設備和中速網絡通信設備)使用的 USB 類別。大部分的作業系統都帶有支持 CDC 類的設備驅動軟體,可以自動識識 CDC 類的裝置,這樣不僅免去了寫專用驅動裝置的負擔,同時簡化了驅動裝置的安裝。

使用 HID 設備的一個好處就是,操作系統自帶了 HID 類的驅動程序,而用戶無需去開發很麻煩的驅動程序,只要直接使用 API 調用即可完成通信。所以很多簡單的 USB 設備,喜歡枚舉成 HID 設備,這樣就可以不用安裝驅動而直接使用。
![](/embedded/USB2CDC.jpg)

CDC Class
=========
### MSC Class
Mass Storage device Class,大容量存儲裝置類別。一種電腦和行動裝置之間的傳輸協議,它允許透過USB裝置來連接主機,使兩者之間進行檔案傳輸。

Communications Device Class,CDC 類是 USB 通信設備類的簡稱。CDC 類是 USB 組織定義的一類專門給各種通信設備(電信通信設備和中速網絡通信設備)使用的 USB 子類。大部分的作業系統都帶有支持 CDC 類的設備驅動程序,可以自動識別 CDC 類的設備,這樣不僅免去了寫專用設備驅動的負擔,同時簡化了設備驅動的安裝。
MSC 支援目前大多數的作業系統,許多舊版本的作業系統經過版本升級或者系統補丁也能支援MSC。MSC的通用性和操作簡單使他成為行動裝置上最常見的檔案系統,USB MSC 並不需要任何特定的檔案系統, 它提供了一個簡單的介面來讀寫插入的硬碟裝置。

MSC Class
=========

Mass Storage device Class,大容量存儲裝置類別。一種電腦和行動裝置之間的傳輸協議,它允許一個通用串行總線(USB)裝置來訪問主機的計算裝置,使兩者之間進行文件傳輸。
## 封包傳遞說明
* 

MSC 支持目前大多數的主流操作系統,許多舊版本的操作系統經過版本升級或者係統補丁也能實現對 MSC 的支持。MSC 的通用性和操作簡單使他成為行動裝置上最常見的文件系統,USB MSC 並不需要任何特定的文件系統, 它提供了一個簡單的界面來讀寫接口用於訪問任何硬碟驅動。
![](/embedded/eumeration.png)

傳輸型態
^^^^^^^^
*

USB 定義了四種傳輸型態:
![](/embedded/eumeration_1.png)

 - 控制傳輸(Control Transfers) :用於控制傳輸命令及狀態操作。像是設定裝置、取得裝置資訊、發送指令到裝置等。每個USB裝置都有一個'端點0'(Endpoint, EP0),USB Core就是使用他在裝置插入後進行設定。
 - 中斷傳輸(Interrupt Transfers) :與一般常見的中斷不同(名詞有點誤導),需要 host 端先詢問才會執行。用一個固定速傳輸少量資料,像是USB鍵盤和滑鼠就是屬於這種方式。
 - 批次傳輸(Bulk Transfers):用於大量資料傳輸且需要確保資料無誤(如傳給印表機或隨身碟),沒有速度限制,若傳輸失敗就會重傳以確保正確。
 - 同時傳輸(Isochronous Transfers) :同樣用於大量資料傳輸,但不確保資料是否到達。例如例如USB視訊裝置,使用者會期望傳輸聲音或影像的速率是穩定的,若有幾張frame遺失,沒有通過CRC資料也不會重傳。
*

每種型態有不同的工作流程(stage),每個 stage 會需要不同的封包類型(packet)來實現,如同下表:
![](/embedded/eumeration_2.png)

+---------------+--------------------+-----------+
| Transfer Type | Stages             | Phases    |
|               | (Transactions)     | (Packets) |
+===============+====================+===========+
| Control       | Setup              | Token     |
+---------------+--------------------+-----------+
|               |                    | Data      |
+---------------+--------------------+-----------+
|               |                    | Handshake |
+---------------+--------------------+-----------+
|               |====================|===========|
+---------------+--------------------+-----------+
|               | Data (IN or Out)   | Token     |
+---------------+--------------------+-----------+
|               |                    | Data      |
+---------------+--------------------+-----------+
|               |                    | Handshake |
+---------------+--------------------+-----------+
|               |====================|===========|
+---------------+--------------------+-----------+
|               | Status (IN or Out) | Token     |  
+---------------+--------------------+-----------+
|               |                    | Data      |
+---------------+--------------------+-----------+
|               |                    | Handshake |
+---------------+--------------------+-----------+
|===============|====================|===========|
+---------------+--------------------+-----------+
| Bulk          | Data (IN or Out)   | Token     |
+---------------+--------------------+-----------+
|               |                    | Data      |
+---------------+--------------------+-----------+
|               |                    | Handshake |
+---------------+--------------------+-----------+
|===============|====================|===========|
+---------------+--------------------+-----------+
| Interrupt     | Data (IN or Out)   | Token     |
+---------------+--------------------+-----------+
|               |                    | Data      |
+---------------+--------------------+-----------+
|               |                    | Handshake |
+---------------+--------------------+-----------+
|===============|====================|===========|
+---------------+--------------------+-----------+
| Isochronous   | Data (IN or Out)   | Token     |
+---------------+--------------------+-----------+
|               |                    | Data      |
+---------------+--------------------+-----------+

Demo 程式
^^^^^^^^^

::

  git clone https://github.com/kvzhao/USB-Demo

如果make有錯誤,請先建一個build資料夾

::

  mkdir build && make

## Demo 程式 - USB MSC HOST
程式碼
```
git clone https://github.com/iGaryGu/USB_MSC_HOST.git
```

目的
========
把STM32F4作為Host,當插入隨身碟後在裡面寫入一份文件。
make 編譯
```
make
```

步驟與現象
========
.. image:: /usb.png
* 紅燈亮起:偵測到隨身碟
* 綠燈亮起:file system mount完成
* 橘燈亮起:已打開隨身碟中的目錄
* 藍燈亮起:完成寫入簽名,並且關閉file
* 當隨身碟拔出後,所有LED燈會熄滅,結束實驗,並且在隨身碟中留下文件。
## 目的
把STM32F429作為Host,當插入隨身碟後在裡面寫入一份檔案。

.. image:: /usb_hacking.png
## 步驟與現象
* 接上隨身碟,偵測到裝置
* file system mount完成
* 打開隨身碟中的目錄
* 寫入簽名檔,並且關閉file
* 當隨身碟拔出後,會在隨身碟中留下檔案。

* `ASCII Art <http://en.wikipedia.org/wiki/ASCII_art>`_
* `Matlab image generator <http://www.mathworks.com/matlabcentral/fileexchange/4732-ascii-text-image-generator>`_
![](/usb_hacking.png)

程式說明
========
* [ASCII Art ](http://en.wikipedia.org/wiki/ASCII_art)
* [Matlab image generator ](http://www.mathworks.com/matlabcentral/fileexchange/4732-ascii-text-image-generator)

## 程式說明
* STM32提供大量的函式庫來操作USB,包跨底層的driver到提供使用者應用的API。

.. image:: /USB_Lib.png
![](/USB_Lib.png)

本實驗主要將裝置STM32F4設定為Host,而隨身碟為Device。
本實驗主要將裝置STM32F429設定為Host,而隨身碟為Device。


* Host state machine 

.. image:: /host_statemachine.png
![](/host_statemachine.png)

* HOST_IDLE : 初始化之後,USB Core會不斷輪詢(Polling)是否有USB裝置被偵測。此時VBus為了省電會關起來。
* HOST_ISSUE_CORE_RESET : 當有裝置連接時,USB為了建立BUS,會進入Reset狀態。
* HOST_DEV_ATTACHED : 當裝置連接完成,Core也偵測到了以後,會進入裝置列舉(Enumeration)的狀態。
* HOST_ENUMERATION : USB Core 會開始列舉所有 USB Device。當列舉完成後,會選擇裝置的初始狀態。(Default device configuration is selected.)
* HOST_USR_INPUT : 一個中間狀態,等待使用者有進一部的指令,若收到後開始 USB Class 的操作。
* HOST_CLASS_REQUEST : 當進入這個狀態,就由驅動程式(Class Driver)接管,處理一些初始的控制請求,像是Get_Report_Request(HID)等等,當這些 Request 正確完成後,就進入HOST_CLASS狀態。
* HOST_CLASS : 此時狀態機會呼叫與應用相關的操作(Class-related Operation),完成指定的任務。
* HOST_CTRL_XFER : 當需要傳送控制訊息(Control Request)都會進入這個狀態。
* HOST_ERROR_STATE : 無法修復的錯誤發生時將進入這個狀態,之後 Host Library將會從新初始化。

* Enumeration 

.. image:: /enumeration.png
Q & A
^^^^^ 
 Q: 如何推導出 USB 3種速度(low speed:1.5 Mb/s、full speed 12 Mb/s、high speed 480 Mb/s)的理論值?
![](/enumeration.png)

 A: 這是原本定義的各種傳輸速度主頻率。可以利用pull-up resistor來控制。
#Demo 程式 - USB HID DEVICE
程式碼
```
git clone https://github.com/iGaryGu/USB_HID_DEVICE.git
```

======
make 編譯
```
make
```

 Q: packet ID 實際上只使用到前四個 bits,為什麼後四個 bits(check field)是採用前四個 bits 的補數?
## 目的
將STM32F429當成device的角色,本實作是鍵盤的功能,只要我們連接到電腦後,按下USER BUTTON鍵,就可以送出我們定義的字母

 A: USB 採用的是 NRZI 編碼,此作法方便執行,更可避免出現 bit-stuffing。
## 步驟與現象
* 首先STM32F429先接上USB OTG線,再連接至電腦
* 此時,電腦開始跟版子做control transfer,完成配置
* 當配置成功,LED燈就會亮起
* 這個時候,我們就可以按下USER_BUTTON鍵,電腦就會接受到"WIN+R"的鍵盤指令
* 圖示

=============
 
 Q: smart phone 接上 PC 後封包傳遞順序?
![](/embedded/HID_image.png)

 A: 主機端的 USB 集線器監視著它的每個端口的信號線的電壓,當USB設備插入主機時,信號線的電壓會發生變化,此時主機知道有新設備插入了。
## 利用電腦軟體分析封包資料

 當主機檢測到設備的插入後會首選重啟這個設備,接著主機發出 Get_Port_Status 請求來驗證設備是否已經重啟,設備重啟後主機通過檢測根信號線的電壓狀態判斷設備的速度。主機發送第一次 Get_Descriptor(wValue 字段的高字節為 0x01,表示設備描述符)請求取得設備描述符,設備描述符提供了設備的多種信息,包括:設備通訊終端 0 的最大封包的大小、設備支持的配置號以及有關這個設備的其它信息、主機通過對這些信息的分析以確定接下來的通信動作。
![](/embedded/USB_analyzer.png)

 device descriptor 裡規定了設備一個或多個 configuration descriptor,主機再次或多次發出 Get_Descriptor(wValue 字段的高字節為 0x02,表示 configuration)指令來讀取這些 configuration descriptor,第一次只讀出 configuration descriptor 的前 9 個字節,其中包含了 configuration descriptor 和它的所有從屬描述符(interface descriptor、endpoint descriptor)的總長度,然後主機根據這個長度讀出設備的所有 configuration descriptor(當然包括其所有從屬描述符)。

 讀取完 configuration descriptor 後,若之間讀取的 configuration descriptor 中指定了相關 string descriptor(用來描述廠商、產品和設備序列號信息的)的索引,主機將發出若干次 Get_Descriptor(wValue 字段的高字節為 0x03,表示string descriptor)命令來獲得這些string descriptor,此時主機將會彈出窗口,展示發現新設備的信息,產商、產品描述、型號等。在主機已經從它的 descriptor 中知道了能夠知道的所有信息後,便開始為這個設備安裝驅動程序。加載了 USB 設備驅動以後,主機發送 Set_Configuration 命令請求為該設備選擇一個合適的配置。

==========

 Q: CRC的長度如何得知?

 A: token packet using 5bit CRC

      data packet using 16bit CRC

===========

參考資料
^^^^^^^

http://www.zeroplus.com.tw/E-paper/201112/images/201112-USB20ProtocolAnalyzer.pdf
![](/embedded/USB_analyzer2.png)

http://www.baiheee.com/Documents/090522/090522165226.htm
## 參考資料
[行動電化學蝕刻  ](http://blog.ntsec.edu.tw/index.php?tid=531&id=228)

http://csuftp.csu.edu.tw/~k0478/981/USB/USB_02_new.pdf
[Basic Concept of USB, Keil ](http://www.keil.com/support/man/docs/rlarm/rlarm_usb_concepts.htm)

`USB Audio Class <http://baike.baidu.com/view/7879812.htm>`_
[USB Made Simple ](http://www.usbmadesimple.co.uk/ums_3.htm)

`MSC <http://baike.baidu.com/view/66940.htm>`_
[STM32Fxx USB on-the-go Host and device library ](http://www.st.com/web/en/catalog/tools/PF257882)

http://chamberplus.myweb.hinet.net/usb.htm
[USB Audio Class ](http://baike.baidu.com/view/7879812.htm)

`USB 3.1 Specification <http://www.usb.org/developers/docs>`_
[USB OTG 中文 ](http://chamberplus.myweb.hinet.net/usb.htm)

`STM32F407xx Reference Manual<http://www.st.com/web/en/resource/technical/document/reference_manual/DM00031020.pdf>`_
[MSC ](http://baike.baidu.com/view/66940.htm)

`USB On The Go <http://www.mem.com.tw/article_content.asp?sn=1101280010>`_
[USB 3.1 Specification ](http://www.usb.org/developers/docs)

`USB in a NutShell <http://www.beyondlogic.org/usbnutshell/usb1.shtml>`_
[STM32F42xxx Reference Manual](http://www.st.com/web/en/resource/technical/document/reference_manual/DM00031020.pdf)

`USB 設備的插入檢測 <http://jienyuan.blogspot.tw>`_
[USB On The Go ](http://www.mem.com.tw/article_content.asp?sn=1101280010)

`USB 2.0 Specification <http://sdphca.ucsd.edu/Lab_Equip_Manuals/usb_20.pdf>`_
[USB in a NutShell ](http://www.beyondlogic.org/usbnutshell/usb1.shtml)
  - [〈USB in a NutShell〉中文修改版](http://www.crifan.com/files/doc/docbook/usb_basic/release/pdf/usb_basic.pdf)

`USB 1.0 Specification <http://www.ece.msstate.edu/~reese/EE3724/lectures/usb/usbspec.pdf>`_
[USB 2.0 Specification ](http://sdphca.ucsd.edu/Lab_Equip_Manuals/usb_20.pdf)