《基于S3C2440的嵌入式Linux開發(fā)實(shí)例》課件第10章_第1頁
《基于S3C2440的嵌入式Linux開發(fā)實(shí)例》課件第10章_第2頁
《基于S3C2440的嵌入式Linux開發(fā)實(shí)例》課件第10章_第3頁
《基于S3C2440的嵌入式Linux開發(fā)實(shí)例》課件第10章_第4頁
《基于S3C2440的嵌入式Linux開發(fā)實(shí)例》課件第10章_第5頁
已閱讀5頁,還剩98頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

10.1S3C2440A/D接口驅(qū)動分析10.2觸摸屏設(shè)備驅(qū)動10.1.1S3C2440A/D接口

A/D轉(zhuǎn)換器是模擬信號源和CPU之間聯(lián)系的接口,它的任務(wù)是將連續(xù)變化的模擬信號轉(zhuǎn)換為數(shù)字信號,以便計算機(jī)和數(shù)字系統(tǒng)進(jìn)行處理、存儲、控制和顯示。在工業(yè)控制和數(shù)據(jù)采集等領(lǐng)域中,A/D轉(zhuǎn)換是不可缺少的。10.1S3C2440A/D接口驅(qū)動分析

1.常用A/D轉(zhuǎn)換器類型

A/D轉(zhuǎn)換器有以下類型:逐位比較型、積分型、計數(shù)型、并行比較型、電壓-頻率型,應(yīng)根據(jù)使用場合的具體要求,按照轉(zhuǎn)換速度、精度、價格、功能以及接口條件等因素來決定選擇何種類型。常用的A/D轉(zhuǎn)換器有以下兩種。

1)?雙積分型的A/D轉(zhuǎn)換器

2)逐次逼近型A/D轉(zhuǎn)換器

逐次逼近型(也稱逐位比較型)?A/D轉(zhuǎn)換器比積分型的應(yīng)用更為廣泛,其原理框圖如圖10-2所示,主要由逐次逼近寄存器SAR、D/A轉(zhuǎn)換器、比較器以及時序和控制邏輯等部分組成。圖10-1雙積分型A/D轉(zhuǎn)換器圖10-2逐次逼近型A/D轉(zhuǎn)換器(a)原理圖;(b)過程圖

2.?A/D轉(zhuǎn)換的幾個重要指標(biāo)

1)分辨率

分辨率反映A/D轉(zhuǎn)換器對輸入微小變化響應(yīng)的能力,通常用數(shù)字輸出最低位(LSB)所對應(yīng)的模擬輸入的電平值表示。

2)精度

精度有絕對精度(AbsoluteAccuracy)和相對精度(RelativeAccuracy)兩種表示方法。

3)轉(zhuǎn)換時間

轉(zhuǎn)換時間是指完成一次A/D轉(zhuǎn)換所需的時間,即由發(fā)出啟動轉(zhuǎn)換命令信號到轉(zhuǎn)換結(jié)束信號開始有效的時間間隔。

4)電源靈敏度

電源靈敏度是指A/D轉(zhuǎn)換芯片的供電電源的電壓發(fā)生變化時產(chǎn)生的轉(zhuǎn)換誤差。

5)量程

量程是指所能轉(zhuǎn)換的模擬輸入電壓范圍,分單極性、雙極性兩種類型。

6)輸出邏輯電平

多數(shù)A/D轉(zhuǎn)換器的輸出邏輯電平與TTL電平兼容。

7)工作溫度范圍

由于溫度會對比較器、運(yùn)算放大器、電阻網(wǎng)絡(luò)等產(chǎn)生影響,故只在一定的溫度范圍內(nèi)才能保證額定精度指標(biāo)。

3.?ARMS3C2440自帶的10位A/D轉(zhuǎn)換器

ARMS3C2440芯片自帶一個8路10位A/D轉(zhuǎn)換器,并且支持觸摸屏功能。ARM2410開發(fā)板A/D轉(zhuǎn)換器最大轉(zhuǎn)換率為500kHz,非線性度為正負(fù)1.5位,其轉(zhuǎn)換時間可以通過下式計算:如果系統(tǒng)時鐘為50?MHz,比例值為49,則

A/D轉(zhuǎn)換器頻率=50MHz/(49+1)=1MHz轉(zhuǎn)換時間?=

