首页 > 其他 > 详细

SylixOS里CT365 I2C触控驱动移植

时间:2017-02-05 14:12:54      阅读:377      评论:0      收藏:0      [点我收藏+]
  1. 适用范围

    本文档为移植LCD8000-97C屏幕电容触控驱动到iMX6平台过程的总结。提供一些SylixOS触控相关的框架理解和移植心得。

  2. 原理概述

    如图21所示:触控屏通过外部中断提醒主机从I2C总线上读取触控坐标和按压数据,主机读取到触控数据后将数据解析并转换成鼠标事件发送给系统上层,完成一次触控。

    技术分享

    2-1触控流程

  3. 技术实现

  4. Touch框架分析

    /driver/touch/touch.c文件主要实现SylixOS的touch框架。主体框架仅需要关注如图31所示的四个函数:

    技术分享

    3-1 Touch框架重要函数

  5. 函数__touchHwInit

    该函数主要完成如下的功能:

    1. 创建触摸屏使用的I2C的总线设备;
    2. 注册设备触控中断;
    3. 申请设备复位管脚,复位设备;
    4. 调用设备Init函数。
  6. 函数__touchIsr

    这是函数__touchHwInit注册的中断响应服务,主要完成接收触控中断、清除中断,并发出一个touch相关的信号的功能。

  7. 函数__touchThread

    该函数是touch设备的一个线程,其在执行过程中等待touch信号,收到信号后调用函数__touchHandleEvents。

  8. 函数__touchHandleEvents

    该函数通过触控芯片驱动提供的getevent回调函数来获取数据生成的鼠标事件,并向上层发送相关鼠标事件。

  9. 框架的流程图

    整个框架的流程如图32所示:

    技术分享

    3-2 Touch主体框架流程

  10. 数据交互流程确认

    移植的触控屏为英蓓特LCD8000-97c,由于原厂不提供相关触控芯片的资料支持,只能从支持该屏幕的Linux或者Android的调试信息和源码来获得相关IC信息,具体方式不再赘述。这里通过调试信息和源码确认屏幕触控芯片型号为CT365。

  11. Linux和Android下驱动源码分析

    在RIotboard官方提供的源码中关于CT365的驱动是以二进制形式提供的,仅有头文件/driver/input/touchscreen/generic_ts_rel/ct365.h能作为参考,如程序清单 31所示,根据该头文件可以获取CT365的触控信息报文结构:

    程序清单 3-1 ct365头文件中关于数据结构的描述

    struct struct_ct365_pts_data {

    unsignedchar    xhi;// X coordinate Hi

    unsignedchar    yhi;// Y coordinate Hi

    unsignedchar    ylo : 4;// Y coordinate Lo

    unsignedchar    xlo : 4;// X coordinate Lo

    unsignedchar    status : 3;// Action information, 1: Down; 2: Move; 3: Up

    unsignedchar    id : 5;// ID information, from 1 to CFG_MAX_POINT_NUM

    unsignedchar    area;// Touch area

    unsignedchar    pressure;// Touch Pressure

    };

    如程序清单 31大致可以判断出CT365的有效报文为6个字节,其中前三个字节的触控坐标信息和第四个字节前三位的触控状态是最为重要的数据,这些数局最终会解析成鼠标事件。

  12. 逻辑分析仪采样

    将触屏的I2C的两根线接入逻辑分析仪,触摸屏幕的时候抓取I2C通信数据(由于无法再次进行实验,不提供抓取的数据截图)。

    根据逻辑分析仪抓取的数据,可以分析得出CT365的I2C设备地址为0x01,数据传输方式如图34所示:

    技术分享

    3-4 CT365的数据通信流程

    根据以上搜集的信息,结合硬件的原理图基本可以确定CT365的工作方式以及数据传输流程。

    CT365和主板连接部分只有一个I2C接口和一个中断管脚,因此不需要初始化和复位,上电之后每次触控都会产生一个中断,通过中断通知系统向CT365数据发送一帧数据为0的写命令,随后发送读命令读取CT365反馈的触控信息,解析生产鼠标事件。

  13. 代码实现

    参考BSP包中其他的触控芯片驱动的实现,针对CT365仅需实现读函数,触摸数据的解析函数。分解成以下几个子函数:

  • ct365GetEvent

  • ct365GetTouchPoint

  • ct365GetRxData

  • ct36xRegRead

  1. 函数ct365GetEvent

    函数ct365GetEvent主要是由touch框架回调的,用来获取触控数据和生成鼠标事件的,所以先调用ct365GetRxData来获取触控数据,在调用ct365GetTouchPoint来解析生成鼠标事件。具体实现如程序清单 32所示:

    程序清单 3-2ct365GetEvent函数实现

    INTct365GetEvent (PTOUCH_DEVpTouchDev,

    mouse_event_notifyevents[])

    {

    INTiError;

    UCHARucBuffer[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);

    }

     

  2. 函数ct365GetTouchPoint

    函数ct365GetTouchPoint通过传入的触控数据,根据CT365头文件的数据报文结构分别解析出触控的坐标和触控的状态,封装出鼠标事件。具体实现如程序清单 33所示:

    程序清单 3-3ct365GetTouchPoint函数实现

    staticINTct365GetTouchPoint (PTOUCH_DEVpTouchDev,

    mouse_event_notifyevents[],

    UINT8 *pucData)

    {

    INTiTouchPoint;

     

    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;

    } elseif (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;

    } elseif (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);

    }

     

  3. 函数ct365GetRxData

    函数ct365GetRxData调用函数ct36xRegRead去读取I2C数据。具体实现如程序清单 34所示:

    程序清单 3-4ct365GetRxData函数实现

    staticINTct365GetRxData (PTOUCH_DEVpTouchDev,

    UINT8 *pucBuffer,

    UINT16usLen)

    {

    INTiError;

     

    iError =ct36xRegRead(pTouchDev->TOUCH_pI2cDevice,

    0,

    pucBuffer,

    usLen);

    return (iError);

    }

     

  4. 函数ct36xRegRead

    函数ct36xRegRead根据CT365的通讯流程读取CT365反馈的触控数据。具体实现如程序清单 35所示:

    程序清单 3-5ct36xRegRead函数实现

    staticINTct36xRegRead (PLW_I2C_DEVICEpI2cDev,

    UINT8ucReg,

    UINT8 *pucBuffer,

    UINT16usLen)

    {

    INTiError;

    LW_I2C_MESSAGEi2cMsgs[] = {

    {

    .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);

    }

     

  5. BSP中驱动配置

    当触控驱动完成后,如程序清单 36所示,根据硬件原理图在BSP文件中配置好CT365的中断管脚和I2C信息:

    程序清单 3-6配置CT365驱动信息信息

    staticTOUCH_DATA_G_Ct365Data = {

    .T_pcBusName ="/bus/i2c/2", /* I2C 总线名称 */

    .T_uiIrq =IMX6Q_GPIO_NUMR(6, 14), /* IRQ 管脚号 */

    .T_uiReset =NULL, /* Reset 管脚号 */

    .T_uiIrqCfg =GPIO_FLAG_IN | GPIO_FLAG_TRIG_FALL, /* IRQ中断模式 */

    .T_uiRstVal =LW_GPIOF_INIT_LOW, /* Reset 复位电平 */

    .T_usAddr = 0x01,/* I2C 从机地址 */

    .T_iWidth = 1024,/* 分辨率 */

    .T_iHeight = 768,/* 分辨率 */

    .T_iTouchNum = 1,/* 最大触摸点数 */

    };

    staticTOUCH_DRV_FUNC_G_CT365DrvFunc = {

    .getevent = ct365GetEvent,

    .init = NULL,

    .deinit = NULL,

    .reset = NULL,

    };

     

    如程序清单 37所示,配置完成后需要在函数boadDevInit里创建触控设备:

    程序清单 3-7创建CT365触控设备

    touchDevCreate("/dev/input/touch0",_G_touchDrvNum, &_G_Ct365Data, &_G_CT365DrvFunc);

     

  6. 测试

    在系统正常启动和驱动正常加载的情况下,运行任意一个带触摸或者鼠标组件的QT程序,进行触控操作,如果正确响应触控事件,说明驱动移植基本完成。


本文出自 “翼辉小健健” 博客,请务必保留此出处http://senjienly.blog.51cto.com/12547888/1894963

SylixOS里CT365 I2C触控驱动移植

原文:http://senjienly.blog.51cto.com/12547888/1894963

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!