1. 程式人生 > >68013 燒錄方式 及iic生成

68013 燒錄方式 及iic生成

硬體程式燒錄

1)因為本產品要求將二進位制程式碼和硬體PID/VID燒錄在EEPROM,而不是使用CYPRESS推薦的線上下載方式,所以外部採用了8K的EEPROM。上電後68013A會將EEPROM中的資料和程式載入到RAM中執行。

2)HEX檔案只是68013A上8051的程式程式碼,還要加上PID/VID等資訊才能正確執行,CYPRESS在開發包中提供了HEX2BIN.EXE這個工具,可以根據HEX生成完備的IIC檔案,將此檔案燒錄到EEPROM上即可。

3)HEX2BIN.EXE的使用方法如下:

將XXX.HEX檔案拷貝到HEX2BIN.EXE所在目錄,開啟CMD,按如下格式輸入:

hex2bix -i -o xxx.iic xxx.hex -f 0xC2( -v 0x1234 -p 0x1234 )這個地方的PID VID 不用加,沒有用,生成的IIC檔案的pid vid 碼是與hex檔案相關,即有程式檔案中裝置描述符設定。

-i      表示輸出檔案,也就是IIC檔案

-o       表示輸入檔案,也就是HEX檔案

-f      表示68013A傳送PID/VID的方式,這裡為C0,即從EEPROM上讀取。

-v   表示VID的BCD碼,開發階段使用1234

-p   表示PID的BCD碼,開發階段使用1234

4)將生成的IIC檔案用燒寫器燒錄到EEPROM上,本專案使用的是深圳思泰佳電子公司的NSP通用燒寫器,此燒寫器不支援IIC型別,選擇BIN型別可替代

韌體除錯完畢後,可以將其轉化為IIC檔案燒寫到EEPROM中,採用C2方式啟動,這樣68013就會從EEPROM中獲取程式和VID、PID,不需要每次上電都下載韌體了。

首先需要將KEIL編譯好的hex檔案轉化為iic檔案,可以使用cypress提供的hex2bix,格式如下:

Hex2bix -i -f 0xC2 -o usb_sfifo.iic usb_sfifo.hex

-i表示要生成iic檔案,-f表示燒寫後採用C2方式啟動(程式、VID、PID都從EEPROM讀取),後面依次是要生成IIC檔案的檔名和原始檔的檔名,關於其他引數的用法可以參見hex2bix的幫助。

通過USB連線到計算機後,通過Cypress USB Console即可燒寫。開啟EZ-USB Interface,點選Lg EEPROM,然後選擇剛才生成好的IIC檔案可以。

需要注意的是在硬體上不同容量的EEPROM接法是不一樣的,否則燒寫之後也無法啟動。如下圖所示,大容量EEPROM的A0管腿需要上拉。

硬體程式燒錄 - Smalming - SmalmingS Blog
另外需要注意的是SCL SDA需要上拉,否則也會出現讀取問題。

 1.先把68013與EEPROM連線的I2C的SDA斷開。 
       2.插上USB線連線電腦 
      3.啟動軟體 
      4.把68013與EEPROM連線的I2C的SDA連上 
      5.在USB CONSOLE上點lg eeprom就可以下載了  
      相當於開始的時候68013沒有EEPROM裝置,EEPROM用片記憶體儲的描述符資料進行列舉。 
主機就通過這個自動的描述符同68013進行通訊。接著連上把68013與EEPROM連線的I2C的SDA連上,

 4.3    驅動的識別

1)將EEPROM連到 68013A 上後,接上USB線,上電。計算機提示找到新硬體,要求安裝驅動。

2)CYPRESS針對 68013A 提供了全新的驅動程式CYUSB.SYS。這個驅動使用了新的API,所以上位機的編寫上和舊的方式完全不同。底層的IOCTL控制字的定義也完全不同,詳見CYAPI.PDF和CYUSB.PDF。

3)安裝驅動之前,必須先根據VID/PID正確編輯CYUSB.INF檔案,在檔案中新增自己的PID/VID程式碼和裝置描述,連線裝置時,將根據硬體上的PID/VID查詢INF檔案中對應的驅動,如果找不到,在裝置管理器中將顯示“68013 EEPROM MISSING”的字樣。

4)詳細的INF配置方法參考CYUSB.PDF PART1/PART2/PART3。這裡不在贅述。

5)安裝驅動時候找到修改好的CYUSB.INF檔案,驅動將被正確安裝,此時裝置可以正常使用。



4.4    測試過程

1)被正確識別的裝置可以在CYPRESS CONSOLE上看到裝置資訊。如圖:



2)CYPRESS CONSOLE的具體使用方法請參考CyConsole.chm。

3)要注意的是,除EP0/EP1外,當其他端點Max Pkt Size大小為64位元組時,表示工作在USB 1.1模式,有可能是軟體的原因,也有可能是外圍上拉電阻的問題。開發中要特別注意。

5.   推薦開發流程

5.1 看本介紹USB 2.0協議的書,對USB 2.0協議有所瞭解。推薦《USB 2.0原理與工程開發》

5.2 看CYUSB.PDF文件。瞭解驅動安裝方法。

5.3 看KEIL C51的書籍,熟悉C51的程式設計方法,熟悉KEIL C程式設計環境。

5.4 看CYPRESS提供的例程,瞭解 68013A 程式設計框架。推薦《EZ-USB 2100系列微控制器原理、程式設計及應用》(基本框架類似,部分暫存器定義不同)。

5.5 對照USB 2.0協議,編寫dscr.a51檔案,配置各種描述符。

5.6 結合FX2 TechRefManual.pdf,研讀FW.C、PERIPH.C、FX2REGS.H、FX2.H,瞭解暫存器的定義。

5.7 根據系統需求編寫響應程式碼,有開發板時,根據開發版上的LED來測試程式正確與否。

5.8 根據CYAPI.PDF CYUSB.PDF編寫上位機通訊程式。

同步讀取資料方法      XferData();

非同步讀取資料方法                 BeginDataXfer()/WaitForXfer()/FinishDataXfer();

5.9 除錯程式。

5.10               編寫其他8051上的程式,並繼續除錯。

6.   釋出時應提供的檔案

1)CYUSB.SYS

2)CYUSB.INF

3)XXX.IIC

7.   重點講解

7.1    如何理解CYPRESS 68013A 程式框架

CYPRESS提供了非常好的程式框架,免去了使用者自己編寫一些通用性比較強、模式化的程式(如果不提供,很少有人能寫出如此高效,結構緊湊的程式,實際上此框架和 68013A 內部結構關係密切,一般人也沒有足夠的內部資料也不可能寫出來)。在框架的基礎上,使用者只需在相應的地方寫相應的程式碼即可完成USB工作。

一般來說框架可以分成3個部分。

1)              描述符檔案。例如dscr.a51檔案,裡面定義了列舉裝置的時候要用的各種描述符資訊,這部分使用者需要根據實際的情況自己編寫。我寫的時候發現一個最大的問題就是各種書籍協議版本不同,翻譯質量不同,同一欄位的意義表述不同,容易讓人產生困惑。例如USB 1.1/2.0/2.13對裝置型別的子類定義都不完全相同,所以寫的時候最好幾種文件對比起來寫。由於USB官方網站的文件中欄位解釋過於專業化,所以對USB不是很熟悉的人比較難以理解其真正含義。所以要多參考不同的書籍,某種程度上降低了開發速度,但對第一次做USB開發的人來說,這也是值得的。

2)              韌體檔案,例如FW.C檔案,這是硬體程式的函式入口。主要有以下這些方法:

void SetupCommand(void);     //握手命令處理

void TD_Init(void);   //初始化,完成配置,啟動時呼叫一次

void TD_Poll(void);   //使用者處理程式,迴圈呼叫

void IO_Init(void);   //8051 IO初始化

void REG_Init(void); //8051暫存器初始化

BOOL TD_Suspend(void);    //掛起處理

BOOL TD_Resume(void);     //喚醒處理

//以下為各種描述符的獲取和設定函式,重列舉時自動呼叫

BOOL DR_GetDescriptor(void);

BOOL DR_SetConfiguration(void);

BOOL DR_GetConfiguration(void);

BOOL DR_SetInterface(void);

BOOL DR_GetInterface(void);

BOOL DR_GetStatus(void);

BOOL DR_ClearFeature(void);

BOOL DR_SetFeature(void);

BOOL DR_VendorCmnd(void);

3)              功能檔案,處理各種中斷。例如PERIPH.C檔案。8051一般預設只有四個中斷,這顯然不夠USB使用,所以CYPRESS引入了自動向量的概念,相當於軟中斷,大大擴充套件了現有的中斷數量。主要的中斷有:

void ISR_Sudav(void) interrupt 0 //收到setup包

void ISR_Sutok(void) interrupt 0 //收到SETUP令牌

void ISR_Sof(void) interrupt 0 //收到起始幀

void ISR_Ures(void) interrupt 0 //收到RESET

void ISR_Susp(void) interrupt 0 //收到掛起資訊

