ChamberPlus System Level Studio

  首頁 | Contact to us

 

News
Products
FAQ
Technicality
Links
OldNews

互動區:

留下您的足跡

想討論嗎?

 

USB DIY 講座 (六) --- USB I/O

----------------------------------------------------------------------------------------------------------------------------------------

        我這樣子寫下去,會不會也像別人寫USB 書一樣?又要講基礎的東西?好了,別擔心,I/O 的東西,我只要寫一個章節就好了,基本的東西會了,要做什麼?就讓各位自行發揮了,直接進入重點吧。

----------------------------------------------------------------------------------------------------------------------------------------

        首先,我們先體會一下使用的環境或特性,既然要作 I/O 就是說,我的程式就會經常修修改改的,所以先看程式更新的機制吧。因為我的程式也是經由USB 下載到USB Controller 的SRAM (您也可以說是Cache Memory ) 跑。

        因為一般這種 IC的SRAM 都不大,所以,下載的路徑是不需要用到  Bulk Transfer 的,只要Control pipe 就嚇嚇叫了。在此先參考一下USB DIY 講座(四) 裡的張架構圖。 所以,我就是利用那個外掛的 Boot EEPROM 來完成程式更新的機制,只要下載過一次,我每個程式裡都含有更新Firmware 的機制,所以,我就可以反覆更新了:

看一下原始檔:

        這種檔頭一看就知道是8051 的,不用我解釋吧。

再來看 USB 傳輸內容:

          看到沒,我就是用 Control pipe 的 Vendor command (0x40)就可以一次傳 4K 的程式了。當程式傳完後, USB controller 他自己會內部 Reset 8051。就可以完成程式更新的動作。簡單容易,比ISP 還快。因為以USB的裝置來說,都是依附在HOST端(Such as PC)工作的,而且,也都要經過 Enumeration 過程,所以,當完成Enumeration 這些工作後,再讓應用程式進入 USB Controller 就可以了,當然,也有人直接把這些韌體直接寫在 Driver 裡面,當Driver 安裝之時,韌體也可以完成下載的動作,這是看每個人的想法或作法了。。

        當然,在PC端也要寫一個美美的程式,這樣子自己做起來也比較賞心悅目(看到左上角那個小小的icon 嗎?沒錯,我是用VC++的MFC 寫的,而且我這個人就是『龜毛』,明明像人家作的 CheckBox 的東西就好,我就是要偏偏作得像PCB版上的東西一樣。或許很多人會覺得VB比較好用,就見仁見智了,只是C對我說:又可以寫PC端的程式也可以用來寫韌體,年紀大了,實在是沒辦法轉來轉去的。):

        就自己設計一個簡單的按鈕: 『Update FW』,來隨時更新韌體,我愛怎麼改就怎麼改,還可以順便叫下載的程式把最新的 CheckSUM 回傳,以便確認更新無誤,當然,也順便叫下載的韌體量一下USB 線上的電壓值:乖乖∼竟然只有  4.74 Volts ,幸好還在規格範圍內,這麼低的原因,是因為我是串接了 CATC 的USB 分析儀的關係,USB Cable 就比較長囉。

        就利用這張圖,說明一下我要DEMO 的東西 : 一般USB Controller 都會內建一棵 Controller (Such as 8051),所以,複習一下USB 特性文章中的第九項:

特質九:USB Projects Require a Significant Code Development Effort

bulletDevice Side
bullet        USB housekeeping firmware。這一部份我想您要寫得好,USB功力要一定的程度。
bullet        Application firmware。就是寫一般8051 ,要我講,就是污辱您了。
bulletHost side
bullet        Driver (maybe)。這一部份一般都用Microsoft DDK 寫。
bullet        Application software。這一部份我都是用Visual C++ 寫,因為跟底層好連接。
bullet 

    USB 裝置的程式分成PC端的程式及裝置端的程式,既然會有兩套程式,理所當然的,我們也可以完成兩件事情:裝置端可以自己作的就叫裝置端內部的 Controller 作;有些事情是可以請 PC 端的 Host 來控制。這是USB相對 RS232 或 Parallel 好的地方。至於,USB Housekeeping 的程式我這裡沒有說明,因為一般USB Controller IC Provider 都已經幫您寫得很好了∼不過∼也很不幸的是∼您都沒機會去體會到這一部份∼而瞭解這一部份卻是調整USB  Performance 最重要的關鍵!這一部份當我們有用到時我再說明。

    而PC 端的程式我們就設計成 : 一個叫『SET  Port』 由HOST 程式直接控制  USB Device 的I/O ,所以他是按鈕『USB Command』則是由PC 端的程式下命令叫 Device 端內部的程式自己跑(我做的是叫 USB Controller他自己利用 8051 的 Timer 跑一個類似跑馬燈的東西),然後我PC端的程式也可以同時去讀他 I/O 的狀態值,並把他 Show 螢幕上,所以,他就是純顯示的燈號了囉。也就有所謂 RUN and STOP 兩個按鈕執行命令了。

        先看 『SET  Port』 部分:這部分就是最簡單的:把要設定的值,直接傳給 USB Device 端,他直接把值Show I/O 上, PC 端程式:

