嵌入式Linux系统之I.MX6触摸屏驱动程序TSC2007.C的分析、移植与校准

学习交流加

  • 个人qq:
    1126137994
  • 个人微信:
    liu1126137994
  • 学习交流资源分享qq群:
    962535112

今天来记录一下I.MX6开发板移植触摸屏驱动程序的过程分析。在移植驱动程序之前,为了学习,先去分析一下触摸屏驱动程序的框架。加qq1126137994 一起学习更多技术。

文章目录

    • 1、tsc2007.c触摸屏驱动程序的分析
    • 2、tsc2007.c触摸屏驱动程序的移植
    • 3、触摸屏的校准

1、tsc2007.c触摸屏驱动程序的分析

I.MX6的触摸屏驱动程序的文件名为:TSC2007.C。

在tsc2007.c文件中初始化tsc2007_init函数注册tsc2007_driver结构体,当tsc2007_driver结构体成员驱动name与平台设备层中name匹配相同时调用tsc2007_probe初始化函数,该函数是tsc2007设备驱动函数的入口。imx6的具体tsc2007设备驱动的实现的主要工作在tsc2007_probe里完成。

下面是分析tsc2007_probe函数的调用关系(并非程序源码,只是列举出关键的函数调用):

tsc2007_probeinput_dev = input_allocate_device();//(向input核心层申请)分配一个input_dev结构体。INIT_DELAYED_WORK;//初始化工作队列,把tsc2007工作任务注册到工作队列中,为下面执行队列的任务作好准备。tsc2007_work;//通过input_report_abs函数向上层上报触摸屏屏的X、Y坐标和压力值,执行tsc2007_calculate_pressure函数进行压力校准,init_platform_hw;//?input_set_abs_params;//通过input_dev结构体设置按键和绝对位置事件以及事件下需要处理的ABS_X、ABS_Y、ABS_PRESSURE的具体事件内容request_irq(ts->irq, tsc2007_irq, 0,client->dev.driver->name, ts);//为tsc2007中断引脚申请一个中断处理函数,schedule_delayed_work;//中断的上半部分tsc2007_work;  //中断的下半部分,tsc2007_read_values;//读取xy坐标 以及获取压力值tc->y = tsc2007_xfer(tsc, READ_Y);tc->x = tsc2007_xfer(tsc, READ_X);tsc2007_xfer(tsc, PWRDOWN);//另一次循环测量rt = tsc2007_calculate_pressure // 计算压力   input_report_abs(input, ABS_X, tc.x);input_report_abs(input, ABS_Y, tc.y);input_report_abs(input, ABS_PRESSURE, rt);//上报获取到的值tsc2007_xfer;							data = i2c_smbus_read_word_data; //检测IIC总线的读写操作val = swab16(data) >> 4; //去掉低4位无效数据(#define	MAX_12BIT 由定义知最大为12bit,所以需要去掉低4位)return val;//tsc2007_xfer返回一个val值,就是xy坐标的值input_register_device;   //像input核心层注册input_dev结构体arch\mips\boot\Elf2ecoff.c中有如下定义
#define swab16(x) \(( \(((x) & 0x00ffU) << 8) | \(((x) & 0xff00U) >> 8) )) //将x的值的高8位和低8位互换

当按下触摸板后产生中断,中断里面调用延时函数进入底半部程序。在调度函数里面,先读取坐标,计算压力,然后根据压力大小上报坐标。若触摸板一直按下,那么就重新调用,并通过压力值来看触摸板是否释放。

2、tsc2007.c触摸屏驱动程序的移植

触摸屏驱动程序的核心部分分析完了,下面就开始移植触摸屏驱动程序,其实,内核自带的驱动程序移植起来非常简单,在理解驱动程序的前提下,在平台设备文件中添加一些私有数据信息,以及配置中断引脚等即可。

IMX6的板级初始化函数:Board-mx6q_sabresd.c
由与tsc2007与imx6之间的通信是通过IIC总线进行的,因此在imx6的平台设备层(platform_device)的mx6_sabresd_board_init函数里就需要配置与tsc2007有关的IIC总线。由于是TSC2007所挂的IIC总线是第二根,在平台初始化函数里将会调用i2c_register_board_info函数注册mxc_i2c2_board_info结构体数组。

向mxc_i2c2_board_info结构体数组里添加如下成员:

{I2C_BOARD_INFO("tsc2007",0x48),.platform_data = (void *)& tsc2007_data_lyy,.irq = gpio_io_irq(SABRESD_TS_INT),
}

其中由于TSC2007的A0、A1两个引脚下拉,通过I2C_BOARD_INFO函数注册的从机设备地址是0x48;通过gpio_to_irq函数获取TSC2007中断号,之后会传给平台驱动层,当申请中断会用到;

再构建tsc2007_data_lyy结构体,并添加4个成员:init_platform_hw函数、get_pendown_state函数、irq_pin中断引脚的选择、触摸屏驱动相关参数。

/*  * 注意:一下添加的函数,位置没有固定要求,但是为了整齐统一,还是把它放到与其它设备定义的相通的位置,方便以后查看*/
#ifdef CONFIG_TOUCHSCREEN_TSC2007
#include <linux/i2c/tsc2007.h>(在头文件里也添加一下)static int tsc2007_hw_init(void){int err;err = gpio_request(SABRESD_TS_INT,"tsc2007 irq");if(err<0){pr_err("tsc2007 irq gpio request err\n");return err;}err = gpio_direction_input(SABRESD_TS_INT);if(err<0){pr_err("tsc2007 irq gpio init input err %d\n",err);gpio_free(SABRESD_TS_INT);return err;}printk("tsc2007 irq gpio init success!\n");return 0;}static void tsc2007_hw_remove(void){gpio_free(SABRESD_TS_INT);}static int tsc2007_get_pendown_state(void){int state;state = gpio_get_value(SABRESD_TS_INT);//printk("tsc2007 get state = %x\n",state);return (state == 0)? 1:0;}static struct tsc2007_platform_data tsc2007_data_lyy= {.model = 2007,.x_plate_ohms =180,.init_platform_hw = tsc2007_hw_init,.exit_platform_hw = tsc2007_hw_remove,.get_pendown_state = tsc2007_get_pendown_state,};
#endif

更改中断引脚号:

将宏SABRESD_TS_INT改为:(之前是3,26)
#define SABRESD_TS_INT		IMX_GPIO_NR(6, 7) //lyy (申请中断引脚)

注:在Linux启动的时候会将信息进行收集,i2c适配器会扫描已经静态注册的i2c_board_info,通过调用i2c_register_board_info函数将包含所有I2C设备的i2c_board_info信息的i2c_devinfo变量加入到__i2c_board_list链表中,并调用i2c_new_device为其实例化一个i2c_client。在驱动加载的时候遇到同名的i2c_board_info就会将i2c_client和driver绑定,并且执行driver的probe函数。这种方式一般放在平台的代码中。

i2c_register_board_info(2, mxc_i2c2_board_info,ARRAY_SIZE(mxc_i2c2_board_info));

注释:
上面的工作,基本完成了驱动程序的移植,但是后来经过测试,发现显示有错误:
Failed to register i2c client tsc2007 at 0x48 (-16)
Can’t create device at 0x48
一开始以为是i2c总线没有识别到,但是经过调试,发现是中断引脚的复用了。

1、首先确定中断的引脚,查看原理图知使用的是:MX6Q_PAD_NANDF_CLE__GPIO_6_7,
在mach-mx6\Board-mx6q_sabresd.h 中加入定义:MX6Q_PAD_NANDF_CLE__GPIO_6_7,当然如果有其它设备用
了这个引脚,要将其注销
2、在板极文件board-mx6q_sabresd.c中注册和申请I2C驱动
首先申请中断的信号,并注释掉原来关于GPIO_6_7的引脚(不然无法识别tsc2007设备)
添加头文件:#define SABRESD_TS_INT		IMX_GPIO_NR(6, 7) //lyy
注释掉之前的://#define SABRESD_CAP_TCH_INT1	IMX_GPIO_NR(6, 7)//之前的

OK!到此,程序添加成功,下一步就是校准触摸屏了!!!

3、触摸屏的校准

校准的目的:为了与显示屏的坐标一一对应。我们一般采用软件校准,使用Tslib库里的校准软件进行校准们首先需要移植Tslib库。

编译tslib(放到rootfs/tslib/tslib):
tar xzf tslib-1.4.tar.gz
cd tslib
./autogen.sh mkdir tmp
echo "ac_cv_func_malloc_0_nonnull=yes" >arm-linux.cache
./configure --host=arm-linux --cache-file=arm-linux.cache --prefix=$(pwd)/tmp
make
make install

