文档章节

am335x触摸屏驱动简要分析

季风_落地窗
 季风_落地窗
发布于 2016/03/17 16:34
字数 2339
阅读 1371
收藏 1
点赞 3
评论 0

 TI文档

综述

AM335x触摸屏控制器支持如下四种工作模式:

• 8路通用的ADC

• 4路作为4线触摸屏连接,4路作为通用ADC

• 5路作为5线触摸屏连接,3路作为通用ADC

• 8路作为8线触摸屏连接

ADC采用的是12位SAR ADC, 采样速率为每秒200k次. AD采样模拟信号是从start of conversion为高时开始并在下降沿后的1个时钟周期内继续采样. 它在采样周期结束时捕获模拟信号并启动转换. 它在12个时钟周期内将采样数据数字化,当end of conversion信号被使能为高时, 表明数据ADCOUT<11:0>已可读. 当以前的数据被读取后一个新的转换周期就可以开始了。 请注意,ADC输出的是加权的二进制数据

一 硬件连接:

4线触摸屏的连接

5线触摸屏连接

8线触摸屏连接

二 Linux driver

2.1 配置使能

Device Drivers  --->
         [*]  Staging drivers  --->
                  [*]  Industrial I/O support  ---> 
                  [*]  Enable buffer support within IIO
                  <*>     Industrial I/O lock free software ring                                                              
                  < >     Industrial I/O buffering based on kfifo
                  -*-  Enable triggered sampling support                                                                     
                  (2)     Maximum number of consumers per trigger
                       Analog to digital converters  --->
                                <*>   TI's ADC driver

这里<*> TI's ADC driver 是直接编译进内核, 如果只是想编译为模块则可以点击空格更改为<M>

2.2 设置驱动的平台数据(platform_data)

在arch/arm/mach-omap2/board-am335xevm.c(我的板子是board-com335x.c)里添加如下代码:

#include <linux/platform_data/ti_adc.h>
static struct adc_data am335x_adc_data = {
        .adc_channels = 4,
};

static struct mfd_tscadc_board tscadc = {
        .tsc_init = &am335x_touchscreen_data,
        .adc_init = &am335x_adc_data,
};

如果你要同时使用adc和触摸屏的话照上边这样设置即可.

如果只使用adc则要移除触摸屏的平台数据(platform data),如下所示:

static struct adc_data am335x_adc_data = {
        .adc_channels = 8,
};

/*     
static struct tsc_data am335x_touchscreen_data  = {
        .wires  = 4,
        .x_plate_resistance = 200,
        .steps_to_configure = 5,
};  
*/

static struct mfd_tscadc_board tscadc = {
        /*   .tsc_init = &am335x_touchscreen_data, */
        .adc_init = &am335x_adc_data,
};

三 测试

将直流电压连接到AIN0到AIN7的引脚上(你使用了哪个就接在哪个引脚),千万注意测试电压只能在0~1.8v之间

3.1 查看IIO设备

root@arago-armv7:~# ls -al /sys/bus/iio/devices/iio\:device0/
drwxr-xr-x    5 root     root            0 Jan  1 00:00 .
drwxr-xr-x    4 root     root            0 Jan  1 00:00 ..
drwxr-xr-x    2 root     root            0 Jan  1 00:00 buffer
-r--r--r--    1 root     root         4096 Jan  1 00:00 dev
-r--r--r--    1 root     root         4096 Jan  1 00:00 in_voltage0_raw
-r--r--r--    1 root     root         4096 Jan  1 00:00 in_voltage1_raw
-r--r--r--    1 root     root         4096 Jan  1 00:00 in_voltage2_raw
-r--r--r--    1 root     root         4096 Jan  1 00:00 in_voltage3_raw
-r--r--r--    1 root     root         4096 Jan  1 00:00 in_voltage4_raw
-r--r--r--    1 root     root         4096 Jan  1 00:00 in_voltage5_raw
-r--r--r--    1 root     root         4096 Jan  1 00:00 in_voltage6_raw
-r--r--r--    1 root     root         4096 Jan  1 00:00 in_voltage7_raw
-rw-r--r--    1 root     root         4096 Jan  1 00:00 mode
-r--r--r--    1 root     root         4096 Jan  1 00:00 name
drwxr-xr-x    2 root     root            0 Jan  1 00:00 power
drwxr-xr-x    2 root     root            0 Jan  1 00:00 scan_elements
lrwxrwxrwx    1 root     root            0 Jan  1 00:00 subsystem -> ../../../../../../bus/iio
-rw-r--r--    1 root     root         4096 Jan  1 00:00 uevent

3.2 单次模式

