觸控螢幕驅動程式

來源:互聯網
上載者:User

標籤:style   blog   color   資料   art   cti   

觸控螢幕驅動程式架構與上一片文章的輸入子系統類似,只是底層驅動由按鍵變成了觸控螢幕。

S3C2440的ADC相關寄存器:

struct s3c_ts_regs {  unsigned long adccon;  unsigned long adctsc;  unsigned long adcdly;  unsigned long adcdat0;  unsigned long adcdat1;  unsigned long adcupdn;};

1.分配input_dev結構體

struct input_dev *s3c_ts_dev = input_allocate_device();
2.設定2.1設定產生哪類事件
set_bit(EV_KEY, s3c_ts_dev->evbit);set_bit(EV_ABS, s3c_ts_dev->evbit);
2.2能產生這類事件中的哪些事件
set_bit(BTN_TOUCH, s3c_ts_dev->keybit);
//表示支援絕對值x座標,並設定它在座標系中的最大值和最小值,以及幹擾值和平焊位置等
input_set_abs_params(s3c_ts_dev, ABS_X,              0, 0x3FF, 0, 0);input_set_abs_params(s3c_ts_dev, ABS_Y,              0, 0x3FF, 0, 0);input_set_abs_params(s3c_ts_dev, ABS_PRESSURE, 0, 1, 0, 0);
3.註冊
inpute_register_device(s3c_ts_dev);
4.硬體相關操作4.1使能ADC時鐘
struct clk *clk = clk_get(NULL, "adc");clk_enable(clk);
4.2設定ADC相應寄存器
s3c_ts_regs = ioremap((0x58000000, sizeof(struct s3c_ts_regs));/* converter prescaler enable , ADCCLK=PCLK/(49+1)=50MHz/(49+1)=1MHz */s3c_ts_regs->adccon = (1<<14)|(49<<6);s3c_ts_regs->adcdly = 0xffff;//為了確保ADC轉換的精度,將這個寄存器設定成最大值
4.3申請中斷,ADC轉換完成中斷和觸控螢幕按下或抬起中斷
request_irq(IRQ_TC, pen_down_up_irq, IRQF_SAMPLE_RANDOM, "ts_pen", NULL);request_irq(IRQ_ADC, adc_irq, IRQF_SAMPLE_RANDOM, "adc", NULL);
4.4初始化定時器,用來處理在觸控螢幕上滑動的情況
init_timer(&ts_timer);ts_timer.function = s3c_ts_timer_function;add_timer(&ts_timer);
4.5讓觸控螢幕進入等待筆尖按下狀態
enter_wait_pen_dowm_mode();
5.觸控螢幕模式設定
void enter_wait_pen_down_mode(void){     s3c_ts_regs->adctsc = 0xd3;}void enter_wait_pen_up_mode(void){     s3c_ts_regs->adctsc = 0x1d3;}void enter_measure_xy_mode(void){     s3c_ts_regs->adctsc = (1<<3) | (1<<2);}void start_adc(void){     s3c_ts_regs->adccon |= (1<<0);}
6.定時器處理函數,上報事件
void s3c_ts_timer_function(void){     if (s3c_ts_regs->adcdat0 & (1<<15))     {          /* 鬆開 */          input_report_abs(s3c_ts_dev, ABS_PRESSURE, 0);          input_report_key(s3c_ts_dev, BTN_TOUCH, 0);          input_sync(s3c_ts_dev);          enter_wait_pen_down_mode();     } else {          /* 按下 */          enter_measure_xy_mode();          start_adc();     }}
7.中斷處理函數
irqreturn_t pen_down_up_irq(int irq, void *dev_id){     if (s3c_ts_regs->adcdat0 & (1<<15)) {          /* 鬆開 */          input_report_abs(s3c_ts_dev, ABS_PRESSURE, 0);          input_report_key(s3c_ts_dev, BTN_TOUCH, 0);          input_sync(s3c_ts_dev);          enter_wait_pen_down_mode();     } else {          /* 按下 */          enter_measure_xy_mode();          start_adc();     }     return IRQ_HANDLED;}irqreturn_t adc_irq(int irq, void *dev_id){     static int cnt = 0;     static int x[4], y[4];     int adcdat0, adcdat1;         adcdat0 = s3c_ts_regs->adcdat0;    adcdat1 = s3c_ts_regs->adcdat1;    if (s3c_ts_regs->adcdat0 & (1<<15)) {          /* 鬆開 */         cnt = 0;         input_report_abs(s3c_ts_dev, ABS_PRESSURE, 0);         input_report_key(s3c_ts_dev, BTN_TOUCH, 0);          input_sync(s3c_ts_dev);         enter_wait_pen_down_mode();     } else {         x[cnt] = adcdat0 & 0x3FFF;         y[cnt] = adcdat1 & 0x3FFF;         ++cnt;         if (cnt == 4) {               if (s3c_filter_ts(x, y)) {                   input_report_abs(s3c_ts_dev, ABS_X, (x[1]+x[2]+x[3]+x[4])/4);                   input_report_abs(s3c_ts_dev, ABS_Y, (y[1]+y[2]+y[3]+y[4])/4);                   input_report_abs(s3c_ts_dev, ABS_PRESSURE, 1);                   input_report_key(s3c_ts_dev, BTN_TOUCH, 1);                   input_sync(s3c_ts_dev);               }              cnt = 0;              enter_wait_pen_up_mode();              mod_timer(&ts_timer, jiffies + HZ / 100);          } else {              enter_measure_xy_mode();              start_adc();          }     }    return IRQ_HANDLED;}
8.過濾ADC轉化的資料
static int s3c_filter_ts(int x[], int y[]){#define ERR_LIMIT 10     int avr_x, avr_y;     int det_x, det_y;     avr_x = (x[0] + x[1])/2;     avr_y = (y[0] + y[1])/2;     det_x = (x[2] > avr_x) ? (x[2] - avr_x) : (avr_x - x[2]);     det_y = (y[2] > avr_y) ? (y[2] - avr_y) : (avr_y - y[2]);     if ((det_x > ERR_LIMIT) || (det_y > ERR_LIMIT))          return 0;     avr_x = (x[1] + x[2])/2;     avr_y = (y[1] + y[2])/2;     det_x = (x[3] > avr_x) ? (x[3] - avr_x) : (avr_x - x[3]);     det_y = (y[3] > avr_y) ? (y[3] - avr_y) : (avr_y - y[3]);     if ((det_x > ERR_LIMIT) || (det_y > ERR_LIMIT))          return 0;     return 1;}
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.