(相當(dāng)于5?μs)

10.1.2S3C2440A/D寄存器介紹

1.?ADC(模數(shù)轉(zhuǎn)換器)控制寄存器

ADC控制寄存器的各位定義如表10-1和表10-2所示。表10-1ADC控制寄存器表10-2ADC控制寄存器位定義2.?ADC觸摸屏控制寄存器

ADC觸摸屏控制寄存器的各位定義如表10-3和表10-4所示。

3.?ADC延時寄存器

ADC延時寄存器的各位定義如表10-5和表10-6所示。表10-3ADC觸摸屏控制寄存器表10-4ADC觸摸屏控制寄存器位定義表10-5ADC延時寄存器表10-6ADC延時寄存器位定義4.?ADC轉(zhuǎn)換數(shù)據(jù)寄存器0

ADC轉(zhuǎn)換數(shù)據(jù)寄存器0的各位定義如表10-7和表10-8所示。表10-7ADC轉(zhuǎn)換數(shù)據(jù)寄存器0表10-8ADC轉(zhuǎn)換數(shù)據(jù)寄存器0位定義5.?ADC轉(zhuǎn)換數(shù)據(jù)寄存器1

ADC轉(zhuǎn)換數(shù)據(jù)寄存器1的各位定義如表10-9和表10-10所示。表10-9ADC轉(zhuǎn)換數(shù)據(jù)寄存器1表10-10ADC轉(zhuǎn)換數(shù)據(jù)寄存器1位定義10.1.3S3C2440A/D驅(qū)動程序分析

1.寄存器地址和功能定義

S3C2440ADC控制器相關(guān)寄存器地址及初始值定義如下:

#defineS3C2440_ADCREG(x)(x)

#defineS3C2440_ADCCON S3C2440_ADCREG(0x00)

#defineS3C2440_ADCTSC S3C2440_ADCREG(0x04)

#defineS3C2440_ADCDLY S3C2440_ADCREG(0x08)

#defineS3C2440_ADCDAT0 S3C2440_ADCREG(0x0C)

#defineS3C2440_ADCDAT1 S3C2440_ADCREG(0x10)#defineADC_IN0 0

#defineADC_IN1 1

#defineADC_IN2 2

#defineADC_IN3 3

#defineADC_IN4 4

#defineADC_IN5 5

#defineADC_IN6 6

#defineADC_IN7 7#defineADC_BUSY 1

#defineADC_READY 0

#defineNOP_MODE 0

#defineX_AXIS_MODE 1

#defineY_AXIS_MODE 2

#defineWAIT_INT_MODE 3/*...*/

#defineADCCON_ECFLG (1<<15)

#definePRESCALE_ENDIS (1<<14)

#definePRESCALE_DIS (PRESCALE_ENDIS*0)

#definePRESCALE_EN (PRESCALE_ENDIS*1)

#definePRSCVL(x) (x<<6)

#defineADC_INPUT(x) (x<<3)#defineADCCON_STDBM (1<<2)/*1:standbymode,0:normalmode*/

#defineADC_NORMAL_MODE (ADCCON_STDBM*0)

#defineADC_STANDBY_MODE (ADCCON_STDBM*1)

#defineADCCON_READ_START (1<<1)

#defineADC_START_BY_RD_DIS (ADCCON_READ_START*0)

#defineADC_START_BY_RD_EN (ADCCON_READ_START*1)

#defineADC_START (1<<0)#defineUD_SEN (1<<8)

#defineDOWN_INT (UD_SEN*0)

#defineUP_INT (UD_SEN*1)

#defineYM_SEN (1<<7)

#defineYM_HIZ (YM_SEN*0)

#defineYM_GND (YM_SEN*1)

#defineYP_SEN (1<<6)

#defineYP_EXTVLT (YP_SEN*0)

#defineYP_AIN (YP_SEN*1)#defineXM_SEN (1<<5)

#defineXM_HIZ (XM_SEN*0)

#defineXM_GND (XM_SEN*1)

#defineXP_SEN (1<<4)

#defineXP_EXTVLT (XP_SEN*0)

#defineXP_AIN (XP_SEN*1)

#defineXP_PULL_UP (1<<3)#defineXP_PULL_UP_EN (XP_PULL_UP*0)

