usb文章.pdf
(558.74 KB, 下載次數: 79)
2010-1-14 15:25 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
由于不能上傳圖片大家詳細請看附件;歡迎大家和我交流 021 54453155 專業代理FTDI芯片
基于FIFO模式的FPGA與 USB2.0通訊接口設計
作者:上海茂晶 楊文達samy@gfgei.com.hk
0 引 言
USB(通用串行總線)是英特爾、微軟、IBM、康柏等公司1994年聯合制定的一種通用串行總線規范,它具有數據傳輸速度快,成本低,可靠性高,支持即插即用和熱插拔等優點,迅速得到廣泛應用。
在高速的數據采集或傳輸中,目前使用較多的都是采用USB 2.0接口控制器和FPGA或DSP實現的,本設計在USB 2.0接口芯片FT2232H的同步 FIFO模式下,利用FPGA作為外部主控制器實現和FT2232H 內部的FIFO進行控制,以實現數據的高速傳輸。該模塊可普遍適用于基于USB 2.0接口的高速數據傳輸或采集中。
l 系統硬件模塊設計
1.1 系統硬件框圖
圖1中展示了 FIFO方式下FT2232H 和FPGA的典型連接。其中,ADBUS[7..O]為8位雙向數據總線OE#用于使能數據總線ADBUS的輸出; RD#和WR#可分別作為FIFO的讀寫選通信號;CLK為同步時鐘輸出;RXF#為FIFO接受數據標志位為當為low時候可以讀取數據;TXE#為 FIFO發送數據標志位當為low時可以寫入操作。
1.2 USB 2.0接口芯片FT2232H
1.2.1 FT2232H的結構特點
FT2232H內部結構圖如圖1所示。FT2232H有2個獨立的UART/FIFO控制器,用于控制異步數據、245 FIFO數據、光電隔離(高速串口)或在安裝程序命令時控制Bit-Bang模式;USB協議引擎控制和管理UTMI PHY與FIFO之間的接口,負責電源管理和USB協議規范;雙端口FIFO TX緩沖區(4KB)存儲來自主機PC的數據,并通過多用途的UART,FIFO控制器使用數據;雙端口FIFO RX緩沖區(4KB)存儲來自多用途UART/FOFO控制器的數據,然后再將數據送至主機;復位發生器模塊上電時為設備內部電路提供可靠的供電復位。 RESETn輸入引腳允許外部設備重置FT2232H。如果不使用RESETn,應將其連接到VCCIO(+3.3 V);獨立波特率發生器提供×16或×10的時鐘信號給UART,通過1個14位比例因子和4個寄存位提供最佳的波特率調諧,決定UART可編程設置的波特率;+1.8 VLDO穩壓器為系統核心,為USB收發器模塊提供+1.8 V電壓,其輸入(VREGIN)必須接+3.3 v外接電源。VREGIN還需外接一只濾波電容器:通用收發器宏單元接口(UTMI)物理層為USBTX/RX數據提供全速/高速SERDES (serialise-deserialise勸能,還可提供時鐘;當不使用外部E2PROM時,FT2232H默認為一個USB到雙串口設備,添加一個外部93C46(93C56或93C66)E2PROM使每個器件的通道獨立配置為一個串行UART(RS232)模式,并行FIFO(245)模式或高速串口(光電隔離)。外部E2PROM也可用于存儲FT223-2H的USB VID,PID,設備驅動號和設備說明文字。
1.2.2 FT2232H的工作模式
FT2232H有Ports模式、245FIFO、bit-bang和MPSSE等接口方式。
Ports模式是一種最基本的數據傳輸方式,其數據傳輸主要由固件程序完成,需要CPU的參與,因此數據傳輸速率比較低,適用于傳輸速率要求不高的場合。
245FIFO模式可以分為異步和同步2種方式,可以通過如FPGA等象普通FIFO一樣對FT2232H緩沖FIFO進行讀寫,FT2232H內部FIFO FIFO提供所需的時序信號、握手信號(滿、空等)和輸出使能等。這里就是在同步FIFO模式下實現USB 2.O接口和FPGA的數據通信。
可編程接口bit-bang是主機方式,bit-bang作為內部主機控制端點,可以軟件編程讀寫控制波形,幾乎可以對任何8/16 b接口的控制器、存儲器和總線進行數據的主動讀寫,非常靈活。
MPSSE模式是FTDI公司的最大亮點之一。FT2232H內部MPSSE單元可以模擬多種串行協議,從而方便實現USB轉換為其他協議,包括SPI,JTAG,I2C等接口,廣泛應用于各種領域。
2 系統軟件模塊設計
2.1 USB固件程序設計
應用中采用同步FIFO方式,使用內部輸出60 MHz時鐘,固件程序采用FTDI公司提供的固件程序D2XX框架,在其初始化函數中添加了用戶配置代碼。該設計中同步自動FIFO數據傳輸的初始化代碼如下:#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#pragma comment(lib, "FTD2XX.lib")
#include "FTD2XX.h"
int main()
{
//FT_Open,FT_Close
FT_HANDLE ftHandle;
FT_STATUS ftStatus;
//FT_EE_Read
FT_PROGRAM_DATA ftData;
char ManufacturerBuf[32];
char ManufacturerIdBuf[16];
char DescriptionBuf[64];
char SerialNumberBuf[16];
//FT_SetBitMode
UCHAR Mask = 0xFF; //UCHAR ModeAsync= 0x01;
UCHAR ModeSync = 0x40;//FT_Write
DWORD BytesWritten;
unsigned char TxBuffer[65536];//FT_GetStatus
DWORD TxBytes;
DWORD EventDWord;//FT_Read
unsigned char RxBuffer[262144];
unsigned char RxBuffer1[1];
unsigned char RxBuffer2[2];
unsigned char flag[32];
unsigned char flag1;
unsigned char flag2;
DWORD RxCount = 0;
DWORD RxBytes = 10;
DWORD BytesReceived;
int i,j,m,n;
FILE *fp;
RxBuffer2[0]=0;
RxBuffer2[1]=1;
flag1=85;
flag2=170;
flag[0]=flag1;
flag[1]=flag1;
for(i=2;i<32;i=i+2)
flag=flag1;
for(i=3;i<32;i=i+2)
flag=flag2;
ftStatus = FT_Open(0, &ftHandle);
if(ftStatus != FT_OK) {
printf("FT_Open failed\n");
return 0;
}
ftStatus = FT_ResetDevice(ftHandle);
if(ftStatus == FT_OK) {
printf("FT_ResetDevice OK\n");
}//FT_EE_Read
ftData.Signature1 = 0x00000000;
ftData.Signature2 = 0xffffffff;
ftData.Version = 0x00000003;
ftData.Manufacturer = ManufacturerBuf;
ftData.ManufacturerId = ManufacturerIdBuf;
ftData.Description = DescriptionBuf;
ftData.SerialNumber = SerialNumberBuf;
ftStatus = FT_EE_Read(ftHandle,&ftData);
if (ftStatus == FT_OK){
printf("FT_EE_Read OK!~\n");
printf("Manufacturer=%s,ManufacturerId=%s\n",ftData.Manufacturer,ftData.ManufacturerId);
printf("Description=%s,SerialNumber=%s\n",ftData.Description,ftData.SerialNumber);
printf("IFAIsFifo7=%d\n",ftData.IFAIsFifo7);
}
else {
printf("FT_EE_Read FAILED!\n");
}
//FT_EE_Program//ftData.VendorId = 0x0403;//ftData.ProductId = 0x6010;//ftData.Manufacturer = "FTDI";
//ftData.ManufacturerId = "FT";
//ftData.SerialNumber = "FTS58JQC";
//ftData.Description = "FT2232H_Mini_Module";
ftData.IFAIsFifo7 = 1;
ftStatus = FT_EE_Program(ftHandle, &ftData);
if (ftStatus == FT_OK) {
printf("FT_EE_Program OK!~\n");
}
else {
printf("FT_EE_Program FAILED!\n");
}//FT_SetBitMode
ftStatus = FT_SetBitMode(ftHandle,Mask,ModeSync);
if (ftStatus == FT_OK) {
printf("SetBitMode ModeSync OK!~\n");
}
else{
printf("FT_SetBitMode FAILED!\n");
}
j = 0;m = 0;n = 0;
}
FT_Close(ftHandle);
printf("FT_Close!\n");
return 0; */
}
2.2 FPGA控制程序設計
FT2232H提供的端口FIFO的讀寫操作,與普通FIFO讀寫操作方式一樣。FT2232H為每個端口提供了“空”標志、“滿”標志和“ 可編程級”標志。FPGA檢測這些信號,用于控制讀寫的過程。FPGA在完成這些端口FIFO的操作時,采用Verilog HDL硬件描述語言實現了FIFO的讀寫時序,并在ALTERA公司提供的QuartusⅡ8.O開發工具中綜合編譯并映射到FPGA中運行。
2.2.1 FIFO同步“讀”操作
實現同步FIFO“讀”的狀態機如下圖所示。其狀態轉移進程如下:
IDLE:當“寫”事件發生時,轉到狀態1。
狀態1:激活OE#,如果FIFO空標志為“假”(FIFO不空),則轉向狀態2;否則停留在狀態1。
狀態2:激活SLOE,SLRD,傳送總線采樣數據;撤銷激活RD(指針加1)和OE,轉向狀態3。
狀態3:如果有更多的數據要求,則轉向狀態2;否則轉向IDLE。
實現以上狀態機的仿真波形如下圖所示。
2.2.2 FIFO同步“寫”操作
實現同步FIFO“寫”的狀態機如圖5所示。其狀態轉移進程如下:
IDLE:當寫事件發生時,轉到狀態1。
狀態1:指向 FIFO,如果FIFO滿標志為“假”(FIFO不滿),則轉向狀態3;否則停留在狀態2。
狀態2:傳送總線驅動數據。為一個激活WR#,轉向狀態3。
狀態3:如果有更多的數據要寫,則轉向狀態1;否則轉向IDLE。
用QuartusⅡ進行仿真驗證,其仿真波形如下圖所示,經分析可知,本狀態機實現的FIFO寫控制信號完全正確。
3 實驗結果
對傳輸的數據進行驗證,可通過FPGA編程生成O~255的數據傳送至FT2232H的pc端,連續傳送兩次,然后通過D2xx所提供API函數編寫軟件測試所接收到的數據,測試結果如下圖所示,可以看出,數據傳輸準確無誤。
4 結 語
USB 2.0控制器FT2232H已經被廣泛應用到許多數據傳輸領域,由于USB具有靈活的接口和可編程特性,大大簡化了外部硬件的設計,提高了系統可靠性。該設計可擴展性好,已經被應用于數據傳輸與采集的板卡上,經實際測試,沒有出現數據的誤碼等錯誤,數據傳送正確,傳輸速率可達30 MHz/s以上,滿足設計要求。
[此貼子已經被admin于2010-1-14 17:49:42編輯過]
|