ChamberPlus System Level Studio

  首頁 | Contact to us

 

News
Products
FAQ
Technicality
Links
OldNews

互動區:

留下您的足跡

想討論嗎?

 

                        USB DIY 講座(十 二)-- 實作範例 USB ISP (一)

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

(2006/11/01) 前言:這個東西自從版主架設網頁時。就說要作,卻就一直被其他事情給耽擱了,不過,說真的∼作這種東西就像版主作 USB ROM Emulator 一樣,只是圖個好玩與一種拿來『交際應酬』的真的要靠技術賺錢的,唯有走在技術的領導地位才有機會,像玩那個FPPATM  -才是一塊完全沒被開發的處女地。他所潛藏的無限空間才是技術創造商機的無窮動能。就像說版主常言:若技術開發只不過想一些Cost Down 或想複製別人成功的模式,來開創事業,我想這種結果:大家也都可以預見得到的結果了。

        FPPATM  -帶給版主的想法是:他不是要去取代市面上的單晶片:Such as 8051 或MicroChip 的PIC 。他是自己去創造出一塊屬於多核心應用市場的。因為這個觀念是領導廠商Intel 所帶出來的。當您發現您在玩一塊或創造一塊人們完全無法想像或全然不解的領域時,就猶如當然哥倫布發現新大陸一般,誰會料到那片土地發展成全球霸權國家?!

        所以,寫寫這幾篇USB ISP的東西是要教導一些年輕學子,像這些顯而易見或垂首可得的東西,您只要在技術領域裡磨個幾年都不難。要傳達給各位的是是當您完成這些稀疏平常的東西之外,您要拿什麼東西給老外看,才能贏得別人對您的讚賞?因為地球是平的了!您未來的競爭不在侷限在島內或一個地區而已。這是版主在進入FPPATM  -領域後接觸到日韓美等國家客戶之後,深深的體會到:作技術也可以昂首闊步的走在國外街上的

        也把這份心得與成果分享給各位。至於,這一系列的東西,大家就多少加減當作大家交朋友的交際應酬的『等路』(台語,禮物之意)。

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

        首先,當然說明一下:版主作這個USP ISP的規劃與想法:就是利用USB 單晶片控制器來寫個簡單的燒錄器,又不想搞得太複雜,只要簡單容易上手就好。所以,就選定常見的8051 與 PIC系列,這個其中的方式就是最好是Serial interface ,這一部份 PIC 還好(不過他有個缺點,就是要12 VDC ,USB 只有5VDC)。而8051 呢?剛好 Atmel 推出所謂ISP (In-System-Programmable) 的89Sxx 系列產品,所以就把這兩個東西當作目標。

        而手上的 USB 單晶片控制器來作這個東西野蠻合適的,而且韌體也可隨時更新,對於功能的驗證與產品開發偵錯野蠻方便的,就開始著手進行了:

        先看整個系統規劃圖:

    有幾個重點先說明一下:

1. 對於PIC 系列來說:比較討厭的是需要一組 12VDC 的電源,不過,拜台灣目前一些類比IC公司一堆,所以,解決方案還蠻好找的,體積也不大。

2.一般IC 對於燒錄電壓都多多少少有一點必須要留意的,所以,我們也利用我這顆USB 單晶片控制器的 A/D 來隨時量測燒錄電壓,其中當然就包括利用USB (5VDC)升壓後的12 VDC 了。

3. 一般這種 Serial interface 所用的I/O 都不多,所以,可以直接利用USB 單晶片控制器上的GPIO 即可。

4. 當然還需要不乏LED燈號顯示啊∼或電源切換開關啊∼都可以利用其他可控制的  I/O 來控制。

5. 當然,要作Parallel Interface 的也可以啊,只是這一次的應用就不先考慮了。

