基于WINCE5.0的差分接口LCD驱动的实现
2012-11-26王新华郭淑琴
沈 杰,王新华,郭淑琴
(1.浙江工业大学信息工程学院,浙江杭州310023;2.浙江科技学院信息与电子工程学院,浙江杭州310023)
0 引言
液晶显示器(Liquid Crystal Display,LCD)作为嵌入式设备中重要的一部分,在人机交互中更是发挥着不可替代的作用。一般的嵌入式设备显示器采用TTL(Transistor-Transistor Logic)接口的液晶屏,由于TTL接口的设计容易产生电磁干扰,信号无法做到长距离的传输,在某些工业领域就不适合。而采用LVDS(Low Voltage Differential Signal)接口的LCD就可以解决这个问题,因为差分信号可以有效抑制电磁干扰,从而达到长距离传输的效果。本文以三星的S3C2440A[1]作为主板核心,采用友达(AUO)G065VN01V2型,分辨率为640×480的LVDS接口TFT_LCD作为显示终端。实现S3C2440A内部LCD控制器TTL信号到显示终端LVDS信号的转换并成功移植了WINCE5.0下的LCD驱动程序。
1 硬件部分
1.1 LCD 控制器
S3C2440A的LCD控制器功能主要是完成视频信号的传输,产生必须的控制信号:垂直同步(Vertical sync,VSYNC)、水平同步(Horizontal sync,HSYNC)、象素时钟(Pixel clock,VCLK)、数据使能(Data,enable,VDEN)、行结束(Line end,LEND)。LCD控制器由寄存器库、专用直接内存存取块、时序发生器等组成。寄存器库包括17个可编程寄存器集合和用于配置LCD控制器的一块256×16的调色板存储器。专用直接内存存取块可以自动的把视频数据从帧存储区传输到LCD驱动器。时序发生器是一个可编程逻辑单元,它支持各种不同LCD驱动器对接口的时序和速率的要求。VSYNC和HSYNC信号的产生取决于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字段都有关系。
参考G065VN01V2手册得到水平显示大小为640,垂直显示大小为480,由S3C2440芯片手册公式得:HOZVAL=639,LINEVAL=479。G065VN01V2对时钟频率的要求是20-50MHz之间,典型的取值为25.2MHz,取整得 VCLK=25MHz,取 HCLK=100MHz,由公式得:CLKVAL=1。对于 Frame Rate的取值,手册推荐的值为60Hz,根据手册提供的数据和VSYNC、HSYNC波形关系得到:HSPW=93、HBPD=41、HFPD=23、VSPW=1、VFPD=10、VBPD=31,由公式得 Frame Rate=59.5HZ,符合手册的要求。
1.2 LVDS 接口电路
G065VN01V2接口分为两部分如图1所示,J1是3.3V的差分信号接口,由3组差分数据流,一组时钟信号和一组左右上下翻转的控制信号组成;J19是12V的LED背光电源接口,直接从S3C2440GPIO口接出控制信号用于电源管理。由于LCD控制器输出的都是TTL电平的信号,不符合接口的要求,因此需要电平转换。本文通过DS90CF363MTD芯片连接LCD控制器和LCD差分接口来实现,转换电路设计如图2所示。
LCDR/G/B 0-5这18bit的信号是从 LCD控制器的 VD[23:0]传输过来的,LCDHSYNC、LCDVSYNC、LCDDEN这3个控制信号就是LCD控制器输出的HSYNC、VSYNC和VDEN信号,总共21bit的TTL信号被芯片转换为TxOut0(+/-)~TxOut2(+/-)3组LVDS信号。LCDCLK连接的是LCD控制器的VCLK,单独被转换为一组TxCLKOUT(+/-)信号输出。这4组差分信号与J1接口直接相连,再从J1口连差分线到显示屏实现对显示屏的控制。
2 软件部分
2.1 WINCE5.0 下 LCD 驱动结构
Wince5.0下的LCD驱动是分层驱动,Gwes.exe调用和加载,图形初级引擎(GPE)用来处理默认的绘图工作,在驱动模型中扮演上层的模型设备驱动(MDD),用户需要开发的就是下层的平台相关驱动(PDD)和硬件相关的代码。当应用层向LCD控制器发送数据时,它首先调用GDI(图形设备接口),该接口由Coredll.dll(操作系统核心函数的动态链接库文件)提供,有关图形绘制和窗口调用的操作都被发往Gwes.exe,然后调用显示驱动(Ddi.dll)导出的DDI(显示设备驱动接口)函数,找到相对应的实现函数,最后通过该函数操纵硬件来实现。其中Ddi.dll就是默认的显示驱动动态链接库的名称,它只导出DrvEnableDriver一个函数,这是任何一个Windows CE的显示设备驱动程序都必不可少需要向GWES子系统导出的,它负责向GDI提供一个指向含有27个DDI函数指针的结构体(DRVENABLEDATA)指针[2]。
在SMDK2440A的LCD驱动程序中,DrvEnableDriver只是直接将全部4个参数传递给函数GPEEnableDriver,这是个微软提供的公共代码函数,在/WINCE500/PUBLIC/COMMON/
OAK/DRIVERS/DISPLAY/GPE/ddi_if.cp中。GPEEnableDriver函数首先保存由pEngCallbacks参数传递而来的GDI回调函数指针集合,第二项主要任务是通过pded指针参数输出DDI函数指针阵列,而在ddi_if.cpp中微软提供了DDI函数实现代码。那么DDI函数又是如何驱动硬件的呢?答案就在ddi_if.cpp的SafeGetGPE函数中,该函数只调用了GetGPE函数,并将后者的返回值作为自己的返回值返回给自己的调用者,而SafeGetGPE函数的调用者就是DDI函数DrvEnablePDEV。本文使用的BSP包中GetGPE函数在s3c2440disp.cpp中实现,这里的gGPE是一个GPE类的全局变量,代码把新生成的S3C2440DISP类实例指针赋值给它。S3C2440DISP类是GPE类的子类,以后使用gGPE所指向的数据或函数时,得到的都是S3C2410DISP类型变量的成员函数和函数,只有在S3C2410DISP未定义的部分才使用父类或更上级类的数据成员和成员函数。获取GPE指针后,微软已经实现的DDI函数就会调用GPE类的成员函数来获取和实际显示硬件相关的信息并进行相应的操作。我们的工作就是实现这个S3C2410DISP类。
2.2 WINCE5.0 下 LCD 驱动移植
本文采用飞凌公司的 SMDK2440A BSP包,通过微软的 PlatformBuilder5.0软件进行移植。S3C2410DISP类在WINCE500PLATFORMSMDK2440ASrcDriversDisplay
s3c2440disp.h 中定义,在 s3c2440disp.cpp 中实现。
2.2.1 驱动程序文件
因为需要和硬件打交道,所以在s3c2440a_lcd.h中定义一个包含所有LCD控制寄存器的结构体S3C2440A_LCD_REG,把CLKVAL、HSPW、VSPW等重要参数定义到了注册表[HKEY_LOCAL_MACHINEDriversDisplayS3C2440CONFIG]下,在类的初始化函数中将被调用去配置寄存器。同时由于接口电路的不同,还要对GPIO口进行配置,在s3c2440a_ioport.h中定义一个包含所有GPIO口寄存器的S3C2440A_IOPORT_REG结构体。GetGPE()会调用该类的构造函数,该函数完成以下工作:给重要的类成员变量赋值,调用类初始化函数InitDisplay,用CreateFileMapping/MapViewOfFile创建虚拟帧缓存共享内存,大小为1M,用VirtualCopy实现物理帧缓存地址到共享内存的映射,用类成员函数AllocSurface创建GPE类实例的首要显示表面。
InitDisplay函数首先为S3C2440A_LCD_REG和S3C2440A_IOPORT_REG结构体分配虚拟内存,接着从注册表下读取Vspw等值,最后对LCD寄存器和GPIO寄存器进行相应的配置。由于S3C2410的LCD控制器不具备硬件加速能力,其他的类成员函数基本是不需要修改的,很多的成员函数都是调用依靠软件实现的GPE类的默认函数。
2.2.2 配置文件
驱动相关的配置文件有platform.bib、source、plarform.Reg等。在wince中,驱动都是以动态链接库(dll)的形式存在,配置文件则用来确定驱动程序最后生成的动态链接库的文件名、存放目录等,并把这些重要信息放在注册表文件中提供给操作系统,以便操作系统对驱动程序进行管理[3-4]。platform.bib中LCD驱动相关内容:
2.2.3 移植注意点
成功移植的关键其实就是HSPW、VSPW等参数的修改,对于不同尺寸的LCD,它的值是不一样的,要对照LCD的手册进行修改;InitDisplay函数中对GPIO和LCD寄存器配置的修改也很重要。如果是高分辨率的显示屏S3C2440DISP类构造函数中分配的1M帧缓存肯定不够,应该根据实际情况进行修改,同时在Config.bib的MEMORY字段下DISPLAY 80100000 00100000 RESERVED,保留的大小也要做相应的调整[6]。修改完成之后,在Platform Builder 5.0中重新编译驱动程序,然后将新生成的内核镜像下载到开发设备中,桌面正常显示,说明LCD驱动运行正常。
3 结束语
本文实现了控制器到液晶屏接口的电平转换电路,采用LVDS接口有效解决了TTL接口电磁干扰的问题;同时详细介绍了Wince5.0下的LCD驱动程序的实现机制,讲解了移植注意点,实现了LCD驱动的移植,对Wince下驱动程序的移植有一定的借鉴。
[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 驱动程序移植[J].微计算机信息,2008,24(9):19-21.
[4] 邓中亮,肖冠兰.Windows CE 6.0下 LCD驱动程序移植[J].计算机与现代化,2011,(1):14-17.
[5] 张东泉,谭南林,王雪梅,等.Windows CE实用开发技术[M].北京:电子工业出版社,2006:119-127.
[6] 赵正辉,李 宇.基于WinCE高分辨率 LCD驱动的设计与实现[J].武汉科技学院学报,2008,21(7):25-29.