Thứ Ba, 4 tháng 12, 2018

Giao tiếp USB với vi điều khiển PIC


    Universal Serial Bus (USB) là một trong những giao  thức phổ biến nhất được sử dụng trong sản phẩm điện tử tiêu dùng hiện nay, bao gồm máy tính, máy ảnh, thiết bị GPS, máy MP3, modem, máy in, máy scan,.... Các chuẩn USB ban đầu được phát triển bởi Compaq, Microsoft, Intel, và NEC, và sau đó bởi Hewlett-Packard, Lucent và Philips. Các công ty này cuối cùng hình thành tổ chức phi lợi nhuận  USB Implementers Forum Inc. tổ chức này phát triển và công bố các thông số kỹ thuật của USB.
Chương này mô tả các nguyên tắc cơ bản của bus USB và đi tìm hiểu các ứng dụng dựa trên USB với vi điều khiển PIC. Các bus USB là một giao thức phức tạp. Một cuộc thảo luận đầy đủ về thiết kế và sử dụng của nó là vượt ra ngoài phạm vi bài nay. Trong bài này chỉ đề cập những nguyên tắc cơ bản của USB và cách kết nối giao tiếp với vi điều khiển PIC 18f4550
     USB là một giao thức nối tiếp tốc độ cao, nó có thể cung cấp điện cho các thiết bị kết nối với nó. Một bus USB hỗ trợ kết nối lên đến 127 thiết bị (giới hạn bởi các trường địa chỉ 7-bit, lưu ý rằng địa chỉ 0 không được sử dụng vì nó có một mục đích đặc biệt) được kết nối thông qua dây cáp với chiều dài lên đến ba hoặc thậm chí năm mét. Nhiều thiết bị USB có thể được kết nối với bus thông qua Hub, Hub này có thể có 4, 8, hoặc thậm chí 16 cổng. Một thiết bị có thể được cắm vào một Hub mà Hub này kết nối đến các Hub khác, và như vậy. Số lượng tối đa cho phép là sáu tầng. Theo các đặc điểm kỹ thuật, khoảng cách tối đa của một thiết bị đến máy chủ của nó là khoảng ba mươi mét, thực hiện bằng cách sử dụng 5 hub. Đây là khoảng cách dài nhất. Nếu cho khoảng cách dài hơn ta có thể dùng chuẩn truyền Ethernet.

Hình hub usb
Các đặc điểm kỹ thuật bus USB có hai phiên bản: phiên bản trước đó là  USB1.1, hỗ trợ tốc độ 11Mbps, trong khi phiên bản mới là USB 2.0, hỗ trợ tốc độ lên đến 480Mbps. Các đặc điểm kỹ thuật USB định nghĩa ba tốc độ dữ liệu:
Low speed—1.5Mb/sec (Tốc độ thấp)
Full speed—12Mb/sec  (Tốc độ đầy đủ)
High speed—480Mb/sec (Tốc độ cao)
Nguồn tối đa cho một thiết bị bên ngoài kết nối sử dụng điện áp cấp bởi cổng USB được giới hạn trong khoảng 100mA tại điện áp 5.0V.
Có hai loại đầu kết nối được sử dụng đó là kiểu A và kiểu B:
Đầu nối kiểu A                             Đầu nối kiểu B   
Chân sốTên Màu sắc
1+ 5.0 VĐỏ
2- DataTrắng
3+ DataXanh lá cây
4Ground (đất)Đen
Bảng 8.2 Quy định chân của đầu kết nối USB
Thông số kỹ thuật còn đề cập loại đầu cắm mini kiểu B, sử dụng cho các thiết bị điện sách tay chẳng hạn như camera và các thiết bị cầm tay khác. Loại đầu cắm này có thêm chân thứ 5 gọi là chân ID, mặt dù chân này không được sử dụng.
Hai dây Data + và Data -, tạo thành 1 cặp xoắn và mang tín hiệu vi sai và trạm dữ liệu kết thúc đơn

Chân sốTên Màu sắc
1+ 5.0 VĐỏ
2- DataTrắng
3+ DataXanh lá cây
4Không sử dụng-
5Ground (đất)Đen
Bảng 8.2 Quy định chân của đầu kết nối USB mini
Tín hiệu USB là lưỡng pha, và tín hiệu được gửi từ máy chủ bằng cách sử dụng kỹ thuật mã hóa dữ liệuNRZI (non-return to zero inverted). Trong kỹ thuật này, hai logic 0 kế tiếp nhau sẽ bị đảo ngược mức tín hiệu. Mức tín hiệu cho mức logic 1 là không thay đổi. Một bit 0 được "nhồi" sau mỗi sáu bit 1 liên tiếp trong dòng dữ liệu để làm dữ liệu động ( được gọi là bit nhồi vì  kéo dài dòng dữ liệu thêm một chút). Hình 8.3 cho thấy cách thức thực hiện NRZI .

Hình 8.3 Dữ liệu NRZI
Một gói dữ liệu truyền bởi máy chủ gửi đến mỗi thiết bị kết nối đến bus, truyền xuống thông qua chuỗi các Hub. Tất cả các thiết bị đều nhận được tín hiệu, nhưng chỉ có một thiết bị , 1 địa chỉ chấp nhận dữ liệu. Ngược lại, tại bất cứ thời gian nào chỉ có một thiết bị có thể truyền đến máy chủ.
Thiết bị USB kết nối đến bus có thể là thiết bị được tùy chỉnh đầy đủ, yêu cầu một trình điều khiển (driver) tùy chỉnh đầy đủ. Phân Lớp thiết bị cho phép cùng một trình điều khiển thiết bị được sử dụng cho nhiều thiết bị có chức năng tương tự.. Ví dụ , thiết bị máy in có phân lớp thiết bị là 0x07, và hầu hết máy in sử dụng kiểu driver này
Hầu hết phân lớp thiết bị thông dụng được trình bày ở bẳng 8.3. Lớp USB human interface device (HID) tạm dịch là lớp thiết bị giao diện con người là lớp được quan tâm đặc biệt, nó được sử dụng trong ví dụ ở bài này.
Một vài thuật ngữ USB thông dụng:
Endpoint (Điểm cuối): một điểm cuối là một bộ nhận hoặc truyền dữ liệu. Endpoint của thiết bị là một bộ nhớ đệm (buffer) để lưu trữ dữ liệu nhận hoặc là dữ liệu để truyền. Thiết bị phải hỗ trợ một endpoint 0, endpoint này có thể nhận và truyền dữ liệu.Một thiết bị USB giới hạn mười sáu enpoint IN (bộ đệm nhận) và mười sáu enpoint out (bộ đệm truyền).
Transaction: một transaction là truyền dữ liệu trên bus.
Pipe (Đường Ống): Một đường ống là kết nối dữ liệu logic giữa máy chủ và một điểm cuối (Enpoint).

Logical pipes: đường ống lôgic
Endpoints in the device: các endpoint trong thiết bị
Phân lớp thiết bịMiêu tảThiết bị ví dụ
0x00Để dành-
0x01USB audio device (USB thiết bị âm thanh )Sound card (card âm thanh)
0x02USB communications device ( USB Thiết bị truyền thông )Modem, fax
0x03USB human interface device ( USB Thiết bị giao diện con người)Keyboard, mouse (Bàn phím, chuột)
0x07USB printer device (USB Thiết bị in)Printer (Máy in)
0x08USB mass storage device (USB Thiết bị lưu trữ )Memory card, flash drive
0x09USB hub device ( USB Thiết bị hub)Hubs
0x0BUSB smart card reader device ( USB Thiết bị đọc thẻ thông minh)Card reader (bộ đọc thẻ nhớ)
0x0EUSB video device ( USB Thiết bị Video)Webcam, scanner
0xE0USB wireless device ( USB Thiết bị wireless)Bluetooth
8.1 Định danh tốc độ trên bus:
Tại thiết bị , chân dữ liệu D+ hoặc D- được kéo lên nguồn 3.3 V thông qua điện trở 1.5K. Khi thiết bị chạy ở tốc độ full-speed, chân D+ được kéo lên nguồn 3.3V, Khi thiết bị chạy ở tốc độ low speed chân D- được kéo lên nguồn 3.3V. Khi cả hai đường dữ liệu ở mức thấp, báo cho host rằng không có thiết bị nào được kết nối. Khi có thiết bị kết nối, khi đó đường dữ liệu D+ hoặc D- sẽ được kéo lên mức cao, nhờ đó mà host biết được có thiết bị đang được kết nối. Phụ thuộc đường dữ liệu nào được kéo lên mức cao host xác định được tốc độ truyền của thiết bị.
Thiết bị chạy ở tốc độ Full speed
Thiết bị chạy ở tốc độ Low speed
 

