WinCE中的Touch Panel驅動是由GWES模塊來管理的,Touch Panel驅動接收用戶的觸摸信息,并將其轉換為屏幕上的坐標信息,傳給GWES模塊。在WinCE中,Touch Panel驅動是分層的,分為MDD層和PDD層,這和其他WinCE設備驅動是一樣的。MDD層由微軟提供,用戶只需要實現MDD和PDD層間的DDSI函數就可以了。如圖
WinCE中的GWES模塊負責加載和管理Touch Panel驅動,Touch Panel的MDD層向上提供DDI接口,PDD層是針對硬件的實現,對MDD層提供DDSI接口。
WinCE中的GWES模塊負責加載和管理Touch Panel驅動,Touch Panel的MDD層向上提供DDI接口,PDD層是針對硬件的實現,對MDD層提供DDSI接口。
1 Touch Panel驅動中的數據結構
(1) TOUCH_PANEL_SAMPLE_FLAGS
用于描述一個采樣點的信息,這些信息被定義在一個枚舉結構中:
enum enumTouchPanelSampleFlags {
TouchSampleValidFlag = 0x01,
TouchSampleDownFlag = 0x02,
TouchSampleIsCalibratedFlag = 0x04,
TouchSamplePreviousDownFlag = 0x08,
TouchSampleIgnore = 0x10,
TouchSampleMouse = 0x40000000
};
TouchSampleValidFlag:一個有效的采樣值
TouchSampleDownFlag:第一次按觸摸屏時,返回該flag
TouchSampleIsCalibratedFlag:采樣的x和y坐標值不需要再被校驗了
TouchSamplePreviousDownFlag:表示上一次采樣狀態是按在觸摸屏上
TouchSampleIgnore:忽略這次采樣值
TouchSampleMouse:預留
(2) TPDC_CALIBRATION_POINT
用于描述一個校驗點的相關信息,結構如下:
struct TPDC_CALIBRATION_POINT {
INT PointNumber;
INT cDisplayWidth;
INT cDisplayHeight;
INT CalibrationX;
INT CalibrationY;
};
PointNumber:校驗點索引值,用于描述校驗點在LCD上的位置
0:中間
1:左上
2:左下
3:右下
4:右上
cDisplayWidth:顯示的寬度
cDisplayHeight:顯示的高度
CalibrationX:校驗點的x坐標值
CalibrationY:校驗點的y坐標值
(3) TPDC_CALIBRATION_POINT_COUNT
用于描述需要校驗的點的個數,結構如下:
struct TPDC_CALIBRATION_POINT_COUNT {
DDI_TOUCH_PANEL_CALIBRATION_FLAGS flags;
INT cCalibrationPoints;
};
flags:一般為0
cCalibrationPoints:需要校驗的點的個數,一般是5
(4) gIntrTouch和gIntrTouchChanged
這是兩個被MDD層用到的中斷,需要在PDD層中定義,如下:
DWORD gIntrTouch = SYSINTR_NOP;
DWORD gIntrTouchChanged = SYSINTR_NOP;
gIntrTouch用于描述觸摸屏中斷,要和硬件的觸摸屏中斷相關聯。
gIntrTouchChanged用于在觸摸屏按下后,每隔一段時間進行一次采樣,應該和硬件的一個定時器中斷相關聯。
這兩個值應該在DdsiTouchPanelEnable(..)函數中和硬件中斷關聯,并在函數DdsiTouchPanelGetPoint(..)中根據情況清除相應的中斷。
2 MDD層API
MDD為上層導出所需的Touch Panel驅動接口函數,上層通過這些函數可以完成對Touch Panel的操作,下面會介紹這些函數的功能。
(1) BOOL TouchPanelEnable(PFN_TOUCH_PANEL_CALLBACK pfnCallback):
使能Touch Panel設備,用于初始化Touch Panel。
pfnCallback:指向處理Touch Panel事件的回調函數
(2) Void TouchPanelDisable(void):
禁用Touch Panel設備。
(3) BOOL TouchPanelGetDeviceCaps(INT iIndex, LPVOID lpOutput ):
獲得Touch Panel設備的相關信息。
iIndex:索引值
TPDC_SAMPLE_RATE_ID:采樣率信息
TPDC_CALIBRATION_POINT_COUNT_ID:采樣點個數信息
TPDC_CALIBRATION_POINT_ID:采樣點坐標信息
lpOutput:指向一個內存區域,用于存放獲得的相關信息
(4) VOID TouchPanelCalibrateAPoint(INT32 UncalX, INT32 UncalY, INT32* pCalX, INT32* pCalY):
將輸入的未經過校驗的坐標信息轉換成校驗后的坐標信息。
UncalX:輸入的X坐標
UncalY:輸入的Y坐標
pCalX:校驗后的X坐標
pCalY: 校驗后的Y坐標
(5) VOID TouchPanelPowerHandler(BOOL bOff):
Touch Panel的電源控制函數。
bOff:TRUE表示關閉電源,FALSE表示打開電源
(6) BOOL TouchPanelReadCalibrationPoint(INT* pRawX, INT* pRawY):
獲得Touch Panel的坐標。
pRawX:觸摸屏的X坐標
PRawY:觸摸屏的Y坐標
(7) VOID TouchPanelReadCalibrationAbort(void):
終止當前的校驗。
(8) VOID TouchPanelSetCalibration(INT32 cCalibrationPoints, INT32* pScreenXBuffer, INT32* pScreenYBuffer, INT32* pUncalXBuffer, INT32* pUncalYBuffer):
校驗函數。通過一組實際的觸摸屏上采集的點坐標和相應的屏幕坐標計算校驗系數。具體公式如下:
Sx = A1*Tx + B1*Ty + C1
Sy = A2*Tx + B2*Ty + C2
這里就是通過顯示屏坐標和采樣的觸摸屏坐標計算A1,B1,C1,A2,B2,C2。
cCalibrationPoints:校驗點的個數
pScreenXBuffer:一組顯示屏上的X坐標
pScreenYBuffer:一組顯示屏上的Y坐標
pUncalXBuffer:一組觸摸屏上采樣的X坐標
pUncalYBuffer:一組觸摸屏上采樣的Y坐標
(9) BOOL TouchPanelSetMode(INT iIndex, LPVOID lpInput):
設置Touch Panel的工作模式。
iIndex:索引模式
TPSM_SAMPLERATE_HIGH:設置高采樣率
TPSM_SAMPLERATE_LOW:設置低采樣率
TPSM_PRIORITY_HIGH_ID:設置觸摸屏的IST為高優先級
TPSM_PRIORITY_NORMAL_ID:設置IST為正常優先級
lpInput:指向一塊內存,其中包含相關信息。
3 PDD層API
(1) LONG DdsiTouchPanelAttach(void):
該函數在Touch Panel驅動的Dll被加載的時候調用
(2) LONG DdsiTouchPanelDettach(void):
該函數在Touch Panel驅動的Dll被卸載的時候調用
(3) BOOL DdsiTouchPanelEnable(void):
打開Touch Panel電源并做初始化。一般會在這里初始化一些信息,打開Touch Panel設備電源并做初始化。
(4) VOID DdsiTouchPanelDisable(void):
關閉Touch Panel設備。關閉Touch Panel電源并釋放資源。
(5) BOOL DdsiTouchPanelGetDeviceCaps(ULONG iIndex, LPVOID lpOutput):
查詢Touch Panel設備的相關信息
iIndex:查詢的索引值
TPDC_SAMPLE_RATE_ID:查詢采樣率信息
TPDC_CALIBRATION_POINT_ID:查詢需要校驗的點的坐標
TPDC_CALIBRATION_POINT_COUNT_ID:查詢用于校驗的點的個數
lpOutput:根據iIndex值分別指向相關的信息
(6) void DdsiTouchPanelGetPoint(TOUCH_PANEL_SAMPLE_FLAGS pTipState, PLONG pUnCalX, PLONG pUnCalY):
獲得Touch Panel上被按下的點的狀態和坐標。
pTipState:當前觸摸點的狀態,比如無效點,有效點,被按下的點等。
pUnCalX:觸摸點的X坐標
pUnCalY:觸摸點的Y坐標
(7) VOID DdsiTouchPanelPowerHandler(BOOL bOff):
設置Touch Panel的電源狀態。
bOff:TRUE表示關閉電源,FALSE表示打開電源
(8) BOOL DdsiTouchPanelSetMode(ULONG iIndex, LPVOID lpInput):
設置Touch Panel工作模式。
iIndex:模式索引
TPSM_SAMPLERATE_HIGH_ID:高采樣率
TPSM_SAMPLERATE_LOW_ID:低采樣率
lpInput:指向包含相關信息的內存
4 注冊表設置
對于Touch Panel驅動來說,有些注冊表項是需要配置的。具體如下:
“InputConfig”:WinCE系統輸入配置。
Bit0表示鍵盤輸入
Bit1表示Touch Panel輸入
Bit2表示硬件按鍵輸入
“DeviceName”:Touch Panel驅動的名字。
“MaxCalError”:Touch Panel的精確度配置。
“CalibrationData”:Touch Panel的校驗值。第一次啟動WinCE后,需要通過WinCE的觸摸屏校驗程序對Touch Panel進行校驗。校驗完成后,校驗值會被寫入注冊表里面。
下面是關于Touch Panel的注冊表配置的例子:
[HKEY_LOCAL_MACHINE\ControlPanel]
"InputConfig"=dword:3 ;3 => keybd and touch screen
[HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\TOUCH]
"DriverName"="touch.dll"
"MaxCalError"=dword:8
"CalibrationData"="446,671 36,191 38,1179 856,1161 862,169 "
個人覺得,要想更好的理解Touch Panel驅動,還是需要去讀讀代碼,基于WinCE6.0下,可以參考"\WINCE600\PLATFORM\H4SAMPLE\SRC\DRIVERS\TOUCH"下面的驅動,基于這個驅動開發自己的驅動會比較方便。
Windows CE下觸摸屏驅動實現的分析
Analysis of Touch Panel Driver Realization Based on Windows CE OS
劉林輝1 張 芬2
Liu,LinHui1 Zhang,Fen2
(1 長沙理工大學能源與動力工程學院,湖南 長沙,410077;2 華中科技大學機械科學與工程學院,湖北 武漢,430074)
摘要:本文介紹了Windows CE操作系統的觸摸屏驅動程序模型,詳細闡述嵌入式系統中電阻式觸摸屏的Windows CE驅動程序的設計和實現方法。
關鍵詞:觸摸屏,Windows CE
中圖分類號:TP316
文獻標識碼:A
Abstract:This article introduced touch panel driver model of Windows CE operating system, and elaborated the driver design and the realization method of resistance-type touch panel based on an embedded system which take Windows CE as operating system.
Keyword:Touch Panel,Windows CE
1. 前言
觸摸屏是嵌入式設備中常用的計算機輸入設備,它可使操作簡單直觀,人人都會使用,這一點無論是鍵盤還是鼠標都無法與其相比。在手機、PDA等手持產品及公共服務設備中大量采用觸摸屏。觸摸屏分為電阻式、電容式、表面聲波式等多種,電阻式觸摸屏是目前應用比較廣泛的一種,有四線、五線、七線等幾種。本文將分析Windows CE操作系統下的觸摸屏驅動程序模型及實現方法。
2. Windows CE觸摸屏驅動程序模型
在Windows CE操作系統中觸摸屏驅動是一種分層驅動。其驅動模型如圖1所示。上層是模型設備驅動程序(Model Device Driver, MDD),下層是依賴平臺的驅動程序(Platform Dependent Driver, PDD)。MDD通常無需修改直接使用,MDD鏈接PDD層并定義它希望調用的函數接口:設備驅動程序提供器接口(Device Driver Service Provider Interface, DDSI)。同時MDD把不同的函數集提供給操作系統,這些函數叫做設備驅動程序接口(Device Driver Interface, DDI),這部分為也就是我們通常驅動需要實現的部分。
3 Windows CE的觸摸屏驅動程序接口
Windows CE的觸摸屏驅動鏈接了tch_cal.lib和tchmdd.lib兩個靜態鏈接庫。觸摸屏驅動由GWES加載,GWES通過DDI調用驅動程序獲取設備狀態,設置驅動功能等,而驅動本身通過DDSI直接獲得硬件信息來確定當前觸摸屏的狀態。
Windows CE觸摸屏驅動要求的DDI接口包括:TouchPanelGetDeviceCaps、TouchPanelEnable、TouchPanelDisable、TouchPanelSetMode、TouchPanelReadCalibrationPoint、TouchPanelReadCalibrationAbort、TouchPanelSetCalibration、TouchPanelCalibrateAPoint、TouchPanelPowerHandler。
Windows CE觸摸屏驅動要求的DDSI接口包括:DdsiTouchPanelAttach、DdsiTouchPanelDetach、DdsiTouchPanelDisable、DdsiTouchPanelEnable、DdsiTouchPanelGetDeviceCaps、DdsiTouchPanelGetPoint、DdsiTouchPanelPowerHandler。
4 Windows CE的觸摸屏數據采集
Windows CE觸摸屏驅動程序采用中斷方式對觸摸筆的按下狀態進行檢測,如果檢測到觸摸筆按下將產生中斷并觸發一個事件通知一個工作線程開始采集數據。同時,驅動將打開一個硬件定時器,只要檢測到觸摸筆仍然在按下狀態將定時觸發同一個事件通知工作線程采集數據,直到觸摸筆抬起后關閉該定時器,并重新檢測按下狀態。驅動中采用了觸摸屏中斷以及定時器中斷兩個中斷源,不僅可以監控觸摸筆按下和抬起狀態,而且可以檢測觸摸筆按下時的拖動軌跡。
觸摸屏驅動在初始化過程調用TouchPanelEnable函數使能觸摸屏。該函數調用的DDSI函數為:DdsiTouchPanelEnable和DdsiTouchPanelDisable。該函數實現如下 內容:
1) 創建事件hTouchPanelEvent和hCalibrationSampleAvailable。hTouchPanelEvent事件在正常狀態下當有觸摸筆按下或者按下后需要定時采集數據時被觸發。而hCalibrationSampleAvailable事件在校準狀態下當有校準數據輸入時被觸發;
2) 檢查并初始化所需的中斷gIntrTouch(觸摸屏中斷)和gIntrTouchChanged(定時器中斷),并將中斷gIntrTouch、gIntrTouchChanged關聯到事件hTouchPanelEvent。當gIntrTouch,gIntrTouchChanged中斷產生時將觸發hTouchPanelEvent事件;
3) 創建一個ISR線程TouchPanelpISR。TouchPanelpISR用于等待和處理觸摸屏事件hTouchPanelEvent,它是整個驅動程序中唯一的事件源。
TouchPanelpISR函數是實現觸摸屏數據采集關鍵函數,它實現的內容為:
1) 等待循環,用于接收hTouchPanelEvent事件,并構成函數的主體;
2) 通過調用DdsiTouchPanelGetPoint函數獲取當前觸摸屏位置和狀態信息;
3) 在獲取有效數據且在校準狀態下,收集并提交按下的位置信息;
4) 在正常狀態下,校準數據,并檢查校準后數據的有效性;
5) 最后調用由GWES傳入的回調函數,提交位置信息和狀態信息。
因此,在觸摸屏驅動程序中DdsiTouchPanelEnable、DdsiTouchPanelDisable和DdsiTouchPanelGetPoint三個DDSI接口函數是驅動實現的關鍵所在。
在DdsiTouchPanelEnable和DdsiTouchPanelDisable函數中分別打開和關閉觸摸屏硬件,這兩個函數其實可以不真正操作硬件,而只是實現軟件上的控制,但是為了降低功耗最好在DdsiTouchPanelDisable中將觸摸屏控制器電源關閉并在DdsiTouchPanelEnable函數中打開。
在DdsiTouchPanelGetPoint函數中實現對觸摸屏數據的采樣。從上面的分析得知MDD通過檢測hTouchPanelEvent和hCalibrationSampleAvailable事件控制采樣,這兩個事件被觸發都將調用該函數。而這兩個事件觸發條件有兩個:
1) 觸摸筆按下時產生觸摸屏中斷gIntrTouch時觸發;
2) 觸摸筆按下后,定時器被打開,定時器將定時產生中斷gIntrTouchChanged,并觸發事件,直到觸摸筆抬起為止。
因此該函數不僅需要對觸摸屏數據采樣,而且需要對觸發條件進行狀態控制,其流程如圖2所示。圖中定義了三個變量,它們分別為:
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函數一開始從觸摸筆抬起狀態開始執行,此時TouchIrq等于TRUE。如果此時觸摸筆按下,將設置TouchIrq為FALSE,表示本次采樣是由于觸摸屏中斷產生并設置下一次調用由定時器產生。然后設置InterruptType狀態為SYSINTR_TOUCH,接著開始采集數據并設置g_NextExpectedInterrupt變量為PEN_UP_OR_TIMER,表示下一次產生的中斷為定時器中斷。接著判斷在觸摸筆按下狀態(g_NextExpectedInterrupt等于PEN_UP_OR_TIMER)下觸摸筆是否抬起,如果抬起則設置g_NextExpectedInterrupt為PEN_DOWN恢復到抬起狀態。最后通過將InterruptType作為參數傳入InterruptDone函數以清除中斷。當觸摸筆按下,并產生定時器中斷時,TouchIrq等于FALSE,此時InterruptType被設置為SYSINTR_TOUCH_CHANGED,其余的動作基本和上面的流程一致。
5 Windows CE下的觸摸屏校準
電阻觸摸屏需要校準。應用程序需要一些參考值,以便將接收到的觸摸屏坐標數據轉換成高層軟件所需的屏幕坐標。理想情況下校準程序只要在產品初次加電測試過程中運行一次就可以了,參考值被存儲在非易失性存儲器中。在理想情況下只需兩組原始數據,即在屏幕對角讀取的最小和最大值。而在實際應用中,因為許多電阻觸摸屏存在顯著的非線性,因此如果在最小和最大值之間簡單的插入位置數值會導致驅動程序非常的不精確。
在Windows CE中通過在函數DdsiTouchPanelGetDeviceCaps 中設置校準點的個數,在TouchDriverCalibrationPointGet中獲取每個校準點的屏幕坐標。常用的校準點數量為5。校準UI將在校準點坐標處相應顯示一個十字叉,用戶需要精確地在該十字叉位置按下觸摸屏,驅動通過TouchPanelReadCalibrationPoint函數讀取相應的觸摸屏坐標值,然后開始下一個校準點。循環設定的次數后,將采集到的觸摸屏坐標值和校準點屏幕坐標送到TouchPanelSetCalibration函數中進行處理。該函數將產生校準基準參數。
TouchPanelSetCalibration函數執行的動作是一套數學算法,具體內容為:
在觸摸屏數據與其位置偏移關系且屏幕像素與其位置偏移關系同為線性關系假設情況下,觸摸屏返回的位置信息與像素位置信息之間成2D坐標變換關系。則對于觸摸屏按下點的觸摸屏坐標(Tx,Ty)與其在顯示設備位置關系上匹配的點的屏幕坐標(Sx,Sy)之間的轉換關系,可以通過下述坐標變換表示:
Sx = A1*Tx + B1*Ty + C1
Sy = A2*Tx + B2*Ty + C2
TouchPanelSetCalibration的具體工作就是通過校準的動作獲取的屏幕坐標和觸摸屏坐標TouchCoordinate來確定A1,B1,C1和A2, B2, C2。
6. 結束語
本文作者的創新點:從分析嵌入式Windows CE操作系統中觸摸屏驅動程序的模型及實現方法的角度深入剖析了Windows CE中觸摸屏數據采集和校準的執行流程,對于類似系統的驅動開發具有一定的借鑒性。
參考文獻:
[1] Paul Kovitz. 電阻式觸摸屏結構和實現原理,夏普公司,2003
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/zhongnanjun_3/archive/2008/11/11/3274020.aspx