歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Linux設備驅動工程師之路——觸摸屏驅動s3c2410_ts.c分析

Linux設備驅動工程師之路——觸摸屏驅動s3c2410_ts.c分析

日期:2017/3/1 11:16:33   编辑:Linux編程

一、觸摸屏硬件知識

1.模塊原理圖

S3C2440有8路的ADC通道其中觸摸屏控制器接口XP,XM,YP,YM與四路ADC通道復用四個IO引腳。從原理圖看出8路ADC只有一個A/D轉換器,通過一個8選1開關MUX來選通哪一路A/D通道進行轉換。觸摸屏控制會產生兩個中斷,一個觸摸屏中斷INT_ADC,一個ADC_轉換完成中斷INT_ADC。ADC需要時鐘才能工作,因為它需要設置采樣率。


再復習一下ARM裸機實驗時觸摸屏寄存器操作流程

流程:

初始化

1設置采樣延時和分頻值ADCDLY ADCCON

2中斷相關設置

3設置觸摸屏AD轉換為等待中斷模式 ADCTSC

中斷服務函數

4清相關掛起寄存器

5設置轉換模式,一般為連續x,y轉換

6 啟動轉換

7 轉換完成後讀取x y坐標ADCDAT0ADCDAT1

8 設置觸摸屏AD轉換為等待中斷模式,設置等待彈起中斷ADCTSC

9 彈起中斷發生後,設置觸摸屏轉換為等待中斷模式,等待下一次觸筆按下rADCTSC

程序

二、觸摸屏驅動程序

1.模塊初始化

  1. static int __init s3c2410ts_init(void)
  2. {
  3. struct input_dev *input_dev;
  4. //獲取時鐘
  5. adc_clock = clk_get(NULL, "adc");
  6. if (!adc_clock) {
  7. printk(KERN_ERR "failed to get adc clock source\n");
  8. return -ENOENT;
  9. }
  10. clk_enable(adc_clock);
  11. //使能時鐘
  12. //需要時鐘的是因為觸摸屏要用到ADC轉換,而完成ADC轉換則需要時鐘(采用時間)
  13. //映射ADC的IO內存
  14. base_addr=ioremap(S3C2410_PA_ADC,0x20);
  15. if (base_addr == NULL) {
  16. printk(KERN_ERR "Failed to remap register block\n");
  17. return -ENOMEM;
  18. }
  19. //初始化觸摸屏的IO引腳
  20. /* Configure GPIOs */
  21. s3c2410_ts_connect();
  22. //設置預分頻值
  23. iowrite32(S3C2410_ADCCON_PRSCEN | S3C2410_ADCCON_PRSCVL(0xFF),\
  24. base_addr+S3C2410_ADCCON);
  25. iowrite32(0xffff, base_addr+S3C2410_ADCDLY);//設置采用延時
  26. iowrite32(WAIT4INT(0), base_addr+S3C2410_ADCTSC);
  27. //設置觸摸屏控制器為等待按下中斷
  28. /* Initialise input stuff */
  29. //申請一個input設備
  30. input_dev = input_allocate_device();
  31. if (!input_dev) {
  32. printk(KERN_ERR "Unable to allocate the input device !!\n");
  33. return -ENOMEM;
  34. }
  35. dev = input_dev;
  36. //設置可被支持的事件為同步、按鍵、絕對坐標事件
  37. dev->evbit[0] = BIT(EV_SYN) | BIT(EV_KEY) | BIT(EV_ABS);
  38. //設置按鍵時間類型為觸摸屏
  39. dev->keybit[BITS_TO_LONGS(BTN_TOUCH)] = BIT(BTN_TOUCH);
  40. //設置事件數值范圍X,Y坐標范圍為0到3FF,按鍵數值范圍從0,到1
  41. input_set_abs_params(dev, ABS_X, 0, 0x3FF, 0, 0);
  42. input_set_abs_params(dev, ABS_Y, 0, 0x3FF, 0, 0);
  43. input_set_abs_params(dev, ABS_PRESSURE, 0, 1, 0, 0);
  44. //設置設備的身份信息
  45. dev->name = s3c2410ts_name;
  46. dev->id.bustype = BUS_RS232;
  47. dev->id.vendor = 0xDEAD;
  48. dev->id.product = 0xBEEF;
  49. dev->id.version = S3C2410TSVERSION;
  50. /* Get irqs */
  51. //獲取觸摸屏中斷IRQ_TC,ADC轉換完成中斷IRQ_ADC
  52. if (request_irq(IRQ_ADC, stylus_action, IRQF_SHARED|IRQF_SAMPLE_RANDOM,
  53. "s3c2410_action", dev)) {
  54. printk(KERN_ERR "s3c2410_ts.c: Could not allocate ts IRQ_ADC !\n");
  55. iounmap(base_addr);
  56. return -EIO;
  57. }
  58. if (request_irq(IRQ_TC, stylus_updown, IRQF_SAMPLE_RANDOM,
  59. "s3c2410_action", dev)) {
  60. printk(KERN_ERR "s3c2410_ts.c: Could not allocate ts IRQ_TC !\n");
  61. iounmap(base_addr);
  62. return -EIO;
  63. }
  64. printk(KERN_INFO "%s successfully loaded\n", s3c2410ts_name);
  65. /* All went ok, so register to the input system */
  66. //注冊設備
  67. input_register_device(dev);
  68. return 0;
  69. }

我們再來看看模塊初始化函數中初始化觸摸屏的IO引腳的s3c2410_ts_connect();函數

  1. static inline void s3c2410_ts_connect(void)
  2. {
  3. s3c2410_gpio_cfgpin(S3C2410_GPG12, S3C2410_GPG12_XMON);
  4. s3c2410_gpio_cfgpin(S3C2410_GPG13, S3C2410_GPG13_nXPON);
  5. s3c2410_gpio_cfgpin(S3C2410_GPG14, S3C2410_GPG14_YMON);
  6. s3c2410_gpio_cfgpin(S3C2410_GPG15, S3C2410_GPG15_nYPON);
  7. }

觸摸屏控制器接口是與IO端口復用的。

2.觸摸屏中斷服務函數

  1. static irqreturn_t stylus_updown(int irq, void *dev_id)
  2. {
  3. unsigned long data0;
  4. unsigned long data1;
  5. int updown;
  6. if (down_trylock(&ADC_LOCK) == 0) {
  7. OwnADC = 1;
  8. //讀取ADCDAT0和ADCDAT1寄存器,判斷是按下中斷還是彈起中斷
  9. //ADCDAT0和ADCDAT1查手冊可知其第15位當按下時為0,彈起為1
  10. data0 = ioread32(base_addr+S3C2410_ADCDAT0);
  11. data1 = ioread32(base_addr+S3C2410_ADCDAT1);
  12. updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!(data1 & S3C2410_ADCDAT0_UPDOWN));
  13. if (updown) {
  14. touch_timer_fire(0);//當判斷為按下時
  15. } else {
  16. OwnADC = 0;
  17. up(&ADC_LOCK);
  18. }
  19. }
  20. return IRQ_HANDLED;
  21. }
Copyright © Linux教程網 All Rights Reserved