Using touch screen features of LCD screen.

Dependencies:   DmTouch_UniGraphic UniGraphic mbed

Fork of DisplayModule24_demo by John Larkin

Files at this revision

API Documentation at this revision

Comitter:
JLarkin
Date:
Wed Jan 20 07:21:30 2016 +0000
Parent:
8:9484e01decd9
Child:
10:ca16a309a737
Commit message:
Revised DmTouch to work with UniGraphics, multiple screen orientations, and flexible mbed pins.

Changed in this revision

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
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DmTouch.cpp	Wed Jan 20 07:21:30 2016 +0000
@@ -0,0 +1,551 @@
+/**********************************************************************************************
+ 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.
+ ********************************************************************************************/
+// Tested with Xpt2046 and RA8875
+
+/* Modified by John M. Larkin, Whitworth University, to remove Arduino code */
+ 
+#include "DmTouch.h"
+//#include "DmTouchCalibration.h"
+ 
+#define MEASUREMENTS 10
+ 
+// disp        - which display is used
+// spiMode     - How to read SPI-data, Software, Hardware or Auto
+// (JML) Modify to include cs and irq as input parameters
+// (JML) Modify so doesn't assume Arduino shield
+// (JML) Using with mbed so assume hardware SPI available
+DmTouch::DmTouch(Display disp, PinName mosi, PinName miso, PinName clk, PinName cs, PinName irq)
+{
+    _disp = disp;
+    _cs = cs;
+    _irq = irq;
+    _clk = clk;
+    _mosi = mosi;
+    _miso = miso;
+    _hardwareSpi = true; 
+    switch (disp) {
+        // Display with 40-pin connector on top of adapter board
+        case DmTouch::DM_TFT28_103:
+        case DmTouch::DM_TFT24_104:  
+            _width = 240;
+            _height = 320;
+            _touch_id = IC_2046;
+            break;
+ 
+    case DmTouch::DM_TFT28_105:
+      _cs = D4;
+      _irq = D2;
+      _clk = D13;
+      _mosi = D11;
+      _miso = D12;
+      _width = 240;
+      _height = 320;
+      _hardwareSpi = true;
+      _touch_id = IC_2046;
+      break;
+ 
+    case DmTouch::DM_TFT35_107:
+      _cs = D4;
+      _irq = D2;
+      _clk = D13;
+      _mosi = D11;
+      _miso = D12;
+      _width = 320;
+      _height = 240;      
+      _hardwareSpi = true;
+      _touch_id = IC_2046;
+      break;
+ 
+    case DmTouch::DM_TFT43_108:  // or DM_TFT43_110
+      _cs = D10;
+      _irq = D2;
+      _clk = D13;
+      _mosi = D11;
+      _miso = D12;
+      _width = 480;
+      _height = 272;
+      _hardwareSpi = true;
+      _touch_id = IC_8875;
+      break;     
+      
+    case DmTouch::DM_TFT50_111:  // or  DM_TFT50_112
+      _cs = D10;
+      _irq = D2;
+      _clk = D13;
+      _mosi = D11;
+      _miso = D12;
+      _width = 800;
+      _height = 480;
+      _hardwareSpi = true;
+      _touch_id = IC_8875;
+      break;    
+      
+    default:
+      _cs = D4;
+      _irq = D2;
+      _clk = D13;
+      _mosi = D11;
+      _miso = D12;
+      _width = 320;
+      _height = 240;
+      _hardwareSpi = true;
+      _touch_id = IC_2046;
+      break;
+  }
+  
+  //setCalibrationMatrix(DmTouchCalibration::getDefaultCalibrationData(disp));
+  setCalibrationMatrix(DmTouch::getDefaultCalibrationData(disp));               // Use new local version
+ 
+  _samplesPerMeasurement = 3;
+}
+ 
+void DmTouch::init() {
+  _pinCS = new DigitalOut(_cs);
+  if (_hardwareSpi) {
+    sbi(_pinCS, _bitmaskCS);
+    _spi = new SPI((PinName)_mosi, (PinName)_miso, (PinName)_clk);
+    _spi->format(8,0);
+    _spi->frequency(2000000); // Max SPI speed    
+  } else {
+    _pinCLK = new DigitalOut(_clk);
+    _pinMISO = new DigitalIn(_miso);
+    _pinMOSI = new DigitalOut(_mosi);
+    sbi(_pinCLK, _bitmaskCLK);
+  }
+ 
+  if (_irq != NC) { // We will use Touch IRQ
+    enableIrq();
+  }
+}
+ 
+void DmTouch::enableIrq() {
+    _pinIrq = new DigitalIn((PinName)_irq);
+    _pinIrq->mode(PullUp);  
+    if(_touch_id == IC_8875) {
+        // enable touch panel
+        cbi(_pinCS, _bitmaskCS);
+        spiWrite(0x80);
+        spiWrite(0x70);
+        sbi(_pinCS, _bitmaskCS);
+ 
+        cbi(_pinCS, _bitmaskCS);
+        spiWrite(0x00);
+        spiWrite(0xB3);
+        sbi(_pinCS, _bitmaskCS);
+ 
+        // set auto mode
+        cbi(_pinCS, _bitmaskCS);
+        spiWrite(0x80);
+        spiWrite(0x71);
+        sbi(_pinCS, _bitmaskCS);
+ 
+        cbi(_pinCS, _bitmaskCS);
+        spiWrite(0x00);
+        spiWrite(0x04);
+        sbi(_pinCS, _bitmaskCS);
+ 
+        // enable touch panel interrupt
+        cbi(_pinCS, _bitmaskCS);
+        spiWrite(0x80);
+        spiWrite(0xF0);
+        sbi(_pinCS, _bitmaskCS);
+ 
+        cbi(_pinCS, _bitmaskCS);
+        uint8_t temp;
+        spiWrite(0x40);
+        temp = spiRead();
+        sbi(_pinCS, _bitmaskCS);
+ 
+        cbi(_pinCS, _bitmaskCS);
+        spiWrite(0x80);
+        spiWrite(0xF0);
+        sbi(_pinCS, _bitmaskCS);
+ 
+        cbi(_pinCS, _bitmaskCS);
+        spiWrite(0x00);
+        spiWrite(temp | 0x04);
+        sbi(_pinCS, _bitmaskCS);
+ 
+        // Clear TP INT Status
+        cbi(_pinCS, _bitmaskCS);
+        spiWrite(0x80);
+        spiWrite(0xF1);
+        sbi(_pinCS, _bitmaskCS);
+ 
+        cbi(_pinCS, _bitmaskCS);
+        spiWrite(0x00);
+        spiWrite(0x04);
+        sbi(_pinCS, _bitmaskCS);
+    } 
+    else{
+        cbi(_pinCS, _bitmaskCS);
+        spiWrite(0x80); // Enable PENIRQ
+        sbi(_pinCS, _bitmaskCS);
+    }      
+}
+ 
+void DmTouch::spiWrite(uint8_t data) {
+  if (_hardwareSpi) {
+    _spi->write(data);
+  }
+  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);
+      }
+      else {
+        cbi(_pinMOSI, _bitmaskMOSI);
+      }
+ 
+      temp=temp<<1;
+ 
+      slow_pulse_low(_pinCLK, _bitmaskCLK);
+    }
+  }
+}
+ 
+uint8_t DmTouch::spiRead() {// Only used for Hardware SPI
+  if (_hardwareSpi) {
+    return _spi->write(0x00); // dummy byte to read
+  } 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++) {
+ 
+      pulse_low(_pinCLK, _bitmaskCLK);
+      temp = temp<<1;
+      temp |= _pinMISO->read();
+    }
+    return temp;
+  }
+}
+ 
+uint16_t DmTouch::readData12(uint8_t command) {
+  uint8_t temp = 0;
+  uint16_t value = 0;
+ 
+  spiWrite(command); // Send command
+  // 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 >>=3;
+  value &= 0xFFF;
+  return value;
+}
+ 
+void DmTouch::readRawData(uint16_t &x, uint16_t &y) {
+  if(_touch_id == IC_8875){
+    uint16_t tx, ty;
+    uint8_t temp;
+ 
+    cbi(_pinCS, _bitmaskCS);
+    spiWrite(0x80);
+    spiWrite(0x72);
+    sbi(_pinCS, _bitmaskCS);
+    
+    cbi(_pinCS, _bitmaskCS);
+    spiWrite(0x40);
+    tx = spiRead();     
+    sbi(_pinCS, _bitmaskCS);
+ 
+    cbi(_pinCS, _bitmaskCS);
+    spiWrite(0x80);
+    spiWrite(0x73);     
+    sbi(_pinCS, _bitmaskCS);
+ 
+    cbi(_pinCS, _bitmaskCS);
+    spiWrite(0x40);
+    ty = spiRead();     
+    sbi(_pinCS, _bitmaskCS);
+ 
+    cbi(_pinCS, _bitmaskCS);
+    spiWrite(0x80);
+    spiWrite(0x74); 
+    sbi(_pinCS, _bitmaskCS);
+ 
+    cbi(_pinCS, _bitmaskCS);
+    spiWrite(0x40);
+    temp = spiRead();       
+    sbi(_pinCS, _bitmaskCS);
+            
+    tx <<= 2;
+    ty <<= 2;
+    tx |= temp & 0x03;              // get the bottom x bits
+    ty |= (temp >> 2) & 0x03; // get the bottom y bits
+            
+    x = tx;
+    y = ty;
+            
+    // Clear TP INT Status 
+    cbi(_pinCS, _bitmaskCS);
+    spiWrite(0x80);
+    spiWrite(0xF1);     
+    sbi(_pinCS, _bitmaskCS);
+ 
+    cbi(_pinCS, _bitmaskCS);
+    spiWrite(0x00);
+    spiWrite(0x04); 
+    sbi(_pinCS, _bitmaskCS);            
+  }
+  else{  
+    cbi(_pinCS, _bitmaskCS);
+    x = readData12(0xD0);
+    y = readData12(0x90);
+    sbi(_pinCS, _bitmaskCS);
+  }
+}
+ 
+void DmTouch::readTouchData(uint16_t& posX, uint16_t& posY, bool& touching) {  
+  uint16_t touchX, touchY;
+  getMiddleXY(touchX,touchY);
+  uint16_t screenX, screenY;
+ 
+  posX = getDisplayCoordinateX(touchX, touchY);
+  posY = getDisplayCoordinateY(touchX, touchY);
+  if(_touch_id == IC_8875) {
+    touching = isTouched() && (posX < _width && posY < _height);
+  }
+  else{
+    touching = (posX < _width && posY < _height);
+  }
+  // Now account for screen orientation and return in "screen coordinates"
+  switch(_orient) {
+        case 0:
+            screenX = posX;
+            screenY = posY;
+            break;
+        case 1:
+            screenX = posY;
+            screenY = _width-posX;
+            break;
+        case 2:
+            screenX = _width - posX;
+            screenY = _height - posY;
+            break;
+        case 3:
+            screenX = _height - posY;
+            screenY = posX;
+            break;
+        default:
+            screenX = posX;
+            screenY = posY;
+        }
+    posX = screenX;
+    posY = screenY;    
+}
+ 
+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(_touch_id == IC_8875) {
+        delay(1);
+        if (!_pinIrq->read()) {
+            // Clear TP INT Status
+            cbi(_pinCS, _bitmaskCS);
+            spiWrite(0x80);
+            spiWrite(0xF1);
+            sbi(_pinCS, _bitmaskCS);
+ 
+            cbi(_pinCS, _bitmaskCS);
+            spiWrite(0x00);
+            spiWrite(0x04);
+            sbi(_pinCS, _bitmaskCS);
+            return true;
+        } else {
+            return false;
+        }
+    }
+  return isSampleValid();
+}
+ 
+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(_touch_id != IC_8875) {
+      if (!isTouched()) {
+        haveAllMeasurements = false;
+        break;
+      }
+    }
+  }
+  if (haveAllMeasurements) {
+    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];
+  }
+}
+
+// (JML) Add a function to set screen orientation to match UniGraphics display feature
+void DmTouch::setOrientation(char orient) {
+    _orient = orient%4;
+}   
+
+
+/* Moved the default function to DmTouch rather than DmTouchCalibration as interim measure
+*/
+CalibrationMatrix DmTouch::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;
+    case DmTouch::DM_TFT43_108:   // or DM_TFT43_110
+      calibrationMatrix.a = 541307;
+      calibrationMatrix.b = -4288;
+      calibrationMatrix.c = -36678732;
+      calibrationMatrix.d = 2730;
+      calibrationMatrix.e = 321714;
+      calibrationMatrix.f = -31439472;    
+      break;
+    case DmTouch::DM_TFT50_111:   // or  DM_TFT50_112
+      calibrationMatrix.a = 875894;
+      calibrationMatrix.b = 1655;
+      calibrationMatrix.c = -53695309;
+      calibrationMatrix.d = -993;
+      calibrationMatrix.e = 544421;
+      calibrationMatrix.f = -41496753;                    
+      break;   
+    default:
+      break;
+  }
+  return calibrationMatrix;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DmTouch.h	Wed Jan 20 07:21:30 2016 +0000
@@ -0,0 +1,104 @@
+/**********************************************************************************************
+ 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_TOUCH_h
+#define DM_TOUCH_h
+ 
+#include "mbed.h"
+//#include "dm_platform.h"  // What is needed from dm_platform.h?
+
+#define sbi(reg, _bitmask) (*(reg) = 1)
+#define cbi(reg, _bitmask) (*(reg) = 0)
+#define delay(ms) wait_ms(ms)
+#define pulse_high(reg, _bitmask) do { *(reg) = 1; *(reg) = 0; } while(0)
+#define pulse_low(reg, _bitmask) do { *(reg) = 0; *(reg) = 1; } while(0)
+#define slow_pulse_high(reg, _bitmask) do {\
+   *(reg) = 1;    \
+   slow_pulse_delay(); \
+   *(reg) = 0;    \
+   slow_pulse_delay(); \
+} while(0)
+#define slow_pulse_low(reg, _bitmask) do {\
+   *(reg) = 0;    \
+   slow_pulse_delay(); \
+   *(reg) = 1;    \
+   slow_pulse_delay(); \
+} while(0)
+#define slow_pulse_delay()
+ 
+typedef struct calibrationMatrix {
+  int  a, b, c, d, e, f;
+} CalibrationMatrix;
+ 
+class DmTouch
+{
+public:
+  enum Display {
+    DM_TFT28_103 = 103,
+    DM_TFT24_104 = 104,
+    DM_TFT28_105 = 105,
+    DM_TFT35_107 = 107,
+    DM_TFT43_108 = 108,
+    DM_TFT50_111 = 111
+  };
+ 
+  enum SpiMode {
+    Auto,
+    Software,
+    Hardware
+  };
+  
+  enum TouchId{
+    IC_8875 = 0x8875,
+    IC_2046 = 0x2046        
+  };
+
+  DmTouch(Display disp, PinName mosi, PinName miso, PinName clk, PinName cs, PinName irq);      // Add cs and irq to input parameters
+  void init();
+  void readTouchData(uint16_t& posX, uint16_t& posY, bool& touching);
+  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; };
+  Display getDisplay() { return _disp; };
+  static CalibrationMatrix getDefaultCalibrationData(Display disp);                             // (JML) Added to this class because avoid DmTouchCalibration initially
+  void setOrientation(char orient);                                                             // Set screen orientation mode
+ 
+private:
+  void spiWrite(uint8_t data);
+  uint8_t spiRead();
+  uint16_t readData12(uint8_t command);
+  void enableIrq();
+  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();
+ 
+  Display _disp;
+  uint16_t _width, _height;
+  bool _hardwareSpi;
+  uint8_t _samplesPerMeasurement;
+  CalibrationMatrix _calibrationMatrix;
+  uint16_t _touch_id;
+  char _orient;                                                         // Adjust to changes in screen orientation
+ 
+  PinName _cs, _clk, _mosi, _miso, _irq;
+  DigitalOut *_pinDC, *_pinCS, *_pinCLK, *_pinMOSI, *_led;
+  DigitalIn *_pinMISO, *_pinIrq;
+  SPI *_spi;
+};
+#endif
\ No newline at end of file
--- a/main.cpp	Thu Jan 14 19:32:42 2016 +0000
+++ b/main.cpp	Wed Jan 20 07:21:30 2016 +0000
@@ -2,6 +2,8 @@
 #include "mbed.h"
 #include "string"
 #include "ILI932x.h"
+#include "DmTouch.h"
+
 
 #include "Arial12x12.h"
 #include "Arial24x23.h"
@@ -30,19 +32,37 @@
     
     p1          GND (L1)
     p40         Vin (L2)
+    p40         LED Backlight (L19)
 */  
 PinName dataBus[]= {p30, p29, p28, p27, p26, p25, p24, p23};
 ILI932x myLCD(BUS_8, dataBus, p15, p17, p16, p14, p20, "myLCD", 240, 320); // Bus 8 bit, bus pin array, CS, RST, DC, WR, RD, name, xpixels, ypixels
 