检查ADC模式, 如下所示即为单次模式

cat /sys/bus/iio/devices/iio\:device0/mode
oneshot

如果不是单次模式可以使用如下命令更改

Echo onesht > /sys/bus/iio/devices/iio\:device0/mode

从某一端口读取ADC输出数据:

in_voltageX_raw: raw value of the channel X of the ADC

从以下命令可知in_voltageX_raw里保存的就是ADC的原始数据, 4095即满量程数据

root@arago:~# cat /sys/bus/iio/devices/iio\:device0/in_voltage0_raw
4095

四 计算结果

D = Vin * (2^n - 1) / Vref

比如读取回来ADC的数据是2298那么输入电压就是

Vin = D / ((2^n - 1) / Vref)

Vin = 2298 / ((2^12 – 1) / 1.8)

Vin = 1.01V

相关资料:

1 AM335x ADC Driver's Guide http://www.deyisupport.com/question_answer/w/faq/469.am335x-linux.aspx

2 AM335X 触摸屏的硬件连接及Linux驱动

http://ti.eetop.cn/viewnews-4453

3 Using resistive touch screens for human/machine interface

http://www.ti.com/lit/an/slyt209a/slyt209a.pdf

input子系统

因为触摸屏使用的是input子系统所以要讲解触摸屏之前首先要讲解一下input子系统, 它的核心文件是input.c

Input子系统结构与功能实现

1 Input子系统是分层结构的,总共分为三层: 硬件驱动层,子系统核心层,事件处理层。 

(1)其中硬件驱动层负责操作具体的硬件设备,这层的代码是针对具体的驱动程序的,需要驱动程序的作者来编写

(2)子系统核心层是链接其他两个层之间的纽带与桥梁,向下提供驱动层的接口,向上提供事件处理层的接口

(3)事件处理层负责与用户程序打交道,将硬件驱动层传来的事件报告给用户程序

2各层之间通信的基本单位就是事件,任何一个输入设备的动作都可以抽象成一种事件,如键盘的按下,触摸屏的按下,鼠标的移动等。事件有三种属性:类型(type),编码(code),值(value),Input子系统支持的所有事件都定义在input.h中,包括所有支持的类型,所属类型支持的编码等。事件传送的方向是 硬件驱动层-->子系统核心-->事件处理层-->用户空间

3 以触摸屏为例说明输入子系统的工作流程:

     注:am335x sdk6的触摸屏驱动所用驱动层对应的模块文件为:ti_tsc.c,事件处理层对应的模块文件为 evdev.c

    (1)ti_tsc模块初始化函数中将触摸屏注册到了输入子系统中,于此同时,注册函数在事件处理层链表中寻找事件处理器,这里找到的是evdev,并且将驱动与事件处理器挂载。并且在/dev/input中生成设备文件event0,以后我们访问这个文件就会找的我们的触摸屏驱动程序。

    (2)应用程序打开设备文件/dev/input/event0,读取设备文件,调用evdev模块中read,如果没有事件,进程就会睡眠。  

    (3)当触摸屏按下,驱动层通过input子系统核心层将事件(就是X,Y坐标, 压感, 按下/松开)传给事件处理层也就是evdev,evdev唤醒睡眠的进程,将事件传给进程处理。

下边看下代码流程:

input_init()
         class_register
register_chrdev(INPUT_MAJOR, "input", &input_fops);
可以看到input子系统帮我们写了以上两个函数, 那么这个input_fops是不是就是我们要填充的file_operations呢?
static const struct file_operations input_fops = {
         .owner = THIS_MODULE,
         .open = input_open_file,
         .llseek = noop_llseek,
};

这个file_operations并没有read/write等接口, 由此我们可知该结构体只是一个连接上下层的作用, 这是一种分层的思想. 那么他就是通过open成员来连接上下层, 我们来看下open成员做了什么事情:

input_open_file
        handler = input_table[iminor(inode) >> 5];//使用此设备号拿到handler结构体
        new_fops = fops_get(handler->fops);      //获取新的file_operations
        file->f_op = new_fops;                             //使用handler的fops成员来作为新的file_operations
        new_fops->open(inode, file);                   //handler->fops->open(indoe, file)

由此可知: 通过次设备号拿到数组中的handler成员, 就完成了上层的input_fops到底层的真实handler->fops的转换,

底层的handler->fops->open(indoe, file) 就是真实的open, 对应的read/write也是

现在最关键的就是input_table[]数组是怎么来的呢?  

通过查找代码发现在 input_register_handler里使用了它, 那么谁调用了这个函数呢? 在input子系统的下边有很多驱动都用到了这个函数, 他们首先查找有没有能匹配的硬件,如果有就调用这个函数将input_handler放入数组里边.

