mbed library for XPT2046 SPI Touchscreen Controller (TFT_320QVT module)
Dependents: TFT_320QVT_Window_Drag_Demo TFT_320QVT_HelloWorld UTFT_SSD1289 Ejemplo_TFT ... more
Revision 0:a275ef704eb8, committed 2016-01-11
- Comitter:
- rpocc
- Date:
- Mon Jan 11 09:35:33 2016 +0000
- Commit message:
- The first version of this mbed port
Changed in this revision
diff -r 000000000000 -r a275ef704eb8 UTouch.cpp --- /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; +} +
diff -r 000000000000 -r a275ef704eb8 UTouch.h --- /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
diff -r 000000000000 -r a275ef704eb8 UTouchCD.h --- /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