From 09293ac73d85f592fcee7a53670b2749bdf41164 Mon Sep 17 00:00:00 2001
From: Stanley Huang <stanleyhuangyc@gmail.com>
Date: Tue, 17 May 2016 11:11:52 +1000
Subject: Added touch screen support for 3.2" and 3.5" LCD

---
 libraries/MultiLCD/MultiLCD.h  |  13 ++
 libraries/MultiLCD/R61581.cpp  | 312 +++++++++++++++++++++++++++--------------
 libraries/MultiLCD/SSD1289.cpp | 101 +++++++++++++
 3 files changed, 320 insertions(+), 106 deletions(-)

diff --git a/libraries/MultiLCD/MultiLCD.h b/libraries/MultiLCD/MultiLCD.h
index ddda23d..620023c 100644
--- a/libraries/MultiLCD/MultiLCD.h
+++ b/libraries/MultiLCD/MultiLCD.h
@@ -62,6 +62,9 @@ public:
     virtual void clear() {}
     virtual void begin() {}
     virtual void setCursor(byte column, byte line) {}
+    virtual byte readTouchData(int& x, int& y) { return 0; }
+    virtual int getScreenWidth() { return 320; }
+    virtual int getScreenHeight() { return 240; }
     void printInt(uint16_t value, int8_t padding = -1);
     void printLong(uint32_t value, int8_t padding = -1);
     void printSpace(byte n)
@@ -248,12 +251,16 @@ public:
         clear(0, line * TFT_LINE_HEIGHT, disp_y_size, 8);
     }
     void setBackLight(byte brightness);
+    void drawPixel(uint16_t poX, uint16_t poY, uint16_t color);
+    byte getTouchData(int& x, int& y);
 private:
     void setXY(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
     void writeDigit(byte n);
     void clearPixels(uint32_t pixels);
     void Enable();
     void Disable();
+    void shiftOutTouchData(unsigned char data);
+    unsigned int shiftInTouchData();
 };
 
 class LCD_R61581 : public UTFT, public LCD_Common, public Print
@@ -303,11 +310,17 @@ public:
         clear(0, line * TFT_LINE_HEIGHT, disp_y_size, 8);
     }
     void setBackLight(byte brightness);
+    void drawPixel(uint16_t poX, uint16_t poY, uint16_t color);
+    byte getTouchData(int& x, int& y);
+    int getScreenWidth() { return 480; }
+    int getScreenHeight() { return 320; }
 private:
     void setXY(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
     void writeDigit(byte n);
     void clearPixels(uint32_t pixels);
     void Enable();
     void Disable();
+    void shiftOutTouchData(unsigned char data);
+    unsigned int shiftInTouchData();
 };
 
diff --git a/libraries/MultiLCD/R61581.cpp b/libraries/MultiLCD/R61581.cpp
index 77c3e0c..ed5fd94 100644
--- a/libraries/MultiLCD/R61581.cpp
+++ b/libraries/MultiLCD/R61581.cpp
@@ -12,15 +12,27 @@
 Define zone
 **********************************************/
 
+#define PIN_CLK 6
+#define PIN_CS 5
+#define PIN_DIN 4
+#define PIN_DOUT 3
+#define PIN_IRQ 2
+
 #define PIN_BACKLIGHT 8
 