-char orient=3;
+/* Additional connections to add touch response
+
+    mbed pin    display pin
+    --------    -----------
+    p5          T_MOSI (R11)
+    p6          T_MISO (R13)
+    p7          T_CLK (R9)
+    p8          T_CS (R10)
+    p9          T_IRQ (R14)
+*/
+DmTouch touch(DmTouch::DM_TFT24_104, p5, p6, p7, p8, p9);
+
+char orient=0;
 int x,y;
+uint16_t tx, ty;
+Timer t;
 
 int main()
 {
+    bool down, lastDown;
+    touch.init();
+    t.start();
     myLCD.set_orientation(orient);
     myLCD.set_font((unsigned char*) Arial24x23);
-    myLCD.background(Blue);    // set background to red
-    myLCD.foreground(White);    // set chars to black
+    myLCD.background(Blue);    // set background to Blue
+    myLCD.foreground(White);    // set chars to White
     myLCD.cls();                // clear the screen
     myLCD.locate(10,30);
     myLCD.printf("UniGraphics Demo\r\n");
@@ -110,6 +130,53 @@
         }
         wait(3);
         
+        // Touch screen demo
+        myLCD.background(Blue);    // set background to Blue
+        myLCD.foreground(White);    // set chars to White
+        myLCD.cls();                // clear the screen
+        myLCD.locate(10,30);
+        myLCD.set_font((unsigned char*) Arial24x23);
+        myLCD.printf("DmTouch Demo\r\n");
+        myLCD.set_font((unsigned char*) Arial12x12);
+        myLCD.locate(10,70);
+        myLCD.printf("Coming soon...\r\nTouch screen and coordinates will display\r\n");
+        myLCD.printf("Moves to next portion of demo after 30 seconds\r\n");
+        wait(2);
+        myLCD.background(Black);    // set background to Black
+        myLCD.foreground(White);    // set chars to White
+        myLCD.cls();                // clear the screen
+
+        touch.setOrientation(orient);
+        down = false;
+        lastDown = false;
+        tx = (uint16_t)0;
+        ty = (uint16_t)0;
+        myLCD.locate(20,20);
+        myLCD.printf("x:");
+        myLCD.locate(100, 20);
+        myLCD.printf("y:");
+
+        t.reset();
+        while (t.read()<30) {
+            touch.readTouchData(tx, ty, down);
+            if (down) {
+                myLCD.locate(40, 20);
+                myLCD.printf("%5i", tx);
+                myLCD.locate(120, 20);
+                myLCD.printf("%5i", ty);
+                myLCD.fillcircle(tx, ty, 2, Red);
+            } else if (lastDown) {
+                // no longer pressed, clean text
+                myLCD.locate(40, 20);
+                myLCD.printf("     ", tx);
+                myLCD.locate(120, 20);
+                myLCD.printf("     ", ty);
+            }
+            wait(0.040);
+            lastDown = down;
+          }
+        
+        
     // scroll test, only for TFT
     myLCD.cls();
     myLCD.set_font((unsigned char*) Arial24x23);