这些驱动在以下的软件部分可以看到:

软件部分

Evdev.c  Joydev.c Keyboard.c Mousedev.c等这些就是input子系统向上注册input_handler

input_register_handler
         input_attach_handler  判断硬件的id_table能否与自己的id_table匹配, 如果匹配这建立连接

硬件部分:

input_register_device
         input_attach_handler   判断软件的id_table能否与自己的id_table匹配, 如果匹配这建立连接

device和handler在注册的时候都会查找对方是否有可以与自己匹配的, 如果有就调用connect函数来连接彼此.

下边以evdev.c为例来说明软硬件两部分是如何建立连接的:

evdev_connect()
         evdev->handle.dev = input_get_device(dev);
         evdev->handle.handler = handler;

在evdev.c中又创建了一个handle结构体他分别指向device和handler, 这样软硬件两边通过这个结构体找到对方.

 

Am335x的sdk6中触摸屏的驱动文件

一 arch/arm/mach-omap2/board-com335x.c        板级初始化

static struct tsc_data am335x_touchscreen_data  = {
         .wires  = 4,                            //4线触摸屏
         .x_plate_resistance = 200,     //阻抗200欧姆
         .steps_to_configure = 5,        //在产生中断之前在fifo中的样本个数, 最大16
};

二 drivers/input/touchscreen/ti_tsc.c         驱动文件

ti_tsc_init
         platform_driver_register (&ti_tsc_driver);
tscadc_probe
         input_allocate_device  //分配

request_irq
         input_dev->name = "ti-tsc";  //设置
         input_dev->dev.parent = &pdev->dev;
         input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);//可以产生按键类事件/绝对位移类事件
         input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);//触摸屏触摸屏事件
         input_register_device//注册

中断处理函数

tscadc_interrupt
         tscadc_readl 读取中断状态寄存器, adc与tsc共用一个中断源
         判断中断原因然后上报事件
         input_report_abs(input_dev, ABS_X, val_x);//x坐标
         input_report_abs(input_dev, ABS_Y, val_y);//y坐标
         input_report_abs(input_dev, ABS_PRESSURE, z);//压感
         input_report_key(input_dev, BTN_TOUCH, 1);//按下/松开
         input_sync(input_dev);

         检查是否是抬起中断
         status = tscadc_readl(ts_dev, TSCADC_REG_RAWIRQSTATUS);
         if (status & TSCADC_IRQENB_PENUP)
             input_report_key(input_dev, BTN_TOUCH, 0);
             input_report_abs(input_dev, ABS_PRESSURE, 0);
             input_sync(input_dev);

 


© 著作权归作者所有

共有 人打赏支持
季风_落地窗
粉丝 4
博文 16
码字总数 16829
作品 0
杨浦
程序员
Beaglebone && GUI

