Stepan Smejkal / UTouch_vyrobek
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers UTouch.cpp Source File

UTouch.cpp

00001 /** \file UTouch.h
00002  *  \brief mbed library for XPT2046 SPI Touchscreen Controller (TFT_320QVT module).
00003  *  \copyright GNU Public License, v2. or later
00004  *
00005  * A known display with this type of controller chip is the ITDB02-3.2S
00006  * from http://imall.iteadstudio.com
00007  *
00008  * This library is based on the Arduino/chipKIT UTFT library by Henning
00009  * Karlsen, http://www.rinkydinkelectronics.com/library.php?id=55
00010  *
00011  * Pressure sensivity added by Dmitry Shtatnov
00012  *
00013  * Copyright (C)2010-2015 Henning Karlsen. All right reserved.
00014  *
00015  * Copyright (C)2016 Dmitry Shtatnov. All right reserved.
00016  * http://modularsynth.ru/
00017  *
00018  * This library is free software; you can redistribute it and/or
00019  * modify it under the terms of the GNU Lesser General Public
00020  * License as published by the Free Software Foundation; either
00021  * version 2.1 of the License, or (at your option) any later version.
00022  *
00023  * This library is distributed in the hope that it will be useful,
00024  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00025  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00026  * Lesser General Public License for more details.
00027  *
00028  * You should have received a copy of the GNU Lesser General Public
00029  * License along with this library; if not, write to:
00030  *
00031  * Free Software Foundation, Inc.
00032  * 51 Franklin St, 5th Floor, Boston, MA 02110-1301, USA
00033  *
00034  *********************************************************************/
00035 
00036 #include "UTouch.h"
00037 #include "UTouchCD.h"
00038 
00039 void UTouch::touch_WriteData(byte data)
00040 {
00041     byte temp;
00042 
00043     temp=data;
00044     P_CLK = LOW;
00045 
00046     for(byte count=0; count<8; count++)
00047     {
00048         if(temp & 0x80)
00049             P_DIN = HIGH;
00050         else
00051             P_DIN = LOW;
00052         temp = temp << 1; 
00053         P_CLK = LOW;
00054         P_CLK = HIGH;
00055     }
00056 }
00057 
00058 word UTouch::touch_ReadData()
00059 {
00060     word data = 0;
00061 
00062     for(byte count=0; count<12; count++)
00063     {
00064         data <<= 1;
00065         P_CLK = HIGH;
00066         P_CLK = LOW;
00067         if (P_DOUT)
00068             data++;
00069     }
00070     return(data);
00071 }
00072 
00073 UTouch::UTouch(PinName tclk, PinName tcs, PinName din, PinName dout, PinName irq)
00074     :P_CLK(tclk), P_CS(tcs), P_DIN(din), P_DOUT(dout), P_IRQ(irq)
00075 {
00076 }
00077 
00078 void UTouch::InitTouch(byte orientation)
00079 {
00080     orient                  = orientation;
00081     _default_orientation    = CAL_S>>31;
00082     touch_x_left            = (CAL_X>>14) & 0x3FFF;
00083     touch_x_right           = CAL_X & 0x3FFF;
00084     touch_y_top             = (CAL_Y>>14) & 0x3FFF;
00085     touch_y_bottom          = CAL_Y & 0x3FFF;
00086     disp_x_size             = (CAL_S>>12) & 0x0FFF;
00087     disp_y_size             = CAL_S & 0x0FFF;
00088     prec                    = 10;
00089     
00090     P_IRQ.output();
00091 
00092     P_CS = HIGH;
00093     P_CLK = HIGH;
00094     P_DIN = HIGH;
00095     P_IRQ = HIGH;
00096     touch_tresholdLow = -1024;
00097     touch_tresholdHigh = 2048;
00098 
00099 }
00100 
00101 int16_t UTouch::touch_getrawdata(uint8_t code) {
00102     int16_t tmp;
00103     P_CS = LOW;
00104     P_IRQ.input();
00105     if(!P_IRQ) {
00106         touch_WriteData(code);
00107         P_CLK = HIGH; P_CLK = LOW;
00108         tmp = touch_ReadData();
00109     }
00110     else {
00111         tmp = 0;
00112     }
00113     P_IRQ.output();
00114     P_CS = LOW;
00115     return tmp;
00116 }
00117     
00118 int16_t UTouch::GetPressure()
00119 {
00120     int16_t _ry, _rz1, _rz2;
00121     _ry = GetYraw();
00122     _rz1 = GetZ1raw();
00123     _rz2 = GetZ2raw();
00124     return _ry*_rz1/_rz2-_ry-5000;
00125 }
00126 
00127 void UTouch::SetTreshold(int16_t trshLow, int16_t trshHigh)
00128 {
00129     touch_tresholdLow = trshLow;
00130     touch_tresholdHigh = trshLow;
00131 }
00132 
00133 int16_t UTouch::GetXraw()
00134 {
00135     return touch_getrawdata(0x90);
00136 }
00137 
00138 int16_t UTouch::GetYraw()
00139 {
00140     return touch_getrawdata(0xD0);
00141 }
00142 
00143 int16_t UTouch::GetZ1raw()
00144 {
00145     return touch_getrawdata(0xC0);
00146 }
00147 
00148 int16_t UTouch::GetZ2raw()
00149 {
00150     return touch_getrawdata(0xB0);
00151 }
00152 
00153 bool UTouch::Read()
00154 {
00155     unsigned long tx=0, temp_x=0;
00156     unsigned long ty=0, temp_y=0;
00157     unsigned long minx=99999, maxx=0;
00158     unsigned long miny=99999, maxy=0;
00159     int datacount=0;
00160     uint16_t _press;
00161 
00162         _press = GetPressure();
00163         if((_press>touch_tresholdLow)&&(_press<touch_tresholdHigh))
00164         {
00165     
00166             P_CS = LOW;
00167 
00168             P_IRQ.input();
00169             for (int i=0; i<prec; i++)
00170             {
00171                 if (!P_IRQ)
00172                 {
00173                     touch_WriteData(0x90);        
00174                     P_CLK = HIGH; P_CLK = LOW;
00175                     temp_x=touch_ReadData();
00176         
00177                     if (!P_IRQ)
00178                     {
00179                         touch_WriteData(0xD0);      
00180                         P_CLK = HIGH; P_CLK = LOW;
00181                         temp_y=touch_ReadData();
00182         
00183                         if ((temp_x>0) and (temp_x<4096) and (temp_y>0) and (temp_y<4096))
00184                         {
00185                             tx+=temp_x;
00186                             ty+=temp_y;
00187                             if (prec>5)
00188                             {
00189                                 if (temp_x<minx)
00190                                     minx=temp_x;
00191                                 if (temp_x>maxx)
00192                                     maxx=temp_x;
00193                                 if (temp_y<miny)
00194                                     miny=temp_y;
00195                                 if (temp_y>maxy)
00196                                     maxy=temp_y;
00197                             }
00198                             datacount++;
00199                         }
00200                     }
00201                 }
00202             }
00203         }
00204     P_IRQ.output();
00205 
00206     if (prec>5)
00207     {
00208         tx = tx-(minx+maxx);
00209         ty = ty-(miny+maxy);
00210         datacount -= 2;
00211     }
00212 
00213     P_CS = HIGH;
00214     if ((datacount==(prec-2)) or (datacount==PREC_LOW))
00215     {
00216         if (orient == _default_orientation)
00217         {
00218             TP_X=ty/datacount;
00219             TP_Y=tx/datacount;
00220             return true;
00221         }
00222         else
00223         {
00224             TP_X=tx/datacount;
00225             TP_Y=ty/datacount;
00226             return true;
00227         }
00228     }
00229     else
00230     {
00231         TP_X=-1;
00232         TP_Y=-1;
00233         return false;
00234     }
00235 }
00236 
00237 bool UTouch::DataAvailable()
00238 {
00239     bool avail;
00240     P_IRQ.input();
00241     avail = !(P_IRQ);
00242     P_IRQ.output();
00243     return avail;
00244 }
00245 
00246 int16_t UTouch::GetX()
00247 {
00248     long c;
00249 
00250     if ((TP_X==-1) or (TP_Y==-1))
00251         return -1;
00252     if (orient == _default_orientation)
00253     {
00254         c = long(long(TP_X - touch_x_left) * (disp_x_size)) / long(touch_x_right - touch_x_left);
00255         if (c<0)
00256             c = 0;
00257         if (c>disp_x_size)
00258             c = disp_x_size;
00259     }
00260     else
00261     {
00262         if (_default_orientation == PORTRAIT)
00263             c = long(long(TP_X - touch_y_top) * (-disp_y_size)) / long(touch_y_bottom - touch_y_top) + long(disp_y_size);
00264         else
00265             c = long(long(TP_X - touch_y_top) * (disp_y_size)) / long(touch_y_bottom - touch_y_top);
00266         if (c<0)
00267             c = 0;
00268         if (c>disp_y_size)
00269             c = disp_y_size;
00270     }
00271     return c;
00272 }
00273 
00274 int16_t UTouch::GetY()
00275 {
00276     int c;
00277 
00278     if ((TP_X==-1) or (TP_Y==-1))
00279         return -1;
00280     if (orient == _default_orientation)
00281     {
00282         c = long(long(TP_Y - touch_y_top) * (disp_y_size)) / long(touch_y_bottom - touch_y_top);
00283         if (c<0)
00284             c = 0;
00285         if (c>disp_y_size)
00286             c = disp_y_size;
00287     }
00288     else
00289     {
00290         if (_default_orientation == PORTRAIT)
00291             c = long(long(TP_Y - touch_x_left) * (disp_x_size)) / long(touch_x_right - touch_x_left);
00292         else
00293             c = long(long(TP_Y - touch_x_left) * (-disp_x_size)) / long(touch_x_right - touch_x_left) + long(disp_x_size);
00294         if (c<0)
00295             c = 0;
00296         if (c>disp_x_size)
00297             c = disp_x_size;
00298     }
00299     return c;
00300 }
00301 
00302 void UTouch::SetPrecision(byte precision)
00303 {
00304     switch (precision)
00305     {
00306         case PREC_LOW:
00307             prec=1;     // DO NOT CHANGE!
00308             break;
00309         case PREC_MEDIUM:
00310             prec=12;    // Iterations + 2
00311             break;
00312         case PREC_HI:
00313             prec=27;    // Iterations + 2
00314             break;
00315         case PREC_EXTREME:
00316             prec=102;   // Iterations + 2
00317             break;
00318         default:
00319             prec=12;    // Iterations + 2
00320             break;
00321     }
00322 }
00323 
00324 void UTouch::CalibrateRead()
00325 {
00326     unsigned long tx=0;
00327     unsigned long ty=0;
00328 
00329     P_CS = LOW;
00330 
00331     touch_WriteData(0x90);        
00332     P_CLK = HIGH; P_CLK = LOW;
00333     tx=touch_ReadData();
00334 
00335     touch_WriteData(0xD0);      
00336     P_CLK = HIGH; P_CLK = LOW;
00337     ty=touch_ReadData();
00338 
00339     P_CS = HIGH;
00340 
00341     TP_X=ty;
00342     TP_Y=tx;
00343 }
00344