• 正文
    • 10.7  典型實(shí)例17:USB 2.0接口的設(shè)計(jì)與實(shí)現(xiàn)
  • 相關(guān)推薦
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

利用FPGA實(shí)現(xiàn)外設(shè)通信接口之: 典型實(shí)例-USB 2.0接口的設(shè)計(jì)與實(shí)現(xiàn)

2013/08/30
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

?

10.7??典型實(shí)例17:USB?2.0接口的設(shè)計(jì)與實(shí)現(xiàn)

10.7.1??實(shí)例的內(nèi)容及目標(biāo)

1.實(shí)例的主要內(nèi)容

本節(jié)旨在設(shè)計(jì)實(shí)現(xiàn)了FPGA通過FX2?USB?2.0接口芯片與PC機(jī)進(jìn)行高速數(shù)據(jù)通信,分為讀數(shù)據(jù)、寫數(shù)據(jù)和讀寫數(shù)據(jù)3部分內(nèi)容。幫助讀者進(jìn)一步了解USB接口芯片的工作原理和設(shè)計(jì)方法。

2.實(shí)例目標(biāo)

通過本實(shí)例,讀者應(yīng)達(dá)到如下目標(biāo)。

·??了解FX2?CY7C68013芯片的工作原理和Slave?FIFO模式時(shí)序。

·??了解FX2的固件設(shè)計(jì)以及USB驅(qū)動(dòng)程序設(shè)計(jì)。

·??熟練掌握狀態(tài)機(jī)的使用。

·??實(shí)現(xiàn)FPGA與PC機(jī)之間的USB接口通信。

10.7.2??USB接口通信實(shí)戰(zhàn)步驟

首先創(chuàng)建工程并為工程添加文件,如圖10.30所示。

然后編譯工程并下載至硬件,如圖10.31所示。

???????

圖10.30??創(chuàng)建工程并添加文件?????? 圖10.31??編譯工程并下載

?

接下來可以加載固件了,固件程序的載入有兩種方式。

(1)通過芯片的I2C總線連接外部的EEPROM,固件代碼事先通過燒寫器寫入EEPROM中,USB設(shè)備上電運(yùn)行時(shí),通過I2C總線將EEPROM中固件代碼載入。EZ-USB支持外部EEPROM通過總線來下載固件,這種方式使開發(fā)者可以從外圍硬件來下載8051程序代碼,但是不利于在設(shè)備開發(fā)階段使用。

(2)使用該芯片特有軟配置功能,將固件程序存儲(chǔ)在計(jì)算機(jī)中,當(dāng)該設(shè)備接入U(xiǎn)SB電纜時(shí),由于EZ-USB具有重新枚舉的能力,所以在初始化枚舉以后,用戶只需要通過Cypress公司提供的開發(fā)軟件USB?Control?Panel中Download項(xiàng),就可以將固件載入到控制芯片中。該方法完全是軟操作,不需要額外的硬件設(shè)備,方便程序的修改調(diào)試。

使用USB?Control?Panel進(jìn)行固件程序下載的界面如圖10.32所示。

圖10.32??USB?Control?Panel界面

單擊“Download…”按鈕,選擇“slavefifo.hex”。下載固件成功以后顯示如圖10.33信息。

圖10.33??下載固件程序

其中,通過單擊“GetPipes”按鈕可以查看通道信息。

現(xiàn)在固件程序后,即可進(jìn)行USB通信測(cè)試。

根據(jù)不同的程序,選擇相應(yīng)的測(cè)試軟件,測(cè)試USB接口的傳輸速度。如圖10.34所示是Red?Logic工作室提供的基于紅色颶風(fēng)II的USB測(cè)試軟件。

圖10.34??USB測(cè)試軟件

?

10.7.3??USB接口通信實(shí)例結(jié)果

實(shí)現(xiàn)FPGA與PC機(jī)之間的USB通信,并且在PC機(jī)的超級(jí)終端上面測(cè)試USB的讀寫速度,如圖10.35和圖10.36所示。關(guān)于EZ-USB的詳細(xì)內(nèi)容,可參見工程文件夾中提供的相關(guān)文檔。