#defineXP_PULL_UP_DIS (XP_PULL_UP*1)

#defineAUTO_PST (1<<2)

#defineCONVERT_MAN (AUTO_PST*0)

#defineCONVERT_AUTO (AUTO_PST*1)

#defineXP_PST(x) (x<<0)2.主要數(shù)據(jù)結(jié)構(gòu)和變量描述

ADC字符設(shè)備結(jié)構(gòu)體ADC_DEV的代碼描述如下:

typedefstruct

{

structsemaphorelock;

wait_queue_head_twait;

intchannel;

intprescale;

}ADC_DEV

file_operations結(jié)構(gòu)體變量s3c2440_adc_fops

staticstructfile_operationss3c2440_adc_fops=

{

.owner=THIS_MODULE,

.read=s3c2440_adc_read,

.write=s3c2440_adc_write,

.open=s3c2440_adc_open,

.release=s3c2440_adc_release,

.ioctl=s3c2440_adc_ioctl,

};3.主要函數(shù)描述

A/D驅(qū)動函數(shù)結(jié)構(gòu)圖如圖10-3所示。圖10-3A/D驅(qū)動函數(shù)結(jié)構(gòu)圖

1)?A/D模塊加載初始化函數(shù)s3c2440_adc_init()

s3c2440_adc_init()函數(shù)主要完成A/D字符設(shè)備的注冊和設(shè)備節(jié)點(diǎn)的創(chuàng)建,代碼描述如下:

staticint_inits3c2440_adc_init(void)

{

interr=0;

if(register_chrdev(ADC_MAJOR,DEVICE_NAME,&s3c2440_adc_fops))

{

printk(DEVICE_NAME“driver:Unabletoregisterdriver\n”);

return-ENODEV;

}

err=devfs_mk_cdev(MKDEV(ADC_MAJOR,0),S_IFCHR|S_IRUGO|S_IWUSR,DEVICE_NAME);

if(err)

returnerr;

}2)?A/D模塊卸載函數(shù)s3c2440_adc_exit()

s3c2440_adc_exit()函數(shù)主要完成A/D字符設(shè)備的卸載和設(shè)備節(jié)點(diǎn)的移除,代碼描述如下:

staticvoid_exits3c2440_adc_exit(void)

{

unregister_chrdev(ADC_MAJOR,DEVICE_NAME);

devfs_remove(DEVICE_NAME);

printk(DEVICE_NAME"driverremoved\n");

}

3)系統(tǒng)調(diào)用打開函數(shù)s3c2440_adc_open()

s3c2440_adc_open()函數(shù)對應(yīng)于系統(tǒng)調(diào)用的open函數(shù),代碼描述如下:

staticints3c2440_adc_open(structinode*inode,structfile*filp)

{

printk(“Addedbyweiang,enters3c2410_adc_openfunction\n”);

init_MUTEX(&adcdev.lock);

init_waitqueue_head(&(adcdev.wait));

adcdev.channel=0;

adcdev.prescale=0xff;

printk(“adcopened\n”);

return0;

}

4)系統(tǒng)調(diào)用讀函數(shù)s3c2440_adc_read()

s3c2440_adc_read()函數(shù)對應(yīng)于系統(tǒng)調(diào)用的read函數(shù),代碼描述如下:

staticssize_ts3c2440_adc_read(structfile*filp,char*buffer,size_tcount,loff_t*ppos)

{

unsignedintret=0;

if(down_interruptible(&adcdev.lock))

return-ERESTARTSYS;

printk(“BeforeSTART_ADC_AIN:\n”);

START_ADC_AIN(adcdev.channel,adcdev.prescale);

while(ADCCON&0x1);

while(!(ADCCON&0x8000));//checkifEC(Endof

ret=readl(ADCDAT0);

printk(“thevalueofretis0x%x\n”,ret);

ret&=0x3ff;

copy_to_user(buffer,(char*)&ret,sizeof(ret));

up(&adcdev.lock);

returnsizeof(ret);

}

5)系統(tǒng)調(diào)用讀函數(shù)s3c2440_adc_write()

s3c2440_adc_write()函數(shù)對應(yīng)于系統(tǒng)調(diào)用的write函數(shù),代碼描述如下:

staticssize_ts3c2440_adc_write(structfile*file,constchar*buffer,size_tcount,loff_t*ppos)

{

intdata;

printk("Addedbyzxh,enters3c2410_adc_writerfunction\n");

if(count!=sizeof(data))

{ //errorinputdatasize

printk(“thesizeofinputdatamustbe%d\n”,sizeof(data));

return0;

}

printk("beforecopy_from_userfunction:\n");

copy_from_user(&data,buffer,count);

adcdev.channel=ADC_WRITE_GETCH(data);

adcdev.prescale=ADC_WRITE_GETPRE(data);

printk(“setadcchannel=%d,prescale=0x%x\n”,adcdev.channel,adcdev.prescale);

returncount;

}

6)系統(tǒng)調(diào)用IOCTL函數(shù)s3c2440_adc_ioctl()

s3c2440_adc_ioctl()函數(shù)對應(yīng)于系統(tǒng)調(diào)用的ioctl函數(shù),代碼描述如下:

staticints3c2440_adc_ioctl(structinode*inode,structfile*file,unsignedintcmd,unsignedlongarg)

{

if((cmd<0)||(cmd>7))

{

printk(“outrangeofadc!\n”);

return-EINVAL;

}if((cmd==5)||(cmd==7))

{

printk(“touchgreenusethischannel!\n”);

return-EINVAL;

}

adcdev.channel=cmd;

return0;

}

10.1.4S3C2440A/D應(yīng)用設(shè)計例程

參考程序源代碼:

#include<sys/stat.h>

#include<fcntl.h>

#include<stdio.h>

#include<sys/time.h>

#include<sys/types.h>

#include<unistd.h>#defineADC_DEV“/dev/s3c2410_adc”

#defineADC_WRITE(ch,prescale)((ch)<<16|(prescale))

#defineADC_WRITE_GETCH(data)(((data)>>16)&0x7)

//得到通道號

#defineADC_WRITE_GETPRE(data)((data)&0xff)

//得到轉(zhuǎn)換的比例因子

/*

staticintget(intchannel)

{

intPRESCALE=0xFF;

intdata=ADC_WRITE(channel,PRESCALE);

write(adc_fd,&data,sizeof(data));

read(adc_fd,&data,sizeof(data));

returndata;

}

*/

intmain(void)

{inti;

intfd;

//floatd;

unsignedlongtmp;

void*retval;

fd=open(ADC_DEV,O_RDWR);

if(fd<0)

{

printf(“Erroropening%sadcdevice\n”,ADC_DEV);

return-1;}

else

printf(“deviceidis%d\n”,fd);

sleep(1);

while(1)

{

printf(“Beforeread:\n”);

ioctl(fd,4,NULL);

read(fd,&tmp,sizeof(unsignedlong));

printf("The4adcis0x%x\n",tmp);sleep(1);

//tmp=671;

//write(fd,&tmp,4);

//printf("write67tothefileofdescriptionfd:\n");

ioctl(fd,0,NULL);

read(fd,&tmp,sizeof(unsignedlong));

printf("The4adcis0x%x\n",tmp);

getchar();}

/*for(i=0;i<=7;i++)

{

d=((float)get(i)*3.3)/1024.0;

printf(“a[%d]=%8.4f\n”,i,d);

}

*/

close(fd);

return0;

}10.2.1觸摸屏的硬件原理

按照觸摸屏的工作原理和傳輸信息的介質(zhì)不同,觸摸屏可以分為4種:電阻式、電容感應(yīng)式、紅外線式以及表面聲波式。10.2觸摸屏設(shè)備驅(qū)動

電阻式觸摸屏利用壓力感應(yīng)進(jìn)行控制,包含上下疊合的兩個透明層,通常還要用一種彈性材料來將兩層隔開。在觸摸某點(diǎn)時,兩層會在此點(diǎn)接通。四線和八線觸摸屏由兩層具有相同表面電阻的透明阻性材料組成,五線和七線觸摸屏由一個阻性層和一個導(dǎo)電層組成。所有的電阻式觸摸屏都采用分壓器原理來產(chǎn)生代表X坐標(biāo)和Y坐標(biāo)的電壓。如圖10-4所示,分壓器是通過將兩個電阻進(jìn)行串聯(lián)來實(shí)現(xiàn)的。圖10-4電阻觸摸屏分壓器

