SylixOS里CT365 I2C触控驱动移植

2024-03-13 07:10

本文主要是介绍SylixOS里CT365 I2C触控驱动移植,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.适用范围

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

2.原理概述

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

图 2-1  触控流程

3.技术实现

3.1Touch框架分析

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

图 3-1  Touch框架重要函数

3.1.1函数__touchHwInit

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

    1)创建触摸屏使用的I2C的总线设备;

    2)注册设备触控中断;

    3)申请设备复位管脚,复位设备;

    4)调用设备Init函数。

3.1.2函数__touchIsr

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

3.1.3函数__touchThread

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

3.1.4函数__touchHandleEvents 

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

3.1.5框架的流程图

    整个框架的流程如图3‑2所示:

图 3-2  Touch主体框架流程

3.2数据交互流程确认

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

3.2.1Linux和Android下驱动源码分析

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

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

struct struct_ct365_pts_data {unsigned char	xhi;           // X coordinate Hiunsigned char	yhi;           // Y coordinate Hiunsigned char	ylo : 4;       // Y coordinate Lounsigned char	xlo : 4;       // X coordinate Lounsigned char	status : 3;    // Action information, 1: Down; 2: Move; 3: Upunsigned char	id : 5;        // ID information, from 1 to CFG_MAX_POINT_NUMunsigned char	area;          // Touch areaunsigned char	pressure;      // Touch Pressure
};

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

3.2.2逻辑分析仪采样

    将触屏的I2C的两根线接入逻辑分析仪,触摸屏幕的时候抓取I2C通信数据(由于无法再次进行实验,不提供抓取的数据截图)。
    根据逻辑分析仪抓取的数据,可以分析得出CT365的I2C设备地址为0x01,数据传输方式如图3-4所示:

图 3-4  CT365的数据通信流程

    根据以上搜集的信息,结合硬件的原理图基本可以确定CT365的工作方式以及数据传输流程。
    CT365和主板连接部分只有一个I2C接口和一个中断管脚,因此不需要初始化和复位,上电之后每次触控都会产生一个中断,通过中断通知系统向CT365数据发送一帧数据为0的写命令,随后发送读命令读取CT365反馈的触控信息,解析生产鼠标事件。

3.3代码实现

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

  • ct365GetEvent

  • ct365GetTouchPoint

  • ct365GetRxData

  • ct36xRegRead

3.3.1函数ct365GetEvent

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

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

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

3.3.2函数ct365GetTouchPoint

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

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

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

3.3.3函数ct365GetRxData

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

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

static INT  ct365GetRxData (PTOUCH_DEV  pTouchDev,UINT8      *pucBuffer,UINT16      usLen)
{INT     iError;iError = ct36xRegRead(pTouchDev->TOUCH_pI2cDevice,0,pucBuffer,usLen);return  (iError);
}

3.3.4函数ct36xRegRead

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

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

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

3.4BSP中驱动配置

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

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

static TOUCH_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,                                            /*  最大触摸点数                */
};
static TOUCH_DRV_FUNC   _G_CT365DrvFunc = {.getevent       = ct365GetEvent,.init           = NULL,.deinit         = NULL,.reset          = NULL,
};

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

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

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

3.5测试

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

转载于:https://my.oschina.net/senjienly/blog/831889

这篇关于SylixOS里CT365 I2C触控驱动移植的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/804028

相关文章

Linux_kernel驱动开发11

一、改回nfs方式挂载根文件系统         在产品将要上线之前,需要制作不同类型格式的根文件系统         在产品研发阶段,我们还是需要使用nfs的方式挂载根文件系统         优点:可以直接在上位机中修改文件系统内容,延长EMMC的寿命         【1】重启上位机nfs服务         sudo service nfs-kernel-server resta

FreeRTOS-基本介绍和移植STM32

