沈 杰,王新華,郭淑琴
(1.浙江工業(yè)大學信息工程學院,浙江杭州310023;2.浙江科技學院信息與電子工程學院,浙江杭州310023)
液晶顯示器(Liquid Crystal Display,LCD)作為嵌入式設備中重要的一部分,在人機交互中更是發(fā)揮著不可替代的作用。一般的嵌入式設備顯示器采用TTL(Transistor-Transistor Logic)接口的液晶屏,由于TTL接口的設計容易產(chǎn)生電磁干擾,信號無法做到長距離的傳輸,在某些工業(yè)領(lǐng)域就不適合。而采用LVDS(Low Voltage Differential Signal)接口的LCD就可以解決這個問題,因為差分信號可以有效抑制電磁干擾,從而達到長距離傳輸?shù)男Ч?。本文以三星的S3C2440A[1]作為主板核心,采用友達(AUO)G065VN01V2型,分辨率為640×480的LVDS接口TFT_LCD作為顯示終端。實現(xiàn)S3C2440A內(nèi)部LCD控制器TTL信號到顯示終端LVDS信號的轉(zhuǎn)換并成功移植了WINCE5.0下的LCD驅(qū)動程序。
S3C2440A的LCD控制器功能主要是完成視頻信號的傳輸,產(chǎn)生必須的控制信號:垂直同步(Vertical sync,VSYNC)、水平同步(Horizontal sync,HSYNC)、象素時鐘(Pixel clock,VCLK)、數(shù)據(jù)使能(Data,enable,VDEN)、行結(jié)束(Line end,LEND)。LCD控制器由寄存器庫、專用直接內(nèi)存存取塊、時序發(fā)生器等組成。寄存器庫包括17個可編程寄存器集合和用于配置LCD控制器的一塊256×16的調(diào)色板存儲器。專用直接內(nèi)存存取塊可以自動的把視頻數(shù)據(jù)從幀存儲區(qū)傳輸?shù)絃CD驅(qū)動器。時序發(fā)生器是一個可編程邏輯單元,它支持各種不同LCD驅(qū)動器對接口的時序和速率的要求。VSYNC和HSYNC信號的產(chǎn)生取決于LCDCON2/3寄存器中的HOZVAL和LINEVAL字段的配置。HOZVAL和LINEVAL由LCD屏幕的大小決定,VCLK信號的頻率取決于LCNCON1寄存器中CLKVAL字段的配置,CLKVAL最小值為0,幀頻(Frame Rate)即為VSYNC信號的頻率,幀頻與LCDCON1/2/3/4寄存器中的VSYNC、垂直后沿(Vertical back porch,VBPD)、垂直前沿(Vertical front porch,VFPD)、垂直同步脈寬(Vertical sync pulse width,VSPW)、LINEVAL、HSYNC、水平后沿(Horizontal back porch,HBPD)、水平前沿(Horizontal front porch,HFPD)、水平同步脈寬(Horizontal sync pulse width,HSPW)、HOZVAL和CLKVAL字段都有關(guān)系。
參考G065VN01V2手冊得到水平顯示大小為640,垂直顯示大小為480,由S3C2440芯片手冊公式得:HOZVAL=639,LINEVAL=479。G065VN01V2對時鐘頻率的要求是20-50MHz之間,典型的取值為25.2MHz,取整得 VCLK=25MHz,取 HCLK=100MHz,由公式得:CLKVAL=1。對于 Frame Rate的取值,手冊推薦的值為60Hz,根據(jù)手冊提供的數(shù)據(jù)和VSYNC、HSYNC波形關(guān)系得到:HSPW=93、HBPD=41、HFPD=23、VSPW=1、VFPD=10、VBPD=31,由公式得 Frame Rate=59.5HZ,符合手冊的要求。
G065VN01V2接口分為兩部分如圖1所示,J1是3.3V的差分信號接口,由3組差分數(shù)據(jù)流,一組時鐘信號和一組左右上下翻轉(zhuǎn)的控制信號組成;J19是12V的LED背光電源接口,直接從S3C2440GPIO口接出控制信號用于電源管理。由于LCD控制器輸出的都是TTL電平的信號,不符合接口的要求,因此需要電平轉(zhuǎn)換。本文通過DS90CF363MTD芯片連接LCD控制器和LCD差分接口來實現(xiàn),轉(zhuǎn)換電路設計如圖2所示。
LCDR/G/B 0-5這18bit的信號是從 LCD控制器的 VD[23:0]傳輸過來的,LCDHSYNC、LCDVSYNC、LCDDEN這3個控制信號就是LCD控制器輸出的HSYNC、VSYNC和VDEN信號,總共21bit的TTL信號被芯片轉(zhuǎn)換為TxOut0(+/-)~TxOut2(+/-)3組LVDS信號。LCDCLK連接的是LCD控制器的VCLK,單獨被轉(zhuǎn)換為一組TxCLKOUT(+/-)信號輸出。這4組差分信號與J1接口直接相連,再從J1口連差分線到顯示屏實現(xiàn)對顯示屏的控制。
Wince5.0下的LCD驅(qū)動是分層驅(qū)動,Gwes.exe調(diào)用和加載,圖形初級引擎(GPE)用來處理默認的繪圖工作,在驅(qū)動模型中扮演上層的模型設備驅(qū)動(MDD),用戶需要開發(fā)的就是下層的平臺相關(guān)驅(qū)動(PDD)和硬件相關(guān)的代碼。當應用層向LCD控制器發(fā)送數(shù)據(jù)時,它首先調(diào)用GDI(圖形設備接口),該接口由Coredll.dll(操作系統(tǒng)核心函數(shù)的動態(tài)鏈接庫文件)提供,有關(guān)圖形繪制和窗口調(diào)用的操作都被發(fā)往Gwes.exe,然后調(diào)用顯示驅(qū)動(Ddi.dll)導出的DDI(顯示設備驅(qū)動接口)函數(shù),找到相對應的實現(xiàn)函數(shù),最后通過該函數(shù)操縱硬件來實現(xiàn)。其中Ddi.dll就是默認的顯示驅(qū)動動態(tài)鏈接庫的名稱,它只導出DrvEnableDriver一個函數(shù),這是任何一個Windows CE的顯示設備驅(qū)動程序都必不可少需要向GWES子系統(tǒng)導出的,它負責向GDI提供一個指向含有27個DDI函數(shù)指針的結(jié)構(gòu)體(DRVENABLEDATA)指針[2]。
在SMDK2440A的LCD驅(qū)動程序中,DrvEnableDriver只是直接將全部4個參數(shù)傳遞給函數(shù)GPEEnableDriver,這是個微軟提供的公共代碼函數(shù),在/WINCE500/PUBLIC/COMMON/
OAK/DRIVERS/DISPLAY/GPE/ddi_if.cp中。GPEEnableDriver函數(shù)首先保存由pEngCallbacks參數(shù)傳遞而來的GDI回調(diào)函數(shù)指針集合,第二項主要任務是通過pded指針參數(shù)輸出DDI函數(shù)指針陣列,而在ddi_if.cpp中微軟提供了DDI函數(shù)實現(xiàn)代碼。那么DDI函數(shù)又是如何驅(qū)動硬件的呢?答案就在ddi_if.cpp的SafeGetGPE函數(shù)中,該函數(shù)只調(diào)用了GetGPE函數(shù),并將后者的返回值作為自己的返回值返回給自己的調(diào)用者,而SafeGetGPE函數(shù)的調(diào)用者就是DDI函數(shù)DrvEnablePDEV。本文使用的BSP包中GetGPE函數(shù)在s3c2440disp.cpp中實現(xiàn),這里的gGPE是一個GPE類的全局變量,代碼把新生成的S3C2440DISP類實例指針賦值給它。S3C2440DISP類是GPE類的子類,以后使用gGPE所指向的數(shù)據(jù)或函數(shù)時,得到的都是S3C2410DISP類型變量的成員函數(shù)和函數(shù),只有在S3C2410DISP未定義的部分才使用父類或更上級類的數(shù)據(jù)成員和成員函數(shù)。獲取GPE指針后,微軟已經(jīng)實現(xiàn)的DDI函數(shù)就會調(diào)用GPE類的成員函數(shù)來獲取和實際顯示硬件相關(guān)的信息并進行相應的操作。我們的工作就是實現(xiàn)這個S3C2410DISP類。
本文采用飛凌公司的 SMDK2440A BSP包,通過微軟的 PlatformBuilder5.0軟件進行移植。S3C2410DISP類在WINCE500PLATFORMSMDK2440ASrcDriversDisplay
s3c2440disp.h 中定義,在 s3c2440disp.cpp 中實現(xiàn)。
2.2.1 驅(qū)動程序文件
因為需要和硬件打交道,所以在s3c2440a_lcd.h中定義一個包含所有LCD控制寄存器的結(jié)構(gòu)體S3C2440A_LCD_REG,把CLKVAL、HSPW、VSPW等重要參數(shù)定義到了注冊表[HKEY_LOCAL_MACHINEDriversDisplayS3C2440CONFIG]下,在類的初始化函數(shù)中將被調(diào)用去配置寄存器。同時由于接口電路的不同,還要對GPIO口進行配置,在s3c2440a_ioport.h中定義一個包含所有GPIO口寄存器的S3C2440A_IOPORT_REG結(jié)構(gòu)體。GetGPE()會調(diào)用該類的構(gòu)造函數(shù),該函數(shù)完成以下工作:給重要的類成員變量賦值,調(diào)用類初始化函數(shù)InitDisplay,用CreateFileMapping/MapViewOfFile創(chuàng)建虛擬幀緩存共享內(nèi)存,大小為1M,用VirtualCopy實現(xiàn)物理幀緩存地址到共享內(nèi)存的映射,用類成員函數(shù)AllocSurface創(chuàng)建GPE類實例的首要顯示表面。
InitDisplay函數(shù)首先為S3C2440A_LCD_REG和S3C2440A_IOPORT_REG結(jié)構(gòu)體分配虛擬內(nèi)存,接著從注冊表下讀取Vspw等值,最后對LCD寄存器和GPIO寄存器進行相應的配置。由于S3C2410的LCD控制器不具備硬件加速能力,其他的類成員函數(shù)基本是不需要修改的,很多的成員函數(shù)都是調(diào)用依靠軟件實現(xiàn)的GPE類的默認函數(shù)。
2.2.2 配置文件
驅(qū)動相關(guān)的配置文件有platform.bib、source、plarform.Reg等。在wince中,驅(qū)動都是以動態(tài)鏈接庫(dll)的形式存在,配置文件則用來確定驅(qū)動程序最后生成的動態(tài)鏈接庫的文件名、存放目錄等,并把這些重要信息放在注冊表文件中提供給操作系統(tǒng),以便操作系統(tǒng)對驅(qū)動程序進行管理[3-4]。platform.bib中LCD驅(qū)動相關(guān)內(nèi)容:
2.2.3 移植注意點
成功移植的關(guān)鍵其實就是HSPW、VSPW等參數(shù)的修改,對于不同尺寸的LCD,它的值是不一樣的,要對照LCD的手冊進行修改;InitDisplay函數(shù)中對GPIO和LCD寄存器配置的修改也很重要。如果是高分辨率的顯示屏S3C2440DISP類構(gòu)造函數(shù)中分配的1M幀緩存肯定不夠,應該根據(jù)實際情況進行修改,同時在Config.bib的MEMORY字段下DISPLAY 80100000 00100000 RESERVED,保留的大小也要做相應的調(diào)整[6]。修改完成之后,在Platform Builder 5.0中重新編譯驅(qū)動程序,然后將新生成的內(nèi)核鏡像下載到開發(fā)設備中,桌面正常顯示,說明LCD驅(qū)動運行正常。
本文實現(xiàn)了控制器到液晶屏接口的電平轉(zhuǎn)換電路,采用LVDS接口有效解決了TTL接口電磁干擾的問題;同時詳細介紹了Wince5.0下的LCD驅(qū)動程序的實現(xiàn)機制,講解了移植注意點,實現(xiàn)了LCD驅(qū)動的移植,對Wince下驅(qū)動程序的移植有一定的借鑒。
[1] Samsung Electronics.S3C2440A 32-Bit CMOSMicrocontroller User's Manual[EB/OL].http://www.samsungsemi.com,2004-11-30.
[2] 李大為.Windows CE工程實踐完全解析[M].北京:中國電力出版社,2008:158-193.
[3] 方安平,丁智勇,庫少平.Windows CE 5.0下LCD 驅(qū)動程序移植[J].微計算機信息,2008,24(9):19-21.
[4] 鄧中亮,肖冠蘭.Windows CE 6.0下 LCD驅(qū)動程序移植[J].計算機與現(xiàn)代化,2011,(1):14-17.
[5] 張東泉,譚南林,王雪梅,等.Windows CE實用開發(fā)技術(shù)[M].北京:電子工業(yè)出版社,2006:119-127.
[6] 趙正輝,李 宇.基于WinCE高分辨率 LCD驅(qū)動的設計與實現(xiàn)[J].武漢科技學院學報,2008,21(7):25-29.