您的位置首页>企业动态>

嵌入式Linux系统的触摸屏驱动开发

导读大家好,我是极客范的本期栏目编辑小友,现在为大家讲解嵌入式Linux系统的触摸屏驱动开发问题。序触摸屏作为嵌入式系统的输入设备,以其方

大家好,我是极客范的本期栏目编辑小友,现在为大家讲解嵌入式Linux系统的触摸屏驱动开发问题。

触摸屏作为嵌入式系统的输入设备,以其方便、灵活、节省空间、直观等优点,越来越受到各种终端产品厂商的青睐。Linux操作系统由于其源代码开放、易于裁剪,是目前嵌入式系统的热门选择。本文将从硬件结构出发,讨论如何在Linux操作系统中编写触摸屏驱动程序。

SPI接口介绍

串行外设接口SPI总线技术是摩托罗拉推出的全双工同步串行接口,提供强大的四线接口(接收线、传输线、时钟线和从线选择)。

SPI从机和主机共用一条时钟线,时钟总是从主机发送。当823e处于主模式时,芯片选择信号线被禁用;如果处于从机模式,其从机芯片选择低电平使能。在这个例子中,823e是主设备,所以我们选择另一个823e GPIO作为从设备的芯片选择信号。大多数同步串行数据转换器都很容易与该接口连接,并且其硬件功能非常强大。所以与SPI相关的软件相当简单,让CPU有更多的时间处理其他事务。

触摸屏硬件

触摸屏输入系统由触摸屏、触摸屏控制芯片和数据处理器组成。触摸屏按其技术原理可分为五类:矢量压力传感型、电阻型、电容型、红外型和表面声波型,其中电阻式触摸屏在嵌入式系统中应用广泛。

我们选择的触摸屏是AMD的电阻式触摸屏AMT 9502。触摸屏控制芯片是TI公司的模数转换芯片ADS7846。该芯片支持SPI通信协议,因此我们使用823e的SPI接口与ADS7846芯片进行通信,从触摸屏获得的模拟信号经过模数转换器,输入823e作为数据处理器。

软件程序

823e通过SPI接口与触摸屏控制器通信,所以触摸屏的控制就是SPI接口的操作。写完SPI接口驱动后,我们就可以和触摸屏控制器建立通信了。Linux内核运行后,应该打开SPI接口,已经分配了一部分内存供其使用。同时,SPI中断程序已经加入等待队列。一旦SPI接口中断,SPI中断服务程序将会唤醒并开始运行。这部分工作由系统启动期间运行的初始化函数完成。下面将用源代码讨论初始化函数的编写,其中重点讨论两点。

由于SCCx的网络参数空间和SPI的参数空间存在冲突,如果要同时使用SCCx作为网络端口和SPI驱动,就要加载微码,然后重新定位SPI的参数空间。微补丁是一个加载微码的文件。该文件中的微码可从摩托罗拉官方网站下载。

包括CPM双向RAM端口的一部分,称为paRAMeter ram,包括USB、SCC、SMC、SPI、I2C和IDMA通道操作。其中,SPI和I2C参数区可以重新定位到另一个32位参数区。仔细阅读以下代码后,您可以很好地理解这个过程是如何工作的:

SPI=(SPI _ t *)CP-CP _ dparam[PROFF _ SPI];printk(' SPI地址为%p\n ',SPI);if((reloc=SPI-SPI _ rpbase)){ SPI=(SPI _ t *)CP-CP _ dpmem[SPI-SPI _ rpbase];printk('微码重定位补丁\ n ');}上面末尾代码的作用是:先查询微码是否被使用过,然后获取重定位指针(加载微码和重定位操作在微码. c中完成)。

内存中的SPI描述符

SPI接口的描述符存储在缓冲区中,缓冲区的地址由双向RAM中SPI缓冲区的描述符指定。要发送的数据在发送缓冲区中,接收的数据将存储在发送缓冲区中。缓冲区描述符循环形成一个循环,帮助逐渐发送(接收)要发送(接收)的数据。由于这些缓冲区描述符,通信处理模块可以完成通信并解释和处理错误。

您可以通过一段代码看到上图所示的过程是如何在初始化函数中实现的:

SPI-SPI _ rbase=r _ rbase=DP _ addr;SPI-SPI _ tbase=r _ tbase=DP _ addr sizeof(CBD _ t);SPI-SPI _ rbptr=SPI-SPI _ rbase;SPI-SPI _ TBP tr=SPI-SPI _ tbase;/*以上两句一定要写,不然你就要读书写字了?/tbdf=(CBD _ t *)CP-CP _ dpmem[r _ t base];rbdf=(CBD _ t *)CP-CP _ dpmem[r _ rbase]; tbdf->cbd_sc &= ~BD_SC_READY; rbdf->cbd_sc &= ~BD_SC_EMPTY; rxbuffer = m8xx_cpm_hostalloc(2); txbuffer = m8xx_cpm_hostalloc(2); tbdf->cbd_bufaddr = __pa(txbuffer); rbdf->cbd_bufaddr = __pa(rxbuffer);

以 上的代码是初始化函数里完成的,一旦初始化函数正确运作,就可以采取正确的步骤进行SPI口通信了。以上初始化完之后,要调用 cpm_install_handler函数,该函数的作用是把中断函数注册进内核,一旦SPI口产生硬件中断,就调用中断函数,中断函数的编写可以依据 不同系统的不同需要,在本例中,我们使得一旦调用中断函数,就读取SPI接收到的数据。

接下来以如何发送数据为例,分析如何操作SPI口通信。

发送数据的步骤

在此例中,设SPI接口为主模式。为了开始数据传送过程,内核把要传送的数据写到一个数据缓冲区,然后配置缓冲区描述符,以达到传送的目的。以下给出发送数据的一段代码,通过代码解释传输的过程。

memset((void*)txbuffer,0,2); tbdf->cbd_sc = BD_SC_READY | BD_SC_LAST | BD_SC_WRAP; tbdf->cbd_datlen = 2; rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP; rbdf->cbd_datlen = 0; cp->cp_spmode = 0x777f; cp->cp_spie = 0xff; cp->cp_spim = 0x37; cp->cp_spcom |= 0x80; udelay(1000); if((tbdf->cbd_sc & 0x8000)) printk("spi write error !"); memset((void*)rxbuffer,0,2);

数 据通信过程中,最重要的是时序,正确的时序要通过反复的实验才能得到。图3是在实验过程中得到的逻辑图(安捷伦公司的1672G逻辑分析仪测试结果)。其 中,CS是片选信号,CK是时钟信号,DO是823e发送的数据。可以使用逻辑分析仪来阅读得到的数据是否和设备发送的数据一致。正确的通信必须经过长时 间的调试才能够取得。

根据ADS7846的使用手册,驱动程序必须在初始化的时候与ADS7846建立通信。所以,823e首先要向ADS7846发送命令,得到ADS7846的回复后建立通信。驱动程序调用SPI的读写函数来实现对ADS7846的操作。

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。