close
想瞭解之前的...可以點選以下連結:

 



 



----------


上回有提到說:我們在一般USB 的Homekeeping 韌體管理程式一定要搞清楚,


所有USB SIE 發給我們MCU 的中斷點,因為我們有提過說:如果您沒有留意


這一點的話,您根本很難塞進相關的USB 應用程式,我們拿著人家USB MCU IC


又不是只是拿來學學好玩而已,也不是像老師上課,教完了就沒事,怎麼用?


所有市面上相關的書籍都不會教您這個問題,您碰到問題想問也問不到,


甚至怎麼問?要問誰都不知道?往代理商丟?人家工程師搞不好也是菜鳥,


搞不好還要您教他呢!....


為什麼這個問題很重要?因為:我之前在USB DIY 系列文章中有提到說:


USB MCU IC 一定要優先處理完USB Protocol 的程式,再來處理PC HOST 交辦的


事宜。否則,當您收到一個USB Token Interrupt 就匆匆忙忙的急著執行相關


應用程式的話,結果,哪知道USB Protocol 上,USB SIE 還發給您MCU 一大堆


中斷,我們都知道:中斷程式都會影響我們韌體程式的Stack 及變數(以8051 來說:


就是那個RAM  Bank的切換),而這一種程式的Bug 卻又是最難追的(問題發生點


每一次不一定一樣,很難複製!)。


在我們一般觀念裡,不管哪一家USB  MCU IC ,大致上這一部份的架構都是差不多的。


至少我還沒有看過不一樣的,所以,我一開始接觸到這一棵新的USB MCU IC 時,


我就有想到這一個問題,但是他原廠資料,也只有交代說:USB 上許多Setup/In/Out ,


甚至Stall 或Reset 等都會發中斷...而原廠給的範例程式也沒有交代,甚至程式裡


根本都沒有處理這一部份的程式。


而您在使用上又沒留意到時,結果批哩啪啦寫了一大堆應用程式,整個韌體程式已經


寫得像狗皮膏藥,或是說:已經一大堆應用工程師們都塞了他們自己程式之後,


在產品實際驗證測試時,才發現好像都一些不尋常的靈異現象,又不容易抓,


最後大家只好全推給原廠,就開始怪人家的IC 不好,不穩...甚至都可以把所謂EMI/EMC ,


全抬出來...一股腦往人家身上推,結果呢?那您還要不要再換另一個MCU 啊?


大家就重新再搞一次?作事情的永遠是最可憐的工程師,如果您自己還不長進的話,


這種事情讓您多作個N 遍,再讓您多換幾家公司也是一樣的啦。


-----------------
好吧,我就從最簡單:在USB插拔時,Enumeration 第一個Get Device Descriptor 來看:



因為他是SETUP-In-外加一個Null-Out ...就是教科書說的:SETUP-Data-Status 啦。


(但是另一種為SETUP-Out- Null-in 也是SETUP-Data-Status...有不一樣嗎?


當然不一樣的啦。所以,看中文書或教科書還是要認真一點。也不要光看書啦!)


這一種Get Device Descriptor 就是先Setup 出USB 標準Command (8 Bytes) ,


然後就要跟您USB DEVICE 要資料了。然後PC Host 收到資料後,會回您一個


Null- out 跟您說他收到了。


從上圖中與我的解析說明:您可以看到說:PC Host 是很厲害的啦,他一下完 Setup 之後,


就開始一直跟您要資料:您有看到 143~157 那一大堆回NAK 的IN...代表您韌體都還沒


處理完呢。然後當您好不容易回完資料後,他又一下子就回您Null-out (ZeroSize Packet)。


所以,我們就可以看到實際上我們有收到三個 SIE發給我們MCU 的的三個中斷,


如圖中藍色箭頭所示。注意一點依原廠所附的範例程式來看,其中:從收到SETUP 中斷


之後,一直到MCU 回資料時,其實,我們的韌體程式是一直停留在SETUP 那一個


ISR (中斷服務程式)裡的。所以就說:他一回完資料之後,就又馬上被中斷叫回!


然後又被另一個Null_OUT 中斷叫回。.....


好了,以上是基本的 Setup _In_NullOut 的動作。


那另一種Setup- Out-Null_IN呢?!...他代表的是說:PC HOST會把一些數據資料


輸出給您MCU...這一種在一般標準 USB Enumeration中是沒有的,他需要跑一些