+#define PixSizeX	1143
+#define PixOffsX	1780
+
+#define PixSizeY	793
+#define PixOffsY	1380
 
 /**********************************************
 Standard C functions zone
 **********************************************/
 void LCD_R61581::begin()
 {
-    delay(50);
+	digitalWrite(PIN_BACKLIGHT, LOW);
+	delay(50);
 	pinMode(__p1,OUTPUT);
 	pinMode(__p2,OUTPUT);
 	pinMode(__p3,OUTPUT);
@@ -46,20 +58,20 @@ void LCD_R61581::begin()
 
 	cbi(P_CS, B_CS);
 
-		LCD_Write_COM(0xB0);		
-		LCD_Write_DATA(0x1E);	    
+	LCD_Write_COM(0xB0);		
+	LCD_Write_DATA(0x1E);	    
 
-		LCD_Write_COM(0xB0);
-		LCD_Write_DATA(0x00);
+	LCD_Write_COM(0xB0);
+	LCD_Write_DATA(0x00);
 
-		LCD_Write_COM(0xB3);
-		LCD_Write_DATA(0x02);
-		LCD_Write_DATA(0x00);
-		LCD_Write_DATA(0x00);
-		LCD_Write_DATA(0x10);
+	LCD_Write_COM(0xB3);
+	LCD_Write_DATA(0x02);
+	LCD_Write_DATA(0x00);
+	LCD_Write_DATA(0x00);
+	LCD_Write_DATA(0x10);
 
-		LCD_Write_COM(0xB4);
-		LCD_Write_DATA(0x00);//0X10
+	LCD_Write_COM(0xB4);
+	LCD_Write_DATA(0x00);//0X10
 
 // 		LCD_Write_COM(0xB9); //PWM Settings for Brightness Control
 // 		LCD_Write_DATA(0x01);// Disabled by default. 
@@ -67,93 +79,93 @@ void LCD_R61581::begin()
 // 		LCD_Write_DATA(0xFF);
 // 		LCD_Write_DATA(0x18);
 
-		LCD_Write_COM(0xC0);
-		LCD_Write_DATA(0x03);
-		LCD_Write_DATA(0x3B);//
-		LCD_Write_DATA(0x00);
-		LCD_Write_DATA(0x00);
-		LCD_Write_DATA(0x00);
-		LCD_Write_DATA(0x01);
-		LCD_Write_DATA(0x00);//NW
-		LCD_Write_DATA(0x43);
-
-		LCD_Write_COM(0xC1);
-		LCD_Write_DATA(0x08);
-		LCD_Write_DATA(0x15);//CLOCK
-		LCD_Write_DATA(0x08);
-		LCD_Write_DATA(0x08);
-
-		LCD_Write_COM(0xC4);
-		LCD_Write_DATA(0x15);
-		LCD_Write_DATA(0x03);
-		LCD_Write_DATA(0x03);
-		LCD_Write_DATA(0x01);
-
-		LCD_Write_COM(0xC6);
-		LCD_Write_DATA(0x02);
-
-		LCD_Write_COM(0xC8);
-		LCD_Write_DATA(0x0c);
-		LCD_Write_DATA(0x05);
-		LCD_Write_DATA(0x0A);//0X12
-		LCD_Write_DATA(0x6B);//0x7D
-		LCD_Write_DATA(0x04);
-		LCD_Write_DATA(0x06);//0x08
-		LCD_Write_DATA(0x15);//0x0A
-		LCD_Write_DATA(0x10);
-		LCD_Write_DATA(0x00);
-		LCD_Write_DATA(0x60);//0x23
- 
-		LCD_Write_COM(0x36);
-		LCD_Write_DATA(0x0A);
-
-		LCD_Write_COM(0x0C);
-		LCD_Write_DATA(0x55);
-
-		LCD_Write_COM(0x3A);
-		LCD_Write_DATA(0x55);
-
-		LCD_Write_COM(0x38);
- 
-		LCD_Write_COM(0xD0);
-		LCD_Write_DATA(0x07);
-		LCD_Write_DATA(0x07);//VCI1
-		LCD_Write_DATA(0x14);//VRH 0x1D
-		LCD_Write_DATA(0xA2);//BT 0x06
-
-		LCD_Write_COM(0xD1);
-		LCD_Write_DATA(0x03);
-		LCD_Write_DATA(0x5A);//VCM  0x5A
-		LCD_Write_DATA(0x10);//VDV
-
-		LCD_Write_COM(0xD2);
-		LCD_Write_DATA(0x03);
-		LCD_Write_DATA(0x04);//0x24
-		LCD_Write_DATA(0x04);
-
-		LCD_Write_COM(0x11);
-		delay(150);
-
-		LCD_Write_COM(0x2A);
-		LCD_Write_DATA(0x00);
-		LCD_Write_DATA(0x00);
-		LCD_Write_DATA(0x01);
-		LCD_Write_DATA(0xDF);//320
-
-		LCD_Write_COM(0x2B);
-		LCD_Write_DATA(0x00);
-		LCD_Write_DATA(0x00);
-		LCD_Write_DATA(0x01);
-		LCD_Write_DATA(0x3F);//480
-
- 
-		delay(100);
-
-		LCD_Write_COM(0x29);
-		delay(30);
-
-		LCD_Write_COM(0x2C);
-		delay(30);
+	LCD_Write_COM(0xC0);
+	LCD_Write_DATA(0x03);
+	LCD_Write_DATA(0x3B);//
+	LCD_Write_DATA(0x00);
+	LCD_Write_DATA(0x00);
+	LCD_Write_DATA(0x00);
+	LCD_Write_DATA(0x01);
+	LCD_Write_DATA(0x00);//NW
+	LCD_Write_DATA(0x43);
+
+	LCD_Write_COM(0xC1);
+	LCD_Write_DATA(0x08);
+	LCD_Write_DATA(0x15);//CLOCK
+	LCD_Write_DATA(0x08);
+	LCD_Write_DATA(0x08);
+
+	LCD_Write_COM(0xC4);
+	LCD_Write_DATA(0x15);
+	LCD_Write_DATA(0x03);
+	LCD_Write_DATA(0x03);
+	LCD_Write_DATA(0x01);
+
+	LCD_Write_COM(0xC6);
+	LCD_Write_DATA(0x02);
+
+	LCD_Write_COM(0xC8);
+	LCD_Write_DATA(0x0c);
+	LCD_Write_DATA(0x05);
+	LCD_Write_DATA(0x0A);//0X12
+	LCD_Write_DATA(0x6B);//0x7D
+	LCD_Write_DATA(0x04);
+	LCD_Write_DATA(0x06);//0x08
+	LCD_Write_DATA(0x15);//0x0A
+	LCD_Write_DATA(0x10);
+	LCD_Write_DATA(0x00);
+	LCD_Write_DATA(0x60);//0x23
+
+	LCD_Write_COM(0x36);
+	LCD_Write_DATA(0x0A);
+
+	LCD_Write_COM(0x0C);
+	LCD_Write_DATA(0x55);
+
+	LCD_Write_COM(0x3A);
+	LCD_Write_DATA(0x55);
+
+	LCD_Write_COM(0x38);
+
+	LCD_Write_COM(0xD0);
+	LCD_Write_DATA(0x07);
+	LCD_Write_DATA(0x07);//VCI1
+	LCD_Write_DATA(0x14);//VRH 0x1D
+	LCD_Write_DATA(0xA2);//BT 0x06
+
+	LCD_Write_COM(0xD1);
+	LCD_Write_DATA(0x03);
+	LCD_Write_DATA(0x5A);//VCM  0x5A
+	LCD_Write_DATA(0x10);//VDV
+
+	LCD_Write_COM(0xD2);
+	LCD_Write_DATA(0x03);
+	LCD_Write_DATA(0x04);//0x24
+	LCD_Write_DATA(0x04);
+
+	LCD_Write_COM(0x11);
+	delay(150);
+
+	LCD_Write_COM(0x2A);
+	LCD_Write_DATA(0x00);
+	LCD_Write_DATA(0x00);
+	LCD_Write_DATA(0x01);
+	LCD_Write_DATA(0xDF);//320
+
+	LCD_Write_COM(0x2B);
+	LCD_Write_DATA(0x00);
+	LCD_Write_DATA(0x00);
+	LCD_Write_DATA(0x01);
+	LCD_Write_DATA(0x3F);//480
+
+
+	delay(100);
+
+	LCD_Write_COM(0x29);
+	delay(30);
+
+	LCD_Write_COM(0x2C);
+	delay(30);
 
 	sbi (P_CS, B_CS);
 
@@ -161,16 +173,28 @@ void LCD_R61581::begin()
 
 	pinMode(PIN_BACKLIGHT, OUTPUT);
 	digitalWrite(PIN_BACKLIGHT, HIGH);
+
+	// init pins for touch controller
+	pinMode(PIN_CLK,  OUTPUT);
+	pinMode(PIN_CS,   OUTPUT);
+	pinMode(PIN_DIN,  OUTPUT);
+	pinMode(PIN_DOUT, INPUT);
+	pinMode(PIN_IRQ,  INPUT_PULLUP);
+
+	digitalWrite(PIN_CS,  HIGH);
+	digitalWrite(PIN_CLK, HIGH);
+	digitalWrite(PIN_DIN, HIGH);
+	digitalWrite(PIN_CLK, HIGH);
 }
 
 void LCD_R61581::setXY(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
 {
-    swap(word, x1, y1);
-    swap(word, x2, y2)
-    //y1=disp_y_size-y1;
-    //y2=disp_y_size-y2;
-    //swap(word, y1, y2)
-    // begin hardware specific code
+	swap(word, x1, y1);
+	swap(word, x2, y2)
+	//y1=disp_y_size-y1;
+	//y2=disp_y_size-y2;
+	//swap(word, y1, y2)
+	// begin hardware specific code
 	LCD_Write_COM(0x2a); 
 	LCD_Write_DATA(x1>>8);
 	LCD_Write_DATA(x1);
@@ -186,7 +210,7 @@ void LCD_R61581::setXY(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
 
 void LCD_R61581::setBackLight(byte brightness)
 {
-    analogWrite(PIN_BACKLIGHT, brightness);
+	analogWrite(PIN_BACKLIGHT, brightness);
 }
 
 void LCD_R61581::Enable()
@@ -198,6 +222,14 @@ void LCD_R61581::Disable()
     sbi(P_CS, B_CS);
 }
 
+void LCD_R61581::drawPixel(uint16_t poX, uint16_t poY,uint16_t color)
+{
+    Enable();
+    setXY(poX, poY, poX, poY);
+    setPixel(color);
+    Disable();
+}
+
 void LCD_R61581::clearPixels(uint32_t pixels)
 {
     Enable();
@@ -414,3 +446,71 @@ void LCD_R61581::draw4bpp(const PROGMEM byte* buffer, uint16_t width, uint16_t h
     Disable();
     m_x += width * 2;
 }
+
+void LCD_R61581::shiftOutTouchData(unsigned char data)
+{
+	unsigned char nop;
+	unsigned char count;
+
+	digitalWrite(PIN_CLK,LOW);
+
+	for(count=0; count<8; count++)
+	{
+		digitalWrite(PIN_DIN, data & 0x80 ? HIGH : LOW);
+		digitalWrite(PIN_CLK, LOW);                
+		nop++;
+		digitalWrite(PIN_CLK, HIGH);
+		data <<= 1; 
+		//nop++;
+	}
+}
+
+unsigned int LCD_R61581::shiftInTouchData()
+{
+	unsigned char nop;
+	unsigned int data = 0;
+	unsigned char count;
+	for(count=0; count<12; count++)
+	{
+		data <<= 1;
+		digitalWrite(PIN_CLK, HIGH);               
+		nop++;
+		digitalWrite(PIN_CLK, LOW);
+		//nop++;
+		data |= digitalRead(PIN_DOUT);
+	}
+	return data;
+}
+
+byte LCD_R61581::getTouchData(int& x, int& y)
+{
+	unsigned long tx = 0;
+	unsigned long ty = 0;
+
+	if (digitalRead(PIN_IRQ) == HIGH)
+		return 0;
+	
+	digitalWrite(PIN_CS,LOW);                    
+	for (int i=0; i < 10; i++)
+	{
+		shiftOutTouchData(0x90);        
+		digitalWrite(PIN_CLK,HIGH);
+		digitalWrite(PIN_CLK,LOW); 
+		int d = shiftInTouchData();
+		if (d >= 4000) {
+			digitalWrite(PIN_CS,HIGH);
+                     return 0;
+		}
+		ty += d;
+
+		shiftOutTouchData(0xD0);      
+		digitalWrite(PIN_CLK,HIGH);
+		digitalWrite(PIN_CLK,LOW);
+		tx+=shiftInTouchData();
+	}
+	digitalWrite(PIN_CS,HIGH);
+	x = 480 - (ty - PixOffsY) * 10 / PixSizeY;
+	y = (tx - PixOffsX) * 10 / PixSizeX;
+	return 1;
+}
+
diff --git a/libraries/MultiLCD/SSD1289.cpp b/libraries/MultiLCD/SSD1289.cpp
index 2fc8d8e..dab0b32 100644
--- a/libraries/MultiLCD/SSD1289.cpp
+++ b/libraries/MultiLCD/SSD1289.cpp
@@ -14,6 +14,21 @@ Define zone
 
 #define PIN_BACKLIGHT 8
 
+#define PIN_CLK 6
+#define PIN_CS 5
+#define PIN_DIN 4
+#define PIN_DOUT 3
+#define PIN_IRQ 2
+
+#define PREC_TOUCH_CONST 10
+
+#define PixSizeX	136
+#define PixOffsX	425
+
+#define PixSizeY	106
+#define PixOffsY	366
+
+
 /**********************************************
 Standard C functions zone
 **********************************************/
@@ -93,6 +108,19 @@ void LCD_SSD1289::begin()
 
 	pinMode(PIN_BACKLIGHT, OUTPUT);
 	digitalWrite(PIN_BACKLIGHT, HIGH);
+
+	// set up pins for touch controller
+	pinMode(PIN_CLK,  OUTPUT);
+	pinMode(PIN_CS,   OUTPUT);
+	pinMode(PIN_DIN,  OUTPUT);
+	pinMode(PIN_DOUT, INPUT);
+	pinMode(PIN_IRQ,  INPUT);
+
+	digitalWrite(PIN_CS,  HIGH);
+	digitalWrite(PIN_CLK, HIGH);
+	digitalWrite(PIN_DIN, HIGH);
+	digitalWrite(PIN_CLK, HIGH);
+
 }
 
 void LCD_SSD1289::setXY(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
@@ -125,6 +153,14 @@ void LCD_SSD1289::Disable()
     sbi(P_CS, B_CS);
 }
 
+void LCD_SSD1289::drawPixel(uint16_t poX, uint16_t poY,uint16_t color)
+{
+    Enable();
+    setXY(poX, poY, poX, poY);
+    setPixel(color);
+    Disable();
+}
+
 void LCD_SSD1289::clearPixels(uint32_t pixels)
 {
     Enable();
@@ -343,3 +379,68 @@ void LCD_SSD1289::draw4bpp(const PROGMEM byte* buffer, uint16_t width, uint16_t
     Disable();
     m_x += width * 2;
 }
+
+void LCD_SSD1289::shiftOutTouchData(unsigned char data)
+{
+	unsigned char nop;
+	unsigned char count;
+
+	digitalWrite(PIN_CLK,LOW);
+
+	for(count=0; count<8; count++)
+	{
+		digitalWrite(PIN_DIN, data & 0x80 ? HIGH : LOW);
+		digitalWrite(PIN_CLK, LOW);                
+		nop++;
+		digitalWrite(PIN_CLK, HIGH);
+		data <<= 1; 
+		//nop++;
+	}
+}
+
+unsigned int LCD_SSD1289::shiftInTouchData()
+{
+	unsigned char nop;
+	unsigned int data = 0;
+	unsigned char count;
+	for(count=0; count<12; count++)
+	{
+		data <<= 1;
+		digitalWrite(PIN_CLK, HIGH);               
+		nop++;
+		digitalWrite(PIN_CLK, LOW);
+		//nop++;
+		data |= digitalRead(PIN_DOUT);
+	}
+	return data;
+}
+
+byte LCD_SSD1289::getTouchData(int& x, int& y)
+{
+	long tx = 0;
+	long ty = 0;
+
+	if (digitalRead(PIN_IRQ) == HIGH)
+		return 0;
+	
+	digitalWrite(PIN_CS,LOW);                    
+	for (int i=0; i < PREC_TOUCH_CONST; i++)
+	{
+		shiftOutTouchData(0x90);        
+		digitalWrite(PIN_CLK,HIGH);
+		digitalWrite(PIN_CLK,LOW); 
+		int d = shiftInTouchData();
+		if (d < PixOffsY) return 0;
+		ty += d;
+
+		shiftOutTouchData(0xD0);      
+		digitalWrite(PIN_CLK,HIGH);
+		digitalWrite(PIN_CLK,LOW);
+		tx+=shiftInTouchData();
+	}
+	digitalWrite(PIN_CS,HIGH);
+	y = (tx - PixOffsX * PREC_TOUCH_CONST) / PixSizeX;
+	x = (ty - PixOffsY * PREC_TOUCH_CONST) / PixSizeY;
+	return 1;
+}
+
-- 
cgit v1.2.3