四線觸摸屏包含兩個阻性層。其中一層在屏幕的左右邊緣各有一條垂直總線,另一層在屏幕的底部和頂部各有一條水平總線,如圖10-5所示。為了能在X軸方向進(jìn)行測量,將左側(cè)總線偏置為0?V,右側(cè)總線偏置為UREF;將頂部或底部總線連接到ADC,當(dāng)頂層和底層相接觸時即可做一次測量。為了能在Y軸方向進(jìn)行測量,將頂部總線偏置為UREF,底部總線偏置為0?V;將ADC輸入端接左側(cè)總線或右側(cè)總線,當(dāng)頂層與底層相接觸時即可對電壓進(jìn)行測量。圖10-5四線電阻式觸摸屏

S3C2440接四線電阻式觸摸屏的電路原理圖如圖10-6所示。S3C2440提供了nYMON、YMON、nXPON和XMON直接作為觸摸屏的控制信號,它通過連接FDC5321場效應(yīng)管觸摸屏驅(qū)動器控制觸摸屏。輸入信號在經(jīng)過阻容式低通濾器濾除坐標(biāo)信號噪聲后被接入S3C2440內(nèi)集成的ADC的模擬信號輸入通道AIN5、AIN7。圖10-6S3C2440連接四線電阻式觸摸屏的電路原理圖

S3C2440的ADC和觸摸屏接口可工作于5種模式。

1)普通轉(zhuǎn)換模式(NormalConversionMode)

2)獨(dú)立X/Y位置轉(zhuǎn)換模式(SeparateX/YPositionConversionMode)

3)自動(連續(xù))X/Y位置轉(zhuǎn)換模式(AutoX/YPositionConversionMode)

4)等待中斷模式(WaitforInterruptMode)

5)待機(jī)模式(StandbyMode)10.2.2觸摸屏設(shè)備驅(qū)動分析

觸摸屏驅(qū)動結(jié)構(gòu)如圖10-7所示。圖10-7觸摸屏驅(qū)動函數(shù)結(jié)構(gòu)圖

1.主要數(shù)據(jù)結(jié)構(gòu)和變量描述

1)觸摸屏設(shè)備結(jié)構(gòu)體TS_DEV

觸摸屏設(shè)備結(jié)構(gòu)體TS_DEV包含一個緩沖區(qū),同時包括自旋鎖、等待隊(duì)列和fasync_struct指針,代碼描述如下:

typedefstruct

{unsignedintpenStatus; /*PEN_UP,PEN_DOWN,PEN_SAMPLE*/

TS_RETbuf[MAX_TS_BUF]; /*緩沖區(qū)*/

unsignedinthead,tail; /*緩沖區(qū)頭和尾*/

wait_queue_head_twq; /*等待隊(duì)列*/

spinlock_tlock;

#ifdefUSE_ASYNC

structfasync_struct*aq;

#endif

structcdevcdev;

}TS_DEV;

2)?TS_RET結(jié)構(gòu)體

TS_RET結(jié)構(gòu)體包含X、Y軸坐標(biāo)和狀態(tài)(PEN_DOWN、PEN_UP)等信息,這個信息會在用戶讀取觸摸信息時復(fù)制到用戶空間,代碼描述如下:

typedefstruct

{

unsignedshortpressure; //PEN_DOWN、PEN_UP

unsignedshortx; //x坐標(biāo)

unsignedshorty; //y坐標(biāo)

unsignedshortpad;

}TS_RET;3)觸摸屏驅(qū)動文件操作結(jié)構(gòu)體變量s3c2410_fops

在觸摸屏設(shè)備驅(qū)動中,將實(shí)現(xiàn)open()、release()、read()、fasync()和poll()函數(shù),代碼描述如下:

staticstructfile_operationss3c2410_fops=

{

owner:THIS_MODULE,

open:s3c2410_ts_open, //打開

read:s3c2410_ts_read, //讀坐標(biāo)

release:

s3c2410_ts_release,#ifdefUSE_ASYNC

fasync:s3c2410_ts_fasync, //fasync()函數(shù)

#endif

poll:s3c2410_ts_poll, //輪詢

};

2.主要函數(shù)描述

1)觸摸屏驅(qū)動模塊加載函數(shù)s3c24x0ts_init()

