<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > AM335x(TQ335x)學(xué)習(xí)筆記——觸摸屏驅(qū)動(dòng)編寫(xiě)

          AM335x(TQ335x)學(xué)習(xí)筆記——觸摸屏驅(qū)動(dòng)編寫(xiě)

          作者: 時(shí)間:2016-11-28 來(lái)源:網(wǎng)絡(luò) 收藏
          前面幾篇文章已經(jīng)通過(guò)配置DTS的方式完成了多個(gè)驅(qū)動(dòng)的移植,接下來(lái)我們解決TQ335x的觸摸驅(qū)動(dòng)問(wèn)題。由于種種原因,TQ335x的觸摸屏驅(qū)動(dòng)是以模塊方式提供的,且Linux官方內(nèi)核中也沒(méi)有帶該觸摸屏的驅(qū)動(dòng)源碼,單純的配置DTS是無(wú)法完成TQ335x的觸摸驅(qū)動(dòng)移植工作的,因此,本文參考內(nèi)核中原有的pixcir_i2c_ts驅(qū)動(dòng)編寫(xiě)TQ335x的觸摸屏(TN92)驅(qū)動(dòng)。

          在之前移植TQ210時(shí),我已經(jīng)編寫(xiě)過(guò)TQ210的觸摸屏驅(qū)動(dòng),我的TQ335x還是使用的TQ210的屏,因此,難度不是很大。這里需要說(shuō)明一點(diǎn),在TQ210驅(qū)動(dòng)移植時(shí)對(duì)多點(diǎn)觸摸協(xié)議的理解還不夠深入,當(dāng)時(shí)編寫(xiě)的驅(qū)動(dòng)單點(diǎn)觸摸是可以正常使用的,但是多點(diǎn)觸摸不對(duì)(這次編寫(xiě)TQ335x的觸摸驅(qū)動(dòng)是才意識(shí)到的)。但是編寫(xiě)的TQ210驅(qū)動(dòng)多點(diǎn)觸摸實(shí)際上使用的多點(diǎn)觸摸的A協(xié)議,但是用錯(cuò)了一些地方,本文基于TQ335x的重新編寫(xiě)的觸摸驅(qū)動(dòng)是按照多點(diǎn)觸摸B協(xié)議編寫(xiě),使用tslib測(cè)試正常,文章末尾有效果圖。

          本文引用地址:http://www.ex-cimer.com/article/201611/322822.htm

          TN92觸摸屏使用的觸控芯片是GT811,下面我們來(lái)分析下觸摸屏驅(qū)動(dòng)的編寫(xiě)。

          (1) 查看原理圖

          從觸摸屏原理圖中可以看到,GT811與開(kāi)發(fā)板相連的引腳有四條,分別是SDA、SDL、INT和RESET。其中,I2C_SDA和I2C_SDL是連接到AM335x的I2C1端口上的,用來(lái)與SoC通信;INT引腳是連接在GPIO1的27號(hào)引腳上的,在檢測(cè)到觸摸時(shí)GT811通過(guò)該引腳向SoC發(fā)起中斷請(qǐng)求;RESET引腳接到SoC的GPIO1的26號(hào)引腳上的,是用來(lái)接收SoC復(fù)位操作,對(duì)于本文,SoC就是AM335x。

          其中,GT811與SoC的管腳連接信息可以從底板原理圖中找到,SDA和SCL的我就不往外貼了,INT和RESET的連接關(guān)系如下:

          YP連接到了GT811的RESET腳上,然后通過(guò)短路帽與GPIO1_26鏈接,YM連接到GT811的INT腳上,通過(guò)短路帽與GPIO1_27鏈接,因此,需要將GPIO1_27配置為終端輸入引腳,GPIO1_26配置為輸出引腳。此外,查看GT811的芯片手冊(cè)可獲得INT和RESET的操作信息:

          1. 1.GT811檢測(cè)到觸摸時(shí)會(huì)拉低中斷引腳,因此,GPIO1_27需要配置為下降沿觸發(fā)。
          2. 2.GT811的RESET腳為低電平有效,因此,上電時(shí)需要拉低RESET引腳。
          3. 3.GT811的RESET引腳自帶上拉,因此,使用GPIO1_26將GT811的RESET拉低復(fù)位后切換為懸浮輸入太即可。
          了解這些信息后我們就可以開(kāi)始分析驅(qū)動(dòng)結(jié)構(gòu)了。

          (2) DTS配置Platform信息

          通過(guò)前面的分析,我們知道需要配置AM335x的四條引腳才能使GT811正常工作。其中,GT811通過(guò)I2C接口連接到AM335x的I2C1上,因此,需要配置AM335x的I2C1的兩條引腳為I2C功能;GPIO1_27需要配置為中斷輸入、下降沿觸發(fā),中斷號(hào)也可以確定下來(lái)了,就是GPIO1的27號(hào)角(內(nèi)核能將引腳轉(zhuǎn)換為中斷號(hào));最后就是RESET腳,驅(qū)動(dòng)初始化GT811時(shí)需要操作RESET引腳,且GT811為拉低復(fù)位,故可將GPIO1的26角設(shè)為輸出電平狀態(tài)。通過(guò)前面幾篇文章的學(xué)習(xí),我們知道DTS可以配置pinmux,然后分析內(nèi)核自帶的DTS文件可以,DTS也可以將連接信息傳遞給內(nèi)核。經(jīng)過(guò)分析及參考,我最TQ335x.dts文件做了如下修改:

          Step1. 檢查I2C引腳的pinmux配置

          查找i2c1可以找到i2c1節(jié)點(diǎn),該節(jié)點(diǎn)的pinctrl-0只想的phandler對(duì)i2c1的兩個(gè)引腳進(jìn)行了相關(guān)的配置,因此,不需任何修改。

          Step2. 配置INT和RESET引腳

          在am33xx_pinmux節(jié)點(diǎn)內(nèi)添加引腳配置信息,具體內(nèi)容如下:

          1. gt811_ts_pins:gt811_ts_pins{
          2. pinctrl-single,pins=<
          3. 0x68(PIN_INPUT_PULLUP|MUX_MODE7)
          4. 0x6c(PIN_INPUT_PULLUP|MUX_MODE7)
          5. >;
          6. };
          Step3. 在i2c1節(jié)點(diǎn)內(nèi)添加GT811設(shè)備信息

          GT811的設(shè)備節(jié)點(diǎn)內(nèi)需要提供以下信息,i2c設(shè)備地址、pinmux配置、中斷信息、屏幕大小等,具體如下(這里就不細(xì)說(shuō)了,有什么不清楚的可以留言討論)。

          1. gt811_ts@5d{
          2. compatible="gt811,gt811_ts";
          3. pinctrl-names="default";
          4. pinctrl-0=<>811_ts_pins>;
          5. reg=<0x5d>;
          6. interrupt-parent=<&gpio1>;
          7. interrupts=<272>;
          8. gpios=<&gpio1260>;
          9. touchscreen-size-x=<800>;
          10. touchscreen-size-y=<480>;
          11. touchscreen-swap=<1>;
          12. touchscreen-revert-x=<1>;
          13. touchscreen-revert-y=<1>;
          14. };
          至此,DTS的配置工作就完成了,下面就是GT811的驅(qū)動(dòng)編寫(xiě)。
          (3)驅(qū)動(dòng)編寫(xiě)

          驅(qū)動(dòng)編寫(xiě)根之前TQ210相比,沒(méi)有多少變化,都是采用的新式I2C設(shè)備驅(qū)動(dòng)架構(gòu),重要的區(qū)別在于支持了多點(diǎn)觸摸,驅(qū)動(dòng)的詳細(xì)分析我就不多說(shuō)了,具體可以參考韋東山老師的視頻教程(絕對(duì)物有所值)。下面是GT811的多點(diǎn)觸摸驅(qū)動(dòng)源碼。從GT811設(shè)備節(jié)點(diǎn)中獲取坐標(biāo)信息的部分我直接貼出來(lái)了,完整的代碼還是請(qǐng)到資源里下載,還是有點(diǎn)貴哈,不過(guò)這個(gè)驅(qū)動(dòng)可以直接拿去使用了,不需要任何修改。下面是不完整的代碼,可以打印出觸摸點(diǎn)坐標(biāo),該代碼已經(jīng)把本驅(qū)動(dòng)的核心的部分都寫(xiě)出來(lái)了。其實(shí)很多朋友不需要下載源碼就可以補(bǔ)充完善這個(gè)驅(qū)動(dòng)了,而且我真心的希望閱讀本文的朋友不需要下載源碼就能自己寫(xiě)出觸摸驅(qū)動(dòng)。

          1. #include
          2. #include
          3. #include
          4. #include
          5. #include
          6. #include
          7. #include
          8. #include
          9. #include
          10. #include
          11. #include
          12. structgt811_ts_platdata
          13. {
          14. u32size_x;
          15. u32size_y;
          16. u32size_p;
          17. u32swap;
          18. u32revert_x;
          19. u32revert_y;
          20. u32reset_pin;
          21. u32interrupt_pin;
          22. u32ponits_max;
          23. structi2c_client*client;
          24. structinput_dev*input;
          25. structwork_structwork;
          26. };
          27. staticconststructof_device_idgt811_ts_of_match[]={
          28. {.compatible="gt811,gt811_ts",.data=NULL},
          29. {}
          30. };
          31. staticinti2c_write_bytes(structi2c_client*client,uint8_t*data,intlen){
          32. structi2c_msgmsg;
          33. msg.flags=!I2C_M_RD;
          34. msg.addr=client->addr;
          35. msg.len=len;
          36. msg.buf=data;
          37. returni2c_transfer(client->adapter,&msg,1);
          38. }
          39. staticinti2c_read_bytes(structi2c_client*client,uint8_t*buf,intlen){
          40. structi2c_msgmsgs[2];
          41. msgs[0].flags=!I2C_M_RD;
          42. msgs[0].addr=client->addr;
          43. msgs[0].len=2;
          44. msgs[0].buf=&buf[0];
          45. msgs[1].flags=I2C_M_RD;
          46. msgs[1].addr=client->addr;
          47. msgs[1].len=len-2;
          48. msgs[1].buf=&buf[2];
          49. returni2c_transfer(client->adapter,msgs,2);
          50. }
          51. staticvoidgt811_ts_handler(structwork_struct*work)
          52. {
          53. structgt811_ts_platdata*pdata=container_of(work,structgt811_ts_platdata,work);
          54. structdevice*dev=&pdata->client->dev;
          55. uint8_tbuffer[36]={0x07,0x21,0};
          56. uint8_tcount,index,flags,position;
          57. intx,y;
          58. buffer[0]=0x0f;
          59. buffer[1]=0xff;
          60. if(i2c_write_bytes(pdata->client,buffer,2)<0){
          61. dev_err(dev,"Failedtowritewakeupmessage.");
          62. gotoreenable_irq;
          63. }
          64. buffer[0]=0x07;
          65. buffer[1]=0x21;
          66. if(i2c_read_bytes(pdata->client,buffer,sizeof(buffer))<0){
          67. dev_err(dev,"Failedtoreadtouchmessage.");
          68. gotoreenable_irq;
          69. }
          70. buffer[0]=0x80;
          71. buffer[1]=0x00;
          72. if(i2c_write_bytes(pdata->client,buffer,2)<0){
          73. dev_err(dev,"Failedtowritesleepmessage.");
          74. gotoreenable_irq;
          75. }
          76. buffer[25]=buffer[19];
          77. buffer[19]=0;
          78. flags=buffer[2]&0x1f;
          79. while(flags){
          80. if(!(flags&0x1)){
          81. continue;
          82. }
          83. if(index<3){
          84. position=4+index*5;
          85. }
          86. else{
          87. position=25+(index-3)*5;
          88. }
          89. x=(buffer[position]<<8)|buffer[position+1];
          90. y=(buffer[position+2]<<8)|buffer[position+3];
          91. if(pdata->swap){
          92. swap(x,y);
          93. }
          94. if(pdata->revert_x){
          95. x=pdata->size_x-x;
          96. }
          97. if(pdata->revert_y){
          98. y=pdata->size_y-y;
          99. }
          100. printk("point:(x:%03d,y:%03d)",x,y);
          101. }
          102. //組織檢測(cè)出來(lái)的觸摸點(diǎn)信息上報(bào)到輸入子系統(tǒng)節(jié)點(diǎn)即可
          103. reenable_irq:
          104. enable_irq(pdata->client->irq);
          105. }
          106. staticirqreturn_tgt811_ts_isr(intirq,void*dev_id)
          107. {
          108. structgt811_ts_platdata*pdata=(structgt811_ts_platdata*)dev_id;
          109. disable_irq_nosync(pdata->client->irq);
          110. schedule_work(&pdata->work);
          111. returnIRQ_HANDLED;
          112. }
          113. staticintgt811_ts_initilize(structi2c_client*client)
          114. {
          115. structdevice*dev=&client->dev;
          116. structgt811_ts_platdata*pdata=(structgt811_ts_platdata*)i2c_get_clientdata(client);
          117. intstatus=0,count=0;
          118. uint8_tversion[4]={0x7,0x17,0};
          119. uint8_tconfig[]={
          120. 0x06,0xA2,
          121. 0x12,0x10,0x0E,0x0C,0x0A,0x08,0x06,0x04,0x02,0x00,0xE2,0x53,0xD2,0x53,0xC2,0x53,
          122. 0xB2,0x53,0xA2,0x53,0x92,0x53,0x82,0x53,0x72,0x53,0x62,0x53,0x52,0x53,0x42,0x53,
          123. 0x32,0x53,0x22,0x53,0x12,0x53,0x02,0x53,0xF2,0x53,0x0F,0x13,0x40,0x40,0x40,0x10,
          124. 0x10,0x10,0x0F,0x0F,0x0A,0x35,0x25,0x0C,0x03,0x00,0x05,0x20,0x03,0xE0,0x01,0x00,
          125. 0x00,0x34,0x2C,0x36,0x2E,0x00,0x00,0x03,0x19,0x03,0x08,0x00,0x00,0x00,0x00,0x00,
          126. 0x14,0x10,0xEC,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0D,0x40,
          127. 0x30,0x3C,0x28,0x00,0x00,0x00,0x00,0xC0,0x12,0x01
          128. };
          129. config[62]=480>>8;
          130. config[61]=480&0xff;
          131. config[64]=800>>8;
          132. config[63]=800&0xff;
          133. if(!gpio_is_valid(pdata->reset_pin)){
          134. dev_err(dev,"Theresetpinnumberisinvalid.");
          135. return-EINVAL;
          136. }
          137. count=3;
          138. while(count--){
          139. gpio_direction_output(pdata->reset_pin,0);
          140. msleep(10);
          141. gpio_direction_output(pdata->reset_pin,1);
          142. msleep(100);
          143. if(i2c_read_bytes(client,version,sizeof(version))<0){
          144. dev_err(dev,"FailedtogettheversionofGT811,tryagain...");
          145. status=-ENODEV;
          146. }
          147. else{
          148. dev_info(dev,"Gt811detected,version(%04x)...",(version[2]<<8)|version[3]);
          149. status=0;
          150. break;
          151. }
          152. }

          153. 上一頁(yè) 1 2 下一頁(yè)

          評(píng)論


          技術(shù)專(zhuān)區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();