本文檔為移植LCD8000-97C屏幕電容觸控驅(qū)動(dòng)到iMX6平臺(tái)過(guò)程的總結(jié)。提供一些SylixOS觸控相關(guān)的框架理解和移植心得。
創(chuàng)新互聯(lián)公司專(zhuān)業(yè)為企業(yè)提供上街網(wǎng)站建設(shè)、上街做網(wǎng)站、上街網(wǎng)站設(shè)計(jì)、上街網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)與制作、上街企業(yè)網(wǎng)站模板建站服務(wù),十年上街做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。
如圖21所示:觸控屏通過(guò)外部中斷提醒主機(jī)從I2C總線上讀取觸控坐標(biāo)和按壓數(shù)據(jù),主機(jī)讀取到觸控?cái)?shù)據(jù)后將數(shù)據(jù)解析并轉(zhuǎn)換成鼠標(biāo)事件發(fā)送給系統(tǒng)上層,完成一次觸控。

圖 2-1 觸控流程
/driver/touch/touch.c文件主要實(shí)現(xiàn)了SylixOS的touch框架。主體框架僅需要關(guān)注如圖31所示的四個(gè)函數(shù):

圖 3-1 Touch框架重要函數(shù)
該函數(shù)主要完成如下的功能:
1)創(chuàng)建觸摸屏使用的I2C的總線設(shè)備;
2)注冊(cè)設(shè)備觸控中斷;
3)申請(qǐng)?jiān)O(shè)備復(fù)位管腳,復(fù)位設(shè)備;
4)調(diào)用設(shè)備Init函數(shù)。
這是函數(shù)__touchHwInit注冊(cè)的中斷響應(yīng)服務(wù),主要完成接收觸控中斷、清除中斷,并發(fā)出一個(gè)touch相關(guān)的信號(hào)的功能。
該函數(shù)是touch設(shè)備的一個(gè)線程,其在執(zhí)行過(guò)程中等待touch信號(hào),收到信號(hào)后調(diào)用函數(shù)__touchHandleEvents.
該函數(shù)通過(guò)觸控芯片驅(qū)動(dòng)提供的getevent回調(diào)函數(shù)來(lái)獲取數(shù)據(jù)生成的鼠標(biāo)事件,并向上層發(fā)送相關(guān)鼠標(biāo)事件。
整個(gè)框架的流程如圖32所示:

圖 3-2 Touch主體框架流程
移植的觸控屏為英蓓特LCD8000-97c,由于原廠不提供相關(guān)觸控芯片的資料支持,只能從支持該屏幕的Linux或者Android的調(diào)試信息和源碼來(lái)獲得相關(guān)IC信息,具體方式不再贅述。這里通過(guò)調(diào)試信息和源碼確認(rèn)屏幕觸控芯片型號(hào)為CT365。
在RIotboard官方提供的源碼中關(guān)于CT365的驅(qū)動(dòng)是以二進(jìn)制形式提供的,僅有頭文件/driver/input/touchscreen/generic_ts_rel/ct365.h能作為參考,如程序清單 31所示,根據(jù)該頭文件可以獲取CT365的觸控信息報(bào)文結(jié)構(gòu):
程序清單 3-1 ct365頭文件中關(guān)于數(shù)據(jù)結(jié)構(gòu)的描述
struct struct_ct365_pts_data { unsigned char xhi; // X coordinate Hi
unsigned char yhi; // Y coordinate Hi
unsigned char ylo : 4; // Y coordinate Lo
unsigned char xlo : 4; // X coordinate Lo
unsigned char status : 3; // Action information, 1: Down; 2: Move; 3: Up
unsigned char id : 5; // ID information, from 1 to CFG_MAX_POINT_NUM
unsigned char area; // Touch area
unsigned char pressure; // Touch Pressure};程序清單 31大致可以判斷出CT365的有效報(bào)文為6個(gè)字節(jié),其中前三個(gè)字節(jié)的觸控坐標(biāo)信息和第四個(gè)字節(jié)前三位的觸控狀態(tài)是最為重要的數(shù)據(jù),這些數(shù)據(jù)最終會(huì)解析成鼠標(biāo)事件。
將觸屏的I2C的兩根線接入邏輯分析儀,觸摸屏幕的時(shí)候抓取I2C通信數(shù)據(jù)(由于無(wú)法再次進(jìn)行實(shí)驗(yàn),不提供抓取的數(shù)據(jù)截圖)。
根據(jù)邏輯分析儀抓取的數(shù)據(jù),可以分析得出CT365的I2C設(shè)備地址為0x01,數(shù)據(jù)傳輸方式如圖3-4所示:

圖 3-4 CT365的數(shù)據(jù)通信流程
根據(jù)以上搜集的信息,結(jié)合硬件的原理圖基本可以確定CT365的工作方式以及數(shù)據(jù)傳輸流程。
CT365和主板連接部分只有一個(gè)I2C接口和一個(gè)中斷管腳,因此不需要初始化和復(fù)位,上電之后每次觸控都會(huì)產(chǎn)生一個(gè)中斷,通過(guò)中斷通知系統(tǒng)向CT365數(shù)據(jù)發(fā)送一幀數(shù)據(jù)為0的寫(xiě)命令,隨后發(fā)送讀命令讀取CT365反饋的觸控信息,解析生產(chǎn)鼠標(biāo)事件。
參考BSP包中其他的觸控芯片驅(qū)動(dòng)的實(shí)現(xiàn),針對(duì)CT365僅需實(shí)現(xiàn)讀函數(shù),觸摸數(shù)據(jù)的解析函數(shù)。分解成以下幾個(gè)子函數(shù):
ct365GetEvent
ct365GetTouchPoint
ct365GetRxData
ct36xRegRead
函數(shù)ct365GetEvent主要是由touch框架回調(diào)的,用來(lái)獲取觸控?cái)?shù)據(jù)和生成鼠標(biāo)事件的,所以先調(diào)用ct365GetRxData來(lái)獲取觸控?cái)?shù)據(jù),在調(diào)用ct365GetTouchPoint來(lái)解析生成鼠標(biāo)事件。具體實(shí)現(xiàn)如程序清單 32所示:
程序清單 3-2 ct365GetEvent函數(shù)實(shí)現(xiàn)
INT ct365GetEvent (PTOUCH_DEV pTouchDev,
mouse_event_notify events[]){
INT iError;
UCHAR ucBuffer[32];
iError = ct365GetRxData(pTouchDev, ucBuffer, sizeof(ucBuffer)); if (iError == PX_ERROR) {
printk(KERN_WARNING "touch: get touch point error!\n"); return (PX_ERROR);
}
iError = ct365GetTouchPoint(pTouchDev, events, ucBuffer); return (iError);
}函數(shù)ct365GetTouchPoint通過(guò)傳入的觸控?cái)?shù)據(jù),根據(jù)CT365頭文件的數(shù)據(jù)報(bào)文結(jié)構(gòu)分別解析出觸控的坐標(biāo)和觸控的狀態(tài),封裝出鼠標(biāo)事件。具體實(shí)現(xiàn)如程序清單 3-3所示:
程序清單 3-3 ct365GetTouchPoint函數(shù)實(shí)現(xiàn)
static INT ct365GetTouchPoint (PTOUCH_DEV pTouchDev,
mouse_event_notify events[],
UINT8 *pucData)
{
INT iTouchPoint;
iTouchPoint = pucData[3] & 0x3; if (iTouchPoint > TOUCH_MAX_INPUT_POINTS) {
iTouchPoint = TOUCH_MAX_INPUT_POINTS;
} if (iTouchPoint == 1) {
events[0].xmovement = (INT16)((pucData[0] << 4) | (pucData[0]>>4 & 0xf));
events[0].ymovement = (INT16)((pucData[1] << 4) | (pucData[2] & 0xf));
events[0].ctype = MOUSE_CTYPE_ABS;
events[0].kstat = MOUSE_LEFT;
pTouchDev->TOUCH_iLastX = events[0].xmovement;
pTouchDev->TOUCH_iLastY = events[0].ymovement;
} else if (iTouchPoint == 2) {
events[0].xmovement = (INT16)((pucData[0] << 4) | (pucData[0]>>4 & 0xf));
events[0].ymovement = (INT16)((pucData[1] << 4) | (pucData[2] & 0xf));
events[0].ctype = MOUSE_CTYPE_ABS;
events[0].kstat = MOUSE_LEFT;
pTouchDev->TOUCH_iLastX = events[0].xmovement;
pTouchDev->TOUCH_iLastY = events[0].ymovement;
iTouchPoint = 1;
} else if (iTouchPoint == 3) {
events[0].xmovement = pTouchDev->TOUCH_iLastX;
events[0].ymovement = pTouchDev->TOUCH_iLastY;
events[0].ctype = MOUSE_CTYPE_ABS;
events[0].kstat = 0;
iTouchPoint = TOUCH_RELEASE_NUM;
}
pTouchDev->TOUCH_iLastX = events[0].xmovement;
pTouchDev->TOUCH_iLastY = events[0].ymovement;
API_InterVectorEnable(pTouchDev->TOUCH_ulVector); return (iTouchPoint);
}函數(shù)ct365GetRxData調(diào)用函數(shù)ct36xRegRead去讀取I2C數(shù)據(jù)。具體實(shí)現(xiàn)如程序清單 3-4所示:
程序清單 3-4 ct365GetRxData函數(shù)實(shí)現(xiàn)
static INT ct365GetRxData (PTOUCH_DEV pTouchDev, UINT8 *pucBuffer, UINT16 usLen)
{
INT iError;
iError = ct36xRegRead(pTouchDev->TOUCH_pI2cDevice, 0,
pucBuffer,
usLen); return (iError);
}函數(shù)ct36xRegRead根據(jù)CT365的通訊流程讀取CT365反饋的觸控?cái)?shù)據(jù)。具體實(shí)現(xiàn)如程序清單 3-5所示:
程序清單 3-5 ct36xRegRead函數(shù)實(shí)現(xiàn)
static INT ct36xRegRead (PLW_I2C_DEVICE pI2cDev, UINT8 ucReg, UINT8 *pucBuffer, UINT16 usLen)
{
INT iError;
LW_I2C_MESSAGE i2cMsgs[] = {
{
.I2CMSG_usAddr = pI2cDev->I2CDEV_usAddr,
.I2CMSG_usFlag = 0,
.I2CMSG_usLen = 1,
.I2CMSG_pucBuffer = (PUCHAR)&ucReg,
},
{
.I2CMSG_usAddr = pI2cDev->I2CDEV_usAddr,
.I2CMSG_usFlag = LW_I2C_M_RD,
.I2CMSG_usLen = usLen,
.I2CMSG_pucBuffer = pucBuffer,
},
};
iError = API_I2cDeviceTransfer(pI2cDev, i2cMsgs, 2); if (iError != 2) {
printk(KERN_ERR "__ft5x06RxData(): failed to i2c transfer!\n"); return (PX_ERROR);
} return (ERROR_NONE);
}當(dāng)觸控驅(qū)動(dòng)完成后,如程序清單 3-6所示,根據(jù)硬件原理圖在BSP文件中配置好CT365的中斷管腳和I2C信息:
程序清單 3-6 配置CT365驅(qū)動(dòng)信息信息
static TOUCH_DATA _G_Ct365Data = {
.T_pcBusName = "/bus/i2c/2", /* I2C 總線名稱(chēng) */
.T_uiIrq = IMX6Q_GPIO_NUMR(6, 14), /* IRQ 管腳號(hào) */
.T_uiReset = NULL, /* Reset 管腳號(hào) */
.T_uiIrqCfg = GPIO_FLAG_IN | GPIO_FLAG_TRIG_FALL, /* IRQ 中斷模式 */
.T_uiRstVal = LW_GPIOF_INIT_LOW, /* Reset 復(fù)位電平 */
.T_usAddr = 0x01, /* I2C 從機(jī)地址 */
.T_iWidth = 1024, /* 分辨率 寬 */
.T_iHeight = 768, /* 分辨率 高 */
.T_iTouchNum = 1, /* 最大觸摸點(diǎn)數(shù) */};static TOUCH_DRV_FUNC _G_CT365DrvFunc = {
.getevent = ct365GetEvent,
.init = NULL,
.deinit = NULL,
.reset = NULL,
};如程序清單 3 7所示,配置完成后需要在函數(shù)boadDevInit里創(chuàng)建觸控設(shè)備:
程序清單 3-7 創(chuàng)建CT365觸控設(shè)備
touchDevCreate("/dev/input/touch0", _G_touchDrvNum, &_G_Ct365Data, &_G_CT365DrvFunc);在系統(tǒng)正常啟動(dòng)和驅(qū)動(dòng)正常加載的情況下,運(yùn)行任意一個(gè)帶觸摸或者鼠標(biāo)組件的QT程序,進(jìn)行觸控操作,如果正確響應(yīng)觸控事件,說(shuō)明驅(qū)動(dòng)移植基本完成。
網(wǎng)站名稱(chēng):SylixOS里CT365I2C觸控驅(qū)動(dòng)移植
當(dāng)前路徑:http://www.chinadenli.net/article44/gjoiee.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站制作、全網(wǎng)營(yíng)銷(xiāo)推廣、企業(yè)網(wǎng)站制作、品牌網(wǎng)站建設(shè)、ChatGPT、網(wǎng)站改版
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)