觸摸屏加載函數(shù)可以注冊一個s3c2410ts_driver()類型的字符型輸入設(shè)備,代碼描述如下:

int_inits3c24x0ts_init(void)

{

returndriver_register(&s3c24x0ts_driver);

}2)觸摸屏卸載函數(shù)s3c2410ts_exit()

觸摸屏卸載函數(shù)主要完成驅(qū)動卸載,代碼描述如下:

void_exits3c2410ts_exit(void)

{

driver_unregister(&s3c2410ts_driver);

}

3)觸摸屏探測函數(shù)s3c2410ts_probe()

觸摸屏探測函數(shù)主要完成申請設(shè)備號、添加cdev、申請中斷、設(shè)置觸摸屏相關(guān)寄存器等功能,代碼描述如下:

staticint_inits3c2410ts_probe(structdevice*dev)

{

…;

/*注冊字符設(shè)備*/

ret=register_chrdev(0,DEVICE_NAME,&s3c2410_fops);

if(ret<0)

{

returnret;

}tsMajor=ret;

/*得到ADC時鐘*/

adc_clock=clk_get(NULL,“adc”);

if(!adc_clock)

{

return-ENOENT;

}

clk_use(adc_clock);

clk_enable(adc_clock);

base_addr=ioremap(S3C2410_PA_ADC,0x20);_raw_writel(WAIT4INT(0),S3C2410_ADCTSC);

_raw_writel(30000,S3C2410_ADCDLY);

//addedbyhzh30000-20000

/*設(shè)置觸摸屏中斷*/

ret=request_irq(IRQ_ADC,s3c2410_isr_adc,SA_INTERRUPT,

DEVICE_NAME,s3c2410_isr_adc);if(ret)

{

gotoadc_failed;

}

ret=request_irq(IRQ_TC,s3c2410_isr_tc,SA_INTERRUPT,DEVICE_NAME,s3c2410_isr_tc);

if(ret)gototc_failed;

/*等待觸摸屏中斷*/

wait_down_int();//flamask!_raw_writel(0x12345678,S3C2410_ADCCON);

#ifdefCONFIG_DEVFS_FS

devfs_mk_dir("touchscreen");

devfs_mk_cdev(MKDEV(tsMajor,TSRAW_MINOR),S_IFCHR|S_IRUGO|S_IWUSR,

"touchscreen/%d",0);#endif

#ifdefCONFIG_PM

#if0

tsdev.pm_dev=pm_register(PM_GP_DEV,PM_USER_INPUT,s3c2410_ts_pm_callback);

#endif

tsdev.pm_dev=pm_register(PM_DEBUG_DEV,PM_USER_INPUT,s3c2410_ts_pm_callback);

#endifreturn0;

tc_failed:

{

printk(KERN_ERR“tcfailed!!!!!!!!!!!!!\n”);

free_irq(IRQ_ADC,s3c2410_isr_adc);

}

adc_failed:

{

printk(KERN_ERR“adcfailed!!!!!!!!!!!!!\n”);

returnret;

}

}

4)觸摸屏設(shè)置驅(qū)動卸載函數(shù)s3c2410ts_remove()

觸摸屏設(shè)置驅(qū)動卸載函數(shù)主要完成釋放中斷、卸載設(shè)備驅(qū)動、取消iomap映射等,代碼描述如下:

staticints3c2410ts_remove(structdevice*dev)

{

disable_irq(IRQ_ADC);

disable_irq(IRQ_TC);

free_irq(IRQ_TC,&ts.dev);

free_irq(IRQ_ADC,&ts.dev);if(adc_clock)

{

clk_disable(adc_clock);

clk_unuse(adc_clock);

clk_put(adc_clock);

adc_clock=NULL;

}

input_unregister_device(&ts.dev);

iounmap(base_addr);

return0;

}

5)觸摸屏驅(qū)動的觸點(diǎn)/抬起中斷處理函數(shù)s3c2410_isr_adc()

觸摸屏驅(qū)動的觸點(diǎn)/抬起中斷處理函數(shù)的代碼描述如下:

staticvoids3c2410_isr_tc(intirq,void*dev_id,structpt_regs*reg)

