//短短兩百餘行程式頗具玄機,在游標抬起後的處理中尤其值得推敲。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/* for ts.dev.id.version */
#define s3c2410tsversion 0x0101
//x為0時為等待按下中斷,x為1是為等待抬起中斷
#define wait4int(x) (((x)<<8) | \
s3c2410_adctsc_ym_sen | s3c2410_adctsc_yp_sen | s3c2410_adctsc_xp_sen | \
s3c2410_adctsc_xy_pst(3))
//自動連續測量x座標和y座標
#define autopst (s3c2410_adctsc_ym_sen | s3c2410_adctsc_yp_sen | s3c2410_adctsc_xp_sen | \
s3c2410_adctsc_auto_pst | s3c2410_adctsc_xy_pst(0))
//裝置名
static char *tq2440ts_name = "tq2440 touchscreen";
static struct input_dev *dev;//
static long xp;
static long yp;
static int count;
extern struct semaphore adc_lock;//申明一訊號量該訊號量在其他檔案中定義
//該標誌在按下中斷處理函式中置1,抬起處理函式中置0,在ad轉換結束中斷處理函式中判斷,
//如果為1則讀取ad轉換的數字,如果為0則什麼也不做。
static int ownadc = 0;
//暫存器基位址
static void __iomem *base_addr;
//管腳配置
static inline void tq2440_ts_connect(void)
//定時器定時時間到處理函式,該函式在按下抬起中斷處理函式中直接呼叫,
//在ad轉換結束中斷處理函式中觸發定時器經延時後被呼叫
static void touch_timer_fire(unsigned long data)
/*以下五句作為在按下中斷處理函式中直接呼叫該函式
時的執行的語句,而以上語句為在ad轉換中斷處理函式中,當4次ad轉換結束時,觸發定時器
經延時而呼叫該函式時執行的語句(向使用者空間報告按下的結果)。以下五句也將在報告完後被執行,
用於初始化變數,並觸發第二個四次ad轉換。這樣的ad轉換會一直執行直到游標抬起即updown為0
*/xp = 0;
yp = 0;
count = 0;
//每次按下有四次ad轉換,以下為在按下中斷中觸發的第一次ad轉換,其餘三次在ad轉換中斷處理函式中觸發
iowrite32(s3c2410_adctsc_pull_up_disable | autopst, base_addr+s3c2410_adctsc);
iowrite32(ioread32(base_addr+s3c2410_adccon) | s3c2410_adccon_enable_start, base_addr+s3c2410_adccon);
}else}}
static struct timer_list touch_timer =//定義一核心定時器
timer_initializer(touch_timer_fire, 0, 0);//初始化定時器賦予處理函式touch_timer_fire
//游標按下抬起抬起中斷處理函式
static irqreturn_t stylus_updown(int irq, void *dev_id)
else//游標抬起時執行的語句
}return irq_handled;//
}///ad轉換結束中斷處理函式
static irqreturn_t stylus_action(int irq, void *dev_id)
else
}return irq_handled;
}static struct clk *adc_clock;
static int __init tq2440ts_init(void)
clk_enable(adc_clock);//使能時鐘
//以s3c2410_pa_adc為起點對映一段io記憶體
base_addr=ioremap(s3c2410_pa_adc,0x20);
if (base_addr == null)
/* configure gpios */
tq2440_ts_connect();//配置管腳
iowrite32(s3c2410_adccon_prscen | s3c2410_adccon_prscvl(0xff),base_addr+s3c2410_adccon);
iowrite32(0xffff, base_addr+s3c2410_adcdly);
iowrite32(wait4int(0), base_addr+s3c2410_adctsc);//將裝置置於等待按下中斷狀態
/* initialise input stuff */
input_dev = input_allocate_device();//為輸入裝置的結構體input_dev分配記憶體並做相應初始化
if (!input_dev)
dev = input_dev;
dev->evbit[0] = bit(ev_syn) | bit(ev_key) | bit(ev_abs);//設定其支援的事件
dev->keybit[bits_to_longs(btn_touch)] = bit(btn_touch);//設定支援的keybit
input_set_abs_params(dev, abs_x, 0, 0x3ff, 0, 0);//設定其最大最小值
input_set_abs_params(dev, abs_y, 0, 0x3ff, 0, 0);
input_set_abs_params(dev, abs_pressure, 0, 1, 0, 0);
dev->name = tq2440ts_name;
dev->id.bustype = bus_rs232;
dev->id.vendor = 0xdead;
dev->id.product = 0xbeef;
dev->id.version = s3c2410tsversion;
//申請ad轉換結束中斷
if (request_irq(irq_adc, stylus_action, irqf_shared|irqf_sample_random, tq2440ts_name, dev))
//申請按下抬起中斷
if (request_irq(irq_tc, stylus_updown, irqf_sample_random, tq2440ts_name, dev))
printk(kern_info "%s successfully loaded\n", tq2440ts_name);
//註冊輸入裝置,在/dev下會產生乙個eventn(n為0,1,2。。。。)的裝置結點
input_register_device(dev);
return 0;
}static void __exit tq2440ts_exit(void)
input_unregister_device(dev);
iounmap(base_addr);
}module_init(tq2440ts_init);
module_exit(tq2440ts_exit);
觸控螢幕驅動分析
觸控螢幕的主要分為四種,分別是電阻式,電容感應式,紅外線式以及表面聲波式。我們現在我們主要談論是電阻式觸控螢幕。看下圖可以大概了解電阻式觸控螢幕。電阻式觸控螢幕的屏體部分是一塊與顯示器表面相匹配的多層復合薄膜,由一層玻璃或有機玻璃作為基層,表面塗有一層透明 的導電層,上面再蓋有一層外表面的硬化處理,...
觸控螢幕驅動分析
模組初始化 static int init s3c2410ts init void 獲得adc時鐘,並使能 對adc暫存器位址對映到記憶體 配置暫存器 gpio口 xm,xp,ym,yp,adc有關的暫存器 申請input裝置 設定可支援的事件為同步 按鍵 絕對座標事件 設定按鍵時間型別為觸控螢幕 ...
S3C2440A的ADC和觸控螢幕介面
s3c2440a內建乙個帶8個模擬輸入通道的10位逐次逼近型 recycling type cmos模數轉換器。在2.5mhz的模數轉換時鐘頻率下,轉換速率可達到500ksps kilo samples per second 並且支援片內取樣保持功能和省電模式。s3c2440a還帶有觸控螢幕介面,可...