Driver Library for our displays

Dependents:   dm_bubbles dm_calc dm_paint dm_sdcard_with_adapter ... more

Files at this revision

API Documentation at this revision

Comitter:
displaymodule
Date:
Fri Jul 04 09:26:32 2014 +0000
Parent:
6:fde03297017b
Child:
8:b24f01d148c4
Commit message:
Improved handling of touch calibration

Changed in this revision

DmTftBase.cpp Show annotated file Show diff for this revision Revisions of this file
DmTftIli9325.cpp Show annotated file Show diff for this revision Revisions of this file
DmTftSsd2119.cpp Show annotated file Show diff for this revision Revisions of this file
DmTouch.cpp Show annotated file Show diff for this revision Revisions of this file
DmTouch.h Show annotated file Show diff for this revision Revisions of this file
DmTouchCalibration.cpp Show annotated file Show diff for this revision Revisions of this file
DmTouchCalibration.h Show annotated file Show diff for this revision Revisions of this file
--- a/DmTftBase.cpp	Fri May 23 08:10:09 2014 +0000
+++ b/DmTftBase.cpp	Fri Jul 04 09:26:32 2014 +0000
@@ -33,6 +33,10 @@
 void DmTftBase::setPixel(uint16_t x, uint16_t y, uint16_t color) {
   cbi(_pinCS, _bitmaskCS);
 
+  if ((x >= _width) || (y >= _height)) {
+    return;
+  }
+
   setAddress(x, y, x, y);
 
   sendData(color);
--- a/DmTftIli9325.cpp	Fri May 23 08:10:09 2014 +0000
+++ b/DmTftIli9325.cpp	Fri Jul 04 09:26:32 2014 +0000
@@ -185,7 +185,7 @@
   sendCommand(0x98); sendData(0x0000);
   sendCommand(0x07); sendData(0x0133);
   sbi(_pinCS, _bitmaskCS);
-
+  delay(500);
   clearScreen();
 }
 
--- a/DmTftSsd2119.cpp	Fri May 23 08:10:09 2014 +0000
+++ b/DmTftSsd2119.cpp	Fri Jul 04 09:26:32 2014 +0000
@@ -49,30 +49,24 @@
 }
 
 void DmTftSsd2119::sendCommand(uint8_t index) {
-  // cbi(_pinCS, _bitmaskCS);
   cbi(_pinDC, _bitmaskDC);
 
-  writeBus(0x00); // Temp
+  writeBus(0x00);
   writeBus(index);
-  // sbi(_pinCS, _bitmaskCS);
 }
 
 void DmTftSsd2119::send8BitData(uint8_t data) {
-  //cbi(_pinCS, _bitmaskCS);
   sbi(_pinDC, _bitmaskDC);
   writeBus(data);
-  //sbi(_pinCS, _bitmaskCS);
 }
 
 void DmTftSsd2119::sendData(uint16_t data) {
   uint8_t dh = data>>8;
   uint8_t dl = data&0xff;
 
-  //cbi(_pinCS, _bitmaskCS);
   sbi(_pinDC, _bitmaskDC);
   writeBus(dh);
   writeBus(dl);
-  //sbi(_pinCS, _bitmaskCS);
 }
 
 void DmTftSsd2119::setAddress(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
@@ -115,8 +109,6 @@
   sbi(_pinCS, _bitmaskCS);
 }
 