void ISR_Highspeed(void) interrupt 0 //高速模式

void ISR_Ep0ack(void) interrupt 0   //正常響應ACK

void ISR_Stub(void) interrupt 0

void ISR_Ep 0in (void) interrupt 0

void ISR_Ep0out(void) interrupt 0

void ISR_Ep 1in (void) interrupt 0

void ISR_Ep1out(void) interrupt 0 //EP1輸入中斷

void ISR_Ep2inout(void) interrupt 0     //EP2中斷

void ISR_Ep4inout(void) interrupt 0

void ISR_Ep6inout(void) interrupt 0

void ISR_Ep8inout(void) interrupt 0

void ISR_Ibn(void) interrupt 0

void ISR_Ep0pingnak(void) interrupt 0

void ISR_Ep1pingnak(void) interrupt 0

void ISR_Ep2pingnak(void) interrupt 0

void ISR_Ep4pingnak(void) interrupt 0

void ISR_Ep6pingnak(void) interrupt 0

void ISR_Ep8pingnak(void) interrupt 0

void ISR_Errorlimit(void) interrupt 0

void ISR_Ep2piderror(void) interrupt 0

void ISR_Ep4piderror(void) interrupt 0

void ISR_Ep6piderror(void) interrupt 0

void ISR_Ep8piderror(void) interrupt 0

void ISR_Ep2pflag(void) interrupt 0

void ISR_Ep4pflag(void) interrupt 0

void ISR_Ep6pflag(void) interrupt 0

void ISR_Ep8pflag(void) interrupt 0

void ISR_Ep2eflag(void) interrupt 0

void ISR_Ep4eflag(void) interrupt 0

void ISR_Ep6eflag(void) interrupt 0

void ISR_Ep8eflag(void) interrupt 0

void ISR_Ep2fflag(void) interrupt 0

void ISR_Ep4fflag(void) interrupt 0

void ISR_Ep6fflag(void) interrupt 0

void ISR_Ep8fflag(void) interrupt 0

void ISR_GpifComplete(void) interrupt 0

void ISR_GpifWaveform(void) interrupt 0

特別是對於接受資料,一般都在中斷中完成相應處理,“中斷中適合進行少量簡短的操作,不適合進行復雜操作”,這句話在此依然有效。如果要進行復雜的操作可以在TD_POLL()中進行(多數操作都是在這個函式中完成的)。

另外非常重要的一點是,中斷程式的結尾應該讓中斷復位,允許下一次中斷,有些端點的計數器也要清零並允許接受新的中斷請求。例如:

    EP1OUTBC = 0; //清空計數

    EZUSB_IRQ_CLEAR(); //USB中斷復位

    EPIRQ = 0x08;     //允許EP1中斷請求

7.2     68013A 端點暫存器介紹

68013A 內部的暫存器約有300個上下,一次都記住是不可能的,而且每個暫存器都有8個位,也就是說一共有2000多個可以配置的位,一次都理解掌握這些位的含義也是不可能的,所幸地是開發中並不會用到所有的暫存器,但是依然強烈建議把FX2REGS.H和FX2.H走讀一邊,這就像讀書一樣,沒有學會識字,再看都是天書。結合FX2 TechRefManual.pdf走讀這些暫存器大約需要一到兩天時間,這點時間投入還是值得的。

在通訊過程中,打交道最多的是各種端點暫存器,掌握好這些暫存器地使用對提升開發效率是很有幫助。值得特別關注的暫存器和配置位如下:

Rwuen、REVCTL、EP1OUTCFG、EP1INCFG、EP2CFG、EP4CFG、EP6CFG、EP8CFG、EP2FIFOCFG、EP4FIFOCFG、EP6FIFOCFG、EP8FIFOCFG、FIFORESET、EPIRQ、EPIE、EP1OUTBC、APTR1H、APTR 1L 、EXTAUTODAT1、AUTOPTRH2、AUTOPTRL2、EXTAUTODAT2、EP2BCH、EP2BCL

其中有些暫存器的設定需要連續設定多次,看似重複了,其實不然,這和設定的緩衝區數量有關。有些暫存器中間必須用SYNCDELAY來延時。這類暫存器FX2 TechRefManual.pdf上有說明。

對於EP0,用於系統握手,相關的暫存器操作基本上都由 68013A 的核心(SIE)來完成了。

對於EP1,分為OUT/IN兩組配置和暫存器。

對於EP2~EP8,不分OUT/IN輸入輸出,主要有EP2CFG/ EP2FIFOCFG/ EP2BCH/EP2BCL暫存器。

