這一次所謂USB DIY 自學計畫並不是什麼USB 自修計畫,
而是以過去所熟悉的USB 觀念,來接受新的USB Controller 。
趁機也來檢視一下我們之前所討論的USB 的基本觀念,是否也可以延伸到別
的USBController 平台上。
當然啊,之前我們所提到的USB Controller 一般學習者也想躍躍欲試,
卻有點摸不著頭緒,也苦無學習機會,這回這個USB Controller 是比較大眾化一點。
相信會更引起更多人的興趣吧。...
------
好吧,我們前幾次已經探討了USB 基本的Setup Token 外,我們也先檢視了
Bulk Transfer中的Bulk-Out pipe 。我們也嘗試調整了一下整個Bulk- out 的原始範例程式。
這是都是一些很基礎的觀念,說真的,我說過:拿人家的範例程式來,不是照本宣科一下,
就代表我們對於USB 觀念就完全吸收了。說真的,如果搞技術只是如此的話,
那這種技術也沒什麼值得大家所學習的...我們要探討的是:從這種基本觀念中,
我們可以將此一普及化的通訊介面裡,可以發揮出多少系統應用?!
----這是我一直強調的:懂USB,學會USB...這沒什麼好值得稱讚的 ;
重點是:當您學會了這個系統應用介面之後,您可以拿此介面為您系統
創造什麼附加價值吧!
不知大家能否體會這樣的呼籲與體會呢?!.... ...
其實我們看完Bulk Out 之後...大概就可以瞭解到單純的Bulk Transaction所
需具備的基本協定吧!
----
針對上回提到的Bulk -out ,我就對於他經由USB傳入8051之後的Buffer 感到好奇,
所以啦,就做一個小實驗,來察看一下他真正的傳輸路徑...
下圖是原廠的技術文件:我們發現他為了USB 傳輸保留 1K Bytes給USB傳輸Buffer之用。
而基本上的分配如下:基本的64 Bytes (For Endpoint 0)... 128/256/512...
很明顯就是為了支援USB 2.0 的...或是ISO Token ...
而在我們的第一範例中:他用到的便是 Bulk Out (endpoint 2 )...
雖然我們還是用了 64 Bytes ...的基本USB Lengths 的傳輸模式...我們就很好奇,
他的內部是如何處理的?!...因為同樣的Endpoint 是可以同時支援In/Out 的 ...
雖然我們在此宣告只是用到Bulk Out(Endpoint2 )!
但他還是會佔用整個Endpoint 2 的範圍的...但只是讓我比較好奇的是:依原廠資料來看:
他要讀此一FIFO Buffer,是要透過他的 USB Registers來依序讀取...
但他明明是8051的 xData範圍啊?!..那我可不可以用Movx 來讀是比較快一點呢?!
於是啊...我就故意傳一個小小的Bulk out 資料...然後比對一下USB 傳輸前後在此
Endpoint 2的Buffer 內容情形:(0x0640 ~ 0x073F) 的內容如下:
我們就發現:其實,我們用8051的Movx 還是可以讀到此一FIFO 的...
只是他的排列方式有點奇怪?!...好像看起來有點像那種Ping-pong Buffer的觀念?!
他基本上還是真的切成上下兩組Buffer來使用的 ...而且因為是FIFO (先進先出) 的架構,
所以,整個資料排列是有點反過來的...看來您也可以用這招抓USB傳進來的資料...
只是您可能要自己稍微調整一下資料讀取的順序的...當然啊...如果您有宣告
Endpoint 2 同時支援 Bulk In/Out 的話...應該就不是如此了.,,.
請看他所謂的Split Mode的用法!
這一點就留給大家作實驗看看!....真的 ...您一定要像我如此的去作個小實驗,
以避免下回在做使用不同模式時,發生一些奇怪的"靈異"現象時,可以很快的釐清問題。
不要屆時在來怪人家的IC 有問題?!或是怪人家IC 不好用?!...只能怪自己學藝不精啊!
------------------------------------
接下來就來看Bulk-in 的範例了...有了Bulk-out 經驗後,再做Bulk-in 就簡單多了:
因為直覺想到的便是:利用Bulk-out 先下Command ...然後就Bulk-in 直接讀取
USB Device的上傳資料了:
跑了範例之後,才發現這個Bulk-in 範例程式更拙了...所以啦...大家就跑一跑範例就好了,
如果您有機會引用此一範例程式時,還是建議您最好修改一下再使用吧!
在上圖中我們發現那個Bulk-out Command 缺乏一點創意...只是跟USB Device 說:
我要來抓資料了...然後,卻要USB Device 自行回覆傳輸資料長度?!...
(您去看PC 端的應用程式...其實,Host PC 自己已經知道他要回傳的資料長度...
那為什麼不直接下Out Command 時,直接告訴USB Device 呢?!....
不好的範例程式想法...強烈不建議使用這種觀念...您寧願請USB Device 在回覆
一次以確認長度...但不可能以這種方式使用...在PC與USB 韌體之間太沒有彈性了...)
-------------------------------------------------------------------------
然後呢?!...我們接著看到說:當我們上傳兩筆很快的資料後...(Packet # 31/34)
整個USB 速度就會稍微慢下來了...(對不起喔...我還改寫了一下原始上傳資料處理,
以加速上傳速度...)所以啦...不管是上傳或下傳...以這種USB Firmware處理
USB 傳輸資料的架構,永遠是讓HOST PC 等我們USB Device 的份啦...
所以,您真的不要以為USB 2.0 對我們這些USB Device 應用程式來說 ,
真的有Gain 什麼好處的...(USB Bus 開始塞一些NAK了....您知道這個NAK 對於 此
USB Controller 是如何處理的嗎?....您真的可以很快的抓到說:在這個USB
Controller 中的那個Registers 是在控制這個NAK 機制的嗎?!....
這個才是我所要強調的USB學習要點...外面的書籍才不會這樣子教您呢! )
我們很明顯的是:自從兩組Bulk -in 之後,就開始固定的產生NAK 的傳輸Latency ...
這個延遲對於這種Buffer不大,又處理速度不夠的USB Controller 中的8051來說:
就是有這種天生宿命...這個在我之前的USB DIY 講座中就有提到了...
這裡只不過再一次驗證給您看而已...
從下圖中:我們就可以看到這個Bulk-in 的Latency 就一路拖到最後....
(Packet # 765 跳到...826 ....再跳到871 ...最後跳到914...,注意喔...
我還因為故意傳固定的資料內容...代表我都沒有去處理傳輸內容的搬移呢!
若加上搬移之後....這個 Latency 鐵定還要加長的!....)
好吧 ...果然如我當初一開始要自學這顆 USB Controller 的想法一般...
在瞭解Bulk-out 之後,我們就很快的學到相對的 Bulk-in 方式。
您看我們還花不到十天工作天,就已經瞭解到大部分的USB上下傳輸的能力了。
您覺得學USB 真的很難嗎?!...只是您有沒有用對方法學而已! ...
接下來我們就可以進入所謂的 HID了 。
(待續)...
------------------
後記:注意,以原廠的Bulk-in 與Bulk-out 範例程式來說:是不可以像我這樣子分開
作實驗的,而且他是要先執行 Bulk-out 後,馬上執行Bulk-in才可以執行成功的...
這是原廠的所有文件資料都沒有提到的...否則的話...您要像我一樣稍微改寫一下
原廠所提供的範例程式(我指的是USB Device 端的韌體),至於PC 端的程式呢?!...
我覺得還好啦 ...只不過,能改寫一下是比較好,因為,您兩邊稍微察看一下,
您就可以發現原廠的範例程式有我所提到的這個問題.....
學習過程中,最難的還是錯誤發生的排除....,排除時間越短,您的學習效果就越彰顯吧!
好好加油喔。...
-------------
1. 改寫原廠的USB應用程式
2. 改寫原廠的USB應用程式(續一)
1. 那個Bulk-out Command 缺乏一點創意...只是跟USB Device 說:
回覆刪除我要來抓資料了...然後,卻要USB Device 自行回覆傳輸資料長度?!...
---看到這段,我笑了^_^---
2.看樣子我還沒將這MCU的程式真正搞懂..因為我都是用Bus Hound來看資料的傳遞.果然跟分析儀插了很多,使用分析儀分析資料才是王道阿~~
Chamber 大大:
回覆刪除冒昧請求,可否將USB DIY--自學計畫 (N) 轉載到USB實驗室?
謝謝 USBLAB Miller敬上
但如果也不是很清楚USB 與MCU 中的韌體關係的話...
回覆刪除有時就算有分析儀,也不知道要留意哪些東西啊?!...
不過,您會看到這篇文章的好笑地方,代表您的功力也不錯啊! =D>
至於轉載的事...您就直接用連結的方式好了...轉貼的我擔心在圖示方面,
會有一些問題吧?!...