Trạng thái USB :
Một số trạng thái bus USB là:
Idle (trạng thái rỗi): bus ở trạng thái rỗi khi một đường dữ liệu kéo lên cao và đường dữ liệu còn lại ở mức thấp. Đây là trạng thái của đường truyền trước và sau khi truyền gói dữ liệu.
Detached (Tháo rời): Khi không có thiết bị kết nối đến bus, cả hai đường dữ liệu đều ở mức thấp

Attached (Gắn): Khi một thiết bị được kết nối đến bus, đường dữ liệu D+ hoặc D- sẽ kéo lên cao, có nghĩa là thiết bị đã được gắn.
J state (Trạng thái J): Giống như trạng thái rỗi.
K state (Trạng thái K): Ngược với trạng thái J.
SE0 (The single ended zero state): Trạng thái 0 kết thúc đơn, khi cả hai đường dữ liệu ở mức thấp.
SE1 (The single ended one state) : Trạng thái một kết thúc đơn, khi cả hai đường dữ liệu ở mức cao. SE1 là điều kiện không được phép xảy ra trên bus, nó phải không bao giờ ở trạng thái này.
Reset: Khi host muốn truyền thông với thiết bị trên bus, đầu tiên nó phải gửi một điều kiện "reset" bởi kéo cả hai đường dữ liệu xuống mức thấp ít nhất 10 ms (Trạng thái SE0).
EOP: Sự kết thúc của trạng thái gói, mà về cơ bản là một trạng thái SE0 cho 2 bit thời gian, theo sau là một trạng thái J cho 1 bit thời gian.
Keep alive: Trạng thái này đạt được bằng cách sử dụng EOP. Keep alive được gửi ít nhất mỗi một mili giây để giữ thiết bị khỏi bị tạm ngưng.
Suspend (Tạm ngưng): Được sử dụng để tiết kiệm năng lượng, tạm ngưng được thực hiện bằng cách không gửi bất cứ gì đến thiết bị trong 3 ms. Thiết bị tạm ngưng sử dụng dòng ít hơn 0.5 mA và phải nhận ra tín hiệu reset và tín hiệu resume (phục hồi).
Resume (Phục hồi)Một thiết bị tạm ngưng được đánh thức bởi bởi đảo ngược cực của tín hiệu trên đường truyền dữ liệu ít nhất 20 ms, theo sau bởi một tín hiệu EOP tốc độ thấp
Truyền thông bus USB:
         USB là một hệ thống kết nối với Host đóng vai trò ở vị trí trung tâm (Ví dụ như máy tính là host và bàn phím, chuột, máy in... là salve (tớ)), nơi host dò tìm phát hiện thiết bị gắn vào hoặc tháo ra, quản lý điều khiển dòng dữ liệu giữa host và thiết bị, có thể cung cấp nguồn cho thiết bị và nhiều hơn nữa. Mỗi thiết bị trên bus được gán một địa chỉ USB duy nhất, và thiết bị tớ không thể đưa tín hiệu trên bus cho đến khi host yêu cầu nó.
         Khi một thiết bị USB mới được cắm vào bus, host USB sử dụng địa chỉ từ 0 để hỏi thông tin cơ bản từ các thiết bị. Sau đó, host gán cho nó một địa chỉ USB duy nhất.
         Sau khi host yêu cầu và nhận được thêm các thông tin về các thiết bị, chẳng hạn như tên của thiết bị, khả năng của thiết bị , và ID thiết bị, truyền thông hai chiều trên bus khi đó có thể bắt đầu.

Packets (Gói tin)
Dữ liệu được truyền trên bus USB bên trong một gói tin. Một gói tin bắt đầu với một mô hình đồng bộ để cho phép đồng hồ thu được đồng bộ hóa với dữ liệu. Tiếp theo là dữ byte dữ liệu của gói, kết thúc với tín hiệu kết thúc gói tin.
Một byte định danh gói tin (PID) theo sau trường đồng bộ của mỗi gói tin USB. Một PID có chiều dài 4 bit, và 4 bit tiếp theo được lặp lại theo hình thức lấy bù. Có 14 giá trị PID khác nhau, nó được thể hiện trong bảng 8.4. Trong đó bao gồm một giá trị để dành và một giá trị khác được sử dụng hai lần, với ý nghĩa khác nhau.
Kiểu PIDTên PIDBits Miêu tả
TokenOUT
IN
SOF
SETUP
1110 0001
0110 1001
1010 0101
0010 1101
Host to device transaction
Device to host transaction
Start of frame
Setup command
Data (Dữ liệu)DATA0
DATA1
DATA2
MDATA
1100 0011
0100 1011
1000 0111
0000 1111
Data packet PID even
Data packet PID odd
Data packet PID high speed
Data packet PID high speed
Handshake (Bắt tay)ACK
NAK
STALL
NYET
1101 0010
0101 1010
0001 1110
1001 0110
Receiver accepts packet
Receiver does not accept packet
Stalled
No response from receiver
Special (Đặc biệt)PRE
ERR
SPLIT
PING
Reserved
0011 1100
0011 1100
0111 1000
1011 0100
1111 0000
Host preample
Split transaction error
High-speed split transaction
High-speed flow control
Reserved
 Bảng 8.4
Có bốn định dạng gói tin, dựa trên PID nào bắt đầu gói tin:  gói tin token, gói tin dữ liệu, gói tin bắt tay, và gói tin đặc biệt.
Hình 8.4 cho thấy định dạng của một gói tin token, được sử dụng cho OUT, IN, SOF (bắt đầu của khung), và SETUP. Các gói tin có chứa một địa chỉ 7-bit, 4-bit ENDP (endpoint số), một checksum CRC có độ dài 5-bit, và một EOP (kết thúc gói).

 
                              Hình 8.4 : Gói tin token
Một gói tin dữ liệu sử dụng cho giao dịch dữ liệu DATA0, DATA1, DATA2 và MDATA . Định dạng gói tin như hình 8.5 bao gồm một PID, 0-1024 byte dữ liệu, 2 byte kiểm tra CRC, và một EOP 
                            Hình 8.5 : Gói tin dữ liệu

 Hình 8.6 cho thấy định dạng của một gói tin bắt tay, được sử dụng cho ACK, NAK, STALL, và NYET. ACK được sử dụng để báo bên nhận đã nhận được một gói tin không bị lỗi. NAK được sử dụng khi thiết bị nhận không thể chấp nhận gói tin. STALL cho thấy khi endpoint bị dừng lại, và NYET được sử dụng khi không có phản hồi từ bên nhận.
 
                            Hình 8.6 : Gói tin bắt tay

8.3.2 Kiểu luồng dữ liệu
Dữ liệu có thể truyền trên bus USB theo bốn cách: truyền số lượng lớn (bulk transfer), Truyền ngắt quản (interrupt transfer), Truyền đẳng thời (isochronous transfer) và truyền kiểm soát (control transfer)
Bulks transfers được thiết kế để truyền số lượng lớn dữ liệu với đảm bảo dữ liệu truyền không có lỗi và không đảm bảo băng thông. Nếu một enpoint Out được xác định sử dụng Bulks transfers khi đó host sẽ truyền dữ liệu đến nó sử dụng OUT transaction. Tương tự, nếu một In endpoint được xác định  sử dụng bulk transfers, khi đó host sẽ truyền dữ liệu sử dụng IN transaction. Nói chung, bulk transfers được sử dụng nơi mà truyền tốc độ chậm không là vấn đề lớn. Kích thước gói tin tối đa trong một bulk transfer là 8 đến 64 gói tin tại tốc độ full speed, và 512 gói tin tại tốc độ truyền high speed (bulk transfer không cho phép tại low speed)
Interrupt transfers được sử dụng để truyền số lượng nhỏ dữ liệu với băng thông cao nơi dữ liệu phải truyền nhanh nhất có thể và không được trễ. lưu ý rằng interrupt tranfers không ảnh hưởng đến interrupts (ngắt) của hệ thống máy tính. Gói tin interrupts có kích thước từ 1 đến 8 byte tại tốc độ truyền low speed, từ 1 đến 64 byte tại full speed và lên đến 1024 byte tại high speed.
Isochronous transfers (Truyền đẳng thời) đảm bảo được băng thông, nhưng không đảm bảo lỗi của dữ liệu truyền. Đây là thể loại truyền sử dụng trong các ứng dụng chẳng hạn như truyền dữ liệu âm thanh nơi tốc độ là quan trọng nhưng có thể sai sót một vài dữ liệu. Một gói tin isochronous có thể chứa đựng 1023 bytes tại tốc độ full speed hoặc lên đến 1024 byte tại high speed (isochronous tranfer không được hỗ trợ tại low speed).
Control transfer là loại truyền dữu liệu hai chiều, sử dụng cả hai IN endpoint và out endpoint. control tranfers thường được sử dụng cho cấu hình khởi tạo thiết bị bởi host . Kích thước gói tin tối đa là 8 byte tại tốc độ thấp, 8 đến 64 byte tại tốc độ full speed , và 64 byte tại tốc độ high speed. Một control tranfer được thực thi theo ba giai đoạn SETUP (thiết lập), DATA (dữ liệu), và STATUS (trạng thái).