int i;
       for(i=0;i<8;i++) STICommandString[i]=0x00;
       STICommandString[0]=0x7A; // SET USB Controller P1
       STICommandString[1]=(UCHAR)(USB_P1&0x00FF); // SET USB Controller P1
       USB_DEVICE_SEND_STI_COMMAND(STICommandString);


到USB Bus 上:

    看到沒? Command 0x7A + 0x02 的值。到這裡,您一定好奇問我,為什麼不用Setup Token 的 Vendor Command 把 0x7A 命令傳下去呢?因為反正您都得 OUT 一筆資料,何必利用 Setup Token 那個資料空間呢(只有 8 Bytes 空間而已)?況且那個空間位置的定義是被限制很多的,譬如 wLength 或wIndex 的;而在我們 OUT Token 中的資料是隨我定義的。而且,您若將要執行的一些命令都寫在 Setup Token 中,除了備受限制外,您的 USB Housekeeping 程式也很難寫,會囉哩囉唆,要模組化也很難。(因為您會將 USB housekeeping 程式與Application 程式給混在一起!)這樣子講不知您是否能體會得到?!因為在別的地方不用有人會教您這件事。再看DEVICE 端的程式:

;------------------------------------------------------------------------------
USB3Cmd7A:        ;; ;; Set P1 Port
         cjne A,#7Ah,USB3Cmd7B
         mov  DPTR, #USBDsrr1
         movx A, @DPTR         //Read the P1 Request Value
         mov  P1, A
         ret

要我解釋或叫我教您這段程式,就真的污辱您的智慧了。

----------------------------------------------------------------------------------------------------------------------------------------

    喔∼忘了介紹一下硬體,也是看圖:

        上面那一塊是我隨便撿的一般版子,下面就是我的USB 控制版子,沒什麼IC,就是我的USB Controller 大了一點。至於,上面的那兩條跳線,是我直接拉USB POWER線分壓後,直接給USB Controller 量電壓用的。結合後成為無敵鐵金剛?(懶人施工法?!)

不要說我呼籠您,隨便寫個東西,就假設會動。我們還是眼見為憑:

        上面那組就是『Set Port』,以紅燈表示。至於他的右邊的是 USB Controller 自己跑出來的跑馬燈,以綠燈表示。您不要誤以為我一次點四個燈,那是我的數位相機爛∼竟然拍到視覺暫留現象,您看PCB 版上的燈就知道。不過,沒關係,您聽我說明即可:

            因為一般 USB Controller 都會Built-in 一棵 MCU (Such as 8051) 所以,有些很緊急或要 real time 的東西,您就不要由HOST PC來控制,而直接請裡面那顆8051 自己來作就可以了。而您只要下啟動命令即可,而此時,您HOST PC 就好像有點閒閒沒事幹,怎麼寫『抓蝨母相咬』?我不會,只好請他一直去監控那組 GPIO 的狀態再把他SHOW在螢幕上了。就成了這負德性。當然我一開始也是只寫個 Enable Timer Command~ 後來就把他變化一下∼把跑馬燈的速度參數也加進來,如此一來,還可以調整跑馬燈的速度:

先看PC程式:

int i;
            for(i=0;i<8;i++) STICommandString[i]=0x00;
            STICommandString[0]=0x7B; // Make 8051 Timer1 Enable
            STICommandString[1]=0x08; // The Delay Counter of Flasher
            USB_DEVICE_SEND_STI_COMMAND(STICommandString);
            //---
而 Device 端呢:

;------------------------------------------------------------------------------
USB3Cmd7B: ;; ;; Set Enable Timer 1
            cjne A,#7Bh,USB3Cmd8E
            mov DPTR, #USBDsrr1
            movx A, @DPTR
            mov Tm1Base, A    ;; Base of Timer1 Counter
            mov Tm1Cnt, A     ;; The Counter of Timer1
            ret

