mbed library for XPT2046 SPI Touchscreen Controller (TFT_320QVT module)

Dependents:   TFT_320QVT_Window_Drag_Demo TFT_320QVT_HelloWorld UTFT_SSD1289 Ejemplo_TFT ... more

Files at this revision

API Documentation at this revision

Comitter:
rpocc
Date:
Mon Jan 11 09:35:33 2016 +0000
Commit message:
The first version of this mbed port

Changed in this revision

UTouch.cpp Show annotated file Show diff for this revision Revisions of this file
UTouch.h Show annotated file Show diff for this revision Revisions of this file
UTouchCD.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/UTouch.cpp	Mon Jan 11 09:35:33 2016 +0000
@@ -0,0 +1,344 @@
+/** \file UTouch.h
+ *  \brief mbed library for XPT2046 SPI Touchscreen Controller (TFT_320QVT module).
+ *  \copyright GNU Public License, v2. or later
+ *
+ * A known display with this type of controller chip is the ITDB02-3.2S
+ * from http://imall.iteadstudio.com
+ *
+ * This library is based on the Arduino/chipKIT UTFT library by Henning
+ * Karlsen, http://www.rinkydinkelectronics.com/library.php?id=55
+ *
+ * Pressure sensivity added by Dmitry Shtatnov
+ *
+ * Copyright (C)2010-2015 Henning Karlsen. All right reserved.
+ *
+ * Copyright (C)2016 Dmitry Shtatnov. All right reserved.
+ * http://modularsynth.ru/
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to:
+ *
+ * Free Software Foundation, Inc.
+ * 51 Franklin St, 5th Floor, Boston, MA 02110-1301, USA
+ *
+ *********************************************************************/
+
+#include "UTouch.h"
+#include "UTouchCD.h"
+
+void UTouch::touch_WriteData(byte data)
+{
+    byte temp;
+
+    temp=data;
+    P_CLK = LOW;
+
+    for(byte count=0; count<8; count++)
+    {
+        if(temp & 0x80)
+            P_DIN = HIGH;
+        else
+            P_DIN = LOW;
+        temp = temp << 1; 
+        P_CLK = LOW;
+        P_CLK = HIGH;
+    }
+}
+
+word UTouch::touch_ReadData()
+{
+    word data = 0;
+
+    for(byte count=0; count<12; count++)
+    {
+        data <<= 1;
+        P_CLK = HIGH;
+        P_CLK = LOW;
+        if (P_DOUT)
+            data++;
+    }
+    return(data);
+}
+
+UTouch::UTouch(PinName tclk, PinName tcs, PinName din, PinName dout, PinName irq)
+    :P_CLK(tclk), P_CS(tcs), P_DIN(din), P_DOUT(dout), P_IRQ(irq)
+{
+}
+
+void UTouch::InitTouch(byte orientation)
+{
+    orient                  = orientation;
+    _default_orientation    = CAL_S>>31;
+    touch_x_left            = (CAL_X>>14) & 0x3FFF;
+    touch_x_right           = CAL_X & 0x3FFF;
+    touch_y_top             = (CAL_Y>>14) & 0x3FFF;
+    touch_y_bottom          = CAL_Y & 0x3FFF;
+    disp_x_size             = (CAL_S>>12) & 0x0FFF;
+    disp_y_size             = CAL_S & 0x0FFF;
+    prec                    = 10;
+    
+    P_IRQ.output();
+
+    P_CS = HIGH;
+    P_CLK = HIGH;
+    P_DIN = HIGH;
+    P_IRQ = HIGH;
+    touch_tresholdLow = -1024;
+    touch_tresholdHigh = 2048;
+
+}
+
+int16_t UTouch::touch_getrawdata(uint8_t code) {
+    int16_t tmp;
+    P_CS = LOW;
+    P_IRQ.input();
+    if(!P_IRQ) {
+        touch_WriteData(code);
+        P_CLK = HIGH; P_CLK = LOW;
+        tmp = touch_ReadData();
+    }
+    else {
+        tmp = 0;
+    }
+    P_IRQ.output();
+    P_CS = LOW;
+    return tmp;
+}
+    
+int16_t UTouch::GetPressure()
+{
+    int16_t _ry, _rz1, _rz2;
+    _ry = GetYraw();
+    _rz1 = GetZ1raw();
+    _rz2 = GetZ2raw();
+    return _ry*_rz1/_rz2-_ry-5000;
+}
+
+void UTouch::SetTreshold(int16_t trshLow, int16_t trshHigh)
+{
+    touch_tresholdLow = trshLow;
+    touch_tresholdHigh = trshLow;
+}
+
+int16_t UTouch::GetXraw()
+{
+    return touch_getrawdata(0x90);
+}
+
+int16_t UTouch::GetYraw()
+{
+    return touch_getrawdata(0xD0);
+}
+
+int16_t UTouch::GetZ1raw()
+{
+    return touch_getrawdata(0xC0);
+}
+
+int16_t UTouch::GetZ2raw()
+{
+    return touch_getrawdata(0xB0);
+}
+
+bool UTouch::Read()
+{
+    unsigned long tx=0, temp_x=0;
+    unsigned long ty=0, temp_y=0;
+    unsigned long minx=99999, maxx=0;
+    unsigned long miny=99999, maxy=0;
+    int datacount=0;
+    uint16_t _press;
+
+        _press = GetPressure();
+        if((_press>touch_tresholdLow)&&(_press<touch_tresholdHigh))
+        {
+    
+            P_CS = LOW;
+
+            P_IRQ.input();
+            for (int i=0; i<prec; i++)
+            {
+                if (!P_IRQ)
+                {
+                    touch_WriteData(0x90);        
+                    P_CLK = HIGH; P_CLK = LOW;
+                    temp_x=touch_ReadData();
+        
+                    if (!P_IRQ)
+                    {
+                        touch_WriteData(0xD0);      
+                        P_CLK = HIGH; P_CLK = LOW;
+                        temp_y=touch_ReadData();
+        
+                        if ((temp_x>0) and (temp_x<4096) and (temp_y>0) and (temp_y<4096))
+                        {
+                            tx+=temp_x;
+                            ty+=temp_y;
+                            if (prec>5)
+                            {
+                                if (temp_x<minx)
+                                    minx=temp_x;
+                                if (temp_x>maxx)
+                                    maxx=temp_x;
+                                if (temp_y<miny)
+                                    miny=temp_y;
+                                if (temp_y>maxy)
+                                    maxy=temp_y;
+                            }
+                            datacount++;
+                        }
+                    }
+                }
+            }
+        }
+    P_IRQ.output();
+
+    if (prec>5)
+    {
+        tx = tx-(minx+maxx);
+        ty = ty-(miny+maxy);
+        datacount -= 2;
+    }
+
+    P_CS = HIGH;
+    if ((datacount==(prec-2)) or (datacount==PREC_LOW))
+    {
+        if (orient == _default_orientation)
+        {
+            TP_X=ty/datacount;
+            TP_Y=tx/datacount;
+            return true;
+        }
+        else
+        {
+            TP_X=tx/datacount;
+            TP_Y=ty/datacount;
+            return true;
+        }
+    }
+    else
+    {
+        TP_X=-1;
+        TP_Y=-1;
+        return false;
+    }
+}
+
+bool UTouch::DataAvailable()
+{
+    bool avail;
+    P_IRQ.input();
+    avail = !(P_IRQ);
+    P_IRQ.output();
+    return avail;
+}
+
+int16_t UTouch::GetX()
+{
+    long c;
+
+    if ((TP_X==-1) or (TP_Y==-1))
+        return -1;
+    if (orient == _default_orientation)
+    {
+        c = long(long(TP_X - touch_x_left) * (disp_x_size)) / long(touch_x_right - touch_x_left);
+        if (c<0)
+            c = 0;
+        if (c>disp_x_size)
+            c = disp_x_size;
+    }
+    else
+    {
+        if (_default_orientation == PORTRAIT)
+            c = long(long(TP_X - touch_y_top) * (-disp_y_size)) / long(touch_y_bottom - touch_y_top) + long(disp_y_size);
+        else
+            c = long(long(TP_X - touch_y_top) * (disp_y_size)) / long(touch_y_bottom - touch_y_top);
+        if (c<0)
+            c = 0;
+        if (c>disp_y_size)
+            c = disp_y_size;
+    }
+    return c;
+}
+
+int16_t UTouch::GetY()
+{
+    int c;
+
+    if ((TP_X==-1) or (TP_Y==-1))
+        return -1;
+    if (orient == _default_orientation)
+    {
+        c = long(long(TP_Y - touch_y_top) * (disp_y_size)) / long(touch_y_bottom - touch_y_top);
+        if (c<0)
+            c = 0;
+        if (c>disp_y_size)
+            c = disp_y_size;
+    }
+    else
+    {
+        if (_default_orientation == PORTRAIT)
+            c = long(long(TP_Y - touch_x_left) * (disp_x_size)) / long(touch_x_right - touch_x_left);
+        else
+            c = long(long(TP_Y - touch_x_left) * (-disp_x_size)) / long(touch_x_right - touch_x_left) + long(disp_x_size);
+        if (c<0)
+            c = 0;
+        if (c>disp_x_size)
+            c = disp_x_size;
+    }
+    return c;
+}
+
+void UTouch::SetPrecision(byte precision)
+{
+    switch (precision)
+    {
+        case PREC_LOW:
+            prec=1;     // DO NOT CHANGE!
+            break;
+        case PREC_MEDIUM:
+            prec=12;    // Iterations + 2
+            break;
+        case PREC_HI:
+            prec=27;    // Iterations + 2
+            break;
+        case PREC_EXTREME:
+            prec=102;   // Iterations + 2
+            break;
+        default:
+            prec=12;    // Iterations + 2
+            break;
+    }
+}
+
+void UTouch::CalibrateRead()
+{
+    unsigned long tx=0;
+    unsigned long ty=0;
+
+    P_CS = LOW;
+
+    touch_WriteData(0x90);        
+    P_CLK = HIGH; P_CLK = LOW;
+    tx=touch_ReadData();
+
+    touch_WriteData(0xD0);      
+    P_CLK = HIGH; P_CLK = LOW;
+    ty=touch_ReadData();
+
+    P_CS = HIGH;
+
+    TP_X=ty;
+    TP_Y=tx;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/UTouch.h	Mon Jan 11 09:35:33 2016 +0000
@@ -0,0 +1,152 @@
+/** \file UTouch.h
+ *  \brief mbed library for XPT2046 SPI Touchscreen Controller (TFT_320QVT module).
+ *  \copyright GNU Public License, v2. or later
+ *
+ * A known display with this type of controller chip is the ITDB02-3.2S
+ * from http://imall.iteadstudio.com
+ *
+ * This library is based on the Arduino/chipKIT UTFT library by Henning
+ * Karlsen, http://www.rinkydinkelectronics.com/library.php?id=55
+ *
+ * Pressure sensivity added by Dmitry Shtatnov
+ *
+ * Copyright (C)2010-2015 Henning Karlsen. All right reserved.
+ *
+ * Copyright (C)2016 Dmitry Shtatnov. All right reserved.
+ * http://modularsynth.ru/
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to:
+ *
+ * Free Software Foundation, Inc.
+ * 51 Franklin St, 5th Floor, Boston, MA 02110-1301, USA
+ *
+ *********************************************************************/
+
+#include "mbed.h"
+
+#ifndef UTouch_h
+#define UTouch_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Represents a Touchscreen instance.
+ *
+ * This is the utility class, through which the XPT2046 touchscreen can be manipulated
+ * How to use:
+ * \code
+ * // If you are using TFT-320QVT TFT LCD module or similar, you also have to add
+ * // SSD1289 library by Todor Todorov or modified version by Dmitry Shtatnov
+ * 
+ * #include "mbed.h"
+ * #include "ssd1289.h"
+ * #include "UTouch.h"
+ * PortOut LCDPA(PortA,0xFF00);
+ * PortOut LCDPC(PortC,0x00FF);
+ * //                 CS,   REST, RS,   WR,   DATA,      BL, RD
+ * SSD1289_LCD myGLCD(PB_3, PB_4, PB_0, PB_1, &LCDPA, &LCDPC, NC, PB_2);
+ * 
+ * UTouch  myTouch(PB_9, PB_8, PB_7, PB_6, PB_5);
+ * 
+ * int main() {
+ *   myGLCD.Initialize();
+ *   myGLCD.SetBackground(COLOR_WHITE);
+ *   myGLCD.SetForeground(COLOR_BLACK);
+ *   myGLCD.FillScreen(COLOR_WHITE);
+ *   myTouch.InitTouch();
+ *   myTouch.SetPrecision(PREC_HI);
+ *   while(1==1)
+ *   {
+ *     if (myTouch.DataAvailable())
+ *     {
+ *       if(myTouch.Read())
+ *       {
+ *         x = myTouch.GetX();
+ *         y = myTouch.GetY();
+ *         myGLCD.DrawPixel(x, y, COLOR_BLACK);
+ *       }
+ *     }
+ *   }
+ * }
+ *
+ * \endcode
+ * \version 0.1
+ * \author Dmitry Shtatnov
+ */
+
+
+#define UTOUCH_VERSION  124
+
+// *** Hardwarespecific defines ***
+#define swap(type, i, j) {type t = i; i = j; j = t;}
+
+#define LOW                 0
+#define HIGH                1
+
+#define PORTRAIT            0
+#define LANDSCAPE           1
+
+#define PREC_LOW            1
+#define PREC_MEDIUM         2
+#define PREC_HI             3
+#define PREC_EXTREME        4
+
+#define byte uint8_t
+#define word uint16_t
+class UTouch
+{
+    public:
+        int16_t TP_X ,TP_Y, TP_Z1, TP_Z2;
+
+                UTouch(PinName tclk, PinName tcs, PinName tdin, PinName dout, PinName irq);
+
+        void    InitTouch(byte orientation = LANDSCAPE);
+        bool    Read();
+        bool    DataAvailable();
+        int16_t GetX();
+        int16_t GetY();
+        void    SetPrecision(byte precision);
+
+        void    CalibrateRead();
+        int16_t GetPressure();
+        void    SetTreshold(int16_t trshLow, int16_t trshHigh);
+    
+    protected:
+        int16_t GetXraw();
+        int16_t GetYraw();
+        int16_t GetZ1raw();
+        int16_t GetZ2raw();
+        DigitalOut P_CLK, P_CS, P_DIN;
+        DigitalIn P_DOUT;
+        DigitalInOut P_IRQ;
+        long    _default_orientation;
+        byte    orient;
+        byte    prec;
+        byte    display_model;
+        long    disp_x_size, disp_y_size, default_orientation;
+        long    touch_x_left, touch_x_right, touch_y_top, touch_y_bottom;
+
+        void    touch_WriteData(byte data);
+        word    touch_ReadData();
+        int16_t touch_tresholdLow;
+        int16_t touch_tresholdHigh;
+        int16_t touch_getrawdata(uint8_t code);
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/UTouchCD.h	Mon Jan 11 09:35:33 2016 +0000
@@ -0,0 +1,43 @@
+// UTouchCD.h
+// ----------
+//
+// Since there are slight deviations in all touch screens you should run a
+// calibration on your display module. Run the UTouch_Calibration sketch
+// that came with this library and follow the on-screen instructions to
+// update this file.
+//
+// Remember that is you have multiple display modules they will probably 
+// require different calibration data so you should run the calibration
+// every time you switch to another module.
+// You can, of course, store calibration data for all your modules here
+// and comment out the ones you dont need at the moment.
+//
+
+// These calibration settings works with my ITDB02-3.2S.
+// They MIGHT work on your 320x240 display module, but you should run the
+// calibration sketch anyway. If you are using a display with any other
+// resolution you MUST calibrate it as these settings WILL NOT work.
+//#define CAL_X 0x00378F66UL
+//#define CAL_Y 0x03C34155UL
+//#define CAL_S 0x000EF13FUL
+
+//#define CAL_X 0x001DC771UL
+//#define CAL_Y 0x01E200A6UL
+//#define CAL_S 0x000EF13FUL
+
+#ifndef UTouchCD_h
+#define UTouchCD_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CAL_X   0x003B8EE2UL
+#define CAL_Y   0x03C4014CUL
+#define CAL_S   0x000EF13FUL
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
\ No newline at end of file