圖10.35??USB測(cè)試結(jié)果

圖10.36??USB測(cè)試結(jié)果

?

10.7.4??FPGA代碼的設(shè)計(jì)實(shí)現(xiàn)

本程序功能是配合CY68013的Slave?FIFO接口時(shí)序。它完成接收從主機(jī)下傳的60KB數(shù)據(jù),寫入板上SRAM里,然后從板上SRAM中讀出,再上傳至主機(jī)。整個(gè)傳輸過程通過CY68013的Slave?FIFO來交互。

整個(gè)程序由一個(gè)狀態(tài)機(jī)構(gòu)成,包括以下狀態(tài):

Parameter?IDLE='H0,

???????????????READ_EVENT='H1,

???????????????POINT_TO_OUT_FIFO='H2,

???????????????DATA_READY='H3,

???????????????READ_INTERVAL='H4,

???????????????READ='H5,

???????????????READ_END='H6,

???????????????WRITE_EVENT='H7,

???????????????POINT_TO_IN_FIFO='H8,

???????????????WRITE_READY='H9,

???????????????WRITE='HA,

???????????????WRITE_END='HB;

每個(gè)狀態(tài)的作用描述如下。

·??IDLE:整個(gè)操作過程(包括讀SLAVE?FIFO和寫SLAVE?FIFO)的入口。對(duì)相關(guān)的寄存器進(jìn)行初始化,然后轉(zhuǎn)入READ_EVENT狀態(tài),開始讀SLAVE?FIFO操作。

·??READ_EVENT:把u_addr[1:0]置為’b00,指向輸出FIFO(對(duì)應(yīng)端點(diǎn)6),然后轉(zhuǎn)入POINT_TO_OUT_FIFO狀態(tài)。

·??POINT_TO_OUT_FIFO:判斷u_flagc是否為高(u_flagc為高指示輸出FIFO為空,即輸出FIFO中有數(shù)據(jù)),如果為高,則啟動(dòng)讀過程,把u_sloe置為低,轉(zhuǎn)入DATA_READY狀態(tài),第一個(gè)16位數(shù)據(jù)出現(xiàn)在總線上;否則說明輸出FIFO中無數(shù)據(jù),等待。

·??DATA_READY:判斷u_flagc是否為高,如果為高,把u_slrd拉低,繼續(xù)讀取下16位數(shù)據(jù)。同時(shí)為把上一16位數(shù)據(jù)寫入SRAM做準(zhǔn)備(主要是SRAM的三態(tài)總線),同時(shí)轉(zhuǎn)入READ狀態(tài),否則轉(zhuǎn)入POINT_TO_OUT_FIFO,等待下一次讀取過程。

·??READ:把上一16位數(shù)據(jù)寫入SRAM,同時(shí)把u_slrd拉高,當(dāng)前16位數(shù)據(jù)讀取結(jié)束。判斷是否是60KB數(shù)據(jù),如果不是,則轉(zhuǎn)入DATA_READY狀態(tài),繼續(xù)讀操作;否則轉(zhuǎn)入READ_END狀態(tài),讀操作結(jié)束。

·??READ_END:把相關(guān)寄存器置為初始態(tài),轉(zhuǎn)入WRITE_EVENT狀態(tài),開始寫操作。

·??POINT_TO_IN_FIFO:為從SRAM中讀取數(shù)據(jù)作準(zhǔn)備,轉(zhuǎn)入WRITE_READY狀態(tài)。

·??WRITE_READY:判斷u_flagb是否為高(u_flagb為高指示輸入FIFO非滿),如果為高,則啟動(dòng)寫過程,從SRAM中讀取數(shù)據(jù)并送到SLAVE?FIFO總線上,把u_lswr置為低,轉(zhuǎn)入WRITE狀態(tài);否則說明輸入FIFO已滿,等待。

·??WRITE:把u_slwr置為高,當(dāng)前數(shù)據(jù)寫入SLAVE?FIFO。判斷是否是60KB數(shù)據(jù),如果不是,則轉(zhuǎn)入WRITE_READY狀態(tài),繼續(xù)寫操作;否則轉(zhuǎn)入WRITE_END狀態(tài),寫操作結(jié)束。

