任何的固件編程離不開與與原理圖參考,圖紙中所采用的是USB的Slave_fifo傳輸方式,具體配置與圖紙對應即可。
•USB_IFCLK:同步Slave_FIFO模式,輸入頻率范圍5M-48M,在FPGA內部將此信號配置為CMOS攝頭cmos_pclk,傳感器像素時鍾的輸出端,作為數據采集時鍾和 68013與FPGA通信的同步時鍾。
assign USB_Data = cmos_data;
•FLAGA/FLAGB/FLAGC/FLAGB:對應FX2LP輸出的FIFO狀態信息。在寫入FIFO或者 讀FIFO之前,需先判斷FIFO內部滿、空等。
•SLCS:FIFO的片選信號,外部邏輯控制,當SLCS無效時,不可進行數據傳輸。
•SLOE:FIFO的輸出使能,外部邏輯控制,當SLOE無效時,數據線不輸出有效數據。
•SLRD:FIFO讀信號,外部邏輯控制,控制讀FIFO。
•USB_WR:FIFO寫信號,外部邏輯控制,同步寫時,在SLWR有效時的每個IFCLK的上 升沿數據被寫入,FIFO指針遞增。
assign USB_WR = i2c_config_done & cmos_href & USB_Trigger
USB_WR在CMOS攝像頭配置完成,CMOS傳感器數據行同步信號和USB_Trigger均有效時,允許寫入FIFO操作。
•USB_PA0:外部中斷信號。通過CMOS_VSYNC信號來觸發中斷。該信號是CMOS傳感 器像素數據場同步信號輸出。代表每幀圖像輸入的結束,下一幀圖像輸入的開始。
•USB_FD[0..7]:8位數據傳輸位。在FPGA內部,將此信號直接連接至傳感器像素的輸出。
assign USB_Data = cmos_data;//cmos_data為傳感器像素時鍾輸出數據位,8位。
•FIFOADR0/FIFOADR1:選擇四個FIFO端點的地址線,外部邏輯控制。68013內部有四個FIFO。
•PKTEND:包結束信號。正常情況下,外部邏輯像FIFO中寫入數據時,當寫入FIFO端點 的字節數等於固件設定的包大小時,數據將自動打包傳輸。但外部邏輯傳輸小數設定的 包大小時,只需在寫入一定數目字節后,使PKTEND信號有效,無論外部邏輯寫入多 少自己,將自動打包傳輸。在固件當中,設置PKTEND低有效,此處直接進行拉高處 理,說明每次傳輸只能固定數據包大小傳輸。
二、USB68013固件程序解讀
首先簡要介紹下CYPRESS提供的固件編程框架,用戶只需要在我們提供的框架基礎上添加修改少量的代碼,即可完成固件的編程。框架內部提供了鈎子函數,用戶在鈎子函數中添加自己的代碼,完成編程。
固件復位上電時,先初始化一些全局變量,接着調用初始化鈎子函數TD_Init(),開中斷,等待設備重枚舉完成,最后進入while(1)循環語句,執行任務調度。這里不具體說了參考源程序,框架的源文件和頭文件如下所示。
EZUSB.LIB |
EZUSB庫文件 |
EZUSB.h |
EZUSB頭文件 |
fx2regs.h |
FX2寄存器頭文件 |
fx2.h |
預定義,宏及函數聲明 |
fw.c |
固件框架源文件 |
dscr.a51 |
USB描述符列表,用戶可修改 |
USBJmpTb.OBJ |
中斷跳轉函數目標文件 |
syncdly.h |
同步延時,定義了程序短延時函數SYNCDELAY |
intrins.h |
C51一些數據類型及函數定義 |
intr.c |
外部中斷處理文件 |
app_xxx.c |
用戶鈎子函數文件,可修改,用戶代碼 |
除此以外,我們需要了解的函數包括:
•void TD_Init():此函數在USB啟動后只調用一次。此函數主要添加USB數據傳輸的初始化代碼,也就是傳輸之前要配置的。通過68013內部寄存器,配置好時鍾、FIFO、中斷等。
•void TD_Poll():用戶調度程序,USB在空閑時反復執行該函數,通常將反復執行的代碼放着里面。
•void ISR_EXTR0(void) interrupt 0:外部中斷處理函數,當外部中斷產生時,程序跳轉至此,執行該中斷子程序。
■void TD_Init(void)
1、設置CPU即68013時鍾為24MHZ。設置時鍾寄存器CPUCS=0x0a;其中CPUCS寄 存器如下所示:
CPUCS
•PORTCSTB --- 1表示讀寫端口C時產生RD#和WR#信號,0不產生讀寫信號,默認 為0。
•CLKSPD1,CLKSPD0 --- CPU時鍾設置。如下表所示:
在CC1601采集卡版本中,可以通過此寄存器修改給cmos提供的時鍾,12M、24M、48M。
注意:時鍾設置太高,可能導致cmos輸出不正常。降低時鍾可以降低幀率,會增加穩定性。
•CLKINV --- 時鍾狀態反轉
•CLKOE --- 時鍾使能
2、接口配置寄存器IFCONFIG
設置IFCONFIG=0x03; //選擇為外部時鍾,同步SlaveFIFO模式,輸入//IFCLK(5-48MHZ)(0000_0011)
IFCONFIG
•IFCLKSRC --- 0外部時鍾源,1內部時鍾源。
•3048MHZ --- 0 IFCLK時鍾為30M,1 IFCLK時鍾為48M。
•IFCLKOE --- IFCLK時鍾輸出使能,0關閉,1打開。
•IFCLKOL ---IFCLK信號反正,0不反轉,1反轉
•ASYNC --- GPIF同步或異步操作,0同步,1異步
•GSTATE---GPIF狀態輸出使能,0關閉,1使能,引腳PE0 PE1 PE2和GPIF狀態GSTATE0,GSTATE1,GSTATE2。
•IFCFG0,IFCFG1 --- 模式設置,決定了端口引腳功能。
3、REVCTL芯片版本控制寄存器
設置REVCTL=0x03;
REVCTL
該寄存器在SLAVE FIFOS編程中用到,建議設置b1b0=11。
4、端點1IN和1OUT配置寄存器
由驅動設計可知,只用到了FIFO 2。因此這兩個寄存器直接采用默認值即可,只作簡單介紹。
TYPE1,TYPE0 --- 端點類型見下表。
5、端點2、4、6、8配置寄存器
由於只用到了端點2,因此設置EP2CFG=0xE0;對於EP2CFG寄存器如下所示。
•VALID --- 0端點無效,1端點有效。
•DIR --- 端點方向,0=OUT方向,1=IN方向,默認端點2,4位IN,端點6,8為OUT。
•TYPE1,TYPE0 --- 端點類型,如下表所示。