-
-
 void DmTftSsd2119::init(void) {
   setTextColor(BLACK, WHITE);
 #if defined (DM_TOOLCHAIN_ARDUINO)
@@ -161,7 +153,7 @@
   sendCommand(0x11);    // Entry Mode ,SET LCM interface Mode.
   sendData(0x6870);     //  SET 65K colors,MCU interface Mode.TypeB ,ID=11 AM=0 the address counter is updated in the horizontal direction.
 
-  sendCommand(0x15);    // Generic Interface Control. DOCLK,HSYNC,VSYNC,DE
+  sendCommand(0x15);    // Generic Interface Control. DOCLK,HSYNC,VSYNC,DE
   sendData(0x0000);
 
   sendCommand(0x01);    // Driver Output Control
@@ -174,25 +166,25 @@
   sendData(0x0000);     // The valid range is from 1 to 240
      
   // LCD POWER CONTROL
-  sendCommand(0x03);    // Power Control 1, VGH,VGL
-  sendData(0x6A38);     // Set dct=fline*4, VGH=2 x VCIX2 + VCI,VGL=-(VGH) + VCix2, DC=Fline × 8, AP=Medium to large   
+  sendCommand(0x03);    // Power Control 1, VGH,VGL
+  sendData(0x6A38);     // Set dct=fline*4, VGH=2 x VCIX2 + VCI,VGL=-(VGH) + VCix2, DC=Fline × 8, AP=Medium to large   
    
   sendCommand(0X0B);    // Frame Cycle Control.
   sendData(0x5308);     // SET NO SDT=1 clock cycle (POR) ,Sets the equalizing period,    
 
-  sendCommand(0x0C);    // Power Control 2 设VCIX2 电压
+  sendCommand(0x0C);    // Power Control 2 VCIX2
   sendData(0x0003);     // Adjust VCIX2 output voltage=5.7V
 
   sendCommand(0x0D);    // Set amplitude magnification of VLCD63     
   sendData(0x000A);     // vlcd63=VREF(2.0V)* 2.335V
 
-  sendCommand(0x0E);    // SET VCOMG VDV .设VCOM电压
+  sendCommand(0x0E);    // SET VCOMG VDV .VCOM
   sendData(0x2B00);     // SET VCOMG=1,VCOM=VLCD63*  //2A 
 
   sendCommand(0X0F);    // Gate Scan Position.
   sendData(0x0000);     // The valid range is from 1 to 240.   
 
-  sendCommand(0x1E);    // SET nOTP VCOMH ,设VCOMH电压
+  sendCommand(0x1E);    // SET nOTP VCOMH ,VCOMH
   sendData(0x00B7);     // SET nOTP=0, VCOMH=VLCD63* //B8
 
   sendCommand(0x25);    // Frame Frequency Control
@@ -204,9 +196,8 @@
   sendCommand(0x27);    // Analog setting
   sendData(0x0078);
 
-  //
-  sendCommand(0x12);    // Sleep mode
-  sendData(0xD999);   
+//  sendCommand(0x12);    // Sleep mode
+//  sendData(0xD999);   
 
   // SET WINDOW
   sendCommand(0x4E);    // Ram Address Set
@@ -263,5 +254,3 @@
 /*********************************************************************************************************
   END FILE
 *********************************************************************************************************/
-
-
--- a/DmTouch.cpp	Fri May 23 08:10:09 2014 +0000
+++ b/DmTouch.cpp	Fri Jul 04 09:26:32 2014 +0000
@@ -12,32 +12,22 @@
 // Tested with Xpt2046
 
 #include "DmTouch.h"
+#include "DmTouchCalibration.h"
+
+#define MEASUREMENTS 10
 
 #if defined(DM_TOOLCHAIN_ARDUINO)
 // disp        - which display is used
-// cs          - pin number CS (Chip Select, SS)
-// irq         - pin number IRQ (set to -1 if you don't want to use)
-// hardwareSpi - set to 1 if you want to use hardware Spi, 0 otherwise
-//               (note, if you use hardware Spi on arduino, clk, mosi and miso will be disregarded)
-// clk         - pin number CLK (SLK)
-// mosi        - pin number MOSI
-// miso        - pin number MISO
-// width       - width of display (default 240)
-// height      - height of display (default 320)
-DmTouch::DmTouch(Display disp, int8_t cs, int8_t irq, int8_t hardwareSpi, int8_t clk, int8_t mosi, int8_t miso, uint16_t width, uint16_t height) : _width(width), _height(height)
-{
-  _hardwareSpi = hardwareSpi;
-  _cs = cs;
-  _irq = irq;
-  _clk = clk;
-  _mosi = mosi;
-  _miso = miso;
+// spiMode     - How to read SPI-data, Software, Hardware or Auto
+// useIrq      - Enable IRQ or disable IRQ
+DmTouch::DmTouch(Display disp, SpiMode spiMode, bool useIrq)
 
 #elif defined (DM_TOOLCHAIN_MBED)
 // disp        - which display is used
-DmTouch::DmTouch(Display disp, bool hardwareSPI)
+// spiMode     - How to read SPI-data, Software, Hardware or Auto
+DmTouch::DmTouch(Display disp, SpiMode spiMode)
+#endif
 {
-  _hardwareSpi = hardwareSPI;
   switch (disp) {
     // Display with 40-pin connector on top of adapter board
     case DmTouch::DM_TFT28_103:
@@ -47,8 +37,7 @@
       _clk = A1;
       _mosi = A0;
       _miso = D9;
-      _width = 240;
-      _height = 320;
+      _hardwareSpi = false;
       break;
 
     case DmTouch::DM_TFT28_105:
@@ -57,8 +46,7 @@
       _clk = D13;
       _mosi = D11;
       _miso = D12;
-      _width = 240;
-      _height = 320;
+      _hardwareSpi = true;
       break;
 
     case DmTouch::DM_TFT35_107:
@@ -68,47 +56,25 @@
       _clk = D13;
       _mosi = D11;
       _miso = D12;
-      _width = 320;
-      _height = 240;
+      _hardwareSpi = true;
       break;
   }
+
+  if (spiMode == DmTouch::Hardware) {
+	_hardwareSpi = true;
+  } else if (spiMode == DmTouch::Software) {
+	_hardwareSpi = false;
+  }
+
+#if defined(DM_TOOLCHAIN_ARDUINO)
+  if (!useIrq) {
+	_irq = -1;
+  }
 #endif
-
-  // Calibration data for the different displays
-  switch (disp) {
-    case DmTouch::DM_TFT28_103:
-      _calibLowX = 220;
-      _calibLowY = 220;
-      _calibModifierX = 15.25;
-      _calibModifierY = 11.16;
-      _calibInvertedTouch = false;
-      break;
+  
+  setCalibrationMatrix(DmTouchCalibration::getDefaultCalibrationData(disp));
 
-    case DmTouch::DM_TFT24_104:
-      _calibLowX = 210;
-      _calibLowY = 280;
-      _calibModifierX = 15;
-      _calibModifierY = 11.24;
-      _calibInvertedTouch = true;
-      break;
-
-    case DmTouch::DM_TFT35_107:
-      _calibLowX = 912;
-      _calibLowY = 422 ;
-      _calibModifierX = 3.25;
-      _calibModifierY = 1.175;
-      _calibInvertedTouch = false;
-	  break;
-
-    case DmTouch::DM_TFT28_105:
-    default:
-      _calibLowX = 260;
-      _calibLowY = 220;
-      _calibModifierX = 14.42;
-      _calibModifierY = 10.78;
-      _calibInvertedTouch = false;
-      break;
-  }
+  _samplesPerMeasurement = 3;
 }
 
 void DmTouch::init() {
@@ -119,7 +85,7 @@
 
   if (_hardwareSpi) {
     SPI.begin();
-    SPI.setClockDivider(SPI_CLOCK_DIV2);
+    SPI.setClockDivider(SPI_CLOCK_DIV32);
     SPI.setBitOrder(MSBFIRST);
     SPI.setDataMode(SPI_MODE0);
     _spiSettings = SPCR;
@@ -172,38 +138,20 @@
 }
 
 void DmTouch::spiWrite(uint8_t data) {
+  if (_hardwareSpi) {
 #if defined (DM_TOOLCHAIN_ARDUINO)
-  if (_hardwareSpi) {
     SPCR = _spiSettings;   // SPI Control Register
     SPDR = data;        // SPI Data Register
     while(!(SPSR & _BV(SPIF)));  // SPI Status Register Wait for transmission to finish
-  }
-  else {
-    uint8_t count=0;
-    uint8_t temp;
-    unsigned nop;
-    temp=data; // really needed?
-    cbi(_pinCLK, _bitmaskCLK);
-    for(count=0;count<8;count++) {
-      if(temp&0x80) {
-        sbi(_pinMOSI, _bitmaskMOSI);
-      }
-      else {
-        cbi(_pinMOSI, _bitmaskMOSI);
-      }
-
-      temp=temp<<1;
-
-      pulse_low(_pinCLK, _bitmaskCLK);
-    }
-  }
 #elif defined (DM_TOOLCHAIN_MBED)
-  if (_hardwareSpi) {
     _spi->write(data);
+#endif
   }
   else {
     uint8_t count=0;
     uint8_t temp = data;
+    delay(1);
+	cbi(_pinCLK, _bitmaskCLK);
     for(count=0;count<8;count++) {
       if(temp&0x80) {
         sbi(_pinMOSI, _bitmaskMOSI);
@@ -217,7 +165,6 @@
       slow_pulse_low(_pinCLK, _bitmaskCLK);
     }
   }
-#endif
 }
 
 uint8_t DmTouch::spiRead() {// Only used for Hardware SPI
@@ -234,6 +181,7 @@
   } else {
     uint8_t count=0;
     uint8_t temp=0;
+    cbi(_pinCLK, _bitmaskCLK);
     cbi(_pinMOSI, _bitmaskMOSI); // same as using 0x00 as dummy byte
     for(count=0;count<8;count++) {
 
@@ -251,18 +199,18 @@
   uint16_t value = 0;
 
   spiWrite(command); // Send command
-//--------------
+
 #if defined (DM_TOOLCHAIN_ARDUINO)
   if (_hardwareSpi) {
     // We use 7-bits from the first byte and 5-bit from the second byte
     temp = spiRead();
     value = temp<<8;
     temp = spiRead();
-    value |= temp;
+
+	value |= temp;
     value >>=3;
     value &= 0xFFF;
-  }
-  else {
+  } else {
     pulse_high(_pinCLK, _bitmaskCLK);
     unsigned nop;
     uint8_t count=0;
@@ -286,53 +234,43 @@
   return value;
 }
 
-void DmTouch::readTouchData(uint16_t& posX, uint16_t& posY, bool& touching) {
+void DmTouch::readRawData(uint16_t &x, uint16_t &y) {
+  cbi(_pinCS, _bitmaskCS);
+  x = readData12(0xD0);
+  y = readData12(0x90);
+  sbi(_pinCS, _bitmaskCS);
+}
+
+void DmTouch::readTouchData(uint16_t& posX, uint16_t& posY, bool& touching) {  
 #if defined (DM_TOOLCHAIN_MBED)
   if (!isTouched()) {
     touching = false;
     return;
   }
-  //touching = true;
 #endif
-  unsigned int TP_X, TP_Y;
-  cbi(_pinCS, _bitmaskCS);
-
-  TP_X = readData12(0xD0);
-  TP_Y = readData12(0x90);
-
-  sbi(_pinCS, _bitmaskCS);
-
-//  Serial.print("Raw X: ");
-//  Serial.println(TP_X);
-//  Serial.print("Raw Y: ");
-//  Serial.println(TP_Y);
+  uint16_t touchX, touchY;
+  getMiddleXY(touchX,touchY);
 
-  // Convert raw data to screen positions
-  if (_calibInvertedTouch) {
-    posX=_width-((TP_X-_calibLowX)/_calibModifierX);
-    posY=_height-((TP_Y-_calibLowY)/_calibModifierY);
-  } else {
-    posX=((TP_X-_calibLowX)/_calibModifierX);
-    posY=((TP_Y-_calibLowY)/_calibModifierY);
-  }
-  //printf("Raw: %5u, %5u, Calibrated: %3u, %u\n", TP_X, TP_Y, posX, posY);
-
-//#if defined (DM_TOOLCHAIN_ARDUINO)
-  if (posX >= 0 && posX <= _width && posY >= 0 && posY <= _height) {
-    touching = true;
-  } else {
-    touching = false;
-  }
-//#endif
+  posX = getDisplayCoordinateX(touchX, touchY);
+  posY = getDisplayCoordinateY(touchX, touchY);
+  
+  touching = isTouched();
 }
 
-uint8_t DmTouch::isTouched() {
+bool DmTouch::isSampleValid() {
+  uint16_t sampleX,sampleY;
+  readRawData(sampleX,sampleY);
+  if (sampleX > 0 && sampleX < 4095 && sampleY > 0 && sampleY < 4095) {
+    return true;
+  } else {
+    return false;
+  }
+}
+
+bool DmTouch::isTouched() {
 #if defined (DM_TOOLCHAIN_ARDUINO)
   if (_irq == -1) {
-    uint16_t posX, posY;
-    bool touched;
-    readTouchData(posX, posY, touched);
-    return touched;
+    return isSampleValid();
   }
 
   if ( !gbi(_pinIrq, _bitmaskIrq) ) {
@@ -344,3 +282,98 @@
   return (*_pinIrq == 0);
 #endif
 }
+
+bool DmTouch::getMiddleXY(uint16_t &x, uint16_t &y) {
+  bool haveAllMeasurements  = true;
+  uint16_t valuesX[MEASUREMENTS];
+  uint16_t valuesY[MEASUREMENTS];
+  uint8_t nbrOfMeasurements = 0;
+
+  for (int i=0; i<MEASUREMENTS; i++) {
+    getAverageXY(valuesX[i], valuesY[i]);
+    nbrOfMeasurements++;
+    if (!isTouched()) {
+      haveAllMeasurements = false;
+      break;
+    }
+  }
+  x = calculateMiddleValue(valuesX, nbrOfMeasurements);
+  y = calculateMiddleValue(valuesY, nbrOfMeasurements);
+
+  return haveAllMeasurements;
+}
+
+void DmTouch::getAverageXY(uint16_t &x, uint16_t &y) {
+  uint32_t sumX = 0;
+  uint32_t sumY = 0;
+  uint16_t sampleX,sampleY;
+  readRawData(sampleX,sampleY);
+
+  for (int i=0; i<_samplesPerMeasurement; i++) {
+	readRawData(sampleX,sampleY);
+    sumX += sampleX;
+    sumY += sampleY;
+  }
+
+  x = (uint32_t)sumX/_samplesPerMeasurement;
+  y = (uint32_t)sumY/_samplesPerMeasurement;
+}
+
+// Total number of samples = MEASUREMENTS * _samplesPerMeasurement
+void DmTouch::setPrecison(uint8_t samplesPerMeasurement) {
+  _samplesPerMeasurement = samplesPerMeasurement;
+}
+
+void DmTouch::setCalibrationMatrix(CalibrationMatrix calibrationMatrix) {
+  _calibrationMatrix = calibrationMatrix;
+}
+
+void DmTouch::waitForTouch() {
+  while(!isTouched()) {}
+}
+
+void DmTouch::waitForTouchRelease() {
+  while(isTouched()) {}
+}
+
+uint16_t DmTouch::getDisplayCoordinateX(uint16_t x_touch, uint16_t y_touch) {
+  uint16_t Xd;
+  float temp;
+  temp = (_calibrationMatrix.a * x_touch + _calibrationMatrix.b * y_touch + _calibrationMatrix.c) / rescaleFactor();
+  Xd = (uint16_t)(temp);
+  if (Xd > 60000) {
+    Xd = 0;
+  }
+  return Xd;
+}
+
+uint16_t DmTouch::getDisplayCoordinateY(uint16_t x_touch, uint16_t y_touch) {
+  uint16_t Yd;
+  float temp;
+  temp = (_calibrationMatrix.d * x_touch + _calibrationMatrix.e * y_touch + _calibrationMatrix.f) / rescaleFactor();
+  Yd = (uint16_t)(temp);
+  if (Yd > 60000) {
+    Yd = 0;
+  }
+  return Yd;
+}
+
+uint16_t DmTouch::calculateMiddleValue(uint16_t values[], uint8_t count) {
+  uint16_t temp;
+
+  for(uint8_t i=0; i<count-1; i++) {
+    for(uint8_t j=i+1; j<count; j++) {
+      if(values[j] < values[i]) {
+        temp = values[i];
+        values[i] = values[j];
+        values[j] = temp;
+      }
+    }
+  }
+
+  if(count%2==0) {
+    return((values[count/2] + values[count/2 - 1]) / 2.0);
+  } else {
+    return values[count/2];
+  }
+}
--- a/DmTouch.h	Fri May 23 08:10:09 2014 +0000
+++ b/DmTouch.h	Fri Jul 04 09:26:32 2014 +0000
@@ -15,38 +15,58 @@
 
 #include "dm_platform.h"
 
+typedef struct calibrationMatrix {
+  int32_t  a, b, c,	d, e, f;
+} CalibrationMatrix;
+
 class DmTouch
 {
 public:
   enum Display {
-    DM_TFT28_103,
-    DM_TFT24_104,
-    DM_TFT28_105,
-	DM_TFT35_107,
+    DM_TFT28_103 = 103,
+    DM_TFT24_104 = 104,
+    DM_TFT28_105 = 105,
+	DM_TFT35_107 = 107
+  };
+
+  enum SpiMode {
+	Auto,
+	Software,
+	Hardware
   };
 
 #if defined (DM_TOOLCHAIN_ARDUINO)
-  DmTouch(Display disp, uint8_t cs, int8_t tIrq = -1, uint8_t hardwareSpi = 1, uint8_t clk = -1, uint8_t mosi = -1, uint8_t miso = -1, uint16_t width = 240, uint16_t height = 320);
+  DmTouch(Display disp, SpiMode spiMode=Auto, bool useIrq=true);
 #elif defined (DM_TOOLCHAIN_MBED)
-  DmTouch(Display disp, bool hardwareSPI=true);
+  DmTouch(Display disp, SpiMode spiMode=Hardware);
 #endif
   void init();
   void readTouchData(uint16_t& posX, uint16_t& posY, bool& touching);
-  uint8_t isTouched();
+  bool isTouched();
+  bool getMiddleXY(uint16_t &x, uint16_t &y); // Raw Touch Data, used for calibration
+  void setCalibrationMatrix(CalibrationMatrix calibrationMatrix);
+  void setPrecison(uint8_t samplesPerMeasurement);
+  void waitForTouch();
+  void waitForTouchRelease();
+  uint32_t rescaleFactor() { return 1000000; };
+
 private:
   void spiWrite(uint8_t data);
   uint8_t spiRead();
   uint16_t readData12(uint8_t command);
   void enableIrq();
-
-  uint16_t _width, _height;
-  uint8_t _cs, _clk, _mosi, _miso;
-  uint8_t _irq;
+  void readRawData(uint16_t &x, uint16_t &y);
+  void getAverageXY(uint16_t &x, uint16_t &y);
+  uint16_t getDisplayCoordinateX(uint16_t x_touch, uint16_t y_touch);
+  uint16_t getDisplayCoordinateY(uint16_t x_touch, uint16_t y_touch);
+  uint16_t calculateMiddleValue(uint16_t values[], uint8_t count);
+  bool isSampleValid();
 
-  int _calibLowX, _calibLowY;
-  float _calibModifierX, _calibModifierY;
-  bool _calibInvertedTouch;
   bool _hardwareSpi;
+  uint8_t _samplesPerMeasurement;
+  CalibrationMatrix _calibrationMatrix;
+  uint8_t _cs, _clk, _mosi, _miso;
+  int8_t _irq;
 
 #if defined (DM_TOOLCHAIN_ARDUINO)
   regtype *_pinDC, *_pinCS, *_pinCLK, *_pinMOSI, *_pinMISO, *_pinIrq;
@@ -60,7 +80,3 @@
 
 };
 #endif
-
-
-
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DmTouchCalibration.cpp	Fri Jul 04 09:26:32 2014 +0000
@@ -0,0 +1,264 @@
+/**********************************************************************************************
+ Copyright (c) 2014 DisplayModule. All rights reserved.
+
+ Redistribution and use of this source code, part of this source code or any compiled binary
+ based on this source code is permitted as long as the above copyright notice and following
+ disclaimer is retained.
+
+ DISCLAIMER:
+ THIS SOFTWARE IS SUPPLIED "AS IS" WITHOUT ANY WARRANTIES AND SUPPORT. DISPLAYMODULE ASSUMES
+ NO RESPONSIBILITY OR LIABILITY FOR THE USE OF THE SOFTWARE.
+ ********************************************************************************************/
+
+#include "DmTouchCalibration.h"
+
+DmTouchCalibration::DmTouchCalibration(DmTftBase *tftBase, DmTouch *touch) {
+  _tft = tftBase;
+  _touch = touch;
+  _textRow = 20;
+}
+
+// For best result, create a calibration for each display
+CalibrationMatrix DmTouchCalibration::getDefaultCalibrationData(DmTouch::Display disp) {
+  CalibrationMatrix calibrationMatrix = {0};
+  switch (disp) {
+    case DmTouch::DM_TFT28_103:
+      calibrationMatrix.a = 67548;    //    63787;
+      calibrationMatrix.b = -625;     //     -138;
+      calibrationMatrix.c = -16854644;//-15921157;
+      calibrationMatrix.d = 362;      //     -244;
+      calibrationMatrix.e = 89504;    //    89313;
+      calibrationMatrix.f = -14380636;//-10726623;
+      break;
+
+    case DmTouch::DM_TFT24_104:
+      calibrationMatrix.a = -71855;
+      calibrationMatrix.b = 2147;
+      calibrationMatrix.c = 259719524;
+      calibrationMatrix.d = -1339;
+      calibrationMatrix.e = -91012;
+      calibrationMatrix.f = 354268832;
+      break;
+
+    case DmTouch::DM_TFT28_105:
+      calibrationMatrix.a = 65521;
+      calibrationMatrix.b = -253;
+      calibrationMatrix.c = -11813673;
+      calibrationMatrix.d = -439;
+      calibrationMatrix.e = 89201;
+      calibrationMatrix.f = -10450920;
+      break;
+
+    case DmTouch::DM_TFT35_107:
+      calibrationMatrix.a = 91302;    //    85984;
+      calibrationMatrix.b = 817;      //      451;
+      calibrationMatrix.c = -26296117;//-16494041;
+      calibrationMatrix.d = -1877;    //     2308;
+      calibrationMatrix.e = 73762;    //    65173;
+      calibrationMatrix.f = -26384255;//-19179080;
+      break;
+
+    default:
+      break;
+  }
+  return calibrationMatrix;
+}
+
+
+bool DmTouchCalibration::getTouchReferencePoints(Point displayRefPoint[], Point touchRefPoint[], uint16_t tftWidth, uint16_t tftHeight) {
+  _touch->setPrecison(60);
+  displayRefPoint[0].x = (tftWidth / 2);
+  displayRefPoint[0].y = (tftHeight / 2);
+  displayRefPoint[1].x = 1 * (tftWidth / 5);
+  displayRefPoint[1].y = 1 * (tftHeight / 5);
+  displayRefPoint[2].x = 4 * (tftWidth / 5);
+  displayRefPoint[2].y = 1 * (tftHeight / 5);
+  displayRefPoint[3].x = 4 * (tftWidth / 5);
+  displayRefPoint[3].y = 4 * (tftHeight / 5);
+  displayRefPoint[4].x = 1 * (tftWidth / 5);
+  displayRefPoint[4].y = 4 * (tftHeight / 5);
+
+  for(int n = 0; n < 5; n++) {
+    drawCalibPoint(displayRefPoint[n].x, displayRefPoint[n].y);
+    if (!getRawTouch(touchRefPoint[n].x, touchRefPoint[n].y)) {
+      return false;
+    }
+    releaseTouch(displayRefPoint[n].x, displayRefPoint[n].y);
+  }
+
+  _touch->setPrecison(3);
+  return true;
+}
+
+bool DmTouchCalibration::getRawTouch(uint16_t& x, uint16_t& y) const {
+  bool touched = false;
+  bool hasAllSamples = false;
+
+  while(!touched) {
+    if (_touch->isTouched()) {
+      //Serial.println("is touched");
+      hasAllSamples = _touch->getMiddleXY(x, y);
+      touched = true;
+    }
+  }
+  return hasAllSamples;
+}
+
+void DmTouchCalibration::drawCalibPoint(uint16_t x, uint16_t y) const {
+  const uint8_t lineSize = 5;
+  _tft->drawHorizontalLine(x-lineSize, y, lineSize*2, RED);
+  _tft->drawVerticalLine(x, y-lineSize, lineSize*2, RED);
+}
+
+void DmTouchCalibration::releaseTouch(uint16_t x, uint16_t y) const {
+  _tft->drawCircle(x, y, 10, YELLOW);
+  delay(100);
+  _tft->fillCircle(x, y, 10, GREEN);
+  delay(100);
+  _tft->fillCircle(x, y, 10, BLACK);
+  delay(300);
+  _touch->waitForTouchRelease();
+}
+
+CalibrationMatrix DmTouchCalibration::calculateCalibrationMatrix(Point displayRefPoint[], Point touchRefPoint[]) {
+  double A = 0.0, B = 0.0, C = 0.0, D = 0.0, E = 0.0, F = 0.0;
+  double d = 0.0, dx1 = 0.0, dx2 = 0.0, dx3 = 0.0, dy1 = 0.0, dy2 = 0.0, dy3 = 0.0;
+  uint32_t X2_1 = 0, X2_2 = 0, X2_3 = 0, X2_4 = 0, X2_5 = 0;
+  uint32_t Y2_1 = 0, Y2_2 = 0, Y2_3 = 0, Y2_4 = 0, Y2_5 = 0;
+  uint32_t XxY_1 = 0, XxY_2 = 0, XxY_3 = 0, XxY_4 = 0, XxY_5 = 0;
+  uint32_t XxXd_1 = 0, XxXd_2 = 0, XxXd_3 = 0, XxXd_4 = 0, XxXd_5 = 0;
+  uint32_t YxXd_1 = 0, YxXd_2 = 0, YxXd_3 = 0, YxXd_4 = 0, YxXd_5 = 0;
+  uint32_t XxYd_1 = 0, XxYd_2 = 0, XxYd_3 = 0, XxYd_4 = 0, XxYd_5 = 0;
+  uint32_t YxYd_1 = 0, YxYd_2 = 0, YxYd_3 = 0, YxYd_4 = 0, YxYd_5 = 0;
+  uint32_t alfa = 0, beta = 0, chi = 0, Kx = 0, Ky = 0, Lx = 0, Ly = 0;
+  uint16_t epsilon = 0, fi = 0, Mx = 0, My = 0;
+
+  X2_1 = ((uint32_t)touchRefPoint[0].x * touchRefPoint[0].x);
+  X2_2 = ((uint32_t)touchRefPoint[1].x * touchRefPoint[1].x);
+  X2_3 = ((uint32_t)touchRefPoint[2].x * touchRefPoint[2].x);
+  X2_4 = ((uint32_t)touchRefPoint[3].x * touchRefPoint[3].x);
+  X2_5 = ((uint32_t)touchRefPoint[4].x * touchRefPoint[4].x);
+
+  Y2_1 = ((uint32_t)touchRefPoint[0].y * touchRefPoint[0].y);
+  Y2_2 = ((uint32_t)touchRefPoint[1].y * touchRefPoint[1].y);
+  Y2_3 = ((uint32_t)touchRefPoint[2].y * touchRefPoint[2].y);
+  Y2_4 = ((uint32_t)touchRefPoint[3].y * touchRefPoint[3].y);
+  Y2_5 = ((uint32_t)touchRefPoint[4].y * touchRefPoint[4].y);
+
+  XxY_1 = ((uint32_t)touchRefPoint[0].x * touchRefPoint[0].y);
+  XxY_2 = ((uint32_t)touchRefPoint[1].x * touchRefPoint[1].y);
+  XxY_3 = ((uint32_t)touchRefPoint[2].x * touchRefPoint[2].y);
+  XxY_4 = ((uint32_t)touchRefPoint[3].x * touchRefPoint[3].y);
+  XxY_5 = ((uint32_t)touchRefPoint[4].x * touchRefPoint[4].y);
+
+  XxXd_1 = ((uint32_t)touchRefPoint[0].x * displayRefPoint[0].x);
+  XxXd_2 = ((uint32_t)touchRefPoint[1].x * displayRefPoint[1].x);
+  XxXd_3 = ((uint32_t)touchRefPoint[2].x * displayRefPoint[2].x);
+  XxXd_4 = ((uint32_t)touchRefPoint[3].x * displayRefPoint[3].x);
+  XxXd_5 = ((uint32_t)touchRefPoint[4].x * displayRefPoint[4].x);
+
+  YxXd_1 = ((uint32_t)touchRefPoint[0].y * displayRefPoint[0].x);
+  YxXd_2 = ((uint32_t)touchRefPoint[1].y * displayRefPoint[1].x);
+  YxXd_3 = ((uint32_t)touchRefPoint[2].y * displayRefPoint[2].x);
+  YxXd_4 = ((uint32_t)touchRefPoint[3].y * displayRefPoint[3].x);
+  YxXd_5 = ((uint32_t)touchRefPoint[4].y * displayRefPoint[4].x);
+
+  XxYd_1 = ((uint32_t)touchRefPoint[0].x * displayRefPoint[0].y);
+  XxYd_2 = ((uint32_t)touchRefPoint[1].x * displayRefPoint[1].y);
+  XxYd_3 = ((uint32_t)touchRefPoint[2].x * displayRefPoint[2].y);
+  XxYd_4 = ((uint32_t)touchRefPoint[3].x * displayRefPoint[3].y);
+  XxYd_5 = ((uint32_t)touchRefPoint[4].x * displayRefPoint[4].y);
+
+  YxYd_1 = ((uint32_t)touchRefPoint[0].y * displayRefPoint[0].y);
+  YxYd_2 = ((uint32_t)touchRefPoint[1].y * displayRefPoint[1].y);
+  YxYd_3 = ((uint32_t)touchRefPoint[2].y * displayRefPoint[2].y);
+  YxYd_4 = ((uint32_t)touchRefPoint[3].y * displayRefPoint[3].y);
+  YxYd_5 = ((uint32_t)touchRefPoint[4].y * displayRefPoint[4].y);
+
+  alfa = X2_1 + X2_2 + X2_3 + X2_4 + X2_5;
+  beta = Y2_1 + Y2_2 + Y2_3 + Y2_4 + Y2_5;
+  chi = XxY_1 + XxY_2 + XxY_3 + XxY_4 + XxY_5;
+  epsilon = touchRefPoint[0].x + touchRefPoint[1].x + touchRefPoint[2].x + touchRefPoint[3].x + touchRefPoint[4].x;
+  fi = touchRefPoint[0].y + touchRefPoint[1].y + touchRefPoint[2].y + touchRefPoint[3].y + touchRefPoint[4].y;
+  Kx = XxXd_1 + XxXd_2 + XxXd_3 + XxXd_4 + XxXd_5;
+  Ky = XxYd_1 + XxYd_2 + XxYd_3 + XxYd_4 + XxYd_5;
+  Lx = YxXd_1 + YxXd_2 + YxXd_3 + YxXd_4 + YxXd_5;
+  Ly = YxYd_1 + YxYd_2 + YxYd_3 + YxYd_4 + YxYd_5;
+  Mx = displayRefPoint[0].x + displayRefPoint[1].x + displayRefPoint[2].x + displayRefPoint[3].x + displayRefPoint[4].x;
+  My = displayRefPoint[0].y + displayRefPoint[1].y + displayRefPoint[2].y + displayRefPoint[3].y + displayRefPoint[4].y;
+  d = 5 * ( ((double)alfa * beta) - ((double)chi * chi) ) + 2 * ((double)chi * epsilon * fi) - ((double)alfa * fi * fi ) - ( (double)beta * epsilon * epsilon );
+  dx1 = 5 * ( ((double)Kx * beta) - ((double)Lx * chi) ) + ((double)fi * ( ((double)Lx * epsilon) - ((double)Kx * fi) )) + ((double)Mx * ( ((double)chi * fi) - ((double)beta * epsilon) ));
+  dx2 = 5 * ( ((double)Lx * alfa) - ((double)Kx * chi) ) + ((double)epsilon * ( ((double)Kx * fi) - ((double)Lx * epsilon) )) + ((double)Mx * ( ((double)chi * epsilon) - ((double)alfa * fi) ));
+  dx3 = ((double)Kx * ( ((double)chi * fi) - ((double)beta * epsilon) )) + ((double)Lx * ( ((double)chi * epsilon) - ((double)alfa * fi) )) + ((double)Mx * ( ((double)alfa * beta) - ((double)chi * chi) ));
+  dy1 = 5 * ( ((double)Ky * beta) - ((double)Ly * chi) ) + ((double)fi * ( ((double)Ly * epsilon) - ((double)Ky * fi) )) + ((double)My * ( ((double)chi * fi) - ((double)beta * epsilon) ));
+  dy2 = 5 * ( ((double)Ly * alfa) - ((double)Ky * chi) ) + ((double)epsilon * ( ((double)Ky * fi) - ((double)Ly * epsilon) )) + ((double)My * ( ((double)chi * epsilon) - ((double)alfa * fi) ));
+  dy3 = ((double)Ky * ( ((double)chi * fi) - ((double)beta * epsilon) )) + ((double)Ly * ( ((double)chi * epsilon) - ((double)alfa * fi) )) + ((double)My * ( ((double)alfa * beta) - ((double)chi * chi) ));
+
+  A = dx1 / d;
+  B = dx2 / d;
+  C = dx3 / d;
+  D = dy1 / d;
+  E = dy2 / d;
+  F = dy3 / d;
+
+  CalibrationMatrix calibrationData;
+  calibrationData.a = (int32_t)(A * _touch->rescaleFactor());
+  calibrationData.b = (int32_t)(B * _touch->rescaleFactor());
+  calibrationData.c = (int32_t)(C * _touch->rescaleFactor());
+  calibrationData.d = (int32_t)(D * _touch->rescaleFactor());
+  calibrationData.e = (int32_t)(E * _touch->rescaleFactor());
+  calibrationData.f = (int32_t)(F * _touch->rescaleFactor());
+
+  return calibrationData;
+}
+
+void DmTouchCalibration::drawCalibration(CalibrationMatrix calibrationMatrix) {
+  printHeadline("CalibrationData: ");
+  printHeadline("a: ");
+  printNumber(calibrationMatrix.a);
+  printHeadline("b: ");
+  printNumber(calibrationMatrix.b);
+  printHeadline("c: ");
+  printNumber(calibrationMatrix.c);
+  printHeadline("d: ");
+  printNumber(calibrationMatrix.d);
+  printHeadline("e: ");
+  printNumber(calibrationMatrix.e);
+  printHeadline("f: ");
+  printNumber(calibrationMatrix.f);
+}
+
+void DmTouchCalibration::printHeadline(char* text) {
+  _textRow += 20;
+  _tft->drawString(5, _textRow, text);
+}
+
+void DmTouchCalibration::printNumber(int32_t number) const {
+  _tft->drawNumber(20, _textRow, number, 10, false);
+}
+
+void DmTouchCalibration::printCalibration(CalibrationMatrix calibrationMatrix) const {
+#if defined (DM_TOOLCHAIN_ARDUINO)
+  Serial.println(F("-------- Calibration data ------"));
+  Serial.println(F("CalibrationMatrix calibrationMatrix;"));
+  Serial.print(F("calibrationMatrix.a = "));
+  Serial.print(calibrationMatrix.a);
+  Serial.println(F(";"));
+  Serial.print(F("calibrationMatrix.b = "));
+  Serial.print(calibrationMatrix.b);
+  Serial.println(F(";"));
+  Serial.print(F("calibrationMatrix.c = "));
+  Serial.print(calibrationMatrix.c);
+  Serial.println(F(";"));
+  Serial.print(F("calibrationMatrix.d = "));
+  Serial.print(calibrationMatrix.d);
+  Serial.println(F(";"));
+  Serial.print(F("calibrationMatrix.e = "));
+  Serial.print(calibrationMatrix.e);
+  Serial.println(F(";"));
+  Serial.print(F("calibrationMatrix.f = "));
+  Serial.print(calibrationMatrix.f);
+  Serial.println(F(";"));
+  Serial.println("-------------------------------");
+#endif
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DmTouchCalibration.h	Fri Jul 04 09:26:32 2014 +0000
@@ -0,0 +1,43 @@
+/**********************************************************************************************
+ Copyright (c) 2014 DisplayModule. All rights reserved.
+
+ Redistribution and use of this source code, part of this source code or any compiled binary
+ based on this source code is permitted as long as the above copyright notice and following
+ disclaimer is retained.
+
+ DISCLAIMER:
+ THIS SOFTWARE IS SUPPLIED "AS IS" WITHOUT ANY WARRANTIES AND SUPPORT. DISPLAYMODULE ASSUMES
+ NO RESPONSIBILITY OR LIABILITY FOR THE USE OF THE SOFTWARE.
+ ********************************************************************************************/
+
+#ifndef DM_TOUCHCALIBRATION_h
+#define DM_TOUCHCALIBRATION_h
+
+#include "dm_platform.h"
+#include "DmTouch.h"
+#include "DmTftBase.h"
+
+typedef struct point {
+  uint16_t x, y;
+} Point;
+
+class DmTouchCalibration
+{
+public:
+  DmTouchCalibration(DmTftBase *tftBase, DmTouch *touch);
+  bool getTouchReferencePoints(Point displayRefPoint[], Point touchRefPoint[], uint16_t tftWidth, uint16_t tftHeight);
+  CalibrationMatrix calculateCalibrationMatrix(Point displayRefPoint[], Point touchRefPoint[]);
+  static CalibrationMatrix getDefaultCalibrationData(DmTouch::Display disp);
+  void drawCalibPoint(uint16_t x, uint16_t y) const;
+  void drawCalibration(CalibrationMatrix calibrationMatrix);
+  void printCalibration(CalibrationMatrix calibrationMatrix) const;
+private:
+  DmTftBase* _tft;
+  DmTouch* _touch;
+  uint16_t _textRow;
+  void printHeadline(char* text);
+  void printNumber(int32_t number) const ;
+  void releaseTouch(uint16_t x, uint16_t y) const;
+  bool getRawTouch(uint16_t& x, uint16_t& y) const;
+};
+#endif