我想在硬體部分,都還算蠻簡單的啊∼這一部份在一般網路上教大家作ISP Cable 的網站都有公布。這也用不著版主來教。

            接下來就直接看PCB的結果:

   放得夠大了吧,這下大家可以好好研究了,沒有任何一IC有任何隱藏的東西(喔∼放心好了,背面沒東西了!)。至於,圖中那條跳線,唉∼人非聖賢,孰能無過呢?PCB 板子回來驗證後,結果還是錯了一條線。已經不錯了啦。(有沒有看到PCB的月份,6月耶∼放到都快要『生菇』了!唉∼嘻∼嘻!)

        至於如何ISP 一般的IC 呢?就看另一片板子:

        您不要問我為何在 PIC 方面只選用這幾顆型號?!因為我就用過這幾顆而已吧,而且這幾顆手上也剛好有Sample ,版主也是作來玩玩的,又不一定要拿來賣您們的喔。對不對?!

        所以,一般使用就把上下兩片組合起來就可以了:

    咦∼有沒有覺得那個盒子很面熟?嘻嘻∼版主是借用 Altera 的那個USB Blaster II 的盒子囉。這一部份就要感謝一下友晶科技的友情贊助,有興趣玩 Altera 的 FPGA 的話,也可以到友晶科技的網站看看囉。

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

        硬體部分,我想大概不會難倒太多人,比較辛苦的是軟體部分,因為一般網路提供硬體的資訊也很多,但軟體部分的比較可憐了,往往只給的執行檔就放牛吃草了。又偏偏不是USB 介面,又不知該如何著手Debug ?而又往往USB的東西又很難上手。如果,看過版主所公布的USB DIY的內容的話,就應該瞭解這一部份,其實野蠻簡單的,如果您還覺得很難看得懂的話?那就代表您對版主之前的USB DIY 內容不夠用心研讀,可能還要多努力一下。

        我們就稍微說明一下軟體的開發技巧:當然就沿用版主所常用的USB Driver ,不過,要注意的是,為了避免跟其他相同USB Controller 發生驅動程式衝突問題,比較建議用不同的GUID ,這樣子就可以避開這個問題了:

...