應用程式才有。....他跟Setup -In-Null_Out 不一樣的地方是:


他是Output(Setup)-Output(out)-Input(Null_IN) ,而 Setup -In-Null_Out是Output-Input-Output。



上圖就是一個利用原廠所附的上層應用程式所完成的一組Endpoint 0 的Setup Command。


這是一個HID Class 的Command ,就是 Set Feature 的一個動作。


同樣的,當PC Host 下完Setup Token 之後,我們的USB MCU 也沒辦法馬上可以接收


PC Host 下過來的資料,我們USB MCU 中的SIE 就會幫我們擋著。


直到我們把USB FIFO 清楚整理完畢才可以。...結果,PC Host 一送完資料就又馬上跟


我們要另一個Null-IN 的Status 的回覆,相對於之前提到那個Set Device Descriptor 來看。


連我們回給PC Host這麼一個簡單的Zero Size Packet 的NULL-In  都還會產生NAK。


之後,PC會緊接著下另一組Get Feature 命令,他也是屬於一般Endpoint 0 的Setup Token 。


您可以自行比對一下他跟Get Device Descriptor 是一樣的動作的。就不再解說了。


但是,並不是所有的Endpoint 0 的命令與動作都是如此的,有些命令是沒有帶任何


資料傳輸的...他可能只是一個簡單的USB 的Protocol 動作。


像我們在USB 的Enumeration 中,最後一個Endpoint 0 命令Set configuration就是:



這些命令您就自行參考原廠標準範例就可以了。這一種東西都已經是標準了。


也沒什麼好解說的。所以,我才一直強調說:USB 其實不難,他比UART(RS232)


還簡單,因為您根本無法在這些標準動作外,加入屬於自己的東西。


-------------------
除了這些東西以外還有沒有其他的?當然有啊。萬一傳輸的內容大小超過一個


In Token 或Out Token 的最大Packet Size時,他又是如何?在一般來說:


在Endpoint 0 中的  In Token 或Out Token 的最大Packet Size是 64 Bytes的。



上圖就是傳輸資料超過 64 Bytes 時的傳輸結果,我們就可以發現他每一個


In Token 都會產生Interrupt Event 的,這代表著我們的USB MCU IC 對於每一筆我們要


傳輸的資料內容都是要我們自己一筆一筆慢慢整理的..所以您就看到一大堆IN - NAK 。


所以我上回說:那個暫存器的那個幫我計數的Packet Counter 是一點鳥用都沒有。


除非他是反過來定義說:我可以把一大筆傳輸資料先塞進FIFO 中,然後SIE 他自己


可以一口氣傳完再發中斷給我們MCU。..這樣子鐵定效能是比較好的!


但是這一種有點類似DMA 的作法,不是每一個使用者容易搞得清楚的。


我之前也一直強調:傳得快,不如傳得穩。所以,人家這一種USB MCU 的設計方式


我們一點也不覺得奇怪。所以啦。下回如果您要做什麼高效能的USB傳輸介面時,


當您要選擇這一種通用型USB MCU時,就不要太在乎他的傳輸效能了,


您也不要老是把那個 USB 1.1/ 2.0 甚至USB 3.0 老是掛在嘴上。沒有人會理您的啦。


-----------------------
我相信我這樣子精闢的解說,外面應該沒有任何USB 教科書或參考書會教您的啦。


因為人家都不會理您這些最基本問題,人家只要把規格拿出來講一講,然後把人家


USB MCU 用力的 Promotion一下,剩下的就是您自己的事了...啊,您自己還要花


多少時間摸?搞不好,買一本看不懂,講不清楚,然後又得再找另一本,


買了一大堆,看來看去總覺得每一本講的內容還是都差不多,甚至還辛辛苦苦的買


了人家的開發版,結果,搞了老半天還是搞不懂。我相信有許多讀者,從我發表


第一篇USB DIY 文章之後,也就想好好學學USB...但是您真的有抓到學習重點嗎?


等我把這一系列的USB  HID 做完、講完之後,應該就沒有什麼好講的了,


那您學起來沒有呢?!...您要好好加油了囉。


(待續)


 



 


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 賈老師的真老公 的頭像
    賈老師的真老公

    ChamberPlus System Level Studio

    賈老師的真老公 發表在 痞客邦 留言(0) 人氣()