{

spin_lock_irq(&(tsdev.lock));

if(tsdev.penStatus==PEN_UP)

{

start_ts_adc(); //開始X/Y位置轉(zhuǎn)換}

else

{

tsdev.penStatus=PEN_UP;

DPRINTK(“PENUP:x:%08d,y:%08d\n”,x,y);

wait_down_int(); //置于等待觸點(diǎn)中斷模式

tsEvent();

}

spin_unlock_irq(&(tsdev.lock));

}

6)觸摸屏設(shè)備驅(qū)動X/Y位置轉(zhuǎn)換中斷處理程函數(shù)

觸摸屏設(shè)備驅(qū)動X/Y位置轉(zhuǎn)換中斷處理函數(shù)當(dāng)X/Y位置轉(zhuǎn)換中斷發(fā)生后,應(yīng)讀取X、Y的坐標(biāo)值,填入緩沖區(qū),代碼描述如下:

staticinlinevoids3c2410_get_XY(void)

{

if(adc_state==0)

{

adc_state=1;disable_ts_adc(); //禁止INT-ADC

y=(ADCDAT0&0x3ff); //讀取坐標(biāo)值

mode_y_axis();

start_adc_y(); //開始y位置轉(zhuǎn)換

}

elseif(adc_state==1)

{

adc_state=0;disable_ts_adc(); //禁止INT-ADC

x=(ADCDAT1&0x3ff); //讀取坐標(biāo)值

tsdev.penStatus=PEN_DOWN;

wait_up_int(); //置于等待抬起中斷模式

tsEvent();

}

}

7)觸摸屏設(shè)備驅(qū)動的tsEvent_raw()函數(shù)

最終調(diào)用的tsEvent_raw()函數(shù)很關(guān)鍵。當(dāng)處于PEN_DOWN狀態(tài)時調(diào)用該函數(shù),將完成緩沖區(qū)的填充、等待隊(duì)列的喚醒以及異步通知信號的釋放;否則(處于PEN_UP狀態(tài)),將緩沖區(qū)頭清零,也喚醒等待隊(duì)列并釋放信號。代碼描述如下:

staticvoidtsEvent_raw(void)

{

if(tsdev.penStatus==PEN_DOWN)

{/*填充緩沖區(qū)*/

BUF_HEAD.x=x;

BUF_HEAD.y=y;

BUF_HEAD.pressure=PEN_DOWN;

#ifdefHOOK_FOR_DRAG

ts_timer.expires=jiffies+TS_TIMER_DELAY;add_timer(&ts_timer); //啟動定時器

#endif

}

else

{

#ifdefHOOK_FOR_DRAG

del_timer(&ts_timer);

#endif/*填充緩沖區(qū)*/

BUF_HEAD.x=0;

BUF_HEAD.y=0;

BUF_HEAD.pressure=PEN_UP;

}tsdev.head=INCBUF(tsdev.head,MAX_TS_BUF);

wake_up_interruptible(&(tsdev.wq));//喚醒等待隊(duì)列

#ifdefUSE_ASYNC

if(tsdev.aq)

kill_fasync(&(tsdev.aq),SIGIO,POLL_IN); //異步通知

#endif

}

8)觸摸屏設(shè)備驅(qū)動的定時器處理函數(shù)

在包含了對拖動軌跡支持的情況下,定時器會被啟用,周期為10ms,在每次定時器處理函數(shù)被引發(fā)時,調(diào)用start_ts_adc()開始X/Y位置轉(zhuǎn)換過程,代碼描述如下:

#ifdefHOOK_FOR_DRAG

staticvoidts_timer_handler(unsignedlongdata)

{

spin_lock_irq(&(tsdev.lock));if(tsdev.penStatus==PEN_DOWN)

{

start_ts_adc();

}

spin_unlock_irq(&(tsdev.lock));

}

#endif

9)觸摸屏設(shè)備驅(qū)動的打開函數(shù)s3c2410_ts_open()

觸摸屏設(shè)備驅(qū)動的打開函數(shù)主要完成初始化緩沖區(qū)、penStatus、定時器、等待隊(duì)列及tsEvent時間處理函數(shù)指針,代碼描述如下:

staticints3c2410_ts_open(structinode*inode,structfile*filp)

{

tsdev.head=tsdev.tail=0;

tsdev.penStatus=PEN_UP;//初始化觸摸屏狀態(tài)為

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論