韋照川,鄧力為,歐陽(yáng)寧,孫希延
(桂林電子科技大學(xué) 信息與通信學(xué)院,廣西 桂林 541004)
本文采用了TI公司的TMS320DM642[1-3](簡(jiǎn)稱DM642)芯片為核心,是基于TMS320C64X系列的高性能DSP芯片,外圍設(shè)備較為豐富,具有多個(gè)視頻采集端口和音頻采集端口,還有網(wǎng)絡(luò)接口、PCI接口、SPI接口以及EMIF接口等。在DM642的實(shí)際應(yīng)用中,經(jīng)常會(huì)涉及到大量視頻數(shù)據(jù)、音頻數(shù)據(jù)或者其他數(shù)據(jù)存儲(chǔ)的問題,使用USB存儲(chǔ)可以比較理想地達(dá)到預(yù)期目標(biāo)。DM642本身不帶有高速USB接口,需要外擴(kuò),這里使用NXP公司的ISP1761[4-6]進(jìn)行 USB[7-8]接口擴(kuò)展。
ISP1761擁有3個(gè)端口,1個(gè)OTG端口可實(shí)現(xiàn)主從功能,2個(gè)主機(jī)端口可連接USB設(shè)備,內(nèi)部含有一個(gè)CPU,對(duì)于主機(jī)功能而言,通過控制CPU寄存器和EHCI寄存器,實(shí)現(xiàn)ISP1761的基本配置。ISP1761通過飛利浦公司定義的傳輸描述符(PTD)來傳輸數(shù)據(jù),具體可分為同步傳輸PTD、異步傳輸PTD、中斷傳輸PTD。用戶按照需要的傳輸方式,填寫對(duì)應(yīng)的PTD區(qū)域,最后啟動(dòng)PTD傳輸,ISP1761將該P(yáng)TD指定的存儲(chǔ)區(qū)通過USB總線發(fā)送給設(shè)備,完成一次事務(wù),并返回該次事務(wù)的反饋信息,用戶讀取對(duì)應(yīng)的中斷寄存器的標(biāo)志位,就可以知道該次事務(wù)的傳輸情況,啟動(dòng)下一次傳輸或是重傳。
基本的DM642應(yīng)用平臺(tái)在外部存儲(chǔ)器接口EMIF總線上連接了ISP1761芯片,可以通過EMIF訪問ISP1761的寄存器實(shí)現(xiàn)其主機(jī)控制功能,完成對(duì)USB大容量設(shè)備的讀寫,實(shí)現(xiàn)實(shí)時(shí)數(shù)據(jù)的存儲(chǔ)。本文中DM642采用統(tǒng)一的32位地址模式,將32 Mbyte的SDRAM分配到CE0以0x80000000起始。4 Mbyte Flash分配到CE1以0x90000000起始。將ISP1761的64 kbyte內(nèi)存空間分配到CE2以0xA0000000起始。圖1為DM642與ISP1761的接口連接電路。
ISP1761提供了16/32位的數(shù)據(jù)讀寫寬度,可編程實(shí)現(xiàn)16位或32位數(shù)據(jù)讀寫方式。本文采用的是32位讀寫方式,PIO及DMA結(jié)合的主機(jī)控制模式。ISP1761不支持字節(jié)尋址,無AD0地址線。所以將EA3對(duì)齊ISP1761的32位地址線(即AD2)。數(shù)據(jù)線依次對(duì)齊,主機(jī)DMA請(qǐng)求線與GPIO1連接,通過GPIO1事件來實(shí)現(xiàn)EDMA傳輸,通過組合邏輯電路產(chǎn)生主機(jī)DMA應(yīng)答信號(hào)。將主機(jī)中斷請(qǐng)求與GPIO4相連,開啟GPINT4的外部中斷,這樣就可以用32位PIO方式訪問ISP1761,用DMA方式填充ISP1761的存儲(chǔ)區(qū),節(jié)省出大部分的CPU資源以便完成其余高開銷的任務(wù)。
軟件設(shè)計(jì)采用了如圖2所示的層次模型,主機(jī)控制器驅(qū)動(dòng)(即HCD)實(shí)現(xiàn)主機(jī)控制器抽象和總線數(shù)據(jù)抽象。USBD調(diào)用HCD時(shí)就避免了硬件的操作,USBD實(shí)現(xiàn)數(shù)據(jù)管理、主機(jī)控制器及USB設(shè)備管理。USBD和HCD構(gòu)成了USB的協(xié)議棧。因?yàn)楸疚氖腔诖笠?guī)模存儲(chǔ)設(shè)備的應(yīng)用,使用了Mass Storage的UFI模型,實(shí)現(xiàn)邏輯塊尋址等目的,然后一個(gè)存儲(chǔ)設(shè)備還需要文件系統(tǒng),在此基礎(chǔ)上搭建一個(gè)文件系統(tǒng),整個(gè)系統(tǒng)的架構(gòu)就初步實(shí)現(xiàn)了。
首先對(duì)于ISP1761要實(shí)現(xiàn)基本的通信,通過PIO方式,可以訪問ISP1761內(nèi)部的CPU寄存器以及EHCI寄存器。讀寫函數(shù)如下:
如果不采用EDMA的方式存放數(shù)據(jù),也可以采用PIO的方式實(shí)現(xiàn)對(duì)存儲(chǔ)區(qū)的讀寫,這里不做具體介紹。
對(duì)ISP1761進(jìn)行初始化,初始化完成以后就可以對(duì)內(nèi)部的集線器進(jìn)行枚舉。部分代碼如下:
完成了HCD初始化就已經(jīng)激活了根集線器端口,可以對(duì)內(nèi)置集線器進(jìn)行枚舉。由于篇幅所限,只列舉基本的步驟:
1)通過缺省管道(即地址0管道)取得集線器的描述符,使用了USB的get descriptor命令。
2)設(shè)置集線器的地址(可以是1~127的任意值,但是必須是未使用的),接下來的通信都采用該地址。
3)激活集線器配置。
4)設(shè)置端口進(jìn)入上電狀態(tài)。5)清除端口當(dāng)前連接狀態(tài)。
這樣,當(dāng)有設(shè)備插入端口時(shí),主機(jī)就能夠發(fā)現(xiàn)設(shè)備,然后對(duì)該端口進(jìn)行復(fù)位后和設(shè)備進(jìn)行最基本的通信。由于內(nèi)置hub只要枚舉后就不會(huì)從根端口上脫落,也就不用再動(dòng)態(tài)檢測(cè)根端口的連接狀態(tài),但是仍然需要定期地對(duì)內(nèi)置hub端口進(jìn)行訪問,以便及時(shí)發(fā)現(xiàn)設(shè)備的連接狀態(tài)有無變化。
需要讀取ISP1761的中斷寄存器,判斷中斷源,以便完成數(shù)據(jù)的重發(fā)或者是啟動(dòng)DSP的下一次EDMA傳輸。主機(jī)在啟動(dòng)下一次PTD傳輸前,需要檢測(cè)V標(biāo)志位有沒有清0,如果沒有,啟動(dòng)3次計(jì)數(shù),3次后則重啟當(dāng)前PTD傳輸。
數(shù)據(jù)傳輸只是涉及到單一事務(wù),從USB驅(qū)動(dòng)發(fā)起的傳輸中,將單一傳輸分解為若干個(gè)事務(wù)。例如本次設(shè)計(jì)中會(huì)用到控制傳輸以及批量傳輸。其中控制傳輸可以分為有數(shù)據(jù)和無數(shù)據(jù)的傳輸,一次傳輸中又可以具體分為SETUP事務(wù)、IN事務(wù)和OUT事務(wù),使用控制端點(diǎn)進(jìn)行。而批量傳輸只使用IN/OUT端點(diǎn),分為IN和OUT事務(wù),單一事務(wù)傳輸時(shí),需要對(duì)ISP1761的PTD區(qū)域進(jìn)行填充,指定傳輸區(qū)域,然后發(fā)起傳輸,完成一次事務(wù)。
該模塊實(shí)現(xiàn)對(duì)USB驅(qū)動(dòng)模塊傳遞的IRP進(jìn)行解析。實(shí)際完整的USB模型,需要對(duì)4種傳輸類型進(jìn)行分類處理。對(duì)于存儲(chǔ)設(shè)備,只需要分別對(duì)控制傳輸及批量傳輸進(jìn)行處理即可。
USBD作為USB主機(jī)軟件的最高層,需要遵循USB 2.0規(guī)范,完成數(shù)據(jù)傳輸管理以及總線枚舉調(diào)度兩個(gè)任務(wù)。在數(shù)據(jù)傳輸任務(wù)中,USB驅(qū)動(dòng)需要建立IRP,指定傳輸類型、傳輸方向、緩沖區(qū)位置以及傳輸長(zhǎng)度等信息。下層的USBD接口模塊接收后,將傳輸分解為多個(gè)事務(wù)進(jìn)行具體的處理。
為實(shí)現(xiàn)USB的即插即用功能,當(dāng)設(shè)備連接到USB總線或設(shè)備從USB總線拔出時(shí),USB驅(qū)動(dòng)都需要一個(gè)總線枚舉的過程,通過控制傳輸來識(shí)別設(shè)備。對(duì)于根端口,可以直接讀取根寄存器了解端口信息。對(duì)于內(nèi)置hub,需要定期地取得端口的連接狀態(tài),判斷是否有設(shè)備連接上來,當(dāng)發(fā)現(xiàn)設(shè)備連接到了端口時(shí),USB主機(jī)驅(qū)動(dòng)將采取以下的措施:
1)為設(shè)備供電,當(dāng)端口處于上電狀態(tài)時(shí),會(huì)自發(fā)地對(duì)外部設(shè)備進(jìn)行供電。
2)等待至少100 ms,確保插入狀態(tài)穩(wěn)定,供電狀態(tài)穩(wěn)定。
3)向內(nèi)置hub的該端口發(fā)出復(fù)位命令,至少等待10 ms,確保集線器完成復(fù)位。
4)為設(shè)備分配一個(gè)地址(1~127),并且是未使用的,接下來的通信都采用該地址。
5)取得該設(shè)備的全部描述符,并激活配置。
到這里,USB驅(qū)動(dòng)就完成了對(duì)設(shè)備的枚舉,接下來就可以對(duì)該設(shè)備進(jìn)行數(shù)據(jù)傳輸了。當(dāng)USB驅(qū)動(dòng)檢測(cè)到設(shè)備拔出時(shí),主機(jī)需要及時(shí)更新設(shè)備信息,提示設(shè)備的拔出,該hub端口處于斷開連接狀態(tài),當(dāng)檢測(cè)到下一次設(shè)備的插入時(shí),對(duì)該端口的設(shè)備再次進(jìn)行枚舉。這樣,就實(shí)現(xiàn)了USB設(shè)備的即插即用功能。
對(duì)大規(guī)模存儲(chǔ)類型的USB設(shè)備,需要使用基于SCSI規(guī)范的UFI子規(guī)范命令。UFI支持在USB設(shè)備之間完成數(shù)據(jù)的讀寫。對(duì)于USB存儲(chǔ)設(shè)備,目前有2種協(xié)議規(guī)范:一種為CBI協(xié)議,使用了控制端點(diǎn),批量傳輸端點(diǎn)以及中斷端點(diǎn)進(jìn)行傳輸;一種為BOT協(xié)議,僅使用批量傳輸端點(diǎn)進(jìn)行傳輸。本文中使用的是BOT傳輸協(xié)議。傳輸模型如圖3所示。
在該傳輸模型下,在USB主機(jī)和設(shè)備之間存在CBW,CSW和普通的3種數(shù)據(jù)。其中CBW命令塊的格式如圖4所示。
該命令數(shù)據(jù)格式為小端模式。
1)dCBWSignature。命令標(biāo)識(shí)符,為常數(shù)(0x43425335)。
2)dCBWTag。主機(jī)發(fā)送的CBW標(biāo)簽,設(shè)備必須在相關(guān)的CSW中以同樣的值返回。
3)dCBWDataTransferLength。在本命令執(zhí)行期間,主機(jī)期望通過Bulk-In或Bulk-Out端點(diǎn)傳輸?shù)臄?shù)據(jù)長(zhǎng)度。如果為0,則表示這之間沒有數(shù)據(jù)傳輸。
4)bmCBWFlags。Bit7Direction(dCBWDataTransfer?Length為0時(shí),該值無意義)取值,DataOut=0數(shù)據(jù)從主機(jī)到設(shè)備;DataIn=1數(shù)據(jù)從設(shè)備到主機(jī),其余位為0。
5)bCBWLUN。表示正在發(fā)送命令字的設(shè)備的邏輯單元號(hào)(LUN),對(duì)于支持多個(gè)LUN的設(shè)備,主機(jī)設(shè)置相對(duì)應(yīng)的LUN值,否則該值為0。
6)bCBWCBLength。CBWCB的有效字節(jié)長(zhǎng)度,在1~16之間。
7)CBWCB。被設(shè)備解析執(zhí)行的命令塊。該塊是重點(diǎn)部分,針對(duì)該塊的命令內(nèi)容,USB設(shè)備會(huì)執(zhí)行不同的任務(wù),具體的命令可以參考UFI規(guī)范手冊(cè)。特別要注意的是,命令的數(shù)據(jù)格式有小端格式也有大端格式。CSW狀態(tài)塊如圖5所示。
1)dCSWSignature。常數(shù) 0x53425355,標(biāo)識(shí)為 CSW狀態(tài)塊。
2)dCSWTag。取相對(duì)應(yīng)的CBW的dCBWTag值。
3)dCSWDataResidue。實(shí)際傳輸?shù)臄?shù)據(jù)個(gè)數(shù)和期望要傳輸?shù)臄?shù)據(jù)個(gè)數(shù)之差。
4)bCSWStatus。命令執(zhí)行情況,0表示執(zhí)行成功;非0表示失敗。失敗原因可以通過REQUEST_SENSE命令詢問出錯(cuò)原因。
文件分配表(File Allocation Table,FAT)。FatFs是一個(gè)開源的文件系統(tǒng)[9],支持FAT16,F(xiàn)AT32等格式。目前FatFs的作者寫了兩個(gè)版本的代碼,一個(gè)是正式的Fat?Fs,比較適合RAM比較大的設(shè)備,另一個(gè)是FatFs/Tiny,比較適合小RAM的系統(tǒng),比如單片機(jī),F(xiàn)atFs/Tiny占用較小的RAM,代價(jià)是更慢的讀寫速度和更少的API函數(shù)。不過兩個(gè)都支持FAT16,F(xiàn)AT32文件系統(tǒng)。FatFs的使用方法和通用的文件操作API函數(shù)有一些區(qū)別,使用時(shí)可以參考FatFs的官方網(wǎng)站,這個(gè)模型是完全免費(fèi)和開源的。之所以推薦使用這個(gè)模型,是因?yàn)樵撓到y(tǒng)具有非常高的效率,不會(huì)成為USB傳輸速率的瓶頸。移植的問題主要有數(shù)據(jù)類型的修改和配置,針對(duì)應(yīng)用的需要,可以裁剪部分的API函數(shù),縮減代碼規(guī)模。最后,F(xiàn)atFs需要用戶編寫底層的驅(qū)動(dòng)函數(shù),包括:
所有的函數(shù)都涉及到邏輯單元號(hào)的問題,如果沒有分區(qū)或是存在多個(gè)設(shè)備,就可以不需要注意drv參數(shù),可以直接寫0。disk_initalize用來對(duì)盤進(jìn)行初始化,分配邏輯單元號(hào),如果不需要,可直接返回0值。disk_status用來返回磁盤狀態(tài),當(dāng)USB設(shè)備枚舉完成后返回0,當(dāng)設(shè)備拔出時(shí)就返回1。disk_read,disk_write兩個(gè)函數(shù)需要注意參數(shù),包括緩沖區(qū)地址、長(zhǎng)度和邏輯扇區(qū)地址。disk_ioctl函數(shù)用于格式化信息,返回扇區(qū)總數(shù),每扇區(qū)字節(jié)數(shù),如果不需要格式化,可以不用理會(huì)。get_fattime用來返回系統(tǒng)時(shí)間。
本文僅測(cè)試f_mount,f_open,f_read,f_write和f_close 5個(gè)函數(shù)來訪問U盤,先把一個(gè)test.txt的文本文檔寫進(jìn)U盤,再讀出來,證明結(jié)果是正確的,如圖6所示。
詳細(xì)介紹了DM642系統(tǒng)中USB接口芯片ISP1761的配置和編程方法,對(duì)于實(shí)現(xiàn)視頻數(shù)據(jù)和音頻數(shù)據(jù)的高效實(shí)時(shí)存儲(chǔ)提供了一個(gè)重要手段,具有較大的應(yīng)用意義。
[1] 王柳祎.基于DM642芯片的嵌入式雙目機(jī)器視覺平臺(tái)[J].電視技術(shù),2007,31(6):94-96.
[2] 張新安.基于DM642的AVS-M視頻編碼器的設(shè)計(jì)與優(yōu)化[J].電視技術(shù),2007,31(12):31-33.
[3] 美國(guó)德州儀器公司.TMS320C6000系列DSP的CPU與外設(shè)[M].卞紅雨,紀(jì)祥春,喬鋼,等,譯.北京:清華大學(xué)出版社,2007.
[4]ISP1761 hi-speed universal serial bus on-the-go controller[EB/OL].[2010-12-20].http://www.icver.com/info.asp?id=527991.
[5]AN10037 interfaceing the isp176x to the intel PXA25x processor[EB/OL].[2010-12-20].http://www.doc88.com/p-5420113033.html.
[6]AN10059 ISP1761 Linux programming guide[EB/OL].[2010-12-20].http://www.stericsson.com/technical_documents/CD00222790.pdf.
[7] 韓龍,劉文潔,徐伯慶,等.USB host技術(shù)在流媒體高清電視中的應(yīng)用[J].電視技術(shù),2006,30(4):32-34.
[8]Enhanced host controller interface specification for universal serial bus[EB/OL].[2010-12-20].http://www.intel.com/technology/usb/download/ehci-r10.pdf.
[9]Mirosoft extensible firmware initiative FAT32 file system specification[EB/OL].[2010-12-20].http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/fatgen103.doc.