实验12触摸屏驱动一、实验目的1.了解CE下本地设备驱动程序的加载过程2.掌握WinCE下本地设备驱动程序的设计方法3.实现本地设备驱动程序的接口函数二、实验环境1.软件:PB5.0,UltraEdit文本编辑器2.硬件:PC,2410实验平台三、实验内容1.分析触摸屏驱动程序2.将现有的触摸屏驱动程序添加进2410的BSP5.0包3.修改代码,以适用于其他尺寸屏幕的驱动4.在PB中调试驱动程序代码四、预备知识1.熟悉各种配置文件:.reg、.bib、.def、sources、makefile等2.熟悉PB的使用3.掌握驱动程序的基本知识五、实验原理1.硬件采样原理(三星自带ADC控制器/触摸屏控制器)触摸屏一般由4层薄膜组成,其中最主要的就是X层和Y层的薄膜。在点击触摸屏时,X层和Y层会在点击处连接,由此形成了测量通路。如图1所示:图1:触摸屏原理当测量X方向电压时(即触摸中断产生时),触摸屏控制器(同时产生触摸中断)控制内部测量电路的切换,在X层形成从X+到X-方向的均匀电势场,而Y层无外加电压。X层在点击处形成电阻分压状态,并与下面的Y层连接形成通路。此时,就可以通过测量Y+或Y-管脚,得到点击处的X方向的电压。反之,可以测量到Y轴方向的电压。于是,形成了坐标点(X,Y)。2410自带ADC控制器和触摸控制器,A/D通道直接与触摸屏相连。如图2所示:图2:2410触摸采样原理触摸控制器切换测量电路,并产生中断;ADC控制器进行采样通道选择。2.驱动分层触摸屏驱动程序属于本地设备驱动程序,经过编译生成一个DLL库,并由GWES加载。在WinCE系统中,触摸屏驱动也是一种分层驱动,上层是模型设备驱动程序MDD,下层是依赖平台的驱动程序PDD。如图3所示:GWESDDI函数设备驱动程序MDD层PDD层DDSI函数图3:驱动分层当系统访问硬件时,首先通过使用DDI函数与驱动程序交互,然后在驱动程序内部,MDD再通过DDSI函数与PDD进行交互,PDD完成真正的硬件访问操作:DDI接口函数DDSI接口(需要填充)TouchPanelGetDeviceCapsDdsiTouchPanelAttachTouchPanelSetModeDdsiTouchPanelDetachTouchPanelSetCalibrationDdsiTouchPanelDisableTouchPanelCalibrateAPointDdsiTouchPanelEnableTouchPanelPowerHandlerDdsiTouchPanelGetDeviceCapsTouchPanelEnableDdsiTouchPanelGetPointTouchPanelDisableDdsiTouchPanelGetPointTouchPanelReadCalibrationPointTouchPanelReadCalibrationAbort3.驱动程序的整体框图触摸屏驱动的整体框图如图4所示:初始化需要校准吗?触摸操作校准是否图4:驱动流程整体框图触摸驱动被加载后,GWES首先执行相关的初始化操作,然后创建一个线程,用来判断采集的点是校准点还是普通的触摸点。无论是校准点还是普通的触摸点,都会把点的坐标和状态信息通过回调函数返回给GWES。GWES根据这些信息,可能进行校准运算(校准点),也可能直接通过消息机制把信息发送给应用程序(非校准点)。4.初始化驱动程序的执行,第一步就是初始化,其过程如图5所示:GWESTouchPanelEnable•调用DdsiTouchPanelEnable为寄存器分配虚拟地址申请触摸中断和定时器中断的逻辑中断号•创建事件并关联•创建IST线程并设置优先级保存回调函数线程阻塞,等待中断图5:驱动初始化过程保存回调函数,以方便返回触摸点的坐标信息和状态信息。接着进入MDD层的TouchPanelEnable函数,在这里检查并初始化所需的gIntrTouch(触摸屏中断)和gIntrTouchChanged(定时器中断),并将中断关联到事件hTouchPanelEvent,当gIntrTouch和gIntrTouchChanged中断产生时都将触发hTouchPanelEvent事件。初始化阶段的最后一步,就是创建一个IST线程。这个线程是整个驱动程序的唯一事件,用来处理触摸坐标。此线程的主要流程如图6所示:IST线程等待触摸事件采样校准事件?校准处理换算否是回调函数GWES通信图6:IST线程流程线程等待触摸事件,判断采集的坐标是否需要校准。同时,利用GWES提供的回调函数,把坐标点和坐标信息返回给GWES。其中,需要与GWES保持通信,一方面可得知采样点是否为校准点,另外一方面可以通知GWES保存校准点数据。5.GWES处理GWES读取校准点坐标和信息,进行校准处理。其流程如图7所示:GWES获取设备信息长和宽光标坐标读取校准点坐标调用校准函数阻塞校准事件直至校准事件触发IST通信图7:GWES读取校准点坐标和信息GWES依次显示5个光标,进行校准引导。每次采样一个点。待5点全部采样完成,就开始调用校准函数,求解校准系数。当然,GWES也可以读取非校准状态下采集的点。前提是,这个采样点已经经过换算处理(使用已经求得的校准系数)。6.触摸处理驱动中采用了触摸屏中断以及定时器中断两个中断源,不仅可以监控触摸笔按下和抬起状态,而且可以检测触摸笔按下时的拖动轨迹。如果检测到触摸笔按下将产生中断并触发一个事件通知一个工作线程开始采集数据。同时,驱动将打开一个硬件定时器,只要检测到触摸笔仍然在按下状态将定时触发同一个事件通知工作线程采集数据,直到触摸笔抬起后关闭该定时器,并重新检测按下状态。程序中定义了三个变量,它们分别为:1)TouchIrq为静态变量或全局变量,且初始值为TRUE,该变量必须在触摸屏按下并产生触摸屏中断时设置为FALSE;2)InterruptType为静态变量或全局变量,且初始值为SYSINTR_NOP,当在处理触摸屏中断时设置为SYSINTR_TOUCH,在处理定时器中断时设置为SYSINTR_TOUCH_CHANGED,其余设置为SYSINTR_NOP,且在处理完毕后必须将其作为参数传入InterruptDone函数以清除中断;3)g_NextExpectedInterrupt为静态变量或全局变量,该变量表示下一个希望产生的中断,初始状态为PEN_DOWN,也就是触摸笔在抬起状态,因此希望下一个产生的中断为PEN_DOWN。当触摸屏中断产生以及定时器中断产生时该变量为PEN_UP_OR_TIMER,也就是下一个可能产生的状态为触摸笔抬起状态或者触摸笔按下但定时器中断产生。在DdsiTouchPanelGetPoint中,每个点采样3次,抛弃其中离另两点最远的点,然后求剩下两点平均值。假设采样的三个x方向的值分别为x1、x2、x3,在三个值都小于x方向最大量程前提下,有|x1-x2|、|x2-x3|、|x3-x1|。if(|x1-x2||x2-x3|){x=x1+((|x3-x1||x1-x2|)?x3:x2}else{x=x3+((|x3-x1||x2-x3|)?x1:x2)}x=17.主要函数及主要数据结构(1)TOUCH_PANEL_SAMPLE_FLAGSgetTouchCoordinate(unsignedchannel,unsignedshort&sample)注释:(回调函数)TOUCH_PANEL_SAMPLE_FLAGS数据结构表示返回到系统的坐标值的属性。函数参数channel表示X坐标、Y坐标或压力值的选择,函数参数&sample表示返回测得的电压值。(2)externCBOOLTouchDriverCalibrationPointGet(TPDC_CALIBRATION_POINT*pTCP)注释:利用屏幕的高和宽来确定中心和四周的坐标值。如果采用不同分辨率的屏,应该在此修改。涉及TPDC_CALIBRATION_POINT结构体:structTPDC_CALIBRATION_POINT{INTPointNumber;INTcDisplayWidth;INTcDisplayHeight;INTCalibrationX;INTCalibrationY;};参数*pTCP表示结构体变量。返回值为TRUE代表成功,FALSE表示失败。(3)externCBOOLDdsiTouchPanelGetDeviceCaps(INTiIndex,LPVOIDlpOutput)注释:查询触摸屏设备的采样频率(决定定时器间隔),并确定校准所需坐标样本数。函数参数iIndex表示查询的项目,函数参数lpOutput表示指向存放返回信息的内存区域,类型与iIndex对应。返回值为TRUE代表成功,FALSE表示失败。其中,调用TouchDriverCalibrationPointGet。(4)BOOLDdsiTouchPanelEnable(void)注释:初始化(寄存器分配内存或逻辑中断号申请)(5)voidDdsiTouchPanelGetPoint(TOUCH_PANEL_SAMPLE_FLAGS*pTipStateFlags,INT*pUncalX,INT*pUncalY)注释:实现对触摸屏数据的采样,获取当前触摸屏位置和状态信息。调用SampleTouchScreen函数,对三次采样得到的值进行评估,抛弃误差较大的采样数据(见前面的介绍)。参数pTipStateFlags依然与TOUCH_PANEL_SAMPLE_FLAGS结构有关,记录采样状态。参数pUncalX和pUncalY表示返回原始的坐标电压值。六、实验步骤(添加驱动代码到BSP包)1.\WINCE500\PLATFORM\SMDK2410A\Src\Drivers下添加Touch文件夹,加入驱动程序源代码文件。同时加入●SOURCE文件:TARGETNAME=s3c2440a_touch//生成的目标文件名RELEASETYPE=PLATFORM//使用该类型将使得生成的文件受平台控制TARGETTYPE=DYNLINK//生成.dll文件DLLENTRY=TouchPanelDllEntry//驱动入口DEFFILE=$(_COMMONOAKROOT)\inc\touch.def//DLL文件的def文件名TARGETLIBS=$(_COMMONSDKROOT)\lib\$(_CPUINDPATH)\coredll.libSOURCELIBS=\$(_COMMONOAKROOT)\lib\$(_CPUINDPATH)\tch_cal.lib\//校准模块$(_COMMONOAKROOT)\lib\$(_CPUINDPATH)\tchmdd.lib//驱动上层代码SOURCES=s3c2410_touch.cppPREPROCESSDEFFILE=1INCLUDES=$(_TARGETPLATROOT)\src\inc;●MAKEFILE文件不用修改:!INCLUDE$(_MAKEENVROOT)\makefile.def●touch.def文件:指定了需要导出的函数名称EXPORTSSTDAPI(TouchPanelGetDeviceCaps,8);STDAPI(TouchPanelEnable,4);STDAPI(TouchPanelDisable,0);STDAPI(TouchPanelSetMode,8);STDAPI(TouchPanelReadCalibrationPoint,8);STDAPI(TouchPanelReadCalibrationAbort,0);STDAPI(TouchPanelSetCalibration,20);STDAPI(TouchPanelCalibrateAPoint,16);STDAPI(TouchPanelPowerHandler,4);2.修改\WINCE500\PLAT