8.3.3 Qúa trình liệt kê (Enumeration):
Khi một thiết bị kết nối đến bus USB, nó được nhận biết bởi host thông qua một quá trình gọi là enumeration. Các bước của enumeration là:
- Khi một thiết bị được kết nối đến bus USB, host nhận thức được thiết bị bởi một trong các đường dữ liệu (D+ hoặc D-) được kéo lên mức cao.
- Host gửi đến thiết bị một tín hiệu reset để đặt thiết bị vào trạng thái biết đến (known state) . Thiết bị reset phản hồi với địa chỉ 0.
- Host gửi một yêu cầu đến đến thiết bị tại địa chỉ 0 để tìm kích thước gói tin tối đa bởi sử dụng lệnh Get Descriptor.
- Thiết bị hồi đáp bởi gửi một phần bộ miêu tả thiết bị.
- Host gửi tín hiệu reset lần nữa.
- Host gán cho thiết bị một địa chỉ duy nhất và gửi một yêu cầu thiết lập địa chỉ đến thiết bị. Sau khi yêu cầu đã hoàn tất, thiết bị thừa nhận địa chỉ mới này. Tại thời điểm này host được giải phóng để reset các thiết bị khác mới gắn lên bus .
- Host gửi một yêu cầu Get Device Descriptor để nhận bộ miêu tả thiết bị đầy đủ, thu thập thông tin như nhà sản xuất, loại thiết bị, và kích thước gói tin control tối đa
- Host gửi một yêu cầu Get Configuration Descriptors để nhận dữ liệu cấu hình thiết bị chẳng hạn như nguồn yêu cầu và thể loại và số giao diện hỗ trợ 
- Host có thể yêu cầu bất kỳ mô tả thêm từ thiết bị .
Các giao tiếp ban đầu giữa host và thiết bị được thực hiện bằng cách sử dụng kiểu luồng dữ liệu Control transfer.
Ban đầu, thiết bị được cấp địa chỉ nhưng ở trạng thái chưa cấu hình. Sau khi host thu thập đủ thông tin về thiết bị, nó nạp trình điều khiển thiết bị (driver) phù hợp với cấu hình thiết bị bởi gửi đến thiết bị một yêu cầu Set Configuration. tại điểm này thiết bị đã được cấu hình và giao dịch gửi nhận dữ liệu có thể bắt đầu
8.4 Mô tả (Descriptor):
Tất cả các thiết bị USB có một hệ thống phân cấp các mô tả mô tả tính năng khác nhau của thiết bị: ID nhà sản xuất, phiên bản của thiết bị, phiên bản của USB nó hỗ trợ, thiết bị là gì, yêu cầu nguồn của thiết bị, số lượng và loại enpoints , và vân vân.
Các mô tả USB phổ biến nhất là:
Device descriptors (Mô tả thiết bị )
Configuration descriptors (mô tả cấu hình)
Interface descriptors ( Mô tả giao diện)
HID descriptors (mô tả HID)
Endpoint descriptors ( mô tả Endpoint)
Các mô tả là một cấu trúc phân cấp như trong hình 8.7. Ở phía trên của hệ thống phân cấp, chúng ta có các mô tả thiết bị, sau đó mô tả các cấu hình, tiếp theo là các mô tả giao diện, và cuối cùng là mô tả Endpoint. Bộ mô tả HID luôn đi theo các mô tả giao diện khi giao diện thuộc về lớp HID.
Tất cả các mô tả có một định dạng phổ biến. Các byte đầu tiên (bLength) quy định rõ chiều dài của mô tả, trong khi các byte thứ hai (bDescriptorType) chỉ ra các loại mô tả.
Hình  8.7: Phân cấp các mô tả USB

 8.4.1 Mô tả thiết bị (device descriptor)
Miêu tả thiết bị là thông tin thiết lập mức cao nhất đọc từ thiết bị  và đây là bộ mô tả đầu tiên mà host đọc từ thiết bị. 
Thiết bị USB chỉ có một mô tả thiết bị, khi đó mô tả thiết bị đại diện cho toàn bộ thiết bị. Nó cung cấp những thông tin cơ bản nhất chẳng hạn như nhà sản xuất, số serial, số sản phẩm , phân lớp thiết bị, và số của cấu hình. Bảng 8.5 mô tả định dạng của mô tả thiết bị với ý nghĩa của các trường .
bLength là độ dài của mô tả thiết bị.
bDescriptorType là kiểu của mô tả., và là hằng số 0x01
bcdUSB là phiên bảng cao nhất của USB mà thiết bị hỗ trợ được biễu diễn theo định dạng BCD. Theo dạng 0JJMM với JJ là số phiên bảng chính, M là số phiên bảng thứ và N là số phiên bảng thứ lẻ. Ví dụ , USB 1.1 được biểu diễn là 00110. 
bDeviceClass, bDeviceSubClass, and bDeviceProtocol được chỉ định bởi tổ chức USB và được sử dụng bởi hệ thống để tìm một phân lớp trình điều khiển cho các thiết bị.
bMaxPacketSize0 là kích thước gói lớn nhất nhận và truyền của endpoint 0.
idVendor được chỉ định bởi tổ chức USB và là ID của nhà cung cấp.
idProduct được chỉ định bởi nhà sản xuất và là ID của sản phẩm.
bcdDevice là số phát hành thiết bị và có định dạng giống như bcdUSB. Các nhà sản xuất sẽ gán giá trị này. Host có thể sử dụng giá trị này để quyết định nạp trình điều khiển .
iManufacturer, iProduct, và iSerialNumber là chi tiết về nhà sản xuất, sản phẩm và số serial của sản phẩm. Những trường này không bắt buộc và có thể set đến zero.
bNumConfigurations  là số cấu hình thiết bị hỗ trợ.
bMaxPacketSize0. Kích thước gói tin tối đa của endpoint 0. Host sử dụng thông tin này trong các yêu cầu tiếp theo. Với thiết bị low speed , giá trị này là 8. Thiết bị full speed , giá trị có thể là 8, 16, 32 hoặc 64. High speed giá trị này là 64
Bảng 8.6 là ví dụ của bộ mô tả thiết bị (device descriptor) của thiết bị chuột. Chiều dài của mô tả là 18 byte (bLength = 18), và kiểu mô tả là 001 (bDescriptorType= 0 01). thiết bị hỗ trợ USB 1.1 (bcdUSB = 0 0110). bDeviceClass, bDeviceSubClass, và bDeviceProtocol được thiết lập bằng 0 để chỉ rằng thông tin lớp ở trong bộ miêu tả giao diện (interface descriptor). bMaxPacketSize0 được thiết lập bằng 8 để chỉ rằng kích thươc gói tin tối đa mà enpoint0 nhận và truyền là 8 byte, ba byte tiếp theo xác định ID nhà cung cấp , ID sản phẩm và số phiên bảng thiết bị. Ba byte tiếp theo chỉ mục trỏ đến chuổi thông tin về nhà sản xuất, sản phẩm, và số serial. Cuối cùng, chúng tôi tôi nhận thấy rằng thiết bị chuột chỉ có một cấu hình (bNumConfigurations = 1).