....
;------------------------------------------------------------------------------
STIstatus7B: ;; ;-- Enable Timer 1
            cjne A,#7Bh,STIstatus7C ;; Chamber modify--1/19/2001
            lcall Timer1Enable
            ret
;------------------------------------------------------------------------------
STIstatus7C: ;; ; inhibit Timer 1
            cjne A,#7Ch,STIstatus7D ;; Chamber modify--1/19/2001
            lcall Timer1Disable
            clr A
            ACC2IO GPIODR
            ret

        注意喔∼這裡所謂的 0x7B  是分成兩部分喔∼這裡有一個很重要的觀念在!原因沒他,因為當USB 下命令及傳資料下來,您只能先收完命令或資料而已,您不能馬上作HOST PC 交辦的事情,否則您會耽誤USB Protocol 中的Handshake 的事。因為USB Protocol 的動作還是需要您MCU去處理的。作USB 的最高指導原則:就是不能因為您應用程式的工作去影響USB基本 Protocol 的東西 !所以大部分 USB Controller 裡的關於Protocol 的東西,都是以中斷方式的原因。所以,雖然像去 Enable  Timer1 這麼簡單的工作,我們還是等完成回完 USB Status 之後才執行,養成這種好習慣,對您寫USB Controller 程式絕對是好事的,而萬一您應用程式真的很忙,那您應該就把HOST PC 下來的命令先用 NAK 把他擋掉∼等到您事情告一段落之後再處理。或許您真的很難體會,但是這種技巧是作USB 不可或缺的重要觀念!!

            至於NAK 可以擋多久?哈∼哈∼您擋到明天或明年都不會有人說您錯了∼因為USB 規格就是這樣子規定的。有些寫軟體或驅動程式的人喜歡自作主張,來個Time-Out ,那是不對的(更何況一旦USB 命令一下,一般上層應用程式只能等∼因為就算您想停,對不起,發 USB Protocol 也不是您的 Driver ,是微軟的作業系統!!除非您拔 USB 線,否則沒解!!以前在 98SE 或所謂非 NT 作業系統還會來個 Blue Screen,當場死給您看!!哈∼哈∼這些觀念一般書本都不會教您!!

        好了,看我們的最後結果,不過真的很難表現跑馬燈的感覺,只好貼一張醜醜的照片∼大家就比照一下PC 螢幕上的綠色燈號與PCB 版子上的燈號吧∼至少我是用數位相機連拍功能的喔,跑馬燈是由兩邊到中間再向外延伸的霹靂燈方式!看圖自己想像一下吧!不用管上面那三顆紅燈。∼

----------------------------------------------------------------------------------------------------------------------------------------

        好了,最後下一個簡單的結論,雖然我們只做了簡單的 I/O 控制,但我想這裡面已經涵蓋許多USB 寫程式的技巧在裡面了,當然這些技巧都已經可以幫我們做出不錯的東西,雖然一些書本都會附上類似的題目或範例程式,但您真的能夠從這些範例程式體會到USB的精髓嗎?!像我上述的所謂的『先回USB Protocol 的東西,等回完 USB Status 的命令再執行應用程式』,這種東西,沒有人教您該怎麼作∼但是您會發現,今天寫簡單的I/O 明明可以,為何我明天再作其他應用就不穩?!又沒有 CATC 看結果∼又要怪軟體的人,然後軟體的人又不知道您的應用程式在做什麼?!就每天在那邊吵?!這樣子說,我相信是許多剛進入USB 領域的人都碰過!

        好了∼講完基礎的 I/O 控制後∼如果要作像 LCD/LCM 或是什麼步進馬達的話,就不用我多說了吧!再寫這些東西,我的網頁塞爆也寫不完。

        而真正USB 的優勢也不侷限如此,他最厲害的是:大量資料的傳輸,所以,接下來我們會直接以資料傳輸搭配一些 I/O 的動作,就可以幫我做出許許多多的東西。說真的∼技術的東西,不難,要作也只是花時間而已罷了∼重點應該還是您腦袋裡的東西,您想拿這個技術要做什麼?!才是最重要的

∼∼(待續)∼∼

 

首頁 | News | Products | FAQ | Technicality | Links | OldNews

Telephone : 886-3-5439918    FAX : 886-3-5437632

Copyright(C) 2005 . ChamberPlus System Level Studio All rights reserved.  Last Update: 2008年01月18日。