?

·??WRITE_END:把相關(guān)寄存器置為初始態(tài),轉(zhuǎn)入IDLE狀態(tài),開始下一個(gè)60KB的讀寫操作。

狀態(tài)機(jī)的源代碼如下:

case(STATE)

?????IDLE:

??????????begin

??????????//添加RESET狀態(tài)

??????????data_wr<='h0;??????????????? //?USB接口信號(hào)初始化

??????????u_slwr<='b1;

??????????u_slrd<='b1;

??????????u_sloe<='b1;

??????????u_addr0<='b1;

??????????u_addr1<='b1;

??????????oe<='b0;

?????

??????????sram_d_i<='h0;?????????????? //?SRAM的控制信號(hào)初始化

??????????sram_a<='h3ffff;

??????????sram_re<='b1;

??????????sram_wr<='b1;

??????????wr_flag<='b0;

??????????

??????????STATE<=READ_EVENT;

??????????end

?????READ_EVENT:

??????????begin

??????????wr_flag<='b1;?????????????? //?設(shè)定讀寫標(biāo)志

??????????u_addr0<='b0;?????????????? //?指定端點(diǎn)FIFO

??????????u_addr1<='b0;

??????????STATE<=POINT_TO_OUT_FIFO;

??????????end

?????POINT_TO_OUT_FIFO:

??????????begin

??????????if(u_flagc)???????????????? //??如果flagc高,F(xiàn)IFO不空,開始讀數(shù)據(jù)

???????????????begin

???????????????u_sloe<='b0;????????? //?開始從FX2的端點(diǎn)FIFO讀數(shù)據(jù)

???????????????u_slrd<='b1;

???????????????STATE<=DATA_READY;

???????????????end

??????????else

??????????????begin????????? ???? //?如果flagc為低,F(xiàn)IFO為空,等待FIFO有數(shù)據(jù)

??????????????u_sloe<='b1;????? //?停止從FX2的端點(diǎn)FIFO讀數(shù)據(jù)

??????????????u_slrd<='b1;

??????????????STATE<=POINT_TO_OUT_FIFO;

??????????????end

??????????end

?????DATA_READY:

??????????begin

??????????if(u_flagc)???????????? //?如果flagc為高,繼續(xù)讀取下一個(gè)數(shù)據(jù)

??????????????begin

??????????????u_slrd<='b0;???????

??????????????sram_a<=sram_a+1;? //?把上一個(gè)讀取的數(shù)據(jù)寫入SRAM

??????????????sram_d_i<=data;

??????????????sram_wr<='b0;

??????????????sram_re<='b1;

??????????????STATE<=READ;??????? //?完成數(shù)據(jù)寫入后,進(jìn)入讀數(shù)據(jù)狀態(tài)

??????????????end

??????????else

??????????????begin

??????????????u_slrd<='b1;??????? //?如果FIFO空,回到等待狀態(tài)

??????????????u_sloe<='b1;

??????????????STATE<=POINT_TO_OUT_FIFO;

??????????????end

??????????end

?????READ:

??????????Begin??????????????

??????????u_slrd<='b1;??????????? //?完成上一個(gè)數(shù)據(jù)的SRAM寫周期

??????????sram_re<='b1;

??????????sram_wr<='b1;

??????????

??????????if(sram_a!=ADDR_FULL)?? //?如果SRAM地址沒有到最大值,繼續(xù)讀操作

??????????????STATE<=DATA_READY;

??????????else

??????????????STATE<=READ_END;? //?如果SRAM地址到達(dá)最大值,結(jié)束讀操作

??????????end

?????READ_END:

??????????begin

??????????u_slrd<='b1;?????????? //?回到初始狀態(tài),準(zhǔn)備寫操作

??????????u_sloe<='b1;

??????????u_addr0<='b0;

??????????u_addr1<='b0;

??????????sram_a<='h3ffff;

??????????STATE<=WRITE_EVENT;

??????????end

?????WRITE_EVENT:

??????????begin

??????????u_addr0<='b0;???????? //?指定寫數(shù)據(jù)的端點(diǎn)FIFO