DEFINE_GUID(GUID_CLASS_GT680X_SCANNER,
//0xa7e7beb7, 0x8099, 0x11d2, 0xbe, 0xbb, 0x0, 0x80, 0xc8, 0x93, 0x8c, 0x65);
//DEFINE_GUID(GUID_CLASS_I82930_BULK,
0xce25239c, 0x6ed5, 0x4895, 0x94, 0x6d, 0x82, 0xc0, 0x38, 0xe4, 0x15, 0xcc); //ChamberPlus
//0x89bb4816, 0x3e22, 0x4979, 0x8b, 0x14, 0x5, 0x38, 0xfd, 0xa9, 0x68, 0x7d); // Romter
//0x6bdd1fc6, 0x810f, 0x11d0, 0xbe, 0xc7, 0x08, 0x0, 0x2b, 0xe2, 0x09, 0x2f);
//#endif

    以上是節錄於軟體程式中的GUID 定義檔。當然啊∼不同的驅動程式就有不同的GUID,這部分是跟著驅動程式產生時,一起產生的喔。所以,您若要用Cypress 的解決方案的話,最好也要有屬於自己的GUID,否則,您要套用別人的驅動程式時,不要出了門才有一天發現:您的親生父親(Cypress)在外面也生了一大堆孿生兄弟一大堆。到時候,您的應用程式跟您的孿生兄弟幹架時,您都不知如何是好啊?!---- 本是同根生,相煎何太急啊?!

        注意喔∼版主這裡所說的GUID 跟一般的PID/VID 是不一樣的喔,不要搞錯了,還來問版主,到時版主還要數落您一下:老師在講您都沒在聽啊∼沒有聽!沒有聽!... 接下來,就是要給這個產品一個PID/VID 囉。這部分是要寫在Boot Code 裡,然後燒在Boot Code 裡的(一般就是24Cxx 那一系列的)。之後當裝置插入USB 之後,您就可以看到:

   不錯,有前途,您已經成功一半了。

    接下來就要開始動手同時上層的應用程式底層的USB 單晶片控制器韌體(一般就是8051 啊),當然,這個時候最好一個人同時間寫會比較快,否則,一些介面或命令,光溝通來,溝通去的就大家就不用作了,更何況是這種屬DIY的小東西呢!

        所以.....時光飛逝(不要笑∼版主是很嚴肅滴!)∼只要短短一兩天內,您就很快可以完成這樣一支美美(或水水)的應用程式了:

    當然這裡面有幾個重點要跟各位解密一下:因為這種韌體程式不會一開始就作得很完美的,因為大家一開始都是一樣的沒經驗,USB 單晶片控制器的韌體也不可能一次就OK 完善的。所以大家可以在我的上層應用程式的右下角偷偷的留一個介面: UpdateFW 就是拿來隨時更新USB 單晶片控制器韌體 的。這個就是版主說的:最好,這些程式都是一個人寫的比較快。不會!?那就慢慢『盧』了吧!當您最後驗證完之後,Relaese 給客戶時,再把他拿掉就可以了。不過,這時要記住您最後版本的Checksum 時,這樣子就不會搞亂您的韌體了,這是一種版控(版本控制)的觀念。

       這個階段的最後我來交代一下韌體介面與USB介面使用上的技巧。若看不太懂或領悟力不夠的話,那就還是老話一句:多多用功唸書!!

        重點一:像做這種Tool 的東西。有百分之九十幾都是利用USB Control Token 完成的。只有很少部分用到Bulk Transfer token  (甚至您不用我也沒意見!)。所以不要太在乎速度問題。因為所有的ISP動作都是交給USB 單晶片控制器韌體作的。所以,我上面的架構圖裡就是利用我USB 單晶片控制器內的那一部份16KBytes 的SRAM 。應該對ISP 4K/8K/16KBytes 綽綽有餘吧!當然,超過也沒問題,只是韌體會比較複雜一點而已。

        像Atmel ISP這種介面,也有他自己的 Instruction Format ,這部分當然是交由USB 單晶片控制器韌體來處理,這一部份就完全是USB Control Token 完成的,那怕是只讀一個Lock Bit也是。而我們上層應用程式就倒不一定要跟著他定義走,像我的作法如下:

            ATmel 89S51 Programmable Enable : AC/53 - - ; 而我上層命令為0x8D ! 反正 我自己USB 單晶片控制器韌體 看得懂就好了。

         重點二:記住一點:那怕是只是用USB Control Token 這慢的介面,他還是遠遠超過 ISP 介面中的SPI(Serial peripheral Interface)的速度,所以,不要下同一個命令去讀資料譬如讀Target IC 的Signatures Bytes。因為您一個 Setup-Out-Null In (Command)再加一個Setup-In-Null Out (Read Data) 最慢也是6mSec ,而且您還有可能打亂USB Contrller 正在處理的SPI 介面。版主的意思是說:先下一個命令讓USB 單晶片控制器 去處理SPI 介面。等一會兒再用另一個Setup Token 去讀 data 。這樣子,就可以完全確保USB 介面命令中斷不會去干擾SPI介面(因為這個介面可能是用8051 I/O 去造出來的!)。而且,也可以正確的讀到您所要的資料。這個重要觀念:在您作USB 轉 I2C 時,也是一樣適用的。所以,在上圖應用範例中:版主就是利用這樣子的觀念去完成那個ChipID 命令(其實就是 Signature Bytes Read 命令執行):

Virual C++ 程式碼:

BOOL CUSBAISPDlg::OnButtonSignature()
{
        // TODO: Add your control notification handler code here
        m_ICSignature= false;
        //----
        m_MessageBlanking=false; //clear blinking string show

        if(!USB_DEVICE_INITIALIZE())
        {
            m_MessageBlanking=true; //clear blinking string show
            BlinkShowString="Check USB Device or Cable...";
            return false;
        }

        m_MessageString.SetTextColor(LIGHTBLUE);
        m_MessageString.SetWindowText("Read Chip Signature...");
        m_TimerMessageUpdate = TRUE;
        //---
        CString BulkInStr;
        char BulkInRaw[5];
        //---
        hDEV = open_dev();
        if(hDEV!=INVALID_HANDLE_VALUE)
        {
            //---- Check RESET STATUS ----
            UINT GPIODR=USB_DEVICE_READ_GPIO();
            CButton *LocalRST;
            LocalRST = (CButton*) GetDlgItem(IDC_CHECK_RESETHOLD);
            if(!(GPIODR&0x80)){
                USB_DEVICE_RESETCOMMAND(1);
                LocalRST->SetCheck(TRUE);
            }
            //---- End of Check RESET STATUS ----
            int i;

            for(i=0;i<8;i++) STICommandString[i]=0x00; // reset the parameters
            STICommandString[0]=0x89; // Read ISP ID Test Command
            STICommandString[1]=0x01; //
            USB_DEVICE_SEND_STI_COMMAND(STICommandString);


            for(i=0;i<8;i++) STICommandString[i]=0x00; // reset the parameters
            STICommandString[0]=0x25; // Read ISP ID Test Command
            STICommandString[1]=0x01; //
            USB_DEVICE_SEND_STI_COMMAND(STICommandString);



            for(i=2;i<0x05;i++)
            {
                char ShwBulkIn[3]="00";
                ATMELSignature[i-2] = iobuffer[i];
                _itoa(iobuffer[i], BulkInRaw,16);
                if(strlen(BulkInRaw)!=2)
                {
                    strcpy(ShwBulkIn+1,strupr(BulkInRaw));
                }
                else
                    strcpy(ShwBulkIn,strupr(BulkInRaw));
                    BulkInStr += (CString)ShwBulkIn;
            }   
            //
            m_ChipSignature.SetWindowText(BulkInStr);
            //---
            //----- Parse the IC ---
            m_ICSignature= true;
            if(ATMELSignature[0]==0x1E && ATMELSignature[1]==0x51 && ATMELSignature[2]==0x06){
                Ini_CHIPCODE = 0x00;
                Ini_CHIPSIZE = 0x1000;
            }else if(ATMELSignature[0]==0x1E && ATMELSignature[1]==0x52 && ATMELSignature[2]==0x06){
                Ini_CHIPCODE = 0x01;
                Ini_CHIPSIZE = 0x2000;
            }else if(ATMELSignature[0]==0x1E && ATMELSignature[1]==0x53 && ATMELSignature[2]==0x06){
                Ini_CHIPCODE = 0x3000;
            }else{
                Ini_CHIPCODE = 0x00;
                Ini_CHIPSIZE = 0x1000;
                m_ICSignature= false;
            }
            m_SelectChip.SetCurSel(Ini_CHIPCODE);
            //----
            CloseHandle(hDEV);
            hDEV=INVALID_HANDLE_VALUE;
            return m_ICSignature;
        }else
        return false;
}

         所以,我們很快的就可以完成ISP的第一個重要命令:讀Target Chip 的ID 值了!

我們再看實際的波形:

    我們就很明顯可以讀到 Atmel 89S51 回給我們的 Signature Bytes 值了。

    那當我們這個環節打通之後,那剩下的那一些功能就輕而易舉了。那您覺得,利用USB介面來作Tool 簡不簡單啊?!

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

   (結語) 說真的,版主深深的體會到 USB 的東西是不可能再帶給版主有多大的激情與成就感的。也不知道最終要完成這樣的東西是有何種意義?!或許,真的只是剩下那一點功德無量的默默的善行吧。下一回也不知未來何年何時才有空寫下一集?所以,趁下一次還沒出國前,趕快補這麼一篇文章,再給版主的網頁再衝一衝人氣指數。

           但也別忘了多多給一點掌聲與鼓勵。

            也多多少少的瀏覽一下相關   FPPATM  - 的應用話題。相信  FPPATM  -會帶給您全然不同的電子領域。

    相較之下,您不覺得USB的東西就比較紅海嗎?!

            也謝謝您的不吝賜教!  下回見。

首頁 | 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日。