Offset Các Trường Giá trịMiêu tả
0bLength18 Kích thước là 18
1bDescriptorType0x01 Kiểu mô tả
2bcdUSB0x0110 Hỗ trợ USB 1.1
4bDeviceClass0x00 Thông tin lớp trong mô tả giao diện
5bDeviceSubClass0x00 Thông tin lớp trong mô tả giao diện
6bDeviceProtocol0x00 Thông tin lớp trong mô tả giao diện
7bMaxPacketSize08 Kích thước gói tin tối đa
8idVendor0x02A XYZ Co Ltd.
10idProduct0x1001 chuột
12bcdDevice0x0011 Số phát hành thiết bị
14iManufacturer0x20Chỉ mục trỏ đến chuổi thông tin về nhà sản xuất
15iProduct0x21 Chỉ mục trỏ đến chuổi thông tin về sản phẩm
16iSerialNumber0x22 Chỉ mục trỏ đến chuổi serial
17bNumConfigurations1 Số cấu hình có thể có
Bảng 8.6 là ví dụ của bộ mô tả thiết bị (device descriptor) của thiết bị chuột

Packets (Gói tin)
Dữ liệu được truyền trên bus USB bên trong một gói tin. Một gói tin bắt đầu với một mô hình đồng bộ để cho phép đồng hồ thu được đồng bộ hóa với dữ liệu. Tiếp theo là dữ byte dữ liệu của gói, kết thúc với tín hiệu kết thúc gói tin.
Một byte định danh gói tin (PID) theo sau trường đồng bộ của mỗi gói tin USB. Một PID có chiều dài 4 bit, và 4 bit tiếp theo được lặp lại theo hình thức lấy bù. Có 14 giá trị PID khác nhau, nó được thể hiện trong bảng 8.4. Trong đó bao gồm một giá trị để dành và một giá trị khác được sử dụng hai lần, với ý nghĩa khác nhau.
Kiểu PIDTên PIDBits Miêu tả
TokenOUT
IN
SOF
SETUP
1110 0001
0110 1001
1010 0101
0010 1101
Host to device transaction
Device to host transaction
Start of frame
Setup command
Data (Dữ liệu)DATA0
DATA1
DATA2
MDATA
1100 0011
0100 1011
1000 0111
0000 1111
Data packet PID even
Data packet PID odd
Data packet PID high speed
Data packet PID high speed
Handshake (Bắt tay)ACK
NAK
STALL
NYET
1101 0010
0101 1010
0001 1110
1001 0110
Receiver accepts packet
Receiver does not accept packet
Stalled
No response from receiver
Special (Đặc biệt)PRE
ERR
SPLIT
PING
Reserved
0011 1100
0011 1100
0111 1000
1011 0100
1111 0000
Host preample
Split transaction error
High-speed split transaction
High-speed flow control
Reserved
 Bảng 8.4
Có bốn định dạng gói tin, dựa trên PID nào bắt đầu gói tin:  gói tin token, gói tin dữ liệu, gói tin bắt tay, và gói tin đặc biệt.
Hình 8.4 cho thấy định dạng của một gói tin token, được sử dụng cho OUT, IN, SOF (bắt đầu của khung), và SETUP. Các gói tin có chứa một địa chỉ 7-bit, 4-bit ENDP (endpoint số), một checksum CRC có độ dài 5-bit, và một EOP (kết thúc gói).

 
                              Hình 8.4 : Gói tin token
Một gói tin dữ liệu sử dụng cho giao dịch dữ liệu DATA0, DATA1, DATA2 và MDATA . Định dạng gói tin như hình 8.5 bao gồm một PID, 0-1024 byte dữ liệu, 2 byte kiểm tra CRC, và một EOP 
                            Hình 8.5 : Gói tin dữ liệu

 Hình 8.6 cho thấy định dạng của một gói tin bắt tay, được sử dụng cho ACK, NAK, STALL, và NYET. ACK được sử dụng để báo bên nhận đã nhận được một gói tin không bị lỗi. NAK được sử dụng khi thiết bị nhận không thể chấp nhận gói tin. STALL cho thấy khi endpoint bị dừng lại, và NYET được sử dụng khi không có phản hồi từ bên nhận.
 
                            Hình 8.6 : Gói tin bắt tay

8.3.2 Kiểu luồng dữ liệu
Dữ liệu có thể truyền trên bus USB theo bốn cách: truyền số lượng lớn (bulk transfer), Truyền ngắt quản (interrupt transfer), Truyền đẳng thời (isochronous transfer) và truyền kiểm soát (control transfer)
Bulks transfers được thiết kế để truyền số lượng lớn dữ liệu với đảm bảo dữ liệu truyền không có lỗi và không đảm bảo băng thông. Nếu một enpoint Out được xác định sử dụng Bulks transfers khi đó host sẽ truyền dữ liệu đến nó sử dụng OUT transaction. Tương tự, nếu một In endpoint được xác định  sử dụng bulk transfers, khi đó host sẽ truyền dữ liệu sử dụng IN transaction. Nói chung, bulk transfers được sử dụng nơi mà truyền tốc độ chậm không là vấn đề lớn. Kích thước gói tin tối đa trong một bulk transfer là 8 đến 64 gói tin tại tốc độ full speed, và 512 gói tin tại tốc độ truyền high speed (bulk transfer không cho phép tại low speed)
Interrupt transfers được sử dụng để truyền số lượng nhỏ dữ liệu với băng thông cao nơi dữ liệu phải truyền nhanh nhất có thể và không được trễ. lưu ý rằng interrupt tranfers không ảnh hưởng đến interrupts (ngắt) của hệ thống máy tính. Gói tin interrupts có kích thước từ 1 đến 8 byte tại tốc độ truyền low speed, từ 1 đến 64 byte tại full speed và lên đến 1024 byte tại high speed.
Isochronous transfers (Truyền đẳng thời) đảm bảo được băng thông, nhưng không đảm bảo lỗi của dữ liệu truyền. Đây là thể loại truyền sử dụng trong các ứng dụng chẳng hạn như truyền dữ liệu âm thanh nơi tốc độ là quan trọng nhưng có thể sai sót một vài dữ liệu. Một gói tin isochronous có thể chứa đựng 1023 bytes tại tốc độ full speed hoặc lên đến 1024 byte tại high speed (isochronous tranfer không được hỗ trợ tại low speed).
Control transfer là loại truyền dữu liệu hai chiều, sử dụng cả hai IN endpoint và out endpoint. control tranfers thường được sử dụng cho cấu hình khởi tạo thiết bị bởi host . Kích thước gói tin tối đa là 8 byte tại tốc độ thấp, 8 đến 64 byte tại tốc độ full speed , và 64 byte tại tốc độ high speed. Một control tranfer được thực thi theo ba giai đoạn SETUP (thiết lập), DATA (dữ liệu), và STATUS (trạng thái).