FreeRTOS-基本介绍和STM32移植 一、裸机开发和操作系统开发介绍二、任务调度和任务状态介绍2.1 任务调度2.1.1 抢占式调度2.1.2 时间片调度 2.2 任务状态 三、FreeRTOS源码和移植STM323.1 FreeRTOS源码3.2 FreeRTOS移植STM323.2.1 代码移植3.2.2 时钟中断配置 一、裸机开发和操作系统开发介绍 裸机:前后台系

驱动(RK3588S)第七课时:单节点设备树

目录 需求一、设备树的概念1、设备树的后缀名:2、设备树的语法格式3、设备树的属性(重要)4、设备树格式举例 二、设备树所用函数1、如何在内核层种获取设备树节点:2、从设备树上获取 gpio 口的属性3、获取节点上的属性只针对于字符串属性的4、函数读取 np 结点中的 propname 属性的值,并将读取到的 u32 类型的值保存在 out_value 指向的内存中,函数的返回值表示读取到的

驱动安装注册表指令

HKCR: HKEY_CLASSES_ROOT HKCU: HKEY_CURRENT_USER HKLM: HKEY_LOCAL_MACHINE HKU: HEKY_USER HER: 相对根键

UMDF驱动安装

VS2013 + WDF8.1,UMDF驱动选择User Mode Driver,不要选User Mode Driver 2.0,否则Win7安装有问题,如图 另外,在驱动安装时不要忘记WUDFUpdate_<主版本号><次版本号>.dll文件,具体文件名在INF中查找。此文件可在WDF的安装目录中找到。注意:在WDF的安装目录中会有3个WUDFUpdate_xxx.dll文件,x86,x6

电脑驱动分类

电脑驱动程序(驱动程序)是操作系统与硬件设备之间的桥梁,用于使操作系统能够识别并与硬件设备进行通信。以下是常见的驱动分类: 1. 设备驱动程序 显示驱动程序:控制显卡和显示器的显示功能,负责图形渲染和屏幕显示。 示例:NVIDIA、AMD 显示驱动程序。打印机驱动程序:允许操作系统与打印机通信,控制打印任务。 示例:HP、Canon 打印机驱动程序。声卡驱动程序:管理音频输入和输出,与声卡硬件

RT-Thread(Nano版本)的快速移植(基于NUCLEO-F446RE)

目录 概述 1 RT-Thread 1.1 RT-Thread的版本  1.2 认识Nano版本 2 STM32F446U上移植RT-Thread  2.1 STM32Cube创建工程 2.2 移植RT-Thread 2.2.1 安装RT-Thread Packet  2.2.2 加载RT-Thread 2.2.3 匹配相关接口 2.2.3.1 初次编译代码  2.2.3.

麒麟系统安装GPU驱动

1.nvidia 1.1显卡驱动 本机显卡型号:nvidia rtx 3090 1.1.1下载驱动 打开 https://www.nvidia.cn/geforce/drivers/ 也可以直接使用下面这个地址下载 https://www.nvidia.com/download/driverResults.aspx/205464/en-us/ 1.1.3安装驱动 右击,

windows10 卸载网络驱动以及重新安装

右键桌面此电脑的图标,点击管理,设备管理器—网络适配器,找到下图中的驱动(不同的系统或者显卡会导致网卡驱动名称与下图不一样,多为Realtek开头),右键选择卸载设备,然后重启电脑,系统会自动重新安装驱动 新电脑首次安装驱动: 根据主板厂家,比如华硕,进入华硕官网,点击服务支持,点击下载中心,选择型号,点击右侧驱动程序和工具软件,选择windows版本,下载相应的驱动,下载完之后在对应文件中找

笔记整理—内核!启动!—kernel部分(1)驱动与内核的关系

首先,恭喜完成了uboot部分的内容整理,其次补充一点,uboot第一部分和第二部分的工作不是一定的,在不同的版本中,可能这个初始化早一点,那个的又放在了第二部分,版本不同,造成的工作顺序不同,但终归是要完成基本内容初始化并传参给kernel的。         那么至于驱动与内核的关系,用一张图来说明最适合不过:         驱动位于OS层的中下层与硬件相接。驱动是内