•SIZE --- 緩沖區大小(僅端口2和端點6),0=512字節,1=1024字節
•BUF1,BUF0 --- 端點緩沖區個數(僅端口2和端點6)。

將其設置為端點2有效,IN方向,批量傳輸方式,傳輸字節為512B,四緩沖方式。
而將EP4CFG、EP6CFG、EP8CFG均設置為無效。
6、Slave FIFO端點2/4/6/8 FIFO配置
設置EP2FIFOCFG=0x08;表示FIFO 8位輸入模式。
•INFM1 --- 1表示IN端點滿減1。
•OEP1 --- 1表示OUT端點空加1。
•AUTOOUT --- 1表示數據自動提交OUT端點FIFO,0表示手動。
•AUTOIN --- 1表示IN端點FIFO數據自動呈交SIE,0表示手動。
•ZEROLENIN --- 1表示使能零長度IN端點數據包,0表示非使能。
•WORDWIED --- 數據寬度,0表示8bit,1表示16bit。
對於其他FIFO,由於沒用到,直接配置成0x00。
7、設置SLWR為高電平有效,其他為低電平有效。通過PORTACFG和FIFOPINPOLAR 寄存器來設置。
PORTACFG
PORTACFG |=0x40表示SLCS設置為復用引腳功能,且低電平有效。
FIFOPINPOLAR
0 表示低電平有效
1表示高電平有效
這里FIFOPINPOLAR = 0x07將SLWR設置為高電平有效,其余的設置為低電平 有效。
8、端點2 AUTOIN數據長度設置
設置EP2AUTOINLENH = 0x02;//包長度高字節,自動傳送包大小為512B。
EP2AUTOINLENL=0x00;
9、AUTOPTRSETUP |= 0x01;//使能自動指針特征,可以很方便在兩個內存間傳輸數 據。
10、SLAVE FIFOs FLAGx配置寄存器
PINFLAGSAB = 0x00;
SYNCDELAY;
PINFLAGSCD = 0x00;
SYNCDELAY;
硬件驅動中都沒用到該部分,忽略不計。
11、復位FIFO寄存器
FIFORESET
NAKALL --- 0表示關閉NAK功能,1表示用NAK響應主控器請求。在復位端點 時,為了保證復位正常,防止主控器請求的干擾,先寫入0x80,復位完成后,再 寫入0x00,以此響應請求。如下所示:
FIFORESET = 0x80;// activate NAK-ALL to avoid race conditions
FIFORESET = 0x02;// reset, FIFO 2
FIFORESET = 0x04;// reset, FIFO 4
FIFORESET = 0x06;// reset, FIFO 6
FIFORESET = 0x08;// reset, FIFO 8
FIFORESET = 0x00;// deactivate NAK-AL
12、配置68013內核引腳
如原理圖所示,USB_PA0作為中斷源,輸入至USB68013,設置USB_PA0引腳為 輸入引腳。而USB_PD5作為USB_Trigger,輸出至FPGA,可認為是68013給予 FPGA的反饋信號。因此,設置USB_PD5為輸出引腳。
•程序中設置PD5為輸出引腳,且初始化PD5為0。
OED |= (1<<5);//PD5 0:Input; 1:output
//OED = 0x20;
PD5 = 0;
OED端口D輸出使能寄存器
•程序中設置PA0為中斷觸發源。
OEA端口A輸出使能寄存器
設置PA0為輸入引腳,即默認D0=0;並將PA0設置為外部中斷INT0#。
OEA &= ~(1<<0); //PA0-INT0 0:Input
//OEA=0x00;
PORTACFG |= (1<<0); //Configure PA0 as INT0#
//PORTACFG = 0x01;
13、特殊功能寄存器TCON
通過特殊功能TCON來設定INT0#的中斷類型。當IT0=1時,采用上升沿觸發中 斷,當IT0=0時,采用低電平觸發中斷。設置IE=1允許中斷,IE=0禁止中斷。
IT0 = 1; //When ITx = 1, posedge edge Sample; When ITx = 0, low-level //Sample.
IE |= (1<<0);//Enable INT0
■ISR_EXTR0(void) interrupt 0
CB的中斷處理,可一言以蔽之:抽幀。由於PC機自身的局限性,為了降低PC的帶寬,對獲取的640*480像素大小的圖像進行抽幀處理。USB68013只接收部分圖像,來有效降低PC的帶寬。其過程如下所示:
•PA0作為中斷源,采取上升沿觸發中斷,連接至CMOS_VSYNC,即攝像頭場信號。當 場信號出現上升沿時標志着一幀圖像的結束和下一幀的開始。
•frame_interval_en做為抽幀的使能信號,初始值為1。每次進入中斷,幀計數器自動加1,通過判斷幀計數器來實現抽幀處理。
•PD5信號是USB連接至FPGA的信號,由assign USB_WR = i2c_config_done & cmos_href & USB_Trigger;可以得知,PD5=1時,USB允許數據寫入。
•當frame_cnt%2==0時,以15FPS寫入FIFO;
•當滿足條件frame_cnt%2==0時,PD5=1,允許寫入FIFO,不滿足時,PD5=0,禁止 寫入FIFO。
•在每次禁止寫入FIFO時,復位FIFO 2。以使FIFO 2數據為空,這樣就不存在FIFO 滿狀態。以此來防止因FIFO滿狀態而引起的數據丟失。
void ISR_EXTR0(void) interrupt 0 //using 0
{
if(frame_interval_en == 1)
{
frame_cnt++;
if((frame_cnt%2)==0) //5:6FPS; 4:7.5FPS; 3:10FPS; 2:15FPS; 1:30FPS;
{
PD5 = 1; //Enable image input
}
else
{
PD5 = 0; //Disable image input
//Reset FIFO of EDP2
SYNCDELAY;
FIFORESET = 0x80;// activate NAK-ALL to avoid race conditions
SYNCDELAY;
FIFORESET = 0x02;// reset, FIFO 2
SYNCDELAY;
FIFORESET = 0x00;// deactivate NAK-AL
SYNCDELAY;
}
}
else
{
PD5 = 1; //Enable image input continue , and no frame interval
}
}