設計背景:
USB(Universal Serial Bus2.0,通用串行總線)是一種應用在計算機領域的新型接口技術。USB接口具有傳輸速度更快,支持熱插拔以及連接多個設備的特點。目前已經在各類外部設備中廣泛的被采用。USB接口有三種:USB1.1,USB2.0和USB3.0。理論上USB1.1的傳輸速度可以達到12Mbps,而USB2.0則可以達到速度480Mbps,并且可以向下兼容USB1.1。
設計原理:
本次的設計主要設計我們用用的開發板是我們至芯出的第一代開發板,其中的USB芯片C是ypress的FX2LP系列中的CY7C68013A代,詳細的介紹不多說,見Cypress的官網:在這里我就簡化的給大家做一個簡單介紹。
FX2的設計架構如下圖,內嵌480MBit/s的收發器,鎖相環PLL,串行接口引擎SIE——集成了整個USB 2.0協議的物理層。為適應USB 2.0的480MBit/s的速率,FIFO端點可配置成2,3,4個緩沖區。 配置用的是“軟配置”——USB固件可由USB總線下載,片上不需集成ROM。擁有四個FIFO接口,可工作在內部或外部時鐘下。端點和FIFO接口的應用使外部邏輯和USB總線可高速連接。
基于FX2LP的USB開發,包括三部分:固件程序、驅動、上位機軟件。
固件程序我們在kiil中寫出來,然后配置到我們的芯片中,固件的開發對我們FPGA工程師來說是不用寫的,是別的工程師配置好芯片我們拿來用的,其主要的配置過程如下圖:先上電復位,然后初始化我們的寄存器變量,然后調用配置函數,打開中斷后,判斷是否接受到了我們的配置包,如果接收到了就調用TD_POLL()函數,這個是函數是不停的執行掃描我們的端點等。然后判斷我們的芯片是否掛起,如果掛起就叫醒芯片,如果沒有就一直調用TD_POLL函數,這樣完成我們所需要的配置。
我們的項目是要把我們的FX2配置成從FIFO的模式, 配置為單片機工作時鐘24M,端點2輸出,字節1024,端點6輸入,字節1024,信號全設置為低電平有效等。我們的模塊驅動時鐘我們配置成內部輸出時鐘,也就是讓FX2給我們的設計當做時鐘源,輸出一個最大的配置時鐘48M的時鐘。
在這邊說一下,我們的FX2的數據存儲區叫端點,有512,1024字節兩個存儲大小之分。
從FIFO的說明:
當有一個與FX2芯片相連的外部邏輯只需要利用FX2做為一個USB 2.0接口而實現與主機的高速通訊,而它本身又能夠提供滿足Slave FIFO要求的傳輸時序,可以做為Slave FIFO主控制器時,即可考慮用此傳輸方式。
Slave FIFO傳輸的示意圖如下:
在這種方式下,FX2內嵌的8051固件的功能只是配置Slave FIFO相關的寄存器以及控制FX2何時工作在Slave FIFO模式下。一旦8051固件將相關的寄存器配置完畢,且使自身工作在Slave FIFO模式下后,外部邏輯(如FPGA)即可按照Slave FIFO的傳輸時序,高速與主機進行通訊,而在通訊過程中不需要8051固件的參與。
FX2系列的有3種封裝方式,我們我的開發板用的是56引腳的封裝方式的電路圖,其電路圖如下所示:
端口介紹:
IFCLK:FX2輸出的時鐘,可做為通訊的同步時鐘;
SLCS:FIFO的片選信號,外部邏輯控制,當SLCS輸出高時,不可進行數據傳輸;
SLOE:FIFO輸出使能,外部邏輯控制,當SLOE無效時,數據線不輸出有效數據;
SLRD:FIFO讀信號,外部邏輯控制,同步讀時,FIFO指針在SLRD有效時的每個IFCLK的上升沿遞增。
SLWR:FIFO寫信號,外部邏輯控制,同步寫時,在SLWR有效時的每個IFCLK的上升沿時數據被寫入,FIFO指針遞增
FD[15:0]:數據線;
FIFOADR[1:0]:選擇四個FIFO端點的地址線,外部邏輯控制。
FLAGA,B,C端點的空滿標志位
我們的開發驅動大家可以在網上找,然后根據自己系統裝上合適的驅動,或者在我們的至芯論壇上搜EZ-USB,就可以看到我們老師發的帖子來講解驅動的安裝。
我們的上位機軟件用的是官方的開發工具,只有如下的安裝包
然后安裝第一個和第二個就好了。
設計代碼:
讀模塊:
0moduleusb_rd(pi_clk,pi_rst_n,pi_usb_flagb,pi_usb_flagc, pio_usb_data,
1 po_usb_oe_n,po_usb_rd_n,po_usb_address,po_usb_wr_n,led);
2
3 inputpi_clk;
4 inputpi_rst_n;
5 inputpi_usb_flagb; //端點2標志信號
6 inputpi_usb_flagc;//端點6標志信號
7 inout[15:0]pio_usb_data;//輸入輸出端口
8
9 outputregpo_usb_oe_n;//讀標志信號
10 outputregpo_usb_rd_n;//寫使能
11 outputregpo_usb_wr_n;//讀使能
12 outputreg[1:0]po_usb_address;//端點地址選擇
13 outputregled; //接收標志正確指示燈
14
15 reg[15:0]temp_data;
16 reg[9:0]count;
17 reg[2:0]state;
18
19 assignpio_usb_data =(state ==10)?1:16'hzzzz; //讀數 據,可以一直釋放數據總線的控制權
20
21 always@(posedgepi_clk ornegedgepi_rst_n)
22 if(!pi_rst_n)
23 begin
24 state <=0;
25 po_usb_oe_n <=1;
26 po_usb_rd_n <=1;
27 count <=0;
28 po_usb_wr_n <=1;
29 temp_data <=0;
30 end
31 else
32 case(state)
33 0 : state <=1;
34
35 1 : begin
36 po_usb_address <=2'b00;//地址指向端點2
37 state <=2;
38 end
39
40 2 : if(!pi_usb_flagb) //判斷端點2已經滿
41 begin
42 po_usb_rd_n <=0;
43 state <=3;
44 po_usb_oe_n <=0;
45 end
46 else
47 state <=2;
48
49 3 : begin
50 if(count <512-1) //接收1024字節的數 據
51 begin
52 count <=count +1'b1;
53 end
54 else
55 begin
56 count <=0;
57 state <=4;
58 end
59 if(count ==2)
60 begin
61 temp_data <=pio_usb_data;
62 end
63 end
64
65 4 : begin
66 po_usb_rd_n <=1;
67 po_usb_oe_n <=1;
68 state <=0;
69 end
70
71 default: state <=0;
72 endcase
73
74 always@(*)
75 if(!pi_rst_n)
76 led <=1;
77 elseif(temp_data ==16'h33ff)//判斷我們接收數據是否正確
78 led <=0;
79
80endmodule
寫模塊:
0moduleusb_wr(pi_clk,pi_rst_n,pi_usb_flagb,pi_usb_flagc, pio_usb_data,
1 po_usb_oe_n,po_usb_wr_n,po_usb_address,po_usb_rd_n);
2
3 inputpi_clk;
4 inputpi_rst_n;
5 inputpi_usb_flagb; //端點2標志信號
6 inputpi_usb_flagc; //端點6標志信號
7 inout[15:0]pio_usb_data; //輸入輸出端口
8
9 outputregpo_usb_oe_n; //讀標志信號
10 outputregpo_usb_wr_n; //寫使能
11 outputregpo_usb_rd_n; //讀使能
12 outputreg[1:0]po_usb_address; //端點地址選擇
13
14 reg[15:0]temp_data;
15 reg[2:0]state;
16
17 //在狀態的3,拿回數據總線控制全,給寫入數據
18 assignpio_usb_data =(state ==3)?temp_data :16'hzzzz;
19
20 always@(posedgepi_clk ornegedgepi_rst_n)
21 if(!pi_rst_n)
22 begin
23 state <=0;
24 po_usb_oe_n <=1;
25 po_usb_wr_n <=1;
26 temp_data <=0;
27 po_usb_rd_n <=1;
28 end
29 else
30 case(state)
31 0 : state <=1;
32
33 1 : begin
34 po_usb_address <=2'b10;//地址指向端點6
35 state <=2;
36 end
37
38 2 : if(!pi_usb_flagc) //判斷端點6已經空
39 begin
40 po_usb_wr_n <=0;
41 state <=3;
42 end
43 else
44 state <=2;
45
46 3 : if(temp_data <256-1) //發送1024 字節的數據
47 temp_data <=temp_data +1'b1;
48 else
49 begin
50 temp_data <=0;
51 state <=4;
52 end
53
54 4 : begin
55 po_usb_wr_n <=1;
56 state <=0;
57 end
58
59 default: state <=0;
60 endcase
61
62endmodule
上位機測試:
我們安裝好驅動和下載的上位機軟件,然后在下面的界面中,點擊”LGEEPROM”按鈕,下載我們寫好的的.IIC固件。
然后在下面的頁面中會出現先選擇other endpt xfers選項
會出現我們的4個端點,然后我們選擇寫入的端點或者讀的端點執行讀寫操作
寫的端點是6端點,我們選擇這個端點,我們的寫入端點是1024個字節,我設置的是512字節,也就是寫入2次就可以寫滿了,
如下圖,和我們代碼中寫入數據值是一樣的。
讀操作也就是要讀我們的端點2,我們先要給端點一個數,然后才能讀我們的端點,我們寫入我們圖中顯示的數,因為我們設計的是讀出的數如果第三個數位33ff 就讓我們的燈亮,值得一說的是,我們上位機顯示的時候是把低位顯示到了前面,高位顯示到了后面,我們一個包是1024字節,后面的數自動補零,讀出數據后可以看到我們的led燈亮,驗證出我們的設計正確。
-
FPGA
+關注
關注
1626文章
21678瀏覽量
602018
發布評論請先 登錄
相關推薦
評論