7.3    什麼是自動指標

自動指標是CYPRESS提供的一個非常有用的特性。在資料互動的過程中,很多時候都涉及到資料的搬遷,比如從EP2OUT收到的資料需要轉發到EP 6IN 上(一些轉換類裝置);再比如從RAM中拷貝資料到EP 4IN 上,傳統的做法是申明兩個指標,指向源和目的地址,然後用迴圈一個個位元組拷貝,同時還要考慮增加指標地址,對於連續的空間這到不是問題,關鍵是如果資料需要拷貝到多個緩衝時,指標地址是迴圈的。這時候如果手工完成操作很容易出錯。

因此CYPRESS提供了兩組自動指標,用的時候一組指向源,一組指向目的地址。然後迴圈拷貝資料就行了,自動指標會自動指向下一個源或目的空間,不論是否是迴圈地址方式。這樣減少了程式出錯的機率。

下面的程式將EP2OUT接受到的資料拷貝到EP 6IN 傳送出去:

     if(!(EP2468STAT & bmEP6FULL))

     { // check EP6 FULL(busy) bit in EP2468STAT (SFR), core set's this bit when FIFO is full

        APTR1H = MSB( &EP2FIFOBUF );

        APTR 1L = LSB( &EP2FIFOBUF );

          AUTOPTRH2 = MSB( &EP6FIFOBUF );

        AUTOPTRL2 = LSB( &EP6FIFOBUF );

          count = (EP2BCH << 8) + EP2BCL;

          // loop EP2OUT buffer data to EP 6IN

        for( i = 0x0000; i < count; i++ )

        {

           // setup to transfer EP2OUT buffer to EP 6IN buffer using AUTOPOINTER(s)

           EXTAUTODAT2 = EXTAUTODAT1;

        }

        EP6BCH = EP2BCH; 

        SYNCDELAY; 

        EP6BCL = EP2BCL;        // arm EP 6IN

        SYNCDELAY;                   

        EP2BCL = 0x80;          // re(arm) EP2OUT

     }

}

APTR1H/APTR1H通過MSB和LSB獲取EP2FIFOBUF的高位地址和地位地址。

EXTAUTODAT1表示APTR1H/APTR1H指向的資料。

AUTOPTRH2/AUTOPTRL2通過MSB和LSB獲取EP6FIFOBUF的高位地址和地位地址。

EXTAUTODAT2表示AUTOPTRH2/AUTOPTRL2指向的資料。



7.4    CYUSB和CYAPI的關係

以前68013上位機程式的編寫過程中,應用程式端通過呼叫DeviceIoControl() API或CREATEPIPE() API與驅動進行互動,繼而讀寫控制硬體裝置,在新的 68013A 的驅動中採用了兩種新的呼叫方法:

第一種是繼續使用DeviceIoControl()函式讀寫,不同的是,IOCTL控制字和老驅動完全不同,具體定義參考CYUSB.PDF。使用者可以通過這些底層API完成操作。

第二種是使用CYPRESS提供的面對物件的類,一共有9個類,呼叫這些類的方法就可以和硬體打交道。這些類是對第一種方法的封裝,使用起來非常簡便。

使用者可以根據需要選擇這兩種方法或混合使用,使用時需要加上標頭檔案CyAPI.h和cyioctl.h,另外在專案中還要引用CyAPI.lib。



7.5    同步和非同步讀寫的比較

CYAPI提供了同步和非同步讀寫方式。同步方式的時候呼叫執行緒阻塞在哪裡,直到讀寫到資料或超時;非同步方式的時候呼叫執行緒立即返回。具體例項參考CYAPI.PDF。



7.6    如何用C++ BUILDER寫上位機程式

1)            首先確定使用7.4中的第幾種方法,新增相應的標頭檔案和庫檔案。

2)            連線USB裝置,確保驅動已經被正確載入。

3)            編寫收發資料執行緒。通過開發板上的LED或CYPRESS CONSOLE或BUS HOUND分析收發正確與否。



7.7    U盤如何正確載入驅動

在WINDOWS 2000/XP上U盤使用的PID/VID應該直接能載入作業系統預設的海量儲存器的驅動程式。為了使用正確的PID/VID,可以通過以下途徑:

1)            找一個現有品牌的U盤,看看他的PID/VID是何值。

2)            在登錄檔中查詢海量儲存器資訊。



8.   其他問題

1)            編寫上位機的時候要注意新增異常處理。

2)            除錯上位機的時候,USB外設應正確連線。

3)            8051其他模組的編寫請參考相應書籍。