8.3.3 Qúa trình liệt kê (Enumeration):
Khi một thiết bị kết nối đến bus USB, nó được nhận biết bởi host thông qua một quá trình gọi là enumeration. Các bước của enumeration là:
- Khi một thiết bị được kết nối đến bus USB, host nhận thức được thiết bị bởi một trong các đường dữ liệu (D+ hoặc D-) được kéo lên mức cao.
- Host gửi đến thiết bị một tín hiệu reset để đặt thiết bị vào trạng thái biết đến (known state) . Thiết bị reset phản hồi với địa chỉ 0.
- Host gửi một yêu cầu đến đến thiết bị tại địa chỉ 0 để tìm kích thước gói tin tối đa bởi sử dụng lệnh Get Descriptor.
- Thiết bị hồi đáp bởi gửi một phần bộ miêu tả thiết bị.
- Host gửi tín hiệu reset lần nữa.
- Host gán cho thiết bị một địa chỉ duy nhất và gửi một yêu cầu thiết lập địa chỉ đến thiết bị. Sau khi yêu cầu đã hoàn tất, thiết bị thừa nhận địa chỉ mới này. Tại thời điểm này host được giải phóng để reset các thiết bị khác mới gắn lên bus .
- Host gửi một yêu cầu Get Device Descriptor để nhận bộ miêu tả thiết bị đầy đủ, thu thập thông tin như nhà sản xuất, loại thiết bị, và kích thước gói tin control tối đa
- Host gửi một yêu cầu Get Configuration Descriptors để nhận dữ liệu cấu hình thiết bị chẳng hạn như nguồn yêu cầu và thể loại và số giao diện hỗ trợ 
- Host có thể yêu cầu bất kỳ mô tả thêm từ thiết bị .
Các giao tiếp ban đầu giữa host và thiết bị được thực hiện bằng cách sử dụng kiểu luồng dữ liệu Control transfer.
Ban đầu, thiết bị được cấp địa chỉ nhưng ở trạng thái chưa cấu hình. Sau khi host thu thập đủ thông tin về thiết bị, nó nạp trình điều khiển thiết bị (driver) phù hợp với cấu hình thiết bị bởi gửi đến thiết bị một yêu cầu Set Configuration. tại điểm này thiết bị đã được cấu hình và giao dịch gửi nhận dữ liệu có thể bắt đầu
8.4 Mô tả (Descriptor):
Tất cả các thiết bị USB có một hệ thống phân cấp các mô tả mô tả tính năng khác nhau của thiết bị: ID nhà sản xuất, phiên bản của thiết bị, phiên bản của USB nó hỗ trợ, thiết bị là gì, yêu cầu nguồn của thiết bị, số lượng và loại enpoints , và vân vân.
Các mô tả USB phổ biến nhất là:
Device descriptors (Mô tả thiết bị )
Configuration descriptors (mô tả cấu hình)
Interface descriptors ( Mô tả giao diện)
HID descriptors (mô tả HID)
Endpoint descriptors ( mô tả Endpoint)
Các mô tả là một cấu trúc phân cấp như trong hình 8.7. Ở phía trên của hệ thống phân cấp, chúng ta có các mô tả thiết bị, sau đó mô tả các cấu hình, tiếp theo là các mô tả giao diện, và cuối cùng là mô tả Endpoint. Bộ mô tả HID luôn đi theo các mô tả giao diện khi giao diện thuộc về lớp HID.
Tất cả các mô tả có một định dạng phổ biến. Các byte đầu tiên (bLength) quy định rõ chiều dài của mô tả, trong khi các byte thứ hai (bDescriptorType) chỉ ra các loại mô tả.

Hình  8.7: Phân cấp các mô tả USB

 8.4.1 Mô tả thiết bị (device descriptor)
Miêu tả thiết bị là thông tin thiết lập mức cao nhất đọc từ thiết bị  và đây là bộ mô tả đầu tiên mà host đọc từ thiết bị. 
Thiết bị USB chỉ có một mô tả thiết bị, khi đó mô tả thiết bị đại diện cho toàn bộ thiết bị. Nó cung cấp những thông tin cơ bản nhất chẳng hạn như nhà sản xuất, số serial, số sản phẩm , phân lớp thiết bị, và số của cấu hình. Bảng 8.5 mô tả định dạng của mô tả thiết bị với ý nghĩa của các trường .
bLength là độ dài của mô tả thiết bị.
bDescriptorType là kiểu của mô tả., và là hằng số 0x01
bcdUSB là phiên bảng cao nhất của USB mà thiết bị hỗ trợ được biễu diễn theo định dạng BCD. Theo dạng 0JJMM với JJ là số phiên bảng chính, M là số phiên bảng thứ và N là số phiên bảng thứ lẻ. Ví dụ , USB 1.1 được biểu diễn là 00110. 
bDeviceClass, bDeviceSubClass, and bDeviceProtocol được chỉ định bởi tổ chức USB và được sử dụng bởi hệ thống để tìm một phân lớp trình điều khiển cho các thiết bị.
bMaxPacketSize0 là kích thước gói lớn nhất nhận và truyền của endpoint 0.
idVendor được chỉ định bởi tổ chức USB và là ID của nhà cung cấp.
idProduct được chỉ định bởi nhà sản xuất và là ID của sản phẩm.
bcdDevice là số phát hành thiết bị và có định dạng giống như bcdUSB. Các nhà sản xuất sẽ gán giá trị này. Host có thể sử dụng giá trị này để quyết định nạp trình điều khiển .
iManufacturer, iProduct, và iSerialNumber là chi tiết về nhà sản xuất, sản phẩm và số serial của sản phẩm. Những trường này không bắt buộc và có thể set đến zero.
bNumConfigurations  là số cấu hình thiết bị hỗ trợ.
bMaxPacketSize0. Kích thước gói tin tối đa của endpoint 0. Host sử dụng thông tin này trong các yêu cầu tiếp theo. Với thiết bị low speed , giá trị này là 8. Thiết bị full speed , giá trị có thể là 8, 16, 32 hoặc 64. High speed giá trị này là 64
Bảng 8.6 là ví dụ của bộ mô tả thiết bị (device descriptor) của thiết bị chuột. Chiều dài của mô tả là 18 byte (bLength = 18), và kiểu mô tả là 001 (bDescriptorType= 0 01). thiết bị hỗ trợ USB 1.1 (bcdUSB = 0 0110). bDeviceClass, bDeviceSubClass, và bDeviceProtocol được thiết lập bằng 0 để chỉ rằng thông tin lớp ở trong bộ miêu tả giao diện (interface descriptor). bMaxPacketSize0 được thiết lập bằng 8 để chỉ rằng kích thươc gói tin tối đa mà enpoint0 nhận và truyền là 8 byte, ba byte tiếp theo xác định ID nhà cung cấp , ID sản phẩm và số phiên bảng thiết bị. Ba byte tiếp theo chỉ mục trỏ đến chuổi thông tin về nhà sản xuất, sản phẩm, và số serial. Cuối cùng, chúng tôi tôi nhận thấy rằng thiết bị chuột chỉ có một cấu hình (bNumConfigurations = 1).

Offset Các Trường Giá trịMiêu tả
0bLength18 Kích thước là 18
1bDescriptorType0x01 Kiểu mô tả
2bcdUSB0x0110 Hỗ trợ USB 1.1
4bDeviceClass0x00 Thông tin lớp trong mô tả giao diện
5bDeviceSubClass0x00 Thông tin lớp trong mô tả giao diện
6bDeviceProtocol0x00 Thông tin lớp trong mô tả giao diện
7bMaxPacketSize08 Kích thước gói tin tối đa
8idVendor0x02A XYZ Co Ltd.
10idProduct0x1001 chuột
12bcdDevice0x0011 Số phát hành thiết bị
14iManufacturer0x20Chỉ mục trỏ đến chuổi thông tin về nhà sản xuất
15iProduct0x21 Chỉ mục trỏ đến chuổi thông tin về sản phẩm
16iSerialNumber0x22 Chỉ mục trỏ đến chuổi serial
17bNumConfigurations1 Số cấu hình có thể có
Bảng 8.6 là ví dụ của bộ mô tả thiết bị (device descriptor) của thiết bị chuột
8.4.2 Bộ mô tả cấu hình:
Bộ mô tả cấu hình cung cấp các thông tin về nguồn điện yêu cầu của thiết bị và nó hỗ trợ bao nhiêu giao diện khác nhau. Có thể có nhiều hơn một bộ cấu hình cho một thiết bị.
Bảng 8.7 cho ta thấy định dạng của bộ mô tả cấu hình và ý nghĩa của mỗi trường
bLength là chiều dài của bộ mô tả 
bDescriptorType là kiểu mô tả , là hằng số 0x002
wTotalLength  kích thước tổng cộng của bộ các mô tả (ví dụ, tổng số mô tả cấu hình + bộ mô tảgiao diện  + bộ mô tả HID + bộ mô tả endpoint). Khi bộ mô tả cấu hình được đọc bởi host, nó sẽ trả về các toàn bộ thông tin cấu hình, trong đó bao gồm tất cả các mô tả giao diện và mô tả endpoint.
bNumInterfaces là số giao diện hiện có cấu hình này
bConfigurationValue được sử dụng bởi các máy chủ (trong lệnh SetConfiguration) để chọn cấu hình.
iConfiguration là chỉ số trỏ đến chuỗi bộ mô tả miêu tả cấu hình theo định dạng có thể đọc.
bmAttributes mô tả các yêu cầu điện của thiết bịNếu thiết bị sử dụng điện trên bus USB, khi đó bit D7 được set (dùng cho phiên bảng USB 1.0) đối với các phiên bảng hiện nay thì điều này thực hiện thông qua bMaxPower. Bit D6 được set nếu nó dùng nguồn điện cấp từ bên ngoài . Bit D7 và D0-D4 là các bit để dành, bit D5 dùng cho remote wakeup, nó cho phép thiết bị đánh thức host khi host đang ở chế độ ngủ (suspend)
bMaxPower xác định công suất nguồn tối đa thiết bị tiêu thụ trên bus với đơn vị 2mA .
OffsetFieldSizeDescription
0bLength1Kích thước bộ miêu tả được tín đơn vị là byte
1bDescriptorType1Device descriptor (0 02)
2wTotalLength2Total bytes returned
4bNumInterfaces1Số giao diện
5bConfigurationValue1Value used to select configuration
6iConfiguration1Index describing configuration string
7bmAttributes1Power supply attributes
8bMaxPower2Max power consumption in 2mA

