Driver Library for our displays
Dependents: dm_bubbles dm_calc dm_paint dm_sdcard_with_adapter ... more
Revision 7:6cd8c36cbdb3, committed 2014-07-04
- 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
--- 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