轉載引用于 http://blog.csdn.net/chenyujing1234
一、 CY7C68013A晶片介紹
1、 特點
* USB 2.0 高速(TID # 40460272)
* 單片的內建USB2.0收發器, Smart SIE 且有加強的8051 微處理器.
* 可程式設計的64Byte 端點。
* 8 bit 或 16 bit 外部資料接口
* Smart Media 标準 ECC Generation
* 為控制傳輸的配置和資料端口的分開資料Buffers
* GPIF(General Programmable Interface)
使能直接連接配接到并行序列槽
可程式設計的波形描述符并配置寄存器來定義波形.
支援RDY輸入和CTL輸出。
2、 應用
* 便攜的視訊記錄器
* MPEG/TV 轉化器
* DSL 子產品
* ATA 接口
* 記憶體讀卡器
* 攝像頭
* Home PNA
* 無線的LAN
* MP3播放器
3、 功能概況
3、1 USB 速度
* 全速,12Mbps
* 高速,480Mbps
(不支援低速的傳輸,1.5 Mbps)
3、2 8051 微處理器
EZ-USB FX2中内嵌的增強型8051微處理器帶有256B的資料存儲器、擴充的中斷系統、3個定時/計數器和2個序列槽UART。
FX2需外接24MHz的晶振,并比對20pF的電容接地,經過内部倍頻電路,産生48MHz的增強型8051預設工作頻率。
FX2還需産生480MHz的時鐘脈沖以供USB2.0串行收發使用。
3、2、1 資料存儲器
資料存儲器分為3個部分:位址範圍為00h-7Fh的直接尋址區、位址範圍為80h-FFh的特殊功能寄存器區(SFR)和位址範圍為80h-ffh的間接尋址區。
3、2、2 中斷系統
3、2、3 挂起和複位
在接收到USB總線發出的挂起信号後,增加型8051通過設定其寄存器PCON.0為1,可使EZ-USB FX2進入省電狀态,這時FX2的振蕩電路将停止工作。
喚醒方法有3種:USB總線的恢複信号、外部信号觸發WAKEUP管腳和外部信号解發WU2(WAKEUP)管腳。
EZ-USB FX2 8051的複位信号由主機通過一個寄存器位CPUCS.0控制。在FX2晶片上電時,9051處于各複位狀态;待軟固件代碼下載下傳至晶片的RAM中後,主機
将清除CPUCS.0,使8051脫離複位狀态,并開始它的固件程式。
3、3 I2C 總線
3、4 總線
3、5 USB Boot 方法
在上電階段,查找内部的I2C端口,如果第一byte是0xC0或0xC2,那麼它用EEPROM中的VID/PID/DID值;
如果沒有EEPROM被找到,那麼FX2LP會枚舉内部存儲的描述符。
預設的ID值是VID/PID/DID(00x4B4, 0x8613,0xAxxx where xxx = 晶片的版本)
3、6 枚舉
當第剛插入USB時,FX2LP會自動枚舉并下載下傳軟硬體和USB描述符表。
接下來,FX2LP會再枚舉。
3、7 Bus-Powered 應用
3、8 中斷系統
3、8、1 INT2中斷請求和全能寄存器
FX2LP執行INT2和INT4的自動vector。 總共有27個INT2(USB)vector,和14個INT4 (FIFO/GPIF)vector.
3、8、2 USB中斷 Autovcetors
主USB中斷被27個中斷源共享。FX2LP提供第二層的中斷vectoring, 叫Autovectoring.
3、9 存儲空間
EZ-USB FX2的片記憶體儲由3部分組成:主RAM(0x000-0xfFFF)、臨時RAM(0xE000-0xE1FF)和寄存器/緩沖器(0xE222-0xFFFF)。如下圖。
其中8k位元組的RAM被程式存儲器和資料存儲器所共享;
0.5k位元組的臨時RAM僅用作為資料存儲器;
7.5K位元組的寄存器/緩沖器包含FX2控制/狀态寄存器和各端點的資料傳輸緩沖區。
3、9、1 片記憶體儲區
在上圖中,位址範圍為0x0000-0x1FFF的8K位元組用于存儲8051的程式代碼和資料,稱為“主RAM“。
3、9、2 片内0xE000-0xFFFF存儲區
其中,512位元組的臨時RAM(0xE000-0xE1FF)僅作為資料存儲器,8051固件代碼不能在該空間運作;
128位元組的0xE400-0xE47F空間用于存儲GPIF的4個波形描述符;
0xE600-0xE6FF空間用于儲存FX2的控制和狀态寄存器;
0xE740-0XE7FF和0xF000-0xFFFF空間作為FX2端點的資料緩沖區,使用者可通過尋址RAM方式或FIFO方式來通路。(重點)
2、9、2、1 FX2端點緩沖區
EZ-USB FX2 晶片内部包含3個固定的64位元組端點緩沖區(0xE740-0xE7FF)和4KB的可配置端點緩沖區空間(0xF000-0xFFFF),如上圖。
3個64位元組的緩沖區分别用于EP0、EP1IN和EP1OUT,
4KB的可配置緩沖區用于EP2、EP4、EP6和EP8
(1)其中,端點1支援傳輸、中斷和同步傳輸,其OUT資料占用緩沖區0xE780-0xE7BF,IN資料占用緩沖區0xE7C0-0xE7FF。
(2)端點0和端點1僅能由FX2的固件程式通路。
(3)端點2、端點4、端點6和端點8是大容量高寬帶的資料傳輸端點,其無需8051固件幹涉就可同外圍電路完成高速資料傳輸。
這4個端點的配置方式非常靈活,以适應不同場合下的帶寬要求。見下表。
其中,雙重緩沖意味着USB讀寫一個緩沖區的同時,另一個緩沖區可與外圍電路進行資料通信;
三重緩沖增加了第三個資料緩沖區,可供USB端或外圍電路使用;
四重緩沖增加了第四個資料緩沖區。
注意:這裡的緩沖區按我的了解:如FPGA給的資料太快時會而MCU還沒來取資料,那麼會先放到緩沖區中,讓值不會被覆寫。
3、10 I/O系統
EZ-USB FX2提供了兩種類型的I/O系統:可程式設計I/O口和I2C控制器。
I/O口由PA、PB、PC、PD、PE組成,共40個腳。注意:如果是100腳和128腳封裝的FX2包含全部5個I/O口,而56腳的僅包含FA、FB和FD。
I2C總線使用SCL和SDA兩個管腳。
3、10、1 I/O口
與EZ-USB不同,FX2的增強型8051使用特殊功能寄存器0Ex(0EA、0EC、0ED、0EE)和IOx(IOA、IOB、IOC、IOD)來控制其I/O管腳。結構如下圖:
3、10、2 從屬FIFO接口模式
為便于端點2、端點4、端點6和端占8的資料緩沖區能更好地和外圍電路進行通信,FX2還提供了2種接口模式:
從屬FIFO和GPIF。其由寄存器IFCFG控制。
(1)從屬FIFO模式。
以下是它的模式結構和外圍電路的典型連接配接圖:
其中IFCLK為接口時鐘,可由晶片内部産生(30MHz/48MHz),也可由外部輸入(5MHz-48MHz);
FLAGA-FLAGD為FIFO标志管腳,用于映射FIFO的目前狀态;
SLCS#為從屬FIFO的片選信号,低電平有效;
FD[15:0]為16位雙向資料總線;
FIFOADR[1:0]用于選擇和FD連接配接的端點緩沖區(00代表端點2,01代表端點4,10代表端點6,11代表端點8)
SLOE用于使能資料總線FD的輸出;
SLRD和SLWR可分别作為FIFO的讀寫選通信号;
外圍電路可通過使能PKTEND管腳向USB發送一個IN資料包,而不用考慮該包的長度。
(2) GPIF接口模式
在GPIF模式下,EZ-USB FX2可由軟體來程式設計輸出讀寫控制波形。這時,它幾乎可對任何通用總線接口進行通路,如ASIC、DSP等。
下圖展示了GPIF模式結構和這種模式下FX2和外圍電路的典型連接配接。
其中,GPIFADR[8:0]用于輸出9位位址;
IFCLK為接口時鐘;
FD[15:0]為16位雙向資料總線;(因為是16根資料線過來,是以得把接收FPGA資料的端點的WORDWIDE屬性設定為1,不然會資料出錯)
CTL[5:0]用于輸出可程式設計的控制信号,如讀寫選通等;
RDY[5:0]為輸入的狀态信号。
GSTATE[2:0]用于輸出目前GPIF狀态碼,通常僅在調試時使用。
3、11 列舉和重列舉
與EZ-USB類似,FX2在上電時,首先由“預設USB裝置”進行“列舉”,并把8051固件下載下傳到晶片的RAM内;之後8051會脫離複位并開始執行這些代碼,
并照固件的内容再一次對裝置進行“重列舉”。再重列舉完成後,對控制端點0的裝置請求可FX2預設USB裝置處理(USBCS中的RENUM位為0),
也可由增強型8051的固件代碼處理(RENUM為1)。
3、11、1 預設USB裝置
當EZ-USB FX2列舉完成後,它将以“預設USB裝置”展現給使用者,這時其隻含有1個USB配置,該配置中包含1個接口,這個接口具有4種可替換設定
0、1、2 和3,見下表(全速模式)和(高速模式)。
3、11、2 端點0對裝置請求的響應
在RENUM == 0時,EZ-USB FX2核心可自動對端點0的控制請求做出響應。除支援USB标準裝置請求外,其還可以支援一些供應商自定義的請求。
3、11、3 無EEPROM列舉模式
當EZ-USB FX2上電并脫離複位狀态後,其就會檢查晶片的I2C總線上是否連接配接有串行EEPROM,如果存在,它将讀取一個位元組以決定其列舉模式。
根據是否存在EEPROM及其首位元組内容,FX2共有3種列舉模式:無串行EEPROM、EEPROM的首位元組為0XC0、EEPROM的首位元組為0XC2.
(1) EEPROM首位元組為0XC0的列舉模式
它将從EEPROM中讀取VID、PID和DID的值,而各種USB描述符仍由FX2晶片内部提供。
下表是這種模式下EEPROM中資料模式,其中位址7為配置位元組,用于設定I2C總線的傳輸速率和USB斷開極性(預設是FX2脫離複位後和USB連接配接)。
(2) EEPROM首位元組為0xC2清單模式
此時VID、PID、DID、各種USB描述符,及其8051代碼都由該EEPROM提供。
二、 系統設計
将CY7C68013A晶片的Slave FIFO塊傳輸接口模式和FPGA技術相結合,實作了計算機與外設之間高速的資料傳輸。
1、硬體及外設控制設計
CY7C68013A與外設有三種接口方式:端口模式、可程式設計接口GPIF和Slave FIFO。
Slave FIFO方式是從機工作方式,在具有外部資料處理邏輯的裝置中,USB資料在主機和外部邏輯裝置中傳輸,通常不需要FX2LP的CPU參與,而是經過FX2LP内部端點FIFO來傳輸。外部控制器可對多個端點的FIFO選擇讀寫。FX2LP的Slave FIFO工作方式可設為同步或異步;工作時鐘均可由内部産生或外部輸入。基于該系統處理的是高速傳輸,需要外部控制器直接對FIFO進行控制,故采用從機,即Slave FIFO方式(也就是EX-USB FX2的從屬FIFO模式)。高速傳輸的原理框圖如圖1所示.
首先圖像可由計算機上層應用軟體發送或者接收,再通過USB接口晶片連接配接高速緩存。
如圖2所示,CY7C68013A的主要功能信号及與FPGA之間的握手信号如:
IFCLK為時鐘信号,可以選擇由外部輸入或者内部輸出;
FIFOADR[1:0]引腳選擇4個FIFO(2,4,6或8)中的一個與USB資料總線FD連接配接。
定義該系統中上行資料傳輸為FIFOADR[1:0]=10,即為EP6端口;
下行資料傳輸為FIFOADR[1:0]=01,即為EP2端口。
FLAGB,FLAGC為所選擇FIFO的标志信号,FLAGB代表FIFO為滿;FLAGC代表FIFO為空;預設低電平有效。(具體是哪個端點的滿空要看FIFOADR[1:0]指向哪個端點)
FPGA可以通過不斷查詢這兩個标志信号決定是否進行讀或寫操作。
SLOE(Slave FIFO Output Enable)為讀/寫使能信号,它使能被選擇的寬度的資料;
SLWR,SLRD分别為讀寫控制信号,在同步和異步模式下,控制信号不一;
FD[15:0]為16位的雙向資料總線。PA0,PA1為輸出信号,作為硬體系統工作狀态的控制信号。
原理圖(有标的都是FPGA的控制有關的引腳):
注: USB_WAKEUP、USB_PA3_WU2要接高,不然會使CY7C68一直在喚醒中,導緻VID、PID讀取不到因為WU2是一個USB喚醒源,通過WU2EN bit (WAKEUP.1)使能,并通過WU2POL(WAKEUP.1)設定。WU2EN bit時, 通過判斷此腳電平喚醒晶片。
項目總結:一開始我們是24LC128,根據下表的比對,我們把A0接高; 後來發現EERPROM中的資料一直無效。
項目是以耽誤了一周。後來發現我們的晶片不是24LC128,而是24C 16。晶片上的銘牌上标有:
ATM 128
24C 16。
真是硬體工程師的馬虎,一查資料,這塊容量隻有2014K Byte。而我的軟硬體是3K啊,怪不得每次EEPROM資料無效。(8051從EEPROM中讀資料後有做校驗)。
沒辦法,隻能換一塊了。後來改為AT24C32,有4KByte容量。
2、 軟體設計
圖像傳輸系統的軟體設計主要包括三個部分:固件程式設計、驅動程式設計和計算機上層應用軟體。
2、1 固件程式設計
固件程式是硬體中的軟體部分,通過執行該軟體可實作特定的硬體功能,主要包括初始化、處理标準的USB裝置請求以及USB挂起時的電源管理等。
步一:固件首先初始化内部的狀态變量,然後調用使用者初始化函數TD_Init()。
TD_Init函數負責CY7C68013A進行初始化,首先設定時鐘為48 MHz,然後設定晶片工作于從屬FIFO塊傳輸模式,并配置端點6工作于自動塊傳輸IN,端點2自動塊傳輸OUT模式。
步二:從該函數傳回後,固件初始化USB接口到未配置狀态并使能中斷。然後每間隔1 s進行一次裝置重枚舉(請看本文的 3、11 列舉和重列舉 ),直到端點0接收到一個SETUP包。
步三:任務分發。一旦檢測到SETUP包,固件函數将開始互動下述任務排程(即一個while循環):
調用使用者函數TD_Poll()輪詢所有的裝置,判斷是否有标準裝置請求等待處理,如果有,分析該請求并響應SetupCommand();
判斷USB核心是否收到USB挂起信号(即判斷Sleep事件)。如果有,則調用使用者函TD_Suspend()。從該函數成功傳回TRUE值後, 再檢測是否發生USB喚醒事件。
如果未檢測到喚醒事件,則處理器進入挂起方式EZUSB_Susp(); ;
如果有喚醒事件,則調用使用者函數TD_Resume(),程式繼續運作。如果從TD_Suspend函數傳回FALSE,則程式繼續進行。
[cpp] view plain copy
- // Task dispatcher
- void main(void)
- {
- DWORD i;
- WORD offset;
- DWORD DevDescrLen;
- DWORD j=0;
- WORD IntDescrAddr;
- WORD ExtDescrAddr;
- // Initialize Global States
- Sleep = FALSE; // Disable sleep mode
- Rwuen = FALSE; // Disable remote wakeup
- Selfpwr = FALSE; // Disable self powered
- GotSUD = FALSE; // Clear "Got setup data" flag
- // 步一:初始化使用者裝置
- TD_Init();
- // 步二:從該函數傳回後,固件初始化USB接口到未配置狀态并使能中斷。
- // 然後每間隔1 s進行一次裝置重枚舉,直到端點0接收到一個SETUP包。
- // The following section of code is used to relocate the descriptor table.
- // The frameworks uses SUDPTRH and SUDPTRL to automate the SETUP requests
- // for descriptors. These registers only work with memory locations
- // in the EZ-USB internal RAM. Therefore, if the descriptors are located
- // in external RAM, they must be copied to in internal RAM.
- // The descriptor table is relocated by the frameworks ONLY if it is found
- // to be located in external memory.
- pDeviceDscr = (WORD)&DeviceDscr;
- pDeviceQualDscr = (WORD)&DeviceQualDscr;
- pHighSpeedConfigDscr = (WORD)&HighSpeedConfigDscr;
- pFullSpeedConfigDscr = (WORD)&FullSpeedConfigDscr;
- pStringDscr = (WORD)&StringDscr;
- // Is the descriptor table in external RAM (> 16Kbytes)? If yes,
- // then relocate.
- // Note that this code only checks if the descriptors START in
- // external RAM. It will not work if the descriptor table spans
- // internal and external RAM.
- if ((WORD)&DeviceDscr & 0xC000)
- {
- // first, relocate the descriptors
- IntDescrAddr = INTERNAL_DSCR_ADDR;
- ExtDescrAddr = (WORD)&DeviceDscr;
- DevDescrLen = (WORD)&UserDscr - (WORD)&DeviceDscr + 2;
- for (i = 0; i < DevDescrLen; i++)
- *((BYTE xdata *)IntDescrAddr+i) = *((BYTE xdata *)ExtDescrAddr+i);
- // update all of the descriptor pointers
- pDeviceDscr = IntDescrAddr;
- offset = (WORD)&DeviceDscr - INTERNAL_DSCR_ADDR;
- pDeviceQualDscr -= offset;
- pConfigDscr -= offset;
- pOtherConfigDscr -= offset;
- pHighSpeedConfigDscr -= offset;
- pFullSpeedConfigDscr -= offset;
- pStringDscr -= offset;
- }
- EZUSB_IRQ_ENABLE(); // Enable USB interrupt (INT2)
- EZUSB_ENABLE_RSMIRQ(); // Wake-up interrupt
- INTSETUP |= (bmAV2EN | bmAV4EN); // Enable INT 2 & 4 autovectoring
- USBIE |= bmSUDAV | bmSUTOK | bmSUSP | bmURES | bmHSGRANT; // Enable selected interrupts
- EA = 1; // Enable 8051 interrupts
- #ifndef NO_RENUM
- // Renumerate if necessary. Do this by checking the renum bit. If it
- // is already set, there is no need to renumerate. The renum bit will
- // already be set if this firmware was loaded from an eeprom.
- if(!(USBCS & bmRENUM))
- {
- EZUSB_Discon(TRUE); // renumerate
- }
- #endif
- // unconditionally re-connect. If we loaded from eeprom we are
- // disconnected and need to connect. If we just renumerated this
- // is not necessary but doesn't hurt anything
- USBCS &=~bmDISCON;
- CKCON = (CKCON&(~bmSTRETCH)) | FW_STRETCH_VALUE; // Set stretch
- // clear the Sleep flag.
- Sleep = FALSE;
- // 步三:任務分發。一旦檢測到SETUP包,固件函數将開始互動下述任務排程
- while(TRUE) // Main Loop
- {
- // 輪詢所有的設
- TD_Poll();
- // 判斷是否有标準裝置請求等待處理,如果有,分析該請求并響應SetupCommand();
- if(GotSUD)
- {
- SetupCommand(); // Implement setup command
- GotSUD = FALSE; // Clear SETUP flag
- }
- // check for and handle suspend.
- // NOTE: Idle mode stops the processor clock. There are only two
- // ways out of idle mode, the WAKEUP pin, and detection of the USB
- // resume state on the USB bus. The timers will stop and the
- // processor will not wake up on any other interrupts.
- // 判斷USB核心是否收到USB挂起信号(即判斷Sleep事件)。如果有,則調用使用者函TD_Suspend
- if (Sleep)
- {
- if(TD_Suspend())
- {
- Sleep = FALSE; // Clear the "go to sleep" flag. Do it here to prevent any race condition between wakeup and the next sleep.
- // 如果未檢測到喚醒事件,則處理器進入挂起方式EZUSB_Susp();
- do
- {
- EZUSB_Susp(); // Place processor in idle mode.
- }
- while(!Rwuen && EZUSB_EXTWAKEUP());
- // above. Must continue to go back into suspend if the host has disabled remote wakeup
- // *and* the wakeup was caused by the external wakeup pin.
- // 8051 activity will resume here due to USB bus or Wakeup# pin activity.
- EZUSB_Resume(); // If source is the Wakeup# pin, signal the host to Resume.
- // 如果有喚醒事件,則調用使用者函數TD_Resume(),程式繼續運作
- TD_Resume();
- }
- }
- }
- }
固件hex二進制代碼下載下傳到CY7C68的的方式有兩種:
(1)開機自動将固件程式下載下傳至晶片RAM中,以由增強性8051執行。結合CYPRESS開發包EZ-Loader Drivers以及HEX2C和Windows DDK即可生成所需要固件自動下載下傳程式.sys檔案。
(2)還有另一種方式就是将确定正确的hex固件寫到EEPROM中,斷電開機時每次都從EEPROM中讀取。
我們有16K的EEPROM晶片24LC128,這裡我們選擇第二種方式。
2、2 驅動程式設計
具體代碼請參考我的下一篇文章: <<Window XP驅動開發(十三) 晶片功能驅動端 (代碼實作,針對USB2.0 晶片CY7C68013A)>>
USB裝置驅動程式負責建立起主機端和裝置端的聯系。
驅動程式主要有兩個:
一、如果是需要自動下載下傳固件hex檔案的,那麼得自行開發帶下載下傳功能的.sys驅動檔案。
是開機自動将固件程式下載下傳至晶片RAM中,以由增強性8051執行。結合CYPRESS開發包EZ-Loader Drivers以及HEX2C和Windows DDK即可生成所需要固件自動下載下傳程式.sys檔案。
二、如果硬體中帶有EEPROM,那麼隻需要完成上位機應用程式和硬體裝置之間的資料傳輸。其主要包括驅動程式入口例程、即插即用例程、分發例程、電源管理例程和解除安裝例程。本系統根據通用驅動結合自身需要,在DDK環境下修改編譯,生成自己需要的驅動程式。USB上層應用程式都通過I/O控制來通路裝置驅動程式。
上層應用程式首先通過調用Win32函數CreaFile()來取得通路裝置驅動程式的句柄;然後應用程式使用Win32函數Devi-ceIoControl()來送出I/O控制碼,并且為CreatFile()函數傳回的裝置句柄設定I/O緩沖區。該系統中,設定USB端口緩沖區FIFO為1 024 B,端口非空即讀取。保持了傳輸的連續性,并且每次以幀結構包形式傳輸,每包的大小為512 B。以實驗中為例。每傳輸大小為245 KB的一幅圖像,需要490個包進行傳輸。