Bảng 8.8 ví dụ bộ mô tả cấu hình của thiết bị chuột. Chiều dài của bộ mô tả là 9 byte (bLength=9), và kiểu mô tả là 002  (bDescriptorType=0 02). Kích thước tổng của bộ mô tả là 34 (wTotalLength=34). Số giao diện cho thiết bị chuột là 1 (bNumInterfaces=1). Lệnh SetConfiguration của host phải sử dụng giá trị 1 như là tham số trong SetConfiguration() để chọn cấu hình. Không có chuỗi mô tả cấu hình này. bmAttributesis được thiết lập đến 040 để chỉ rằng thiết bị self-powered. bMaxPower được thiết lập bằng 10 để chỉ rằng dòng tối đa cho thiết bị là 20mA .

OffsetFieldGiá trịDescription
0bLength9Kích tước bộ miêu tả là 9 byte
1bDescriptorType0x02Device descriptor (0 x02)
2wTotalLength3434 byte
4bNumInterfaces1Số giao diện là 1
5bConfigurationValue1Giá trị được sử dụng để lựa chọn cấu hình
6iConfiguration0x2AIndex describing configuration string
7bmAttributes0x40Power supply attributes
8bMaxPower10tiêu thụ nguồn tối đa là 20mA
8.4.3 Bộ mô tả giao diện
Bộ mô tả giao diện chỉ định lớp của giao diện và số endpoint được sử dụng. Có thể có nhiều hơn một giao diện.
Bảng 8.9 là định dạng của mô tả giao diện với ý nghĩa của từng trường
OffsetTrườngKích cỡMiêu tả
0bLength 1 Tính theo byte
1bDescriptorType 1 Device descriptor (0 x04)
2bInterfaceNumber 1 số giao diện
3 bAlternateSetting 1 Value to select alternate setting
4 bNumEndpoints 1 Số endpoints
5 bInterfaceClass 1 Mã lớp
6 bInterfaceSubClass 1 Mã lớp con
7 bInterfaceProtocol 1 Mã giao thức
8 iInterface 1 Index of string descriptor to interface
 Bảng 8.9: Bộ miêu tả giao diện
bLength là chiều dài của bộ mô tả.
bDescriptorType là kiểu mô tả.
bInterfaceNumber chỉ ra các chỉ số của các mô tả giao diện.
bAlternateSetting có thể được sử dụng để xác định các giao diện khác mà có thể được lựa chọn bởi máy chủ sử dụng lệnh Set Interface.
bNumEndpoints chỉ ra số lượng các endpoint được sử dụng bởi giao diện.
bInterfaceClass quy định cụ thể các mã lớp thiết bị (do tổ chức USB cấp).
bInterfaceSubClass chỉ định mã thiết bị phân lớp con (do tổ chức USB cấp).
bInterfaceProtocol chỉ định mã giao thức thiết bị (cấp bởi tổ chức USB) 
iInterface là chỉ số trỏ đến một chuỗi miêu tả của giao diện.
Bảng 8.10 là ví dụ của bộ mô tả giao diện cho thiết bị chuột. Chiều dài bộ mô tả là 9 byte (blength=9) và kiểu mô tả là 0x04 (bDescriptorType = 0 04). Số giao diện sử dụng để tham chiếu giao diện này là 1  (bInterfaceNumber=1).

OffsetTrườngGiá trị Miêu tả
0bLength 9 Tính theo byte
1bDescriptorType 0x04 Device descriptor (0 x04)
2bInterfaceNumber 0 số giao diện
3 bAlternateSetting 0 Giá trị để chọn thiết lập thay thế
4 bNumEndpoints 1 Số endpoints
5 bInterfaceClass 0x03 Mã lớp là 0x03
6 bInterfaceSubClass 0x02 Mã lớp con là 0x02 
7 bInterfaceProtocol 0x02 Mã giao thức là 0x02
8 iInterface 0Chỉ số của chuỗi mô tả giao diện
bAlternateSetting được thiết lập bằng 0 ( ví dụ, không có giao diện thay thế). Số enpoint sử dụng bởi giao diện này là 1 (không kể endpoint 0), và đây là endpoint sử dụng cho chuột để gửi dữ liệu. Mã lớp thiết bị là 0x03 (bInterfaceClass =  0 x03). Đây là kiểu lớp HID  (human interface device) . Lớp con giao diện là 0x02. Giao thức thiết bị là 0x02 (chuột). Không có chuỗi mô tả trong giao diện này interface (iInterface = 0).
8.4.4 Bộ mô tả HID.
Bộ mô tả HID luôn luôn theo sau bộ mô tả giao diện khi bộ giao diện thuộc về lớp HID. Bảng 8.11 là định dạng của bộ mô tả HID.
bLength là chiều dài của bộ mô tả của thiết bị.
bDescriptorType là kiểu bộ mô tả của thiết bị .
bcdHID là phân lớp chỉ định HID.
bCountryCodespecifies Chỉ định mã quốc gia.
bNumDescriptors quy định cụ thể nếu có bất kỳ mô tả bổ sung liên quan với lớp này.
bDescriptorType  loại mô tả bổ sung quy định tại bNumDescriptors.
wDescriptorLeng Là chiều dài của bộ mô tả thêm tính bằng byte 

OffsetTrườngKích thướcMô tả
0bLength1Kích thước bộ mô tả tính theo đơn vị byte
1bDescriptorType1HID (0x21)
2bcdHID2Lớp HID
4bCountryCode1
Mã phụ thuộc từng quốc gia riêng
5bNumDescriptors1Số mô tả thêm
6bDescriptorType1
Loại mô tả thêm
7wDescriptorLength2Chiều dài của bộ mô tả thêm
Bảng 8.12 là một ví dụ bộ mô tả HID cho một thiết bị chuộtChiều dài của mô tả  9 byte (bLength = 9),  loại mô tả  0x21 (bDescriptorType = 0x21). Lớp HID được thiết lập là 1.1 (bcdHID=0x0110). Mã quốc gia được thiết lập = 0.
OffsetFieldGiá trịMô tả
0bLength9Bộ mô tả có kích thước là 9 byte
1bDescriptorType0 x 21HID (0x21)
2bcdHID0 x 0110Phân lớp phiên bảng 1.1
4bCountryCode0Mã không phụ thuộc vào quốc gia riêng nào
5bNumDescriptors1Số bộ mô tả thêm
6bDescriptorTypeREPORTKiểu bộ mô tả thêm
7wDescriptorLength5Chiều dài của bộ mô tả thêm

8.4.5 Bộ mô tả Endpoint (Endpoint Descriptor)
Bộ mô tả endpoint chỉ định thể loại truyền, hướng truyền, thời gian hỏi vòng (polling interval) và kích thước tối đa của gói tin cho mỗi endpoint. Endpoint 0 (zero) là endpoint mặc định , nó là endpoint control và không có mô tả.
Bảng 8.13 cho ta thấy định dạng của bộ mô tả endpoint
bLength : là chiều dài của bộ mô tả
bDescriptorType : là thể loại bộ mô tả
bEndpointAddress : là địa chỉ của endpoint
- Bit 3...0: Endpoint số- Bit 6...4: Để dành, thiết lập bằng 0- Bit 7: Hướng truyền, Ngoại trừ control endpoints.
+ 0 = OUT endpoint+ 1 = IN endpoint