本文基于chipsee平台的扩展板为Beaglebone平台添加GUI支持。 首先是开发环境的选择,这里我们使用TI SDK(ti-sdk-am335x-evm-05.06.00.00-Linux-x86)中提供的Linux内核与最精简根文件系统(ar...

Cedric_Sun
2013/04/28
0
0
Am335x lcd驱动分析

一 文件列表 本文使用的为sdk6.0 kernel版本为3.2 并未使用dts am335x的lcd驱动相关文件有: (kernel)/drivers/video/da8xx-fb.c(kernel)/drivers/video/fbmem.c(kernel)/arch/arm/mach-davin......

季风_落地窗
2016/03/09
828
0
tslib-1.4在arm11上的交叉编译

Tslib校准原理 在采用触摸屏的移动终端中,触摸屏性能的调试是个重要问题之一,因为电磁噪声的缘 故,触摸屏容易存在点击不准确、有抖动等问题。 Tslib是一个开源的程序,能够为触摸屏驱动获...

mjrao
2012/04/26
0
0
Enable DCAN For BeagleBoneBlack ChipSee Exp V1

给ChipSee的一段话: 1.买了beagblebone_black+7'电容屏,看中的是CAN接口和电容屏,买之前问过CAN的相关资源,确认了是SocketCAN接口; 2.在使用CAN接口时遇到了问题咨询ChipSee工程师“许工...

机油战士
2013/08/19
0
2
gslx680.c触摸屏驱动

转:http://blog.csdn.net/zgkxzx/article/details/56980769 前言 gslx680电容触摸屏是一种目前Android嵌入式设备中比较常用的触摸屏类型。这里我们以Exynos4412为Android bsp平台,移植一款...

WXXGoodJob
2017/08/29
0
0
linux触摸屏驱动

版权所有,转载请说明转自 http://my.csdn.net/weiqing1981127 一.触摸屏理论概述 对于触摸屏驱动,我们主要需要掌握触摸屏驱动代码和应用层测试代码。下面讲的是基于Mini2440的触摸屏驱动,...

So_care_about_y
2017/08/05
0
0
NUC970平台触摸屏驱动移植

原理概述 1.首先要区分lcd和触摸屏,lcd是一个屏幕,触摸屏是贴在lcd上的两层膜。 2.四线电阻触摸屏的原理:触摸屏就是上下两层膜,比如上层代表x轴(XM:负端,XP:正端),下层代表y轴(Y...

诸葛一帆丶
2017/02/15
0
0
深度剖析安卓Framebuffer设备驱动

忙了几天,今天在公司居然没什么活干 ,所以早上就用公司的电脑写写之前在公司编写framebuffer的使用心得体会总结,这也算是一点开发经验,不过我还没写全,精华部分还是自己藏着吧。直到下午...

DB_Terrill
05/04
0
0
Android Input系统之触摸屏

最近开始在TI平台调试触摸屏,之前研究过Android的Event输入设备驱动,对键盘比较了解。Input驱动程序包含游戏杆、鼠标和事件设备3中驱动,而键盘和触摸屏都输入事件设备。 Input驱动程序的主...

kingsOSZT
2015/10/22
173
0
TI-ICS-在子模块下mm出错

今天拿到TI的ICS源码,发现在system/core/adb目录下使用mm出错: make: Entering directory out/target/product/generic/obj/lib/crtbegindynamic.o', needed by out/target/product/generic......

中华大吉
2012/06/27
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

gcviewer的使用

1、没有安装git软件 在编译打包GCViewer的过程中,不能执行git命令,错误信息如下: [ERROR] Failed to execute goal org.codehaus.mojo:buildnumber-maven-plugin:1.4:create (create-build...

刀锋
9分钟前
0
0
Android LogUtil 日志优化 调试的时候打印 点击跳转

打印日志的时候,可以点击跳转 LogUtil.java public class LogUtil { private static boolean IS_DEBUG = BuildConfig.DEBUG; public static void i(String tag, String message) {......

Jay_kyzg
19分钟前
0
0
人工智能你必须掌握的32个算法(二)归并排序算法

归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子...

木头释然
21分钟前
0
0
第十四章NFS服务搭建与配置

14.1 NFS介绍 NFS介绍 NFS是Network File System的缩写;这个文件系统是基于网路层面,通过网络层面实现数据同步 NFS最早由Sun公司开发,分2,3,4三个版本,2和3由Sun起草开发,4.0开始Netap...

Linux学习笔记
44分钟前
1
0
流利阅读笔记27-20180716待学习

生了娃照样能打,两位母亲温网会师 Lala 2018-07-16 1.今日导读 现今在生儿育女后回归事业的母亲们已经非常多见,但是很少有人想到,以高强度运动与竞争激烈为特色的竞技体育项目也会有 work...

aibinxiao
45分钟前
6
0
Guava 源码分析(Cache 原理【二阶段】)

前言 在上文「Guava 源码分析(Cache 原理)」中分析了 Guava Cache 的相关原理。 文末提到了回收机制、移除时间通知等内容,许多朋友也挺感兴趣,这次就这两个内容再来分析分析。 在开始之前...

crossoverJie
57分钟前
0
0
OSChina 周一乱弹 —— 如果是你喜欢的女同学找你借钱

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @guanglun :分享Michael Learns To Rock的单曲《Fairy Tale》 《Fairy Tale》- Michael Learns To Rock 手机党少年们想听歌,请使劲儿戳(这...

小小编辑
今天
749
19
NNS域名系统之域名竞拍

0x00 前言 其实在官方文档中已经对域名竞拍的过程有详细的描述,感兴趣的可以移步http://doc.neons.name/zh_CN/latest/nns_protocol.html#id30 此处查阅。 我这里主要对轻钱包开发中会用到的...

暖冰
今天
0
0
32.filter表案例 nat表应用 (iptables)

10.15 iptables filter表案例 10.16/10.17/10.18 iptables nat表应用 10.15 iptables filter表案例: ~1. 写一个具体的iptables小案例,需求是把80端口、22端口、21 端口放行。但是,22端口我...

王鑫linux
今天
0
0
shell中的函数&shell中的数组&告警系统需求分析

20.16/20.17 shell中的函数 20.18 shell中的数组 20.19 告警系统需求分析

影夜Linux
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部