我的这一部分是放到开发的环境中做的,其实可以直接在单板上搞,如果单板上是有编译器的话。

然后将系统烧写的单板,在单板上操作:

cd /tslib/tslib/tmp
cp * / -rfd1.
修改 /etc/ts.conf第1行(去掉#号和第一个空格):
# module_raw input
改为:
module_raw input2.
export TSLIB_TSDEVICE=/dev/input/event1
export TSLIB_CALIBFILE=/etc/pointercal
export TSLIB_CONFFILE=/etc/ts.conf
export TSLIB_PLUGINDIR=/lib/ts
export TSLIB_CONSOLEDEVICE=none
export TSLIB_FBDEVICE=/dev/fb0

测试:
ts_calibrate

ts_test
备注:如果出现段错误,解决办法如下:
1、ts.conf文件中的各个设置选项之前不能有空格,否则会出现: Segmentation fault 错误,
我就不小心在module…之前多了个空格,害我查了好久。
2、不要在pointercal对应的目录下,建立一个空的pointercal文件,否则在运行ts_calibrate时,
也可能会出现Segmentation fault

想一起探讨以及获得各种学习资源加我(有我博客中写的代码的原稿):
qq:1126137994
微信:liu1126137994
可以共同交流关于嵌入式,操作系统,C++语言,C语言,数据结构等技术问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/423232.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

docker 安装及打springboot jar打镜像

1.首先是安装 centos7 2.安装docker 建议参考 https://www.jianshu.com/p/ef14131fe900 2.1docker 一些常用的命令 docker ps 查看容器 docker run 创建容器 docker rmi imageId 删除容器 docker images 列出索引镜像 各个选项说明: REPOSITORY&#xff1a;表示镜像的…

java编程思想学习(2):对象

按照课本上的案例 我们也来创建一个小灯泡的案例 package geyao02;public class Light {public void on() {System.out.println("我可以发光");}public void off() {System.out.println("我可以关闭");}}运行结果 package geyao02;public class TestLig…

【C++深度剖析教程27】多态的概念与意义

今天来学习一个新的概念&#xff0c;多态&#xff01;&#xff01;&#xff01;多态在C编程中具有重要的地位与意义&#xff0c;是面向对象的一个重要思想&#xff01; 加qq1126137994一起学习更多技术~ 1、问题引入 父类与子类之间具有赋值兼容性; *子类对象可以当做父类对…

母亲的革命

做了几个星期思想工作&#xff0c;经过一天的舟车之劳&#xff0c;终于把母亲接到了县城住下来。 按理说&#xff0c;老早就想接母亲出来享享清福&#xff0c;顺便带带金果。可母亲一来放心不下家里的土地&#xff0c;二来怕婆媳之间不好相处&#xff0c;所以都推绝了。 母亲今…

springboot+hbase 集成

项目中使用 phoenix 使用SQL 方式来操作Hbase 数据库&#xff0c;但是遇到一个是&#xff0c;SQL在Dbeaver 中查询速度还可以&#xff0c;但是使用phoenixibatis 后返回结果集数据量20w &#xff0c;速度特别慢&#xff0c;先是考虑用redis方式缓存&#xff0c;但是内存有限&am…

java编程思想学习(3):Java中的private、protected、public和default的区别

&#xff08;1&#xff09;对于public修饰符&#xff0c;它具有最大的访问权限&#xff0c;可以访问任何一个在CLASSPATH下的类、接口、异常等。它往往用于对外的情况&#xff0c;也就是对象或类对外的一种接口的形式。 &#xff08;2&#xff09;对于protected修饰符&#xf…

【Makefile由浅入深完全学习记录2】初识 makefile 的结构

继续学习makefile&#xff0c;希望尽快掌握makefile好在面试中更好的掌握方向&#xff01;加qq1126137994一起学习更多技术&#xff01;&#xff01; 1、回顾 makefile的意义&#xff1a; makefile用于定义源文件之间的依赖关系makefile说明如何编译各个源文件并生成可执行文…

只进ResultSet 不支持请求的操作

使用jdbc操作时 抛出异常 只进ResultSet 不支持请求的操作 那肯定是 在使用resultset的游标操作时调用 resultSet.first () resultSet.last等等方法 你要做的就是设置游标支持滚动操作 如果是statement Statement stmtcon.createStatement&#xff08;ResultSet.TYPE_SCROLL_…

【Makefile由浅入深完全学习记录3】伪目标的引入

只有不停的努力&#xff0c;才能看起来很轻松&#xff01;&#xff01;&#xff01;加qq1126137994共同学习探讨更多技术&#xff01;&#xff01;&#xff01; 1、思考&#xff1a; makefile中的目标究竟是什么&#xff1f; 在默认的情况下&#xff1a; make认为目标对应一…

InnoDB的auto_increment指定值被重置问题

有时候新建的表需要对自增列指定初始值&#xff0c;但是有时候会出现明明指定过的初始值却被重置的现象。下面以一个小实验来说明这个问题&#xff1a;MySQL version:5.1.42 OS:redhat5.3无废话&#xff0c;建张表先&#xff1a;代码CREATETABLEsbtest1 ( id int(10) unsigned…

java ReentrantLock 使用

1.ReentrantLock 简单的使用 private Lock lock new ReentrantLock(); lock.lock();用来获取锁。 lock.unlock();用来释放锁 package com.qey.lock;import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Thr…

【Makefile由浅入深完全学习记录4】变量和不同的赋值方式

今天来学习Makefile中变量的不同的赋值方式&#xff01;努力的意义就是让贫穷不再限制你的想象&#xff01;加qq共同学习交流1126137994 1、概念 makefile中支持程序设计中变量的概念makefile中的变量只代表文本数据&#xff08;字符串&#xff09;makefile中的变量名规则 -…

前端学习(100):float注意点整理1

1只会影响后面得元素 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><meta http-equiv"X-UA-Compatible…

ASP.NET小技巧——回传后保持页面的滚动位置

今天在MSDN上看到一篇文章&#xff0c;关于如何在ASP.NET页面回传后保持当前的滚动&#xff08;垂直&#xff09;位置。这个技巧挺实用的&#xff0c;在此做简单的翻译介绍。默认情况下&#xff0c;ASP.NET页面回传到服务器后&#xff0c;页面会跳回顶部。对于一个内容较多的页…

USB转WIFI无线网卡驱动程序(RT5370驱动程序)的移植记录之一

学习交流加 个人qq&#xff1a; 1126137994个人微信&#xff1a; liu1126137994学习交流资源分享qq群&#xff1a; 962535112 今天记录我在I.MX6Q平台移植RT5370无线网卡驱动程序的过程&#xff0c;加qq1126137994 微信&#xff1a;liu1126137994 共同学习更多技术&#xff01;…

HTTP和RPC的优缺点

在HTTP和RPC的选择上&#xff0c;可能有些人是迷惑的&#xff0c;主要是因为&#xff0c;有些RPC框架配置复杂&#xff0c;如果走HTTP也能完成同样的功能&#xff0c;那么为什么要选择RPC&#xff0c;而不是更容易上手的HTTP来实现了。 本文主要来阐述HTTP和RPC的异同&#xff…

【Makefile由浅入深完全学习记录5】预定义变量的使用

今天学习Makefile预定义变量的使用&#xff0c;加qq&#xff1a;1126137994.微信&#xff1a;liu1126137994一起学习更多技术&#xff01;&#xff01;&#xff01; 1.预定义变量&#xff1a;自动变量 在Makefile中存在一些预定义过的变量&#xff0c;我们可以直接拿来使用而…

NFC 验证平台搭建

如何把 NFC 挂载到 G7的系统中去&#xff0c;调试一步一步的过程中分别做了什么。 1. 在AHB1上找到1个slave的空挡&#xff0c;ahb-slave8&#xff0c;修改相应AMAB里面的ahb_dcdr.v 文件&#xff0c;给NFC分配基地址空间 0x110050002.在ahb1_top文件当中例化NFC&#xff0c;同…

两个原子操作组合到一块不一定是能保证原子性

1.两个原子操作组合到一块不一定是能保证原子性 ConcurrentLinkedQueue AtomicInteger 两个类都为线程安全的类&#xff0c;但是组合起来并不能保证原子性: public static ConcurrentLinkedQueue concurrentLinkedQueue new ConcurrentLinkedQueue();public static Atomic…

【Makefile由浅入深完全学习记录6】Makefile中变量的高级主题上

抓住基础&#xff0c;学习更多技术&#xff0c;迎接挑战&#xff0c;加qq&#xff1a;1126137994 微信&#xff1a;liu1126137994 一起学习更多技术~ 上一篇文章学习了makefile中的预定义变量的使用&#xff0c;今天来继续学习makefile中的变量&#xff01; 1、变量值的替换 …