bmAttributes : quy định cụ thể những loại endpoint của nó.
- Bits 1..0: Kiểu truyền
+ 00 = Control+ 01 = Isochronous+ 10 = Bulk+ 11 = Interrupt
Đối với endpoint không đẳng thời (non-isochronous), bit 5..2 phải được thiết lập bằng 0. Đối với endpoint đẳng thời (isochronous), chúng được định nghĩa như sau 
- Bits 3..2: Kiểu đồng bộ
+ 00 = No Synchronization+ 01 = Asynchronous+ 10 = Adaptive+ 11 = Synchronous
- Bits 5..4: Kiểu sử dụng
+ 00 = Data+ 01 = Feedback+ 10 = Implicit feedback+ 11 = Reserved
Tất cả các bit khác là để dành và phải thiết lập bằng 0

wMaxPacketSize : là kích thước gói tin tối đa mà endpoint có khả năng gửi và nhận
bIntervalspecifies : độ thường xuyên mà các endpoint nên hỏi vòng (tính trong đơn vị ms).
OffsetTrườngKích cỡBộ mô tả
0bLength1Kích thước bộ mô tả tính theo byte.
1bDescriptorType1Endpoint (0x05).
2bcdEndpointAddress1Địa chỉ của endpoint.
4bmAttributes1Thể loại Endpoint
5wMaxPacketSize2Kích thước gói tin tối đa
6bInterval1Thời gian thăm dò
Bảng 8.13: Bộ mô tả Endpoints

OffsetTrườngKích cỡBộ mô tả
0bLength7Kích thước bộ mô tả tính theo byte.
1bDescriptorType0x05Endpoint (0x05).
2bcdEndpointAddress0x50Địa chỉ của Endpoint.
4bmAttributes0x03Loại Endpoint interrupt
5wMaxPacketSize0x0002Kích thước gói tin tối đa là 2
6bInterval0x14Thời gian thăm dò là 20 ms
 Bảng 8.14: Bộ mô tả endpoint của thiết bị chuột
Bảng 8.14 là mộ ví dụ bộ mô tả endpoint của thiết bị chuột. Chiều dài của bộ mô tả là 7 byte (bLength = 7), và kiểu bộ mô tả là 0x05 ( bDescriptorType = 0x05). Địa chỉ của endpoint là 0x50 (bEndpointAddress = 0x 50). Endpoint này được sử dụng như là một interrupts endpoint (bmAttributes=0x 03). Kích thước gói tin tối đa là 2 (wMaxPacketSize=0x 02) để chỉ rằng gói tin lớn hơn 2 bytes sẽ không gửi từ endpoint. Endpoint nên được kiểm tra ít nhất sau mỗi 20 ms ( bInterval=0 x14).

Bộ mô tả chuỗi (String descriptors):

Bộ mô tả chuỗi cung cấp các thông tin mà con người có thể đọc và là tùy chọn. Nếu bộ mô tả chuỗi không được sử dụng, tất cả các trường chỉ mục chuỗi của các bộ mô tả đã đề cập phải được thiết lập bằng 0 để báo rằng không có bộ mô tả chuỗi.
Chuỗi được mã hóa theo mã Unicode và thiết bị có thể được hỗ trợ nhiều ngôn ngữ. Chỉ mục chuỗi 0 (String Index 0) trả về một danh sách các ngôn ngữ được hỗ trợ. Một danh sách các ID ngôn ngữ USB các thể tìm thấy tại Universal Serial Bus Language Identifiers (LANGIDs) version 1.0

0bLength1Kích thước bộ mô tả tính theo byte
1bDescriptorType1Bộ mô tả chuỗi (0x03)
2wLANGID[0]2Hỗ trợ ngôn ngữ mã 0 
(e.g. 0x0409 English - United States)
4wLANGID[1]2Hỗ trợ ngôn ngữ mã 1 
(e.g. 0x0c09 English - Australian)
nwLANGID[x]2Hỗ trợ ngôn ngữ mã x 
(e.g. 0x0407 German - Standard)


Một số vi điều khiển PIC18 hỗ trợ giao tiếp USB. Ví dụ, các vi điều khiển PIC18F4550 hỗ trợ cả hai chuẩn USB low speed và full speed cho phép giao tiếp giữa PC và vi điều khiển . Các ví dụ ở chương này chúng ta sẽ sử dụng vi điều khiển PIC18F4550.
Hình 8.8 mô tả tổng quan về khối giao tiếp USB của pic PIC18F4550. Pin RC4 (pin 23) và RC5 (pin 24) của PORTC được sử dụng cho giao tiếp USB. RC4 là chân dữ liệu D- và RC5 là chân dữ liệu D+. Các điện trở kéo lên được tích hợp sẳn bên trong vi điều khiển có thể kích hoạt hoặc vô hiệu hóa (UPUEN = 0) nếu muốn. Khi đó ta có thể sử dụng các điện trở mắc thêm ở ngoài. Để hoạt động ở chế độ low speed một điện trở kéo lên bên trong hoặc bên ngoài kết nối với chân D-, ở chế độ full speed một điện trở kéo lên bên trong hoặc bên ngoài kết nối với chân D+.
Hoạt động của các mô-đun USB được cấu hình sử dụng ba thanh ghi điều khiển, và tổng cộng hai mươi hai thanh ghi được sử dụng để quản lý giao tiếp USB. Cấu hình của các thanh ghi là một nhiệm vụ rất phức tạp và không được đề cập trong cuốn sách này. Bạn đọc quan tâm có thể tham khảo datasheet của PIC18F4550. 
 
                                                     Mô-đun USB trong pic18f4550

 Các hàm trong hỗ trợ giao tiếp USB của trình biên dịch CCS
usb_init()
Khởi tạo phần cứng USB. Khi đó chờ thiết bị kết nối đến bus bằng một vòng lặp vô tận. Hàm sẽ kích hoạt cho phép chức năng ngắt USB
usb_init_cs()
Giống như usb_init(), nhưng nó không chờ thiết bị kết nối đến bus. Đây hữu ích khi thiết bị hoạt động không sử dụng nguồn cấp từ cổng USB và thiết bị có thể hoạt động mà không cần kết nối đến cổng USB
usb_task()
 Nếu bạn sử dụng kết nối nhạy (connection sense), và sử dụng hàmusb_init_cs() , khi đó bạn gọi hàm này theo định kỳ để quan sát chân kết nối nhạy (connection sense pin). Khi PIC được kết nối đến BUS, hàm này sẽ khởi tạo (chuẩn bị) các khối ngoại vi giao tiếp USB. Khi thiết bị bị ngắt kết nối khỏi bus, nó sẽ reset USB stack và các khối ngoại vi. Hàm kích hoạt cho phép chức năng ngắt USB
Chú ý: trong ứng dụng bạn phải định nghĩa  USB_CON_SENSE_PIN đến chân kết nối nhạy
usb_detach()
 Khi bạn ngắt kết nối PIC đến Bus. Hàm này được gọi tự động bởi usb_task() nếu kết nối bị mất, nhưng nó có thể gọi bởi người sử dụng.
usb_attach()
Khi kết nối PIC đến bus. Hàm này được gọi tự động bởi usb_task() nếu có kết nối , nhưng có thể gọi bởi người sử dụng.
usb_attached()
 Trả về TRUE nếu thiết bị kết nối đến cổng USB. Một đoạn macro co nhiệm vụ quan sát chân được định nghĩa trong USB_CON_SENSE_PIN

usb_wait_for_enumeration() 

 Một vòng lặp vô tận chờ đến khi thiết bị được enumerated 
usb_enumerated()
Trả lại TRUE nếu thiết bị được enumerated thành công bởi CPU. Nếu thiết bị đã được enumerated bởi PC, khi đó bạn có thể gửi/nhận các gói tin
usb_put_packet
(endpoint, data, len, tgl)
 Đặt một gói tin vào một bộ đệm của endpoint được chỉ định. Trả lại TRUE nếu thành công, FALSE nếu buffer đang còn đầy với các gói tin trước
usb_puts
(endpoint, data, len,
timeout)
Đưa dữ liệu đến endpoint được chỉ định. Sự khác biệt giữa usb_puts() và usb_put_packet() là usb_puts() gửi liên tiếp nhiều gói tin nếu dữ liệu muốn gửi có kích thước lớn hơn kích thước gói tin
usb_kbhit(endpoint)
Hàm trả về TRUE nếu endpoint chỉ định có dữ liệu trong bộ đệm nhận
usb_get_packet
(endpoint, ptr, max)
Đọc tất cả các bytes từ bộ đệm của enpoint được chỉ định và con trỏ ptr trỏ đến địa chỉ lưu của byte. Hàm trả về số byte được lưu
usb_gets(endpoint, ptr,
max, timeout)
Đọc một thông điệp ( message ) từ endpoint được chỉ định. Sự khác biệt giữa usb_get_packet() and usb_gets() đó là usb_gets() chờ thông điệp nhận đầy đủ khi thông điệp được chứa nhiều hơn trong một gói tin. Trả về số byte được nhận

Các phần mềm phân tích giao thức USB
Nếu vì một lý do nào đó project về giao tiếp USB mà bạn làm không chạy, khi đó bộ phân tích giao thức USB có thể được sử dụng để kiểm tra dữ liệu truyền trên bus USB. Hiện nay có nhiều bộ phân tích giao thức USB trên thị trường. Có một vài bộ phân tích chuyên nghiệp nhưng có giá thành cao dựa trên nền tảng phần cứng khi sử dụng cần đặt mua một phần cứng chuyên dụng. Hầu hết các bộ phân tích giao thức USB miễn phí sử dụng bằng phần mềm. Ở bài này ta tìm hiểu hai phần mềm điển hình.
UVCView
UVCView là một phần mềm của hãng Microsoft dùng để hiển thị bộ mô tả  của một thiết bị USB sau khi cắm vào máy. Hình 8.1 là cửa sổ hiển thị UVCView. Bên trái của cửa sổ hiển thị các port USB hiện có của máy. khi click chuột chọn cổng đang kết nối đến thiết bị USB sẽ hiển thị bộ mô tả chi tiết của thiết bị ở cửa sổ bên phải. Bạn có thể tải phần mềm tại đây:
USBTrace:
USBTrace là một phần mềm phân tích giao thức USB phát triển bởi hãng SysNucleus (www.sysnucleus.com). Phần mềm này theo dõi các cổng USB của máy tính và hiển thị tất các giao dịch trên Bus. Phần mềm là một công cụ vô giá khi ta muốn tất cả các giao dịch trên đường truyền phải được theo dõi và ghi lại. Trên trang web của hãng có phiên bảng dùng thử .


Trong bài này ta viết một chương trình firmware nhỏ cho PIC 18f4550, chương trình này mục đích để kiểm tra phần cứng giao tiếp USB, cũng như quá trình enumerated bởi PC thành công hay chưa, trong bài này có sử dụng công cụ phân tích UVCView (đã đề cập ở bài 7) để xem bộ mô tả thiết bị được đọc bởi máy tính

 

Sơ đồ khối của ví dụ


Sơ đồ mạch của ví dụ

Các file bạn cần include vào project CCS là: 
#include
#include
#include // Chứa các tác vụ quản lý các ngắt USB, các yêu cầu thiết lập USB của enpoint 0
Đoạn chương trình bên dưới thực hiện khởi tạo cổng USB và kiểm tra quá trình enumerated bởi máy tính và vi điều khiển PIC đã thành công hay chưa
#include <18F4550.h>
#device ADC=8
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL2,CPUDIV1,VREGEN
#use delay(clock=48000000)
#include
#include
#include
/***************************************/

void main(void)
{
output_d(0x00); //tắt tất cả các led kết nối đến port B
usb_init_cs();
Delay_ms(1000);
    while(1)
    {
        usb_task();
        if(usb_enumerated())
        {
           //nếu quá trình enumerated thành công , tại đây bạn có thể truyền và nhận dữ liệu
if(usb_kbhit(1))
            {
             output_d(0xff); // nếu có dữ liệu trong bộ đệm nhận thì bật tất cả các đèn led 
            }
         } 
    }
}
 Sau khi biên dịch và kết nối đến cổng USB , một thông điệp xuất hiện báo máy tính đã nhận thiết bi
 
Ta mở chương trình UVCView để xem bộ mô tả của thiết bị USB ta mới gắn vào được đọc bởi máy tính:
 

 Đây là bộ mô tả ví dụ của CCS trong file usb_desc_hid.hcác bạn có thể mở xem và chỉnh sửa cho phù hợp với ý muốn của mình.

Trong bài này tôi viết chương trình mẫu sử dụng C# (sử dụng thư viện Hidsharp) giao tiếp với PIC18F4550 
Giới thiệu Hidshard:
Hidsharp là thư viện mã nguồn mở miễn phí giúp giao tiếp với thiết bị usb thông qua lớp HID bằng C#. Các bạn có thể xem chi tiết tại địa chỉ: https://www.zer7.com/software/hidsharp các bạn có thể tải phiên bảng mới nhất tại địa chỉ này hoặc tải tại đây.
Mở visual studio và tạo mới project với tên USB_Csharp
giao tiếp USB bằng C#

Add thư viện  Hidshard bằng cách nhấn chuột phải lên tên project, chọn Add Reference trỏ đến thư viện Hidshard (file: HidSharp.dll) đã tải về ở trên.
giao tiếp USB bằng C#
Add 1 button và lable1, lable2 và chương trình chúng ta
Trong sự kiện nhấn nút, chèn đoạn code bên dưới vào:
Đoạn chương trình này có chức năng đơn giản là kết nối với thiết bị chúng ta thông qua lớp HID, sao đó gửi dữ liệu xuống vi điều khiển và nhận dữ liệu từ vi điều khiển gửi lên, hiển thị dữ liệu nhận bằng lable1 và lable2 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var loader = new HidDeviceLoader();
var device = loader.GetDevices(0x0461, 0x0020).FirstOrDefault();
if (device == null) {
MessageBox.Show("Không tìm thấy thiết bị");
return;
}
HidStream stream;
if (!device.TryOpen(out stream)) {
MessageBox.Show("Failed to open device.");
return;
}
 
var message = new byte[] { 0, 0xaa };
stream.Write(message);
byte[] mybyte = stream.Read();
label1.Text = mybyte[1].ToString();
label2.Text = mybyte[2].ToString(); 

Nhớ khai báo using HidSharp; ở đầu chương trình. Code hoàn chỉnh như bên dưới:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using HidSharp;
 
namespace USB_Csharp
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
 
private void button1_Click(object sender, EventArgs e)
{
var loader = new HidDeviceLoader();
var device = loader.GetDevices(0x0461, 0x0020).FirstOrDefault();
if (device == null)
{
MessageBox.Show("Không tìm thấy thiết bị");
return;
}
HidStream stream;
if (!device.TryOpen(out stream))
{
MessageBox.Show("Failed to open device.");
return;
}
 
var message = new byte[] { 0, 0xaa };
stream.Write(message);
byte[] mybyte = stream.Read();
label1.Text = mybyte[1].ToString();
label2.Text = mybyte[2].ToString();
}
}
}
Đoạn chương trình viết bằng CCS trên pic 18f4550:
Chức năng của đoạn chương trình này: Đoạn chương trình dưới vi điều khiển làm chức năng đơn giản là sau khi nhận được 1 gói tin từ phần mềm C sharp trên máy tính gửi xuống, vi điều khiển sẽ tăng biến i lên 1 đơn vị vào gửi 1 gói tin này lên máy tính.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <18F4550.h>
#device ADC=8
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=48000000)
#include <pic18_usb.h> 
#include <usb_desc_hid.h>   //USB Configuration and Device descriptors for this UBS device 
#include <usb.h>
/***************************************/
void main(void)
{
int i=0;
int8 out_data[USB_CONFIG_HID_TX_SIZE];
int8 in_data[USB_CONFIG_HID_RX_SIZE];
//memset(in_data, 0x00, USB_CONFIG_HID_RX_SIZE);
//memset(out_data, 0x00, USB_CONFIG_HID_TX_SIZE);
set_tris_d(0x00);
output_d(0x00);
usb_init_cs();
Delay_ms(1000);
while(1)
{
usb_task();
if(usb_enumerated())
{
//nếu quá trình enumerated thành công , tới đây bạn có thể truyền và nhận dữ liệu
if(usb_kbhit(1))
{
usb_get_packet(1, in_data, USB_CONFIG_HID_RX_SIZE);
usb_put_packet(1, out_data, USB_CONFIG_HID_TX_SIZE, USB_DTS_TOGGLE);
output_d(0xff); // nếu có dữ liệu trong bộ đệm nhận thì bật tất cả các dèn led
out_data[1]=++i;
out_data[2]=2;
}
}
}
}



Không có nhận xét nào:

Đăng nhận xét

Bài đăng mới nhất

Valdes Fernando - Microcontrollers Applications With Pic

Bài đăng phổ biến