??????????u_addr1<='b1;

??????????oe<='b1;

??????????wr_flag<='b0;

??????????STATE<=POINT_TO_IN_FIFO;

??????????end

?????POINT_TO_IN_FIFO:

??????????begin

??????????sram_a<=sram_a+1;?? //?從SRAM中讀取一個(gè)數(shù)據(jù)

??????????sram_re<='b0;

??????????sram_wr<='b1;

??????????STATE<=WRITE_READY;

??????????end

?????WRITE_READY:

??????????begin

??????????if(u_flagb)?

??????????????begin????????????? //?如果FIFO不滿,開始寫數(shù)據(jù)到FX2的FIFO

??????????????data_wr<=sram_d;

??????????????u_slwr<='b0;

??????????????u_slrd<='b1;

??????????????STATE<=WRITE;

??????????????end

??????????else

??????????????begin???????

??????????????u_slwr<='b1;??????? //?如果FIFO已滿,等待

??????????????u_slrd<='b1;

??????????????STATE<=WRITE_READY;

??????????????end

??????????end

?????WRITE:

??????????begin

??????????u_slwr<='b1;????????????

??????????u_slrd<='b1;

??????????if(sram_a!=ADDR_FULL)

??????????????begin

??????????????sram_a<=sram_a+1;? //?如果SRAM地址沒有達(dá)到最大值,繼續(xù)從SRAM讀數(shù)據(jù)

??????????????sram_wr<='b1;

??????????????sram_re<='b0;

??????????????STATE<=WRITE_READY;

??????????????end

??????????else

??????????????begin

??????????????sram_a<='h3ffff;?//?如果SRAM地址達(dá)到最大值,復(fù)位SRAM地址,進(jìn)入寫結(jié)束

??????????????sram_wr<='b1;

??????????????sram_re<='b1;

??????????????STATE<=WRITE_END;

??????????????end

??????????end

?????WRITE_END:

??????????begin

??????????wr_flag='b0;????????? //?結(jié)束寫FX2?FIFO狀態(tài),回到初始的IDLE狀態(tài)

??????????sram_a<='h3ffff;

??????????u_addr0<='b1;

??????????u_addr1<='b1;

??????????STATE<=IDLE;

??????????end

?????default:

??????????STATE<=IDLE;

?????endcase

10.7.5??小結(jié)

本節(jié)對(duì)利用USB接口芯片F(xiàn)X2來完成FPGA和PC機(jī)的高速數(shù)據(jù)傳輸做了介紹,并通過編譯下載在紅色颶風(fēng)的開發(fā)板上實(shí)現(xiàn)了預(yù)定功能。

相關(guān)推薦

登錄即可解鎖
  • 海量技術(shù)文章
  • 設(shè)計(jì)資源下載
  • 產(chǎn)業(yè)鏈客戶資源
  • 寫文章/發(fā)需求
立即登錄

華清遠(yuǎn)見(www.farsight.com.cn)是國(guó)內(nèi)領(lǐng)先嵌入師培訓(xùn)機(jī)構(gòu),2004年注冊(cè)于中國(guó)北京海淀高科技園區(qū),除北京總部外,上海、深圳、成都、南京、武漢、西安、廣州均有直營(yíng)分公司。華清遠(yuǎn)見除提供嵌入式相關(guān)的長(zhǎng)期就業(yè)培訓(xùn)、短期高端培訓(xùn)、師資培訓(xùn)及企業(yè)員工內(nèi)訓(xùn)等業(yè)務(wù)外,其下屬研發(fā)中心還負(fù)責(zé)嵌入式、Android及物聯(lián)網(wǎng)方向的教學(xué)實(shí)驗(yàn)平臺(tái)的研發(fā)及培訓(xùn)教材的出版,截止目前為止已公開出版70余本嵌入式/移動(dòng)開發(fā)/物聯(lián)網(wǎng)相關(guān)圖書。企業(yè)理念:專業(yè)始于專注 卓識(shí)源于遠(yuǎn)見。企業(yè)價(jià)值觀:做良心教育、做專業(yè)教育,更